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"