Changeset View
Standalone View
kdevplatform/project/tests/abstractfilemanagerpluginimportbenchmark.cpp
Show All 11 Lines | 1 | /* This file is part of KDevelop | |||
---|---|---|---|---|---|
12 | Library General Public License for more details. | 12 | Library General Public License for more details. | ||
13 | 13 | | |||
14 | You should have received a copy of the GNU Library General Public License | 14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this library; see the file COPYING.LIB. If not, write to | 15 | along with this library; see the file COPYING.LIB. If not, write to | ||
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301, USA. | 17 | Boston, MA 02110-1301, USA. | ||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include <interfaces/iplugin.h> | ||||
21 | #include <interfaces/icore.h> | ||||
22 | #include <interfaces/iplugincontroller.h> | ||||
23 | | ||||
20 | #include <project/abstractfilemanagerplugin.h> | 24 | #include <project/abstractfilemanagerplugin.h> | ||
21 | #include <project/projectmodel.h> | 25 | #include <project/projectmodel.h> | ||
22 | 26 | | |||
27 | #include <shell/projectcontroller.h> | ||||
28 | | ||||
23 | #include <tests/autotestshell.h> | 29 | #include <tests/autotestshell.h> | ||
24 | #include <tests/testcore.h> | 30 | #include <tests/testcore.h> | ||
25 | #include <tests/testproject.h> | 31 | #include <tests/testproject.h> | ||
32 | #include <tests/testplugincontroller.h> | ||||
26 | 33 | | |||
27 | #include <util/path.h> | 34 | #include <util/path.h> | ||
28 | 35 | | |||
29 | #include <KJob> | 36 | #include <KJob> | ||
30 | #include <KDirWatch> | 37 | #include <KDirWatch> | ||
31 | 38 | | |||
32 | #include <QCoreApplication> | 39 | #include <QApplication> | ||
33 | #include <QList> | 40 | #include <QList> | ||
34 | #include <QFileInfo> | 41 | #include <QFileInfo> | ||
35 | #include <QElapsedTimer> | 42 | #include <QElapsedTimer> | ||
36 | #include <QMap> | 43 | #include <QMap> | ||
37 | #include <QDebug> | 44 | #include <QDebug> | ||
38 | #include <QTextStream> | 45 | #include <QTextStream> | ||
39 | 46 | | |||
40 | using namespace KDevelop; | 47 | using namespace KDevelop; | ||
41 | 48 | | |||
42 | namespace KDevelop { | 49 | namespace KDevelop { | ||
43 | 50 | | |||
51 | // wrap the ProjectController to make its addProject() method public | ||||
52 | class ProjectControllerWrapper : public ProjectController | ||||
53 | { | ||||
54 | Q_OBJECT | ||||
55 | public: | ||||
56 | ProjectControllerWrapper(Core* core) | ||||
57 | : ProjectController(core) | ||||
58 | {} | ||||
59 | | ||||
60 | using ProjectController::addProject; | ||||
61 | }; | ||||
62 | | ||||
44 | class AbstractFileManagerPluginImportBenchmark : public QObject | 63 | class AbstractFileManagerPluginImportBenchmark : public QObject | ||
45 | { | 64 | { | ||
46 | Q_OBJECT | 65 | Q_OBJECT | ||
47 | public: | 66 | public: | ||
48 | AbstractFileManagerPluginImportBenchmark(AbstractFileManagerPlugin* manager, const QString& path, | 67 | AbstractFileManagerPluginImportBenchmark(AbstractFileManagerPlugin* manager, const QString& path, | ||
49 | QObject* parent) | 68 | TestCore* core) | ||
50 | : QObject(parent) | 69 | : QObject(core) | ||
51 | , m_out(stdout) | 70 | , m_out(stdout) | ||
71 | , m_core(core) | ||||
52 | { | 72 | { | ||
53 | m_manager = manager; | 73 | m_manager = manager; | ||
54 | m_project = new TestProject(Path(path)); | 74 | m_project = new TestProject(Path(path)); | ||
55 | } | 75 | } | ||
56 | 76 | | |||
57 | void start() | 77 | void start() | ||
58 | { | 78 | { | ||
59 | m_projectNumber = s_numBenchmarksRunning++; | 79 | m_projectNumber = s_numBenchmarksRunning++; | ||
60 | m_out << "Starting import of project " << m_project->path().toLocalFile() << endl; | 80 | m_out << "Starting import of project " << m_project->path().toLocalFile() << endl; | ||
81 | ProjectControllerWrapper *projectController = qobject_cast<ProjectControllerWrapper*>(m_core->projectController()); | ||||
mwolff: why is this required? | |||||
It replaces a full-blown ProjectController initialisation, and tells the ProjectFilterProvider to set up the project filter. Without that signal, the filter doesn't do its full job (it only filters out the .kdev4 directories). I tried setting up the ProjectController, but got crashes while plugins were being loaded that aren't of interest anyway, and in addition we'd have to import the test projects through the ProjectController in order for it to send out that signal. I don't think we want that here. rjvbb: It replaces a full-blown ProjectController initialisation, and tells the ProjectFilterProvider… | |||||
hm, I'd prefer using the actual controller setup as that is less brittle. I.e. if anything changes in the future, this will silently break, most probably. mwolff: hm, I'd prefer using the actual controller setup as that is less brittle. I.e. if anything… | |||||
82 | projectController->addProject(m_project); | ||||
assert the project controller, always add the project, remove the else branch mwolff: assert the project controller, always add the project, remove the else branch | |||||
61 | m_timer.start(); | 83 | m_timer.start(); | ||
62 | auto root = m_manager->import(m_project); | 84 | auto root = m_manager->import(m_project); | ||
63 | int elapsed = m_timer.elapsed(); | 85 | int elapsed = m_timer.elapsed(); | ||
64 | m_out << "\tcreating dirwatcher took " | 86 | m_out << "\tcreating dirwatcher took " | ||
65 | << elapsed / 1000.0 << " seconds" << endl; | 87 | << elapsed / 1000.0 << " seconds" << endl; | ||
66 | auto import = m_manager->createImportJob(root); | 88 | auto import = m_manager->createImportJob(root); | ||
67 | connect(import, &KJob::finished, | 89 | connect(import, &KJob::finished, | ||
68 | this, &AbstractFileManagerPluginImportBenchmark::projectImportDone); | 90 | this, &AbstractFileManagerPluginImportBenchmark::projectImportDone); | ||
69 | m_timer.restart(); | 91 | m_timer.restart(); | ||
70 | import->start(); | 92 | import->start(); | ||
71 | } | 93 | } | ||
72 | 94 | | |||
73 | AbstractFileManagerPlugin* m_manager; | 95 | AbstractFileManagerPlugin* m_manager; | ||
74 | TestProject* m_project; | 96 | TestProject* m_project; | ||
75 | QElapsedTimer m_timer; | 97 | QElapsedTimer m_timer; | ||
76 | int m_projectNumber; | 98 | int m_projectNumber; | ||
77 | QTextStream m_out; | 99 | QTextStream m_out; | ||
100 | TestCore* m_core; | ||||
78 | 101 | | |||
79 | static int s_numBenchmarksRunning; | 102 | static int s_numBenchmarksRunning; | ||
80 | 103 | | |||
81 | Q_SIGNALS: | 104 | Q_SIGNALS: | ||
82 | void finished(); | 105 | void finished(); | ||
83 | 106 | | |||
84 | private Q_SLOTS: | 107 | private Q_SLOTS: | ||
85 | void projectImportDone(KJob* job) | 108 | void projectImportDone(KJob* job) | ||
86 | { | 109 | { | ||
87 | Q_UNUSED(job); | 110 | Q_UNUSED(job); | ||
88 | int elapsed = m_timer.elapsed(); | 111 | int elapsed = m_timer.elapsed(); | ||
89 | m_out << "importing project " << m_projectNumber << " took " | 112 | m_out << "importing " << m_project->fileSet().size() | ||
90 | << elapsed / 1000.0 << " seconds" << endl; | 113 | << " items into project #" << m_projectNumber | ||
114 | << " took " << elapsed / 1000.0 << " seconds" << endl; | ||||
91 | 115 | | |||
92 | s_numBenchmarksRunning -= 1; | 116 | s_numBenchmarksRunning -= 1; | ||
93 | if (s_numBenchmarksRunning <= 0) { | 117 | if (s_numBenchmarksRunning <= 0) { | ||
94 | emit finished(); | 118 | emit finished(); | ||
95 | } | 119 | } | ||
96 | } | 120 | } | ||
97 | 121 | | |||
98 | }; | 122 | }; | ||
99 | 123 | | |||
100 | int AbstractFileManagerPluginImportBenchmark::s_numBenchmarksRunning = 0; | 124 | int AbstractFileManagerPluginImportBenchmark::s_numBenchmarksRunning = 0; | ||
101 | } | 125 | } | ||
102 | 126 | | |||
103 | int main(int argc, char** argv) | 127 | int main(int argc, char** argv) | ||
104 | { | 128 | { | ||
105 | if (argc < 2) { | 129 | if (argc < 2) { | ||
106 | qWarning() << "Usage:" << argv[0] << "projectDir1 [...projectDirN]"; | 130 | qWarning() << "Usage:" << argv[0] << "projectDir1 [...projectDirN]"; | ||
107 | return 1; | 131 | return 1; | ||
108 | } | 132 | } | ||
109 | QCoreApplication app(argc, argv); | 133 | QApplication app(argc, argv); | ||
110 | QTextStream qout(stdout); | 134 | QTextStream qout(stdout); | ||
111 | // measure the total test time, this provides an indication | 135 | // measure the total test time, this provides an indication | ||
112 | // of overhead and how well multiple projects are imported in parallel | 136 | // of overhead and how well multiple projects are imported in parallel | ||
113 | // (= how different is the total time from the import time of the largest | 137 | // (= how different is the total time from the import time of the largest | ||
114 | // project). When testing a single project the difference between this | 138 | // project). When testing a single project the difference between this | ||
115 | // value and total runtime will provide an estimate of the time required | 139 | // value and total runtime will provide an estimate of the time required | ||
116 | // to destroy the dirwatcher. | 140 | // to destroy the dirwatcher. | ||
117 | QElapsedTimer runTimer; | 141 | QElapsedTimer runTimer; | ||
118 | 142 | | |||
119 | AutoTestShell::init({"no plugins"}); | 143 | AutoTestShell::init({"no plugins"}); | ||
120 | auto core = TestCore::initialize(Core::NoUi); | 144 | auto core = TestCore::initialize(); | ||
145 | // load/activate the "Project Filter" plugin (it won't be available to us without this step): | ||||
mwolff: this isn't needed anymore, is it? i.e. it should never happen? | |||||
I suppose it should indeed never happen. The call itself is required though (I checked again), and if it fails it will do so quietly and results will be for project import without filtering. I wouldn't mind putting an assert here, but a version that doesn't disappear in release builds. rjvbb: I suppose it should indeed never happen. The call itself is required though (I checked again)… | |||||
mwolff: I'd say remove it | |||||
mwolff: why is this required to be done explictly? add a comment | |||||
146 | core->pluginController()->allPluginsForExtension(QStringLiteral("org.kdevelop.IProjectFilter")); | ||||
147 | auto projectController = new ProjectControllerWrapper(core); | ||||
148 | delete core->projectController(); | ||||
149 | core->setProjectController(projectController); | ||||
121 | auto manager = new AbstractFileManagerPlugin({}, core); | 150 | auto manager = new AbstractFileManagerPlugin({}, core); | ||
122 | 151 | | |||
123 | const char *kdwMethod[] = {"FAM", "Inotify", "Stat", "QFSWatch"}; | 152 | const char *kdwMethod[] = {"FAM", "Inotify", "Stat", "QFSWatch"}; | ||
124 | qout << "KDirWatch backend: " << kdwMethod[KDirWatch().internalMethod()] << endl; | 153 | qout << "KDirWatch backend: " << kdwMethod[KDirWatch().internalMethod()] << endl; | ||
125 | 154 | | |||
126 | QList<AbstractFileManagerPluginImportBenchmark*> benchmarks; | 155 | QList<AbstractFileManagerPluginImportBenchmark*> benchmarks; | ||
127 | 156 | | |||
128 | for (int i = 1 ; i < argc ; ++i) { | 157 | for (int i = 1 ; i < argc ; ++i) { | ||
Show All 27 Lines |
why is this required?