From 769bc094a6a74adc1bc34dc1a31522cfa590c0a7 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 7 Feb 2018 15:23:24 +0100 Subject: QmlDebug tests: Return the right value from connect(...) If the process terminates shortly after connecting, we would return the wrong value because the services would be NotConnected again, due to the timeout mechanism we used to detect this. Instead, rather directly react to the stateChanged signals and return as soon as all services are in the correct state (or if the debug connection is dropped before, or on timeout, which are failures). Change-Id: I3f0c1c8519fc450627a803c76ec9b0a703104022 Reviewed-by: Simon Hausmann --- tests/auto/qml/debugger/shared/debugutil.cpp | 85 +++++++++++++++++----------- 1 file changed, 53 insertions(+), 32 deletions(-) (limited to 'tests/auto/qml/debugger/shared/debugutil.cpp') diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 46f504f6d3..602e533388 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -120,19 +120,6 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba) emit serverMessage(ba); } -template -struct Finalizer { - F m_lambda; - Finalizer(F &&lambda) : m_lambda(std::forward(lambda)) {} - ~Finalizer() { m_lambda(); } -}; - -template -static Finalizer defer(F &&lambda) -{ - return Finalizer(std::forward(lambda)); -} - QQmlDebugTest::ConnectResult QQmlDebugTest::connect( const QString &executable, const QString &services, const QString &extraArgs, bool block) @@ -159,31 +146,27 @@ QQmlDebugTest::ConnectResult QQmlDebugTest::connect( if (m_clients.contains(nullptr)) return ClientsFailed; - auto allEnabled = [this]() { - for (QQmlDebugClient *client : m_clients) { - if (client->state() != QQmlDebugClient::Enabled) - return false; - } - return true; - }; + ClientStateHandler stateHandler(m_clients, createOtherClients(m_connection), services.isEmpty() + ? QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); - QList others = createOtherClients(m_connection); - auto deleter = defer([&others]() { qDeleteAll(others); }); - Q_UNUSED(deleter); const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); - for (int tries = 0; tries < 100 && !allEnabled(); ++tries) - QTest::qWait(50); - if (!allEnabled()) + + QEventLoop loop; + QTimer timer; + QObject::connect(&stateHandler, &ClientStateHandler::allOk, &loop, &QEventLoop::quit); + QObject::connect(m_connection, &QQmlDebugConnection::disconnected, &loop, &QEventLoop::quit); + QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + + timer.start(5000); + loop.exec(); + + if (!stateHandler.allEnabled()) return EnableFailed; - const QQmlDebugClient::State expectedState = services.isEmpty() ? QQmlDebugClient::Enabled - : QQmlDebugClient::Unavailable; - for (QQmlDebugClient *other : others) { - if (other->state() != expectedState) - return RestrictFailed; - } + if (!stateHandler.othersAsExpected()) + return RestrictFailed; return ConnectSuccess; } @@ -231,3 +214,41 @@ void QQmlDebugTest::cleanup() m_process = nullptr; } } + +ClientStateHandler::ClientStateHandler(const QList &clients, + const QList &others, + QQmlDebugClient::State expectedOthers) : + m_clients(clients), m_others(others), m_expectedOthers(expectedOthers) +{ + for (QQmlDebugClient *client : m_clients) { + QObject::connect(client, &QQmlDebugClient::stateChanged, + this, &ClientStateHandler::checkStates); + } + for (QQmlDebugClient *client : m_others) { + QObject::connect(client, &QQmlDebugClient::stateChanged, + this, &ClientStateHandler::checkStates); + } +} + +ClientStateHandler::~ClientStateHandler() +{ + qDeleteAll(m_others); +} + +void ClientStateHandler::checkStates() +{ + for (QQmlDebugClient *client : m_clients) { + if (client->state() != QQmlDebugClient::Enabled) + return; + } + + m_allEnabled = true; + + for (QQmlDebugClient *other : m_others) { + if (other->state() != m_expectedOthers) + return; + } + + m_othersAsExpected = true; + emit allOk(); +} -- cgit v1.2.3