| 172 | } |
| 173 | |
| 174 | bool waitForState(MIDebugSession* session, KDevelop::IDebugSession::DebuggerState state, const char* file, int line, |
| 175 | bool waitForIdle, const ActiveStateSessionSpy* sessionSpy) |
| 176 | { |
| 177 | QPointer<MIDebugSession> s(session); //session can get deleted in DebugController |
| 178 | QElapsedTimer stopWatch; |
| 179 | stopWatch.start(); |
| 180 | |
| 181 | // legacy behavior for tests that implicitly may require waiting for idle, |
| 182 | // but which were written before waitForIdle was added |
| 183 | waitForIdle = waitForIdle || state != MIDebugSession::EndedState; |
| 184 | |
| 185 | const auto areWaitConditionsSatisfied = [session, state, sessionSpy, waitForIdle] { |
| 186 | return session->state() == state && !(waitForIdle && session->debuggerStateIsOn(s_dbgBusy)) |
| 187 | && (!sessionSpy || sessionSpy->hasEnteredActiveState()); |
| 188 | }; |
| 189 | |
| 190 | constexpr auto timeout = 50'000; |
| 191 | while (s && !areWaitConditionsSatisfied()) { |
| 192 | if (stopWatch.elapsed() > timeout) { |
| 193 | qWarning() << "current state" << s->state() << "waiting for" << state; |
| 194 | QTest::qFail(qPrintable(QString("Timeout before reaching state %0").arg(state)), |
| 195 | file, line); |
| 196 | return false; |
| 197 | } |
| 198 | QTest::qWait(20); |
| 199 | } |
| 200 | |
| 201 | // NOTE: don't wait anymore after leaving the loop. Waiting reenters event loop and |
| 202 | // may change session state. |
| 203 | |
| 204 | if (!s && state != MIDebugSession::EndedState) { |
| 205 | QTest::qFail(qPrintable(QString("Session ended before reaching state %0").arg(state)), |
| 206 | file, line); |
| 207 | return false; |
| 208 | } |
| 209 | |
| 210 | qDebug() << "Reached state " << state << " in " << file << ':' << line; |
| 211 | return true; |
| 212 | } |
| 213 | |
| 214 | TestLaunchConfiguration::TestLaunchConfiguration(const QUrl& executable, const QUrl& workingDirectory) |
| 215 | { |
nothing calls this directly
no test coverage detected