From: Kai Koehne Date: Mon, 17 Oct 2011 14:09:17 +0000 (+0200) Subject: Debugger: Add autotest skeleton for inspector service X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=e2993352a5b3773413e16af4c4c3c83c370250ae;p=konrad%2Fqtdeclarative.git Debugger: Add autotest skeleton for inspector service Change-Id: I2edd0d46f9b82262b91833945515374b9683be4b Reviewed-by: Christiaan Janssen --- diff --git a/tests/auto/declarative/debugger/debugger.pro b/tests/auto/declarative/debugger/debugger.pro index a9c5bde..869b3a8 100644 --- a/tests/auto/declarative/debugger/debugger.pro +++ b/tests/auto/declarative/debugger/debugger.pro @@ -5,6 +5,7 @@ PRIVATETESTS += \ qdeclarativedebugclient \ qdeclarativedebugservice \ qdeclarativedebugjs \ + qdeclarativeinspector \ qpacketprotocol contains(QT_CONFIG, private_tests) { diff --git a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp index 2386d0b..73cea4e 100644 --- a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp +++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp @@ -131,7 +131,6 @@ const char *JSFILE = "test.js"; jsonVal.setProperty(SEQ,QJSValue(seq++)); \ jsonVal.setProperty(TYPE,REQUEST); -class QJSDebugProcess; class QJSDebugClient; class tst_QDeclarativeDebugJS : public QObject @@ -197,109 +196,11 @@ private slots: // void verifyQMLOptimizerDisabled(); private: - QJSDebugProcess *process; + QDeclarativeDebugProcess *process; QJSDebugClient *client; QDeclarativeDebugConnection *connection; }; -class QJSDebugProcess : public QObject -{ - Q_OBJECT -public: - QJSDebugProcess(); - ~QJSDebugProcess(); - - void start(const QStringList &arguments); - bool waitForSessionStart(); - -private slots: - void processAppOutput(); - -private: - void stop(); - -private: - QProcess m_process; - QTimer m_timer; - QEventLoop m_eventLoop; - QMutex m_mutex; - bool m_started; -}; - -QJSDebugProcess::QJSDebugProcess() - : m_started(false) -{ - m_process.setProcessChannelMode(QProcess::MergedChannels); - m_timer.setSingleShot(true); - m_timer.setInterval(5000); - connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput())); - connect(&m_timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit())); - -// QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); -// env.insert("QML_DISABLE_OPTIMIZER", "1"); // Add an environment variable -// m_process.setProcessEnvironment(env); - -} - -QJSDebugProcess::~QJSDebugProcess() -{ - stop(); -} - -void QJSDebugProcess::start(const QStringList &arguments) -{ - m_mutex.lock(); - m_process.start(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", arguments); - m_process.waitForStarted(); - m_timer.start(); - m_mutex.unlock(); -} - -void QJSDebugProcess::stop() -{ - if (m_process.state() != QProcess::NotRunning) { - m_process.terminate(); - m_process.waitForFinished(5000); - } -} - -bool QJSDebugProcess::waitForSessionStart() -{ - m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents); - - return m_started; -} - -void QJSDebugProcess::processAppOutput() -{ - m_mutex.lock(); - const QString appOutput = m_process.readAll(); - static QRegExp newline("[\n\r]{1,2}"); - QStringList lines = appOutput.split(newline); - foreach (const QString &line, lines) { - if (line.isEmpty()) - continue; - if (line.startsWith("Qml debugging is enabled")) // ignore - continue; - if (line.startsWith("QDeclarativeDebugServer:")) { - if (line.contains("Waiting for connection ")) { - m_started = true; - m_eventLoop.quit(); - continue; - } - if (line.contains("Connection established")) { - continue; - } - } - if (line.startsWith("QDeclarativeDebugServer: Unable to listen on port")) { - QFAIL("Application cannot open port 3771: Port is blocked?"); - break; - } -// qWarning() << line; - } - m_mutex.unlock(); -} - class QJSDebugClient : public QDeclarativeDebugClient { Q_OBJECT @@ -1051,11 +952,13 @@ void tst_QDeclarativeDebugJS::cleanupTestCase() void tst_QDeclarativeDebugJS::init() { connection = new QDeclarativeDebugConnection(); - process = new QJSDebugProcess(); + process = new QDeclarativeDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"); client = new QJSDebugClient(connection); process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(QLatin1String(QMLFILE))); - QVERIFY(process->waitForSessionStart()); + if (!process->waitForSessionStart()) { + QFAIL(QString("Could not launch app. Application output: \n%1").arg(process->output()).toAscii()); + } connection->connectToHost("127.0.0.1", 3771); QVERIFY(connection->waitForConnected()); diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro b/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro new file mode 100644 index 0000000..59aa745 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro @@ -0,0 +1,9 @@ +TARGET = app +QT = core gui declarative qtquick1 + +CONFIG += declarative_debug +macx:CONFIG -= app_bundle + +SOURCES += main.cpp + +OTHER_FILES += qtquick1.qml qtquick2.qml diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp b/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp new file mode 100644 index 0000000..e6b9fb3 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + bool qtquick2 = true; + for (int i = 1; i < app.arguments().size(); ++i) { + const QString arg = app.arguments().at(i); + if (arg == "-qtquick1") { + qtquick2 = false; + } else if (arg == "-qtquick2") { + qtquick2 = true; + } else { + qWarning() << "Usage: " << app.arguments().at(0) << "[-qtquick1|-qtquick2]"; + return -1; + } + } + + if (qtquick2) { + QQuickView *view = new QQuickView(); + view->setSource(QUrl::fromLocalFile("qtquick2.qml")); + } else { + QDeclarativeView *view = new QDeclarativeView(); + view->setSource(QUrl::fromLocalFile("qtquick1.qml")); + } + return app.exec(); +} diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick1.qml b/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick1.qml new file mode 100644 index 0000000..1709ef1 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick1.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +Item { + +} diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick2.qml b/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick2.qml new file mode 100644 index 0000000..9c36e13 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/qtquick2.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + +} diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/qdeclarativeinspector.pro b/tests/auto/declarative/debugger/qdeclarativeinspector/qdeclarativeinspector.pro new file mode 100644 index 0000000..28d16a5 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/qdeclarativeinspector.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS += tst_qdeclarativeinspector.pro app diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp new file mode 100644 index 0000000..fe079d6 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include "../../../../src/plugins/qmltooling/qmldbg_inspector/qdeclarativeinspectorprotocol.h" +#include "../../../../shared/util.h" +#include "../shared/debugutil_p.h" + +using namespace QmlJSDebugger; + +#define PORT 13772 +#define STR_PORT "13772" + +class QDeclarativeInspectorClient : public QDeclarativeDebugClient +{ + Q_OBJECT + +public: + QDeclarativeInspectorClient(QDeclarativeDebugConnection *connection) + : QDeclarativeDebugClient(QLatin1String("QDeclarativeObserverMode"), connection) + , m_showAppOnTop(false) + { + } + + bool showAppOnTop() const { return m_showAppOnTop; } + void setShowAppOnTop(bool showOnTop); + +signals: + void showAppOnTopChanged(); + +protected: + void messageReceived(const QByteArray &message); + +private: + bool m_showAppOnTop; +}; + +class tst_QDeclarativeInspector : public QObject +{ + Q_OBJECT + +public: + tst_QDeclarativeInspector() + : m_process(0) + , m_connection(0) + , m_client(0) + { + } + + +private: + QDeclarativeDebugProcess *m_process; + QDeclarativeDebugConnection *m_connection; + QDeclarativeInspectorClient *m_client; + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void connect(); + void showAppOnTop(); +}; + + +void QDeclarativeInspectorClient::setShowAppOnTop(bool showOnTop) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << InspectorProtocol::ShowAppOnTop << showOnTop; + + sendMessage(message); +} + +void QDeclarativeInspectorClient::messageReceived(const QByteArray &message) +{ + QDataStream ds(message); + InspectorProtocol::Message type; + ds >> type; + + switch (type) { + case InspectorProtocol::ShowAppOnTop: + ds >> m_showAppOnTop; + emit showAppOnTopChanged(); + break; + default: + qDebug() << "Unhandled message " << (int)type; + } +} + +void tst_QDeclarativeInspector::initTestCase() +{ +} + +void tst_QDeclarativeInspector::cleanupTestCase() +{ +} + +void tst_QDeclarativeInspector::init() +{ + const QString executable = SRCDIR"/app/app"; + const QString argument = "-qmljsdebugger=port:"STR_PORT",block"; + + m_process = new QDeclarativeDebugProcess(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()); + } + + QDeclarativeDebugConnection *m_connection = new QDeclarativeDebugConnection(); + m_client = new QDeclarativeInspectorClient(m_connection); + + m_connection->connectToHost(QLatin1String("127.0.0.1"), PORT); +} + +void tst_QDeclarativeInspector::cleanup() +{ + delete m_process; + delete m_connection; + delete m_client; +} + +void tst_QDeclarativeInspector::connect() +{ + QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled); +} + +void tst_QDeclarativeInspector::showAppOnTop() +{ + QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled); + + m_client->setShowAppOnTop(true); + QVERIFY(QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(showAppOnTopChanged()))); + QCOMPARE(m_client->showAppOnTop(), true); + + m_client->setShowAppOnTop(false); + QVERIFY(QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(showAppOnTopChanged()))); + QCOMPARE(m_client->showAppOnTop(), false); +} + +QTEST_MAIN(tst_QDeclarativeInspector) + +#include "tst_qdeclarativeinspector.moc" diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro new file mode 100644 index 0000000..26e4208 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdeclarativinspector +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h +SOURCES += tst_qdeclarativeinspector.cpp \ + ../shared/debugutil.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" +CONFIG += parallel_test declarative_debug + +QT += core-private gui-private v8-private declarative-private network testlib diff --git a/tests/auto/declarative/debugger/shared/debugutil.cpp b/tests/auto/declarative/debugger/shared/debugutil.cpp index 99f8dcc..6ab15f3 100644 --- a/tests/auto/declarative/debugger/shared/debugutil.cpp +++ b/tests/auto/declarative/debugger/shared/debugutil.cpp @@ -102,3 +102,78 @@ void QDeclarativeDebugTestClient::messageReceived(const QByteArray &ba) lastMsg = ba; emit serverMessage(ba); } + +QDeclarativeDebugProcess::QDeclarativeDebugProcess(const QString &executable) + : m_executable(executable) + , m_started(false) +{ + m_process.setProcessChannelMode(QProcess::MergedChannels); + m_timer.setSingleShot(true); + m_timer.setInterval(5000); + connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput())); + connect(&m_timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit())); +} + +QDeclarativeDebugProcess::~QDeclarativeDebugProcess() +{ + stop(); +} + +void QDeclarativeDebugProcess::start(const QStringList &arguments) +{ + m_mutex.lock(); + m_process.start(m_executable, arguments); + m_process.waitForStarted(); + m_timer.start(); + m_mutex.unlock(); +} + +void QDeclarativeDebugProcess::stop() +{ + if (m_process.state() != QProcess::NotRunning) { + m_process.terminate(); + m_process.waitForFinished(5000); + } +} + +bool QDeclarativeDebugProcess::waitForSessionStart() +{ + if (m_process.state() != QProcess::Running) { + qWarning() << "Could not start up " << m_executable; + return false; + } + m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents); + + return m_started; +} + +QString QDeclarativeDebugProcess::output() const +{ + return m_outputBuffer; +} + +void QDeclarativeDebugProcess::processAppOutput() +{ + m_mutex.lock(); + const QString appOutput = m_process.readAll(); + static QRegExp newline("[\n\r]{1,2}"); + QStringList lines = appOutput.split(newline); + foreach (const QString &line, lines) { + if (line.isEmpty()) + continue; + if (line.startsWith("Qml debugging is enabled")) // ignore + continue; + if (line.startsWith("QDeclarativeDebugServer:")) { + if (line.contains("Waiting for connection ")) { + m_started = true; + m_eventLoop.quit(); + continue; + } + if (line.contains("Connection established")) { + continue; + } + } + m_outputBuffer.append(appOutput); + } + m_mutex.unlock(); +} diff --git a/tests/auto/declarative/debugger/shared/debugutil_p.h b/tests/auto/declarative/debugger/shared/debugutil_p.h index be8df86..99a482c 100644 --- a/tests/auto/declarative/debugger/shared/debugutil_p.h +++ b/tests/auto/declarative/debugger/shared/debugutil_p.h @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -90,4 +91,30 @@ private: QByteArray lastMsg; }; +class QDeclarativeDebugProcess : public QObject +{ + Q_OBJECT +public: + QDeclarativeDebugProcess(const QString &executable); + ~QDeclarativeDebugProcess(); + + void start(const QStringList &arguments); + bool waitForSessionStart(); + + QString output() const; +private slots: + void processAppOutput(); + +private: + void stop(); + +private: + QString m_executable; + QProcess m_process; + QString m_outputBuffer; + QTimer m_timer; + QEventLoop m_eventLoop; + QMutex m_mutex; + bool m_started; +};