Changeset View
Changeset View
Standalone View
Standalone View
plugins/cmake/testing/ctestrunjob.cpp
Show All 24 Lines | |||||
25 | #include <interfaces/ilaunchconfiguration.h> | 25 | #include <interfaces/ilaunchconfiguration.h> | ||
26 | #include <interfaces/icore.h> | 26 | #include <interfaces/icore.h> | ||
27 | #include <interfaces/itestcontroller.h> | 27 | #include <interfaces/itestcontroller.h> | ||
28 | #include <interfaces/iruncontroller.h> | 28 | #include <interfaces/iruncontroller.h> | ||
29 | #include <interfaces/ilauncher.h> | 29 | #include <interfaces/ilauncher.h> | ||
30 | #include <interfaces/launchconfigurationtype.h> | 30 | #include <interfaces/launchconfigurationtype.h> | ||
31 | #include <interfaces/ilaunchmode.h> | 31 | #include <interfaces/ilaunchmode.h> | ||
32 | #include <util/executecompositejob.h> | 32 | #include <util/executecompositejob.h> | ||
33 | #include <outputview/outputmodel.h> | ||||
33 | 34 | | |||
34 | #include <KConfigGroup> | 35 | #include <KConfigGroup> | ||
35 | #include <KLocalizedString> | 36 | #include <KLocalizedString> | ||
36 | 37 | | |||
37 | using namespace KDevelop; | 38 | using namespace KDevelop; | ||
38 | 39 | | |||
39 | CTestRunJob::CTestRunJob(CTestSuite* suite, const QStringList& cases, OutputJob::OutputJobVerbosity verbosity, QObject* parent) | 40 | CTestRunJob::CTestRunJob(CTestSuite* suite, const QStringList& cases, OutputJob::OutputJobVerbosity verbosity, QObject* parent) | ||
40 | : KJob(parent) | 41 | : KJob(parent) | ||
41 | , m_suite(suite) | 42 | , m_suite(suite) | ||
42 | , m_cases(cases) | 43 | , m_cases(cases) | ||
43 | , m_job(nullptr) | 44 | , m_job(nullptr) | ||
44 | , m_outputJob(nullptr) | 45 | , m_outputModel(nullptr) | ||
45 | , m_verbosity(verbosity) | 46 | , m_verbosity(verbosity) | ||
46 | { | 47 | { | ||
47 | foreach (const QString& testCase, cases) | 48 | foreach (const QString& testCase, cases) | ||
48 | { | 49 | { | ||
49 | m_caseResults[testCase] = TestResult::NotRun; | 50 | m_caseResults[testCase] = TestResult::NotRun; | ||
50 | } | 51 | } | ||
51 | 52 | | |||
52 | setCapabilities(Killable); | 53 | setCapabilities(Killable); | ||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Line(s) | 108 | // setStandardToolView(IOutputView::RunView); | |||
114 | 115 | | |||
115 | QStringList cases_selected = arguments; | 116 | QStringList cases_selected = arguments; | ||
116 | arguments.prepend(m_suite->executable().toLocalFile()); | 117 | arguments.prepend(m_suite->executable().toLocalFile()); | ||
117 | const QString workingDirectory = m_suite->properties().value(QLatin1String("WORKING_DIRECTORY"), QString()); | 118 | const QString workingDirectory = m_suite->properties().value(QLatin1String("WORKING_DIRECTORY"), QString()); | ||
118 | 119 | | |||
119 | m_job = createTestJob(QStringLiteral("execute"), arguments, workingDirectory); | 120 | m_job = createTestJob(QStringLiteral("execute"), arguments, workingDirectory); | ||
120 | 121 | | |||
121 | if (ExecuteCompositeJob* cjob = qobject_cast<ExecuteCompositeJob*>(m_job)) { | 122 | if (ExecuteCompositeJob* cjob = qobject_cast<ExecuteCompositeJob*>(m_job)) { | ||
122 | m_outputJob = cjob->findChild<OutputJob*>(); | 123 | OutputJob* outputJob = cjob->findChild<OutputJob*>(); | ||
123 | Q_ASSERT(m_outputJob); | 124 | Q_ASSERT(outputJob); | ||
124 | m_outputJob->setVerbosity(m_verbosity); | 125 | outputJob->setVerbosity(m_verbosity); | ||
125 | 126 | | |||
126 | QString testName = m_suite->name(); | 127 | QString testName = m_suite->name(); | ||
127 | QString title; | 128 | QString title; | ||
128 | if (cases_selected.count() == 1) | 129 | if (cases_selected.count() == 1) | ||
129 | title = i18nc("running test %1, %2 test case", "CTest %1: %2", testName, cases_selected.value(0)); | 130 | title = i18nc("running test %1, %2 test case", "CTest %1: %2", testName, cases_selected.value(0)); | ||
130 | else | 131 | else | ||
131 | title = i18ncp("running test %1, %2 number of test cases", "CTest %2 (%1)", "CTest %2 (%1)", cases_selected.count(), testName); | 132 | title = i18ncp("running test %1, %2 number of test cases", "CTest %2 (%1)", "CTest %2 (%1)", cases_selected.count(), testName); | ||
132 | 133 | | |||
133 | m_outputJob->setTitle(title); | 134 | outputJob->setTitle(title); | ||
134 | 135 | | |||
135 | connect(m_outputJob->model(), &QAbstractItemModel::rowsInserted, this, &CTestRunJob::rowsInserted); | 136 | m_outputModel = qobject_cast<OutputModel*>(outputJob->model()); | ||
137 | connect(m_outputModel, &QAbstractItemModel::rowsInserted, this, &CTestRunJob::rowsInserted); | ||||
136 | } | 138 | } | ||
137 | connect(m_job, &KJob::finished, this, &CTestRunJob::processFinished); | 139 | connect(m_job, &KJob::finished, this, &CTestRunJob::processFinished); | ||
138 | 140 | | |||
139 | ICore::self()->testController()->notifyTestRunStarted(m_suite, cases_selected); | 141 | ICore::self()->testController()->notifyTestRunStarted(m_suite, cases_selected); | ||
140 | } | 142 | } | ||
141 | 143 | | |||
142 | bool CTestRunJob::doKill() | 144 | bool CTestRunJob::doKill() | ||
143 | { | 145 | { | ||
144 | if (m_job) | 146 | if (m_job) | ||
145 | { | 147 | { | ||
146 | m_job->kill(); | 148 | m_job->kill(); | ||
147 | } | 149 | } | ||
148 | return true; | 150 | return true; | ||
149 | } | 151 | } | ||
150 | 152 | | |||
151 | void CTestRunJob::processFinished(KJob* job) | 153 | void CTestRunJob::processFinished(KJob* job) | ||
152 | { | 154 | { | ||
155 | int error = job->error(); | ||||
156 | auto finished = [this,error]() { | ||||
153 | TestResult result; | 157 | TestResult result; | ||
154 | result.testCaseResults = m_caseResults; | 158 | result.testCaseResults = m_caseResults; | ||
155 | if (job->error() == OutputJob::FailedShownError) { | 159 | if (error == OutputJob::FailedShownError) { | ||
156 | result.suiteResult = TestResult::Failed; | 160 | result.suiteResult = TestResult::Failed; | ||
157 | } else if (job->error() == KJob::NoError) { | 161 | } else if (error == KJob::NoError) { | ||
158 | result.suiteResult = TestResult::Passed; | 162 | result.suiteResult = TestResult::Passed; | ||
159 | } else { | 163 | } else { | ||
160 | result.suiteResult = TestResult::Error; | 164 | result.suiteResult = TestResult::Error; | ||
161 | } | 165 | } | ||
162 | 166 | | |||
163 | // in case the job was killed, mark this job as killed as well | 167 | // in case the job was killed, mark this job as killed as well | ||
164 | if (job->error() == KJob::KilledJobError) { | 168 | if (error == KJob::KilledJobError) { | ||
165 | setError(KJob::KilledJobError); | 169 | setError(KJob::KilledJobError); | ||
166 | setErrorText(QStringLiteral("Child job was killed.")); | 170 | setErrorText(QStringLiteral("Child job was killed.")); | ||
167 | } | 171 | } | ||
168 | 172 | | |||
169 | qCDebug(CMAKE) << result.suiteResult << result.testCaseResults; | 173 | qCDebug(CMAKE) << result.suiteResult << result.testCaseResults; | ||
170 | ICore::self()->testController()->notifyTestRunFinished(m_suite, result); | 174 | ICore::self()->testController()->notifyTestRunFinished(m_suite, result); | ||
171 | emitResult(); | 175 | emitResult(); | ||
176 | }; | ||||
177 | | ||||
178 | if (m_outputModel) | ||||
179 | { | ||||
180 | connect(m_outputModel, &OutputModel::allDone, this, finished, Qt::QueuedConnection); | ||||
181 | m_outputModel->ensureAllDone(); | ||||
182 | } | ||||
183 | else | ||||
184 | { | ||||
185 | finished(); | ||||
186 | } | ||||
172 | } | 187 | } | ||
173 | 188 | | |||
174 | void CTestRunJob::rowsInserted(const QModelIndex &parent, int startRow, int endRow) | 189 | void CTestRunJob::rowsInserted(const QModelIndex &parent, int startRow, int endRow) | ||
175 | { | 190 | { | ||
176 | // This regular expression matches the name of the testcase (whatever between "::" and "(", indeed ) | 191 | // This regular expression matches the name of the testcase (whatever between "::" and "(", indeed ) | ||
177 | // For example, from: | 192 | // For example, from: | ||
178 | // PASS : ExpTest::testExp(sum) | 193 | // PASS : ExpTest::testExp(sum) | ||
179 | // matches "testExp" | 194 | // matches "testExp" | ||
180 | static QRegExp caseRx("::(.*)\\(", Qt::CaseSensitive, QRegExp::RegExp2); | 195 | static QRegExp caseRx("::(.*)\\(", Qt::CaseSensitive, QRegExp::RegExp2); | ||
181 | for (int row = startRow; row <= endRow; ++row) | 196 | for (int row = startRow; row <= endRow; ++row) | ||
182 | { | 197 | { | ||
183 | QString line = m_outputJob->model()->data(m_outputJob->model()->index(row, 0, parent), Qt::DisplayRole).toString(); | 198 | QString line = m_outputModel->data(m_outputModel->index(row, 0, parent), Qt::DisplayRole).toString(); | ||
184 | 199 | | |||
185 | QString testCase; | 200 | QString testCase; | ||
186 | if (caseRx.indexIn(line) >= 0) { | 201 | if (caseRx.indexIn(line) >= 0) { | ||
187 | testCase = caseRx.cap(1); | 202 | testCase = caseRx.cap(1); | ||
188 | } | 203 | } | ||
189 | 204 | | |||
190 | TestResult::TestCaseResult prevResult = m_caseResults.value(testCase, TestResult::NotRun); | 205 | TestResult::TestCaseResult prevResult = m_caseResults.value(testCase, TestResult::NotRun); | ||
191 | if (prevResult == TestResult::Passed || prevResult == TestResult::NotRun) | 206 | if (prevResult == TestResult::Passed || prevResult == TestResult::NotRun) | ||
Show All 31 Lines |