File indexing completed on 2024-05-12 04:38:11

0001 /*
0002     SPDX-FileCopyrightText: 2017 René J.V. Bertin <rjvbertin@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <interfaces/iplugin.h>
0008 #include <interfaces/icore.h>
0009 #include <interfaces/iplugincontroller.h>
0010 
0011 #include <project/abstractfilemanagerplugin.h>
0012 #include <project/projectmodel.h>
0013 
0014 #include <shell/projectcontroller.h>
0015 
0016 #include <tests/autotestshell.h>
0017 #include <tests/testcore.h>
0018 #include <tests/testproject.h>
0019 #include <tests/testplugincontroller.h>
0020 
0021 #include <util/path.h>
0022 
0023 #include <KJob>
0024 #include <KDirWatch>
0025 
0026 #include <QApplication>
0027 #include <QList>
0028 #include <QFileInfo>
0029 #include <QElapsedTimer>
0030 #include <QMap>
0031 #include <QDebug>
0032 #include <QTextStream>
0033 
0034 using namespace KDevelop;
0035 
0036 namespace KDevelop {
0037 // wrap the ProjectController to make its addProject() method public
0038 class ProjectControllerWrapper : public ProjectController
0039 {
0040     Q_OBJECT
0041 public:
0042     ProjectControllerWrapper(Core* core)
0043         : ProjectController(core)
0044     {}
0045 
0046     using ProjectController::addProject;
0047 };
0048 
0049 class AbstractFileManagerPluginImportBenchmark : public QObject
0050 {
0051     Q_OBJECT
0052 public:
0053     AbstractFileManagerPluginImportBenchmark(AbstractFileManagerPlugin* manager, const QString& path,
0054                                              TestCore* core)
0055         : QObject(core)
0056         , m_out(stdout)
0057         , m_core(core)
0058     {
0059         m_manager = manager;
0060         m_project = new TestProject(Path(path));
0061     }
0062 
0063     void start()
0064     {
0065         m_projectNumber = s_numBenchmarksRunning++;
0066         m_out << "Starting import of project " << m_project->path().toLocalFile() << Qt::endl;
0067         auto *projectController = qobject_cast<ProjectControllerWrapper*>(m_core->projectController());
0068         projectController->addProject(m_project);
0069         m_timer.start();
0070         auto root = m_manager->import(m_project);
0071         int elapsed = m_timer.elapsed();
0072         m_out << "\tcreating dirwatcher took " << elapsed / 1000.0 << " seconds" << Qt::endl;
0073         auto import = m_manager->createImportJob(root);
0074         connect(import, &KJob::finished,
0075             this, &AbstractFileManagerPluginImportBenchmark::projectImportDone);
0076         m_timer.restart();
0077         import->start();
0078     }
0079 
0080     AbstractFileManagerPlugin* m_manager;
0081     TestProject* m_project;
0082     QElapsedTimer m_timer;
0083     int m_projectNumber;
0084     QTextStream m_out;
0085     TestCore* m_core;
0086 
0087     static int s_numBenchmarksRunning;
0088 
0089 Q_SIGNALS:
0090     void finished();
0091 
0092 private Q_SLOTS:
0093     void projectImportDone(KJob* job)
0094     {
0095         Q_UNUSED(job);
0096         int elapsed = m_timer.elapsed();
0097         m_out << "importing " << m_project->fileSet().size() << " items into project #" << m_projectNumber << " took "
0098               << elapsed / 1000.0 << " seconds" << Qt::endl;
0099 
0100         s_numBenchmarksRunning -= 1;
0101         if (s_numBenchmarksRunning <= 0) {
0102             emit finished();
0103         }
0104     }
0105 
0106 };
0107 
0108 int AbstractFileManagerPluginImportBenchmark::s_numBenchmarksRunning = 0;
0109 }
0110 
0111 int main(int argc, char** argv)
0112 {
0113     if (argc < 2) {
0114         qWarning() << "Usage:" << argv[0] << "projectDir1 [...projectDirN]";
0115         return 1;
0116     }
0117     QApplication app(argc, argv);
0118     QTextStream qout(stdout);
0119     // measure the total test time, this provides an indication
0120     // of overhead and how well multiple projects are imported in parallel
0121     // (= how different is the total time from the import time of the largest
0122     // project). When testing a single project the difference between this
0123     // value and total runtime will provide an estimate of the time required
0124     // to destroy the dirwatcher.
0125     QElapsedTimer runTimer;
0126 
0127     AutoTestShell::init({"no plugins"});
0128     auto core = TestCore::initialize();
0129     // load/activate the "Project Filter" plugin (it won't be available to us without this step):
0130     core->pluginController()->allPluginsForExtension(QStringLiteral("org.kdevelop.IProjectFilter"));
0131     auto projectController = new ProjectControllerWrapper(core);
0132     delete core->projectController();
0133     core->setProjectController(projectController);
0134     auto manager = new AbstractFileManagerPlugin({}, core);
0135 
0136     const char *kdwMethod[] = {"FAM", "Inotify", "Stat", "QFSWatch"};
0137     qout << "KDirWatch backend: " << kdwMethod[KDirWatch().internalMethod()] << Qt::endl;
0138 
0139     QList<AbstractFileManagerPluginImportBenchmark*> benchmarks;
0140 
0141     for (int i = 1 ; i < argc ; ++i) {
0142         const QString path = QString::fromUtf8(argv[i]);
0143         if (QFileInfo(path).isDir()) {
0144             const auto benchmark = new AbstractFileManagerPluginImportBenchmark(manager, path, core);
0145             benchmarks << benchmark;
0146             QObject::connect(benchmark, &AbstractFileManagerPluginImportBenchmark::finished,
0147                              &app, [&runTimer, &qout] {
0148                                 qout << "Done in " << runTimer.elapsed() / 1000.0
0149                                     << " seconds total\n";
0150                                 QCoreApplication::instance()->quit();
0151                              });
0152         }
0153     }
0154 
0155     if (benchmarks.isEmpty()) {
0156         qWarning() << "no projects to import (arguments must be directories)";
0157         return 1;
0158     }
0159 
0160     runTimer.start();
0161     for (auto benchmark : qAsConst(benchmarks)) {
0162         benchmark->start();
0163     }
0164 
0165     return app.exec();
0166 }
0167 
0168 #include "abstractfilemanagerpluginimportbenchmark.moc"