Debugger: Improve output of autotests
authorKai Koehne <kai.koehne@nokia.com>
Fri, 16 Mar 2012 15:44:24 +0000 (16:44 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 25 Apr 2012 09:46:16 +0000 (11:46 +0200)
Change-Id: Ib938d2f39d8a0928c257ef923df5d5fcfa85c4cf
Reviewed-by: Aurindam Jana <aurindam.jana@nokia.com>
tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp
tests/auto/qml/debugger/shared/debugutil.cpp
tests/auto/qml/debugger/shared/debugutil_p.h
tests/auto/qml/debugger/shared/qqmldebugclient.cpp

index 8473774..5df196c 100644 (file)
@@ -183,20 +183,24 @@ void tst_QDebugMessageService::init()
     m_client = new QQmlDebugMsgClient(m_connection);
 
     m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
-    if (!m_process->waitForSessionStart()) {
-        QFAIL(QString("Could not launch app. Application output: \n%1").arg(m_process->output()).toAscii());
-    }
+    QVERIFY2(m_process->waitForSessionStart(),
+             "Could not launch application, or did not get 'Waiting for connection'.");
 
     m_connection->connectToHost("127.0.0.1", 3777);
     QVERIFY(m_connection->waitForConnected());
 
-    QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled())));
+    if (m_client->state() != QQmlDebugClient::Enabled)
+        QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled()));
+
+    QVERIFY(m_client->state() == QQmlDebugClient::Enabled);
 }
 
 void tst_QDebugMessageService::cleanup()
 {
-    if (QTest::currentTestFailed())
-        qDebug() << m_process->output();
+    if (QTest::currentTestFailed()) {
+        qDebug() << "Process State:" << m_process->state();
+        qDebug() << "Application Output:" << m_process->output();
+    }
     if (m_process)
         delete m_process;
 
index 036641c..1ff4575 100644 (file)
@@ -153,7 +153,6 @@ void tst_QQmlDebugClient::parallelConnect()
     QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Another client is already connected.");
     // will connect & immediately disconnect
     connection2.connectToHost("127.0.0.1", PORT);
-    QVERIFY(connection2.waitForConnected());
     QTRY_COMPARE(connection2.state(), QAbstractSocket::UnconnectedState);
     QVERIFY(m_conn->isConnected());
 }
index b93be16..8275f18 100644 (file)
@@ -1011,18 +1011,29 @@ bool tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode)
         process->start(QStringList() << QLatin1String(NORMALMODE) << testFile(qmlFile));
 
     if (!process->waitForSessionStart()) {
+        qDebug() << "could not launch application, or did not get 'Waiting for connection'.";
         return false;
     }
 
     connection->connectToHost("127.0.0.1", 3771);
-    if (!connection->waitForConnected())
+    if (!connection->waitForConnected()) {
+        qDebug() << "could not connect to host!";
         return false;
+    }
+
+    if (client->state() == QQmlDebugClient::Enabled)
+        return true;
 
     return QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()));
 }
 
 void tst_QQmlDebugJS::cleanup()
 {
+    if (QTest::currentTestFailed()) {
+        qDebug() << "Process State:" << process->state();
+        qDebug() << "Application Output:" << process->output();
+    }
+
     if (process) {
         process->stop();
         delete process;
index 39e0f0d..e033700 100644 (file)
@@ -150,9 +150,8 @@ void tst_QQmlInspector::init()
 
     m_process = new QQmlDebugProcess(executable);
     m_process->start(QStringList() << argument);
-    if (!m_process->waitForSessionStart()) {
-        QFAIL(QString("Could not launch app '%1'.\nApplication output:\n%2").arg(executable, m_process->output()).toAscii());
-    }
+    QVERIFY2(m_process->waitForSessionStart(),
+             "Could not launch application, or did not get 'Waiting for connection'.");
 
     QQmlDebugConnection *m_connection = new QQmlDebugConnection();
     m_client = new QQmlInspectorClient(m_connection);
@@ -162,6 +161,10 @@ void tst_QQmlInspector::init()
 
 void tst_QQmlInspector::cleanup()
 {
+    if (QTest::currentTestFailed()) {
+        qDebug() << "Process State:" << m_process->state();
+        qDebug() << "Application Output:" << m_process->output();
+    }
     delete m_process;
     delete m_connection;
     delete m_client;
index 972c3ac..bb17d1d 100644 (file)
@@ -242,11 +242,7 @@ void tst_QQmlProfilerService::connect(bool block, const QString &testFile)
 
     m_process = new QQmlDebugProcess(executable);
     m_process->start(QStringList() << arguments);
-    if (!m_process->waitForSessionStart()) {
-        QString failMsg = QString("Could not launch app '%1'.\nApplication output:\n%2").arg(
-                    executable, m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
 
     QQmlDebugConnection *m_connection = new QQmlDebugConnection();
     m_client = new QQmlProfilerClient(m_connection);
@@ -256,6 +252,10 @@ void tst_QQmlProfilerService::connect(bool block, const QString &testFile)
 
 void tst_QQmlProfilerService::cleanup()
 {
+    if (QTest::currentTestFailed()) {
+        qDebug() << "Process State:" << m_process->state();
+        qDebug() << "Application Output:" << m_process->output();
+    }
     delete m_process;
     delete m_connection;
     delete m_client;
@@ -268,11 +268,7 @@ void tst_QQmlProfilerService::blockingConnectWithTraceEnabled()
 
     m_client->setTraceState(true);
     m_client->setTraceState(false);
-    if (!QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
-        QString failMsg
-                = QString("No trace received in time. App output: \n%1\n").arg(m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time.");
 
     QVERIFY(m_client->traceMessages.count());
     // must start with "StartTrace"
@@ -292,11 +288,7 @@ void tst_QQmlProfilerService::blockingConnectWithTraceDisabled()
     m_client->setTraceState(false);
     m_client->setTraceState(true);
     m_client->setTraceState(false);
-    if (!QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
-        QString failMsg
-                = QString("No trace received in time. App output: \n%1\n").arg(m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time.");
 
     QVERIFY(m_client->traceMessages.count());
 
@@ -316,11 +308,7 @@ void tst_QQmlProfilerService::nonBlockingConnect()
 
     m_client->setTraceState(true);
     m_client->setTraceState(false);
-    if (!QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
-        QString failMsg
-                = QString("No trace received in time. App output: \n%1\n").arg(m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time.");
 
     // must start with "StartTrace"
     QCOMPARE(m_client->traceMessages.first().messageType, (int)QQmlProfilerClient::Event);
@@ -338,11 +326,7 @@ void tst_QQmlProfilerService::profileOnExit()
 
     m_client->setTraceState(true);
 
-    if (!QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
-        QString failMsg
-                = QString("No trace received in time. App output: \n%1\n").arg(m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time.");
 
     // must start with "StartTrace"
     QCOMPARE(m_client->traceMessages.first().messageType, (int)QQmlProfilerClient::Event);
index d482e81..0c35d10 100644 (file)
@@ -220,7 +220,7 @@ bool tst_QV8ProfilerService::connect(bool block, const QString &testFile,
     m_process = new QQmlDebugProcess(executable);
     m_process->start(QStringList() << arguments);
     if (!m_process->waitForSessionStart()) {
-        *error = QLatin1String("Could not launch app ") + executable;
+        *error = QLatin1String("Could not launch application, or did not get 'Waiting for connection'.");
         return false;
     }
 
@@ -234,9 +234,10 @@ bool tst_QV8ProfilerService::connect(bool block, const QString &testFile,
 
 void tst_QV8ProfilerService::cleanup()
 {
-    if (QTest::currentTestFailed())
+    if (QTest::currentTestFailed()) {
+        qDebug() << "Process State:" << m_process->state();
         qDebug() << "Application Output:" << m_process->output();
-
+    }
     delete m_client;
     delete m_process;
     delete m_connection;
@@ -265,11 +266,8 @@ void tst_QV8ProfilerService::blockingConnectWithTraceDisabled()
     QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
 
     m_client->stopProfiling("");
-    if (QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()), 1000)) {
-        QString failMsg
-                = QString("Unexpected trace received! App output: %1\n\n").arg(m_process->output());
-        QFAIL(qPrintable(failMsg));
-    }
+    QVERIFY2(!QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete()), 1000),
+             "Unexpected trace received.");
     m_client->startProfiling("");
     m_client->stopProfiling("");
     QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())),
index eea777f..a6b24ae 100644 (file)
@@ -99,13 +99,36 @@ QQmlDebugProcess::~QQmlDebugProcess()
     stop();
 }
 
+QString QQmlDebugProcess::state()
+{
+    QString stateStr;
+    switch (m_process.state()) {
+    case QProcess::NotRunning: {
+        stateStr = "not running";
+        if (m_process.exitStatus() == QProcess::CrashExit)
+            stateStr += " (crashed!)";
+        else
+            stateStr += ", return value" + m_process.exitCode();
+        break;
+    }
+    case QProcess::Starting: stateStr = "starting"; break;
+    case QProcess::Running: stateStr = "running"; break;
+    }
+    return stateStr;
+}
+
 void QQmlDebugProcess::start(const QStringList &arguments)
 {
     m_mutex.lock();
     m_process.setEnvironment(m_environment);
     m_process.start(m_executable, arguments);
-    m_process.waitForStarted();
-    m_timer.start();
+    if (!m_process.waitForStarted()) {
+        qWarning() << "QML Debug Client: Could not launch app " << m_executable
+                   << ": " << m_process.errorString();
+        m_eventLoop.quit();
+    } else {
+        m_timer.start();
+    }
     m_mutex.unlock();
 }
 
@@ -120,7 +143,7 @@ void QQmlDebugProcess::stop()
 void QQmlDebugProcess::timeout()
 {
     qWarning() << "Timeout while waiting for QML debugging messages "
-                  "in application output";
+                  "in application output. Process is in state" << m_process.state() << ".";
     m_eventLoop.quit();
 }
 
@@ -162,12 +185,14 @@ void QQmlDebugProcess::processAppOutput()
 
         if (line.startsWith("QML Debugger:")) {
             if (line.contains("Waiting for connection ")) {
+                m_timer.stop();
                 m_started = true;
                 m_eventLoop.quit();
                 continue;
             }
             if (line.contains("Unable to listen")) {
                 qWarning() << "App was unable to bind to port!";
+                m_timer.stop();
                 m_eventLoop.quit();
                 continue;
             }
index 0b3b8ec..fa65230 100644 (file)
@@ -87,6 +87,8 @@ public:
     QQmlDebugProcess(const QString &executable);
     ~QQmlDebugProcess();
 
+    QString state();
+
     void setEnvironment(const QStringList &environment);
 
     void start(const QStringList &arguments);
index 50feb95..f0fa499 100644 (file)
@@ -43,7 +43,9 @@
 #include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h"
 
 #include <QtCore/qdebug.h>
+#include <QtCore/qeventloop.h>
 #include <QtCore/qstringlist.h>
+#include <QtCore/qtimer.h>
 #include <QtNetwork/qnetworkproxy.h>
 
 const int protocolVersion = 1;
@@ -67,6 +69,8 @@ public:
     QQmlDebugConnection *q;
     QPacketProtocol *protocol;
     QIODevice *device;
+    QEventLoop handshakeEventLoop;
+    QTimer handshakeTimer;
 
     bool gotHello;
     QHash <QString, float> serverPlugins;
@@ -79,6 +83,7 @@ public Q_SLOTS:
     void connected();
     void readyRead();
     void deviceAboutToClose();
+    void handshakeTimeout();
 };
 
 QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c)
@@ -87,6 +92,10 @@ QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c)
     protocol = new QPacketProtocol(q, this);
     QObject::connect(c, SIGNAL(connected()), this, SLOT(connected()));
     QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
+
+    handshakeTimer.setSingleShot(true);
+    handshakeTimer.setInterval(3000);
+    connect(&handshakeTimer, SIGNAL(timeout()), SLOT(handshakeTimeout()));
 }
 
 void QQmlDebugConnectionPrivate::advertisePlugins()
@@ -158,6 +167,9 @@ void QQmlDebugConnectionPrivate::readyRead()
                 newState = QQmlDebugClient::Enabled;
             iter.value()->stateChanged(newState);
         }
+
+        handshakeTimer.stop();
+        handshakeEventLoop.quit();
     }
 
     while (protocol->packetsAvailable()) {
@@ -226,6 +238,14 @@ void QQmlDebugConnectionPrivate::deviceAboutToClose()
     q->QIODevice::close();
 }
 
+void QQmlDebugConnectionPrivate::handshakeTimeout()
+{
+    if (!gotHello) {
+        qWarning() << "Qml Debug Client: Did not get handshake answer in time";
+        handshakeEventLoop.quit();
+    }
+}
+
 QQmlDebugConnection::QQmlDebugConnection(QObject *parent)
     : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this))
 {
@@ -282,9 +302,14 @@ void QQmlDebugConnection::close()
 bool QQmlDebugConnection::waitForConnected(int msecs)
 {
     QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
-    if (socket)
-        return socket->waitForConnected(msecs);
-    return false;
+    if (!socket)
+        return false;
+    if (!socket->waitForConnected(msecs))
+        return false;
+    // wait for handshake
+    d->handshakeTimer.start();
+    d->handshakeEventLoop.exec();
+    return d->gotHello;
 }
 
 QAbstractSocket::SocketState QQmlDebugConnection::state() const