aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/debugger')
-rw-r--r--tests/auto/qml/debugger/debugger.pro3
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro2
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp84
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp153
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp534
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro4
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro14
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp126
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp39
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro11
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp24
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp86
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp106
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp26
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp83
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml7
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml2
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml9
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp760
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp37
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp241
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri11
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h84
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess.cpp245
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess_p.h99
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp2
38 files changed, 1445 insertions, 1374 deletions
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index a50411e18b..63721cc575 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -10,7 +10,8 @@ PUBLICTESTS += \
qqmlenginedebuginspectorintegrationtest \
qqmlenginecontrol \
qqmldebuggingenabler \
- qqmlnativeconnector
+ qqmlnativeconnector \
+ qqmldebugprocess
PRIVATETESTS += \
qqmldebugclient \
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
index 6c729ab235..9cf323ba36 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
+++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qdebugmessageservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index f193d3928a..f851688b5e 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -28,7 +28,6 @@
//QQmlDebugTest
#include "debugutil_p.h"
-#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
@@ -38,31 +37,19 @@
#include <QtCore/qlibraryinfo.h>
#include <QtTest/qtest.h>
-const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
class QQmlDebugMsgClient;
-class tst_QDebugMessageService : public QQmlDataTest
+class tst_QDebugMessageService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QDebugMessageService();
-
- void init();
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
-
void retrieveDebugOutput();
private:
- QQmlDebugProcess *m_process;
- QQmlDebugMsgClient *m_client;
- QQmlDebugConnection *m_connection;
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugMsgClient> m_client;
};
struct LogEntry {
@@ -150,73 +137,16 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
}
}
-tst_QDebugMessageService::tst_QDebugMessageService()
-{
-}
-
-void tst_QDebugMessageService::initTestCase()
-{
- QQmlDataTest::initTestCase();
- m_process = 0;
- m_client = 0;
- m_connection = 0;
-}
-
-void tst_QDebugMessageService::cleanupTestCase()
+QList<QQmlDebugClient *> tst_QDebugMessageService::createClients()
{
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-}
-
-void tst_QDebugMessageService::init()
-{
- m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
m_client = new QQmlDebugMsgClient(m_connection);
-
- m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- const int port = m_process->debugPort();
- m_connection->connectToHost("127.0.0.1", port);
- QVERIFY(m_connection->waitForConnected());
-
- if (m_client->state() != QQmlDebugClient::Enabled)
- QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled()));
-
- QCOMPARE(m_client->state(), QQmlDebugClient::Enabled);
-}
-
-void tst_QDebugMessageService::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-
- m_process = 0;
- m_client = 0;
- m_connection = 0;
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QDebugMessageService::retrieveDebugOutput()
{
- init();
+ QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ QString(), testFile(QMLFILE), true), ConnectSuccess);
QTRY_VERIFY(m_client->logBuffer.size() >= 2);
diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
index a7c0fa7f8e..b1e3835844 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -4,7 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qpacketprotocol.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml network testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
index 622b373692..673330a3cf 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
+++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugclient.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
index f8014f04f4..bd382ebaab 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebuggingenabler.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
index 3aa3a5c87e..a76740a3f9 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
@@ -27,11 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtTest/qtest.h>
#include <QtCore/qprocess.h>
#include <QtCore/qtimer.h>
@@ -40,17 +43,11 @@
#include <QtCore/qmutex.h>
#include <QtCore/qlibraryinfo.h>
-class tst_QQmlDebuggingEnabler : public QQmlDataTest
+class tst_QQmlDebuggingEnabler : public QQmlDebugTest
{
Q_OBJECT
- bool init(bool blockMode, bool qmlscene, int portFrom, int portTo);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
void qmlscene_data();
void qmlscene();
void custom_data();
@@ -58,88 +55,8 @@ private slots:
private:
void data();
- QQmlDebugProcess *process;
- QQmlDebugConnection *connection;
- QTime t;
};
-void tst_QQmlDebuggingEnabler::initTestCase()
-{
- QQmlDataTest::initTestCase();
- t.start();
- process = 0;
- connection = 0;
-}
-
-void tst_QQmlDebuggingEnabler::cleanupTestCase()
-{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (connection)
- delete connection;
-}
-
-bool tst_QQmlDebuggingEnabler::init(bool blockMode, bool qmlscene, int portFrom, int portTo)
-{
- connection = new QQmlDebugConnection();
-
- if (qmlscene) {
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
- process->setMaximumBindErrors(1);
- } else {
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
- }
-
- if (qmlscene) {
- process->start(QStringList() << QLatin1String("-qmljsdebugger=port:") +
- QString::number(portFrom) + QLatin1Char(',') + QString::number(portTo) +
- QLatin1String(blockMode ? ",block": "") <<
- testFile(QLatin1String("test.qml")));
- } else {
- QStringList args;
- if (blockMode)
- args << QLatin1String("-block");
- args << QString::number(portFrom) << QString::number(portTo);
- process->start(args);
- }
-
- if (!process->waitForSessionStart()) {
- return false;
- }
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- if (!connection->waitForConnected()) {
- qDebug() << "could not connect to host!";
- return false;
- }
- return true;
-}
-
-void tst_QQmlDebuggingEnabler::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
-
- if (connection)
- delete connection;
-
- process = 0;
- connection = 0;
-}
-
void tst_QQmlDebuggingEnabler::data()
{
QTest::addColumn<QString>("connector");
@@ -185,32 +102,32 @@ void tst_QQmlDebuggingEnabler::qmlscene()
QFETCH(bool, blockMode);
QFETCH(QStringList, services);
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
- this);
- process->setMaximumBindErrors(1);
- process->start(QStringList()
- << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
- .arg(connector + (connector == QLatin1String("QQmlDebugServer") ?
- QLatin1String(",port:5555,5565") : QString()))
- .arg(blockMode ? QLatin1String(",block") : QString())
- .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
- .arg(services.isEmpty() ? QString() : services.join(","))
- << testFile(QLatin1String("test.qml")));
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_process->setMaximumBindErrors(1);
+ m_process->start(QStringList()
+ << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
+ .arg(connector + (connector == QLatin1String("QQmlDebugServer")
+ ? QLatin1String(",port:5555,5565") : QString()))
+ .arg(blockMode ? QLatin1String(",block") : QString())
+ .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
+ .arg(services.isEmpty() ? QString() : services.join(","))
+ << testFile(QLatin1String("test.qml")));
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ foreach (QQmlDebugClient *client, m_clients)
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("qml: Component.onCompleted")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("qml: Component.onCompleted")));
}
void tst_QQmlDebuggingEnabler::custom_data()
@@ -226,9 +143,9 @@ void tst_QQmlDebuggingEnabler::custom()
const int portFrom = 5555;
const int portTo = 5565;
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
+ m_process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebuggingenablerserver"), this);
+ m_process->setMaximumBindErrors(portTo - portFrom);
QStringList args;
if (blockMode)
@@ -240,22 +157,22 @@ void tst_QQmlDebuggingEnabler::custom()
if (!services.isEmpty())
args << QLatin1String("-services") << services;
- process->start(args);
+ m_process->start(args);
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ for (QQmlDebugClient *client : qAsConst(m_clients))
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("QQmlEngine created")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("QQmlEngine created")));
}
QTEST_MAIN(tst_QQmlDebuggingEnabler)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
index cbaf3b5309..90623c75a6 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebugjs.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
include(../../shared/qqmlenginedebugclient.pri)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
index d248cf9708..3cd359cf48 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../shared/qqmlenginedebugclient.h"
#include "../../../../shared/util.h"
@@ -136,7 +137,7 @@ const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
do {\
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
if (QTest::currentTestFailed()) \
- qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
+ qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << m_process->output();\
return;\
}\
} while (0)
@@ -144,18 +145,12 @@ do {\
class QJSDebugClient;
-class tst_QQmlDebugJS : public QQmlDataTest
+class tst_QQmlDebugJS : public QQmlDebugTest
{
Q_OBJECT
- void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
- bool restrictServices = false);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
+ void initTestCase() override;
void connect_data();
void connect();
@@ -223,11 +218,12 @@ private slots:
void getScripts();
private:
- void targetData();
+ ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE),
+ bool blockMode = true, bool restrictServices = false);
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QJSDebugClient> m_client;
- QQmlDebugProcess *process;
- QJSDebugClient *client;
- QQmlDebugConnection *connection;
+ void targetData();
QTime t;
};
@@ -280,7 +276,6 @@ protected:
void messageReceived(const QByteArray &data);
signals:
- void enabled();
void connected();
void interruptRequested();
void result();
@@ -667,10 +662,8 @@ void QJSDebugClient::disconnect()
void QJSDebugClient::stateChanged(State state)
{
- if (state == Enabled) {
+ if (state == Enabled)
flushSendBuffer();
- emit enabled();
- }
}
void QJSDebugClient::messageReceived(const QByteArray &data)
@@ -763,85 +756,19 @@ QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray
void tst_QQmlDebugJS::initTestCase()
{
- QQmlDataTest::initTestCase();
+ QQmlDebugTest::initTestCase();
t.start();
- process = 0;
- client = 0;
- connection = 0;
}
-void tst_QQmlDebugJS::cleanupTestCase()
+QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile,
+ bool blockMode, bool restrictServices)
{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-}
-
-void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
- bool restrictServices)
-{
- connection = new QQmlDebugConnection();
- if (qmlscene)
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qmlscene", this);
- else
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebugjsserver"), this);
- client = new QJSDebugClient(connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection);
-
- const char *args = 0;
- if (blockMode)
- args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE;
- else
- args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE;
-
- process->start(QStringList() << QLatin1String(args) << testFile(qmlFile));
-
- QVERIFY(process->waitForSessionStart());
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- QVERIFY(connection->waitForConnected());
-
-
- if (client->state() != QQmlDebugClient::Enabled)
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())));
-
- foreach (QQmlDebugClient *otherClient, others)
- QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-}
-
-void tst_QQmlDebugJS::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-
- process = 0;
- client = 0;
- connection = 0;
+ const QString executable = qmlscene
+ ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"
+ : QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebugjsserver");
+ return QQmlDebugTest::connect(
+ executable, restrictServices ? QStringLiteral("V8Debugger") : QString(),
+ testFile(qmlFile), blockMode);
}
void tst_QQmlDebugJS::connect_data()
@@ -864,9 +791,9 @@ void tst_QQmlDebugJS::connect()
QFETCH(bool, blockMode);
QFETCH(bool, restrictMode);
QFETCH(bool, qmlscene);
- init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
- client->connect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode), ConnectSuccess);
+ m_client->connect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
}
void tst_QQmlDebugJS::interrupt()
@@ -876,11 +803,11 @@ void tst_QQmlDebugJS::interrupt()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->interrupt();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
+ m_client->interrupt();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(interruptRequested())));
}
void tst_QQmlDebugJS::getVersion()
@@ -890,12 +817,12 @@ void tst_QQmlDebugJS::getVersion()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getVersionWhenAttaching()
@@ -905,11 +832,11 @@ void tst_QQmlDebugJS::getVersionWhenAttaching()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QLatin1String(TIMER_QMLFILE), false);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::disconnect()
@@ -919,11 +846,11 @@ void tst_QQmlDebugJS::disconnect()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->disconnect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->disconnect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
@@ -934,14 +861,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -957,14 +884,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, CREATECOMPONENT_QMLFILE);
+ QCOMPARE(init(qmlscene, CREATECOMPONENT_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -978,16 +905,16 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 35;
- init(qmlscene, TIMER_QMLFILE);
+ QCOMPARE(init(qmlscene, TIMER_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//We can set the breakpoint after connect() here because the timer is repeating and if we miss
//its first iteration we can still catch the second one.
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1003,14 +930,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
QFETCH(bool, namesAsObjects);
int sourceLine = 31;
- init(qmlscene, LOADJSFILE_QMLFILE);
+ QCOMPARE(init(qmlscene, LOADJSFILE_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1027,15 +954,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
int sourceLine = 34;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1052,15 +979,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
int sourceLine = 35;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1076,14 +1003,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
QFETCH(bool, namesAsObjects);
int sourceLine = 39;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1098,28 +1025,28 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
QFETCH(bool, namesAsObjects);
int out = 10;
int sourceLine = 37;
- init(qmlscene, CONDITION_QMLFILE);
+ QCOMPARE(init(qmlscene, CONDITION_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Get the frame index
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString = m_client->response;
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
{
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
//Verify the value of 'result'
- client->evaluate(QLatin1String("a"),frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("a"),frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
- jsonString = client->response;
- QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString));
+ jsonString = m_client->response;
+ QJSValue val = m_client->parser.call(QJSValueList() << QJSValue(jsonString));
QVERIFY(val.isObject());
QJSValue body = val.property(QStringLiteral("body"));
QVERIFY(body.isObject());
@@ -1135,42 +1062,42 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QUIT_QMLFILE);
+ QCOMPARE(init(qmlscene, QUIT_QMLFILE), ConnectSuccess);
int sourceLine = 36;
- client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(process->waitForFinished());
- QCOMPARE(process->exitStatus(), QProcess::NormalExit);
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(m_process->waitForFinished());
+ QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlDebugJS::setBreakpointWhenAttaching()
{
int sourceLine = 35;
- init(true, QLatin1String(TIMER_QMLFILE), false);
+ QCOMPARE(init(true, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
- client->connect();
+ m_client->connect();
QSKIP("\nThe breakpoint may not hit because the engine may run in JIT mode or not have debug\n"
"instructions, as we've connected in non-blocking mode above. That means we may have\n"
"connected after the engine was already running, with all the QML already compiled.");
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::clearBreakpoint()
@@ -1182,41 +1109,41 @@ void tst_QQmlDebugJS::clearBreakpoint()
int sourceLine1 = 37;
int sourceLine2 = 38;
- init(qmlscene, CHANGEBREAKPOINT_QMLFILE);
+ QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoints are in a timer loop so we can set them after connect().
//Furthermore the breakpoints should be hit in the right order because setting of breakpoints
//can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below)
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Will hit 1st brakpoint, change this breakpoint enable = false
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
int breakpoint = breakpointsHit.at(0).toInt();
- client->clearBreakpoint(breakpoint);
+ m_client->clearBreakpoint(breakpoint);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1230,10 +1157,10 @@ void tst_QQmlDebugJS::setExceptionBreak()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, EXCEPTION_QMLFILE);
- client->setExceptionBreak(QJSDebugClient::All,true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess);
+ m_client->setExceptionBreak(QJSDebugClient::All,true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::stepNext()
@@ -1244,17 +1171,17 @@ void tst_QQmlDebugJS::stepNext()
QFETCH(bool, namesAsObjects);
int sourceLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Next);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Next);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1262,6 +1189,14 @@ void tst_QQmlDebugJS::stepNext()
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
+static QVariantMap responseBody(QJSDebugClient *client)
+{
+ const QString jsonString(client->response);
+ const QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString))
+ .toVariant().toMap();
+ return value.value("body").toMap();
+}
+
void tst_QQmlDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
@@ -1270,21 +1205,18 @@ void tst_QQmlDebugJS::stepIn()
QFETCH(bool, namesAsObjects);
int sourceLine = 41;
- int actualLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
-
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::In);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::In);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1298,20 +1230,17 @@ void tst_QQmlDebugJS::stepOut()
int sourceLine = 37;
int actualLine = 41;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- client->continueDebugging(QJSDebugClient::Out);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::Out);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1325,18 +1254,18 @@ void tst_QQmlDebugJS::continueDebugging()
int sourceLine1 = 41;
int sourceLine2 = 38;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1352,14 +1281,14 @@ void tst_QQmlDebugJS::backtrace()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->backtrace();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->backtrace();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getFrameDetails()
@@ -1370,14 +1299,14 @@ void tst_QQmlDebugJS::getFrameDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getScopeDetails()
@@ -1388,33 +1317,32 @@ void tst_QQmlDebugJS::getScopeDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scope();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->scope();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::evaluateInGlobalScope()
{
//void evaluate(QString expr, int frame = -1);
- init(true);
+ QCOMPARE(init(true), ConnectSuccess);
- client->connect();
+ m_client->connect();
- do {
+ for (int i = 0; i < 10; ++i) {
// The engine might not be initialized, yet. We just try until it shows up.
- client->evaluate(QLatin1String("console.log('Hello World')"));
- } while (!QQmlDebugTest::waitForSignal(client, SIGNAL(result()), 500));
+ m_client->evaluate(QLatin1String("console.log('Hello World')"));
+ if (QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()), 500))
+ break;
+ }
//Verify the return value of 'console.log()', which is "undefined"
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QVariantMap body = value.value("body").toMap();
- QCOMPARE(body.value("type").toString(),QLatin1String("undefined"));
+ QCOMPARE(responseBody(m_client).value("type").toString(), QLatin1String("undefined"));
}
void tst_QQmlDebugJS::evaluateInLocalScope()
@@ -1425,29 +1353,29 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Get the frame index
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
- client->evaluate(QLatin1String("root.a"), frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("root.a"), frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Verify the value of 'timer.interval'
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1456,25 +1384,25 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
void tst_QQmlDebugJS::evaluateInContext()
{
- connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ m_connection = new QQmlDebugConnection();
+ m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ "/qmlscene", this);
- client = new QJSDebugClient(connection);
- QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(connection));
- process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
+ m_client = new QJSDebugClient(m_connection);
+ QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection));
+ m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
- QVERIFY(process->waitForSessionStart());
+ QVERIFY(m_process->waitForSessionStart());
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
- QTRY_COMPARE(client->state(), QQmlEngineDebugClient::Enabled);
+ QTRY_COMPARE(m_client->state(), QQmlEngineDebugClient::Enabled);
QTRY_COMPARE(engineClient->state(), QQmlEngineDebugClient::Enabled);
- client->connect();
+ m_client->connect();
// "a" not accessible without extra context
- client->evaluate(QLatin1String("a + 10"), -1, -1);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(failure())));
+ m_client->evaluate(QLatin1String("a + 10"), -1, -1);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(failure())));
bool success = false;
engineClient->queryAvailableEngines(&success);
@@ -1496,14 +1424,10 @@ void tst_QQmlDebugJS::evaluateInContext()
auto object = engineClient->object();
// "a" accessible in context of surrounding object
- client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
- QVariantMap body = value.value("body").toMap();
- QTRY_COMPARE(body.value("value").toInt(), 20);
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
}
void tst_QQmlDebugJS::getScripts()
@@ -1513,16 +1437,16 @@ void tst_QQmlDebugJS::getScripts()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
- client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scripts();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList()
+ m_client->scripts();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList()
<< QJSValue(jsonString)).toVariant().toMap();
QList<QVariant> scripts = value.value("body").toList();
@@ -1531,6 +1455,12 @@ void tst_QQmlDebugJS::getScripts()
QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
}
+QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients()
+{
+ m_client = new QJSDebugClient(m_connection);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
void tst_QQmlDebugJS::targetData()
{
QTest::addColumn<bool>("qmlscene");
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
index 860d39cca4..1dc9de8f34 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
+++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebuglocal.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml-private testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
index 8d21a8a45a..4b28857fc0 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
+++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
@@ -32,6 +32,9 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+#include <QtQml/qqmlengine.h>
+
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..331d87b9f1
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = qqmldebugprocess qqmldebugprocessprocess
+
+qqmldebugprocess.depends = qqmldebugprocessprocess
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..9bea2d222c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qqmldebugprocess
+QT = core testlib
+CONFIG -= debug_and_release_target
+macos:CONFIG -= app_bundle
+
+SOURCES += \
+ ../../shared/qqmldebugprocess.cpp \
+ tst_qqmldebugprocess.cpp
+
+HEADERS += \
+ ../../shared/qqmldebugprocess_p.h
+
+INCLUDEPATH += ../../shared
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
new file mode 100644
index 0000000000..993a1d5f63
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qqmldebugprocess_p.h>
+#include <QtTest>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qscopedpointer.h>
+
+class tst_QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void sessionStart_data();
+ void sessionStart();
+};
+
+void tst_QQmlDebugProcess::sessionStart_data()
+{
+ QTest::addColumn<int>("delay");
+ QTest::addColumn<QString>("arg");
+ QTest::addColumn<bool>("sessionExpected");
+ QTest::addColumn<bool>("outputExpected");
+
+ QTest::addRow("synchronous / waiting") << -1
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("synchronous / failed") << -1 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("synchronous / unknown") << -1 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("synchronous / appout") << -1 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("no delay / waiting") << 0
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("no delay / failed") << 0 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("no delay / unknown") << 0 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("no delay / appout") << 0 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("delay / waiting") << 1000
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("delay / failed") << 1000 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("delay / unknown") << 1000 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("delay / appout") << 1000 << "Output from app itself."
+ << false << true;
+}
+
+void tst_QQmlDebugProcess::sessionStart()
+{
+ QFETCH(int, delay);
+ QFETCH(QString, arg);
+ QFETCH(bool, sessionExpected);
+ QFETCH(bool, outputExpected);
+
+ QScopedPointer<QQmlDebugProcess> process(
+ new QQmlDebugProcess(QCoreApplication::applicationDirPath()
+ + QLatin1String("/qqmldebugprocessprocess"), this));
+ QVERIFY(process);
+
+ bool outputReceived = false;
+ connect(process.data(), &QQmlDebugProcess::readyReadStandardOutput, this, [&]() {
+ QVERIFY(outputExpected);
+ QVERIFY(!outputReceived);
+ QCOMPARE(process->output().trimmed(), arg);
+ outputReceived = true;
+ QTimer::singleShot(qMax(delay, 0), process.data(), &QQmlDebugProcess::stop);
+ });
+
+ if (!outputExpected && !sessionExpected)
+ QTest::ignoreMessage(QtWarningMsg, "App was unable to bind to port!");
+ process->start(QStringList({arg}));
+
+ bool done = false;
+ auto wait = [&](){
+ QCOMPARE(process->waitForSessionStart(), sessionExpected);
+ QCOMPARE(outputReceived, outputExpected);
+ process->stop();
+ done = true;
+ };
+
+ if (delay < 0)
+ wait();
+ else
+ QTimer::singleShot(delay, process.data(), wait);
+
+ QTRY_VERIFY(done);
+ QVERIFY(process->state().startsWith("not running"));
+}
+
+QTEST_MAIN(tst_QQmlDebugProcess)
+
+#include "tst_qqmldebugprocess.moc"
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
new file mode 100644
index 0000000000..21cce53fc3
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+// Process that just outputs a fake "Waiting" message.
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ if (argc > 1)
+ qDebug() << argv[1];
+ return app.exec();
+}
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
new file mode 100644
index 0000000000..a8eb4885d4
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
@@ -0,0 +1,11 @@
+QT = core
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+CONFIG += console
+SOURCES += qqmldebugprocessprocess.cpp
+
+DESTDIR = ../qqmldebugprocess
+
+target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugprocess
+INSTALLS += target
+
diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
index 79cbe52331..3101d09ea5 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
+++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
@@ -7,8 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugservice.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
index 8092faba04..4e103e9a65 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
@@ -29,6 +29,7 @@
#include "qqmldebugtestservice.h"
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
@@ -105,10 +106,13 @@ void tst_QQmlDebugService::initTestCase()
void tst_QQmlDebugService::checkPortRange()
{
- QQmlDebugConnection *connection1 = new QQmlDebugConnection();
- QQmlDebugProcess *process1 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection1(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process1(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process1->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -119,10 +123,13 @@ void tst_QQmlDebugService::checkPortRange()
QFAIL("could not connect to host!");
// Second instance
- QQmlDebugConnection *connection2 = new QQmlDebugConnection();
- QQmlDebugProcess *process2 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection2(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process2(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process2->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -131,11 +138,6 @@ void tst_QQmlDebugService::checkPortRange()
connection2->connectToHost("127.0.0.1", port2);
if (!connection2->waitForConnected())
QFAIL("could not connect to host!");
-
- delete connection1;
- delete process1;
- delete connection2;
- delete process2;
}
void tst_QQmlDebugService::name()
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
index 40ec1230d6..73455bd903 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
@@ -4,13 +4,11 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginecontrol.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-QT += core qml testlib testlib-private gui-private core-private
+QT += core qml testlib gui-private core-private
OTHER_FILES += \
data/test.qml \
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index 2c515d7cf5..a8c43b1c75 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -35,12 +35,8 @@
#include <private/qqmlenginecontrolclient_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
-
class QQmlEngineBlocker : public QObject
{
Q_OBJECT
@@ -65,77 +61,37 @@ void QQmlEngineBlocker::blockEngine(int engineId, const QString &name)
static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId);
}
-class tst_QQmlEngineControl : public QQmlDataTest
+class tst_QQmlEngineControl : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineControl()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {}
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlEngineControlClient *m_client;
+ ConnectResult connect(const QString &testFile, bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
- void connect(const QString &testFile, bool restrictServices);
void engine_data();
+ QPointer<QQmlEngineControlClient> m_client;
private slots:
- void cleanup();
-
void startEngine_data();
void startEngine();
void stopEngine_data();
void stopEngine();
};
-void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file,
+ bool restrictServices)
{
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:EngineControl") : QString());
-
- arguments << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlEngineControlClient(m_connection);
- new QQmlEngineBlocker(m_client);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
-
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QStringLiteral("EngineControl") : QString(),
+ testFile(file), true);
}
-void tst_QQmlEngineControl::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineControl::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
- }
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+ m_client = new QQmlEngineControlClient(m_connection);
+ new QQmlEngineBlocker(m_client);
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QQmlEngineControl::engine_data()
@@ -153,16 +109,16 @@ void tst_QQmlEngineControl::startEngine_data()
void tst_QQmlEngineControl::startEngine()
{
QFETCH(bool, restrictMode);
-
- connect("test.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
void tst_QQmlEngineControl::stopEngine_data()
@@ -174,21 +130,23 @@ void tst_QQmlEngineControl::stopEngine()
{
QFETCH(bool, restrictMode);
- connect("exit.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))),
"No engine about to stop message received in time.");
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))),
"No engine stop message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
QTEST_MAIN(tst_QQmlEngineControl)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
index b8b4c3fc8b..5f58e5ec7f 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
@@ -1,13 +1,11 @@
CONFIG += testcase
TARGET = tst_qqmlenginedebuginspectorintegration
-QT += qml testlib testlib-private gui-private core-private
+QT += qml testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginedebuginspectorintegration.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index aba9eb39ab..249416a3b9 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -34,7 +34,6 @@
#include <private/qqmldebugconnection_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
#include <QtCore/qtimer.h>
@@ -42,35 +41,21 @@
#include <QtCore/qthread.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "3776"
-#define STR_PORT_TO "3786"
-
-class tst_QQmlEngineDebugInspectorIntegration : public QQmlDataTest
+class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineDebugInspectorIntegration()
- : m_process(0)
- , m_inspectorClient(0)
- , m_engineDebugClient(0)
- , m_recipient(0)
- {
- }
-
-
private:
- void init(bool restrictServices);
+ ConnectResult init(bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
+
QmlDebugObjectReference findRootObject();
- QQmlDebugProcess *m_process;
- QQmlInspectorClient *m_inspectorClient;
- QQmlEngineDebugClient *m_engineDebugClient;
- QQmlInspectorResultRecipient *m_recipient;
+ QPointer<QQmlInspectorClient> m_inspectorClient;
+ QPointer<QQmlEngineDebugClient> m_engineDebugClient;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void objectLocationLookup();
@@ -100,53 +85,22 @@ QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject(
return m_engineDebugClient->object();
}
-void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlDebugger,QmlInspector") :
- QString());
-
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
- this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- QQmlDebugConnection *m_connection = new QQmlDebugConnection(this);
- m_inspectorClient = new QQmlInspectorClient(m_connection);
- m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
- m_recipient = new QQmlInspectorResultRecipient(this);
- QObject::connect(m_inspectorClient, &QQmlInspectorClient::responseReceived,
- m_recipient, &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QVERIFY(m_connection->waitForConnected());
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-
- QTRY_COMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
- QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
+ testFile("qtquick2.qml"), true);
}
-void tst_QQmlEngineDebugInspectorIntegration::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineDebugInspectorIntegration::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- delete m_process;
- m_process = 0;
- delete m_engineDebugClient;
- m_engineDebugClient = 0;
- delete m_inspectorClient;
- m_inspectorClient = 0;
- delete m_recipient;
- m_recipient = 0;
+ m_inspectorClient = new QQmlInspectorClient(m_connection);
+ m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_inspectorClient);
+ QObject::connect(m_inspectorClient.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_inspectorClient, m_engineDebugClient});
}
void tst_QQmlEngineDebugInspectorIntegration::connect_data()
@@ -159,14 +113,12 @@ void tst_QQmlEngineDebugInspectorIntegration::connect_data()
void tst_QQmlEngineDebugInspectorIntegration::connect()
{
QFETCH(bool, restrictMode);
- init(restrictMode);
+ QCOMPARE(init(restrictMode), ConnectSuccess);
}
void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
bool success = false;
QmlDebugObjectReference rootObject = findRootObject();
@@ -192,9 +144,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
void tst_QQmlEngineDebugInspectorIntegration::select()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QmlDebugObjectReference rootObject = findRootObject();
QList<int> childIds;
@@ -212,9 +162,7 @@ void tst_QQmlEngineDebugInspectorIntegration::select()
void tst_QQmlEngineDebugInspectorIntegration::createObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QString qml = QLatin1String("Rectangle {\n"
" id: xxxyxxx\n"
@@ -241,9 +189,7 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject()
void tst_QQmlEngineDebugInspectorIntegration::moveObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
@@ -268,9 +214,7 @@ void tst_QQmlEngineDebugInspectorIntegration::moveObject()
void tst_QQmlEngineDebugInspectorIntegration::destroyObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
index 06250d9940..33ee023c06 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += \
tst_qqmlenginedebugservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 6d31ff9219..8993ce7cf4 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -229,9 +229,23 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
QCOMPARE(p.name, QString::fromUtf8(pmeta.name()));
- if (pmeta.type() < QVariant::UserType && pmeta.userType() !=
- QMetaType::QVariant) // TODO test complex types
- QCOMPARE(p.value , pmeta.read(o));
+ if (pmeta.userType() == QMetaType::QObjectStar) {
+ const QmlDebugObjectReference ref = qvariant_cast<QmlDebugObjectReference>(p.value);
+ QObject *pobj = qvariant_cast<QObject *>(pmeta.read(o));
+ if (pobj) {
+ if (pobj->objectName().isEmpty())
+ QCOMPARE(ref.name, QString("<unnamed object>"));
+ else
+ QCOMPARE(ref.name, pobj->objectName());
+ } else {
+ QCOMPARE(ref.name, QString("<unknown value>"));
+ }
+ } else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
+ const QVariant expected = pmeta.read(o);
+ QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
+ .arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
+ .arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
+ }
if (p.name == "parent")
QVERIFY(p.valueTypeName == "QGraphicsObject*" ||
@@ -1259,7 +1273,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
// check transition
QmlDebugObjectReference transition = obj.children[0];
@@ -1277,7 +1292,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
QCOMPARE(findProperty(animation.properties,"property").value.toString(), QString("width"));
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
index ee5f3c708a..fd07255ae5 100644
--- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
+++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlinspector.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 9461922eff..5c9506eb21 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -28,6 +28,7 @@
#include "qqmlinspectorclient.h"
#include "../shared/debugutil_p.h"
+#include "../shared/qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugconnection_p.h>
@@ -40,64 +41,32 @@
#include <QtCore/qlibraryinfo.h>
#include <QtNetwork/qhostaddress.h>
-#define STR_PORT_FROM "3772"
-#define STR_PORT_TO "3782"
-
-
-class tst_QQmlInspector : public QQmlDataTest
+class tst_QQmlInspector : public QQmlDebugTest
{
Q_OBJECT
private:
- void startQmlProcess(const QString &qmlFile, bool restrictMode = true);
+ ConnectResult startQmlProcess(const QString &qmlFile, bool restrictMode = true);
void checkAnimationSpeed(int targetMillisPerDegree);
+ QList<QQmlDebugClient *> createClients() override;
+ QQmlDebugProcess *createProcess(const QString &executable) override;
-private:
- QScopedPointer<QQmlDebugProcess> m_process;
- QScopedPointer<QQmlDebugConnection> m_connection;
- QScopedPointer<QQmlInspectorClient> m_client;
- QScopedPointer<QQmlInspectorResultRecipient> m_recipient;
+ QPointer<QQmlInspectorClient> m_client;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void setAnimationSpeed();
void showAppOnTop();
};
-void tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile,
+ bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlInspector") : QString());
-
- m_process.reset(new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qml"));
- // Make sure the animation timing is exact
- m_process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
- m_process->start(QStringList() << argument << testFile(qmlFile));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_client.reset();
- m_connection.reset(new QQmlDebugConnection);
- m_client.reset(new QQmlInspectorClient(m_connection.data()));
-
- m_recipient.reset(new QQmlInspectorResultRecipient);
- QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
- m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection.data());
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
-
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlInspector") : QString(),
+ testFile(qmlFile), true);
}
void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
@@ -114,8 +83,7 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
QString output = m_process->output();
int position = output.length();
do {
- QVERIFY(QQmlDebugTest::waitForSignal(m_process.data(),
- SIGNAL(readyReadStandardOutput())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
output = m_process->output();
} while (!output.mid(position).contains(markerString));
@@ -144,12 +112,21 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
.arg(targetMillisPerDegree).toLocal8Bit().constData());
}
-void tst_QQmlInspector::cleanup()
+QList<QQmlDebugClient *> tst_QQmlInspector::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
+ m_client = new QQmlInspectorClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_client);
+ QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+QQmlDebugProcess *tst_QQmlInspector::createProcess(const QString &executable)
+{
+ QQmlDebugProcess *process = QQmlDebugTest::createProcess(executable);
+ // Make sure the animation timing is exact
+ process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
+ return process;
}
void tst_QQmlInspector::connect_data()
@@ -166,7 +143,7 @@ void tst_QQmlInspector::connect()
{
QFETCH(QString, file);
QFETCH(bool, restrictMode);
- startQmlProcess(file, restrictMode);
+ QCOMPARE(startQmlProcess(file, restrictMode), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -181,7 +158,7 @@ void tst_QQmlInspector::connect()
void tst_QQmlInspector::showAppOnTop()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -196,7 +173,7 @@ void tst_QQmlInspector::showAppOnTop()
void tst_QQmlInspector::setAnimationSpeed()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
checkAnimationSpeed(10);
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
index dd7cb2055d..4235a2d55f 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
@@ -43,13 +43,6 @@ QtObject {
interval: 1000
onTriggered: {
console.profileEnd();
- endTimer.start();
}
}
-
- property var endTimer: Timer {
- id: endTimer
- interval: 1000
- onTriggered: Qt.quit();
- }
}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
index 4236d70ea3..3b28e65174 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
@@ -1,7 +1,7 @@
import QtQml 2.0
QtObject {
- Timer {
+ property Timer timer: Timer {
running: true
interval: 1
onTriggered: Qt.quit();
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
new file mode 100644
index 0000000000..09dcd34b5c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+Timer {
+ property string stuff: qsTr("foo")
+
+ running: true
+ interval: 1
+ onTriggered: Qt.quit();
+}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
index 56840d5c8f..7c78b5fcb3 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
@@ -4,8 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlprofilerservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
@@ -22,4 +20,5 @@ OTHER_FILES += \
data/signalSourceLocation.qml \
data/javascript.qml \
data/timer.qml \
+ data/qstr.qml \
data/memory.qml
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index bc6c51707a..db28d3202d 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmlprofilerclient_p.h>
@@ -36,246 +37,144 @@
#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
-struct QQmlProfilerData
-{
- QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1,
- const QString &detailData = QString()) :
- time(time), messageType(messageType), detailType(detailType), detailData(detailData),
- line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1)
- {}
-
- qint64 time;
- int messageType;
- int detailType;
-
- //###
- QString detailData; //used by RangeData and RangeLocation
- int line; //used by RangeLocation
- int column; //used by RangeLocation
- int framerate; //used by animation events
- int animationcount; //used by animation events
- qint64 amount; //used by heap events
-};
-
-class QQmlProfilerTestClient : public QQmlProfilerClient
+class QQmlProfilerTestClient : public QQmlProfilerEventReceiver, public QQmlProfilerDefinitions
{
Q_OBJECT
public:
- QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection),
- lastTimestamp(-1) {}
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) :
+ client(new QQmlProfilerClient(connection, this))
+ {
+ connect(client.data(), &QQmlProfilerClient::traceStarted,
+ this, &QQmlProfilerTestClient::startTrace);
+ connect(client.data(), &QQmlProfilerClient::traceFinished,
+ this, &QQmlProfilerTestClient::endTrace);
+ }
- QVector<QQmlProfilerData> qmlMessages;
- QVector<QQmlProfilerData> javascriptMessages;
- QVector<QQmlProfilerData> jsHeapMessages;
- QVector<QQmlProfilerData> asynchronousMessages;
- QVector<QQmlProfilerData> pixmapMessages;
+ void startTrace(qint64 timestamp, const QList<int> &engineIds);
+ void endTrace(qint64 timestamp, const QList<int> &engineIds);
- qint64 lastTimestamp;
+ QPointer<QQmlProfilerClient> client; // Owned by QQmlDebugTest
+ QVector<QQmlProfilerEventType> types;
-signals:
- void recordingFinished();
+ QVector<QQmlProfilerEvent> qmlMessages;
+ QVector<QQmlProfilerEvent> javascriptMessages;
+ QVector<QQmlProfilerEvent> jsHeapMessages;
+ QVector<QQmlProfilerEvent> asynchronousMessages;
+ QVector<QQmlProfilerEvent> pixmapMessages;
-private:
- void traceStarted(qint64 time, int engineId);
- void traceFinished(qint64 time, int engineId);
- void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
- void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
- void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location);
- void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
- void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
- void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
- void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2);
- void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
- void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
- void complete();
-
- void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType);
- void unknownData(QPacket &stream);
+ int numLoadedEventTypes() const override;
+ void addEventType(const QQmlProfilerEventType &type) override;
+ void addEvent(const QQmlProfilerEvent &event) override;
};
-void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId)
-{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace,
- QString::number(engineId)));
-}
-
-void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
+void QQmlProfilerTestClient::startTrace(qint64 timestamp, const QList<int> &engineIds)
{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::EndTrace,
- QString::number(engineId)));
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, StartTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+void QQmlProfilerTestClient::endTrace(qint64 timestamp, const QList<int> &engineIds)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= startTime);
- lastTimestamp = startTime;
- QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, EndTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &string)
+int QQmlProfilerTestClient::numLoadedEventTypes() const
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ return types.length();
}
-void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
+void QQmlProfilerTestClient::addEventType(const QQmlProfilerEventType &type)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(location.line >= -2);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
- data.line = location.line;
- data.column = location.column;
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(type);
}
-void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+void QQmlProfilerTestClient::addEvent(const QQmlProfilerEvent &event)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= endTime);
- lastTimestamp = endTime;
- QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
+ const int typeIndex = event.typeIndex();
+ QVERIFY(typeIndex < types.length());
-void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
-{
- QVERIFY(threadId >= 0);
- QVERIFY(frameRate != -1);
- QVERIFY(animationCount != -1);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::AnimationFrame);
- data.framerate = frameRate;
- data.animationcount = animationCount;
- asynchronousMessages.append(data);
-}
-
-void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
- Q_UNUSED(numericData3);
- Q_UNUSED(numericData4);
- Q_UNUSED(numericData5);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
- type));
-}
+ const QQmlProfilerEventType &type = types[typeIndex];
-void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &url, int numericData1,
- int numericData2)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
- switch (type) {
- case QQmlProfilerDefinitions::PixmapSizeKnown:
- data.line = numericData1;
- data.column = numericData2;
+ switch (type.message()) {
+ case Event: {
+ switch (type.detailType()) {
+ case StartTrace:
+ QFAIL("StartTrace should not be passed on as event");
+ break;
+ case EndTrace:
+ QFAIL("EndTrace should not be passed on as event");
+ break;
+ case AnimationFrame:
+ asynchronousMessages.append(event);
+ break;
+ case Mouse:
+ case Key:
+ qmlMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(QString::fromLatin1("Event with unknown detailType %1 received at %2.")
+ .arg(type.detailType()).arg(event.timestamp())));
+ break;
+ }
+ break;
+ }
+ case RangeStart:
+ case RangeData:
+ case RangeLocation:
+ case RangeEnd:
+ QFAIL("Range stages are transmitted as part of events");
+ break;
+ case Complete:
+ QFAIL("Complete should not be passed on as event");
+ break;
+ case PixmapCacheEvent:
+ pixmapMessages.append(event);
+ break;
+ case SceneGraphFrame:
+ asynchronousMessages.append(event);
break;
- case QQmlProfilerDefinitions::PixmapReferenceCountChanged:
- case QQmlProfilerDefinitions::PixmapCacheCountChanged:
- data.animationcount = numericData1;
+ case MemoryAllocation:
+ jsHeapMessages.append(event);
break;
- default:
+ case DebugMessage:
+ // Unhandled
+ break;
+ case MaximumMessage:
+ switch (type.rangeType()) {
+ case Painting:
+ QFAIL("QtQuick1 paint message received.");
+ break;
+ case Compiling:
+ case Creating:
+ case Binding:
+ case HandlingSignal:
+ qmlMessages.append(event);
+ break;
+ case Javascript:
+ javascriptMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(
+ QString::fromLatin1("Unknown range event %1 received at %2.")
+ .arg(type.rangeType()).arg(event.timestamp())));
+ break;
+ }
break;
}
- pixmapMessages.append(data);
-}
-
-void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
- data.amount = amount;
- jsHeapMessages.append(data);
}
-void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
- QString::number(a) + QLatin1Char('x') +
- QString::number(b)));
-}
-
-void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType)
-{
- QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.")
- .arg(messageType).arg(detailType).arg(time)));
-}
-
-void QQmlProfilerTestClient::unknownData(QPacket &stream)
-{
- QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.")
- .arg(stream.device()->bytesAvailable())));
-}
-
-void QQmlProfilerTestClient::complete()
-{
- emit recordingFinished();
-}
-
-class tst_QQmlProfilerService : public QQmlDataTest
+class tst_QQmlProfilerService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlProfilerService()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {
- }
-
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlProfilerTestClient *m_client;
-
enum MessageListType {
MessageListQML,
MessageListJavaScript,
@@ -290,18 +189,26 @@ private:
CheckLine = 1 << 2,
CheckColumn = 1 << 3,
CheckDataEndsWith = 1 << 4,
+ CheckFileEndsWith = 1 << 5,
+ CheckNumbers = 1 << 6,
- CheckAll = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckDataEndsWith
+ CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith
};
- void connect(bool block, const QString &testFile, bool restrictServices = true);
+ ConnectResult connect(bool block, const QString &testFile, bool recordFromStart = true,
+ uint flushInterval = 0, bool restrictServices = true);
+ void checkProcessTerminated();
void checkTraceReceived();
void checkJsHeap();
- bool verify(MessageListType type, int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks);
+ bool verify(MessageListType type, int expectedPosition,
+ const QQmlProfilerEventType &expectedType, quint32 checks,
+ const QVector<qint64> &numbers);
+
+ QList<QQmlDebugClient *> createClients() override;
+ QScopedPointer<QQmlProfilerTestClient> m_client;
private slots:
- void cleanup();
+ void cleanup() override;
void connect_data();
void connect();
@@ -312,55 +219,69 @@ private slots:
void signalSourceLocation();
void javascript();
void flushInterval();
+ void translationBinding();
void memory();
+
+private:
+ bool m_recordFromStart = true;
+ bool m_flushInterval = 0;
+ bool m_isComplete = false;
+
+ // Don't use ({...}) here as MSVC will interpret that as the "QVector(int size)" ctor.
+ const QVector<qint64> m_rangeStart = (QVector<qint64>() << QQmlProfilerDefinitions::RangeStart);
+ const QVector<qint64> m_rangeEnd = (QVector<qint64>() << QQmlProfilerDefinitions::RangeEnd);
};
-#define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks))
+#define VERIFY(type, position, expected, checks, numbers) \
+ QVERIFY(verify(type, position, expected, checks, numbers))
-void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
+ bool block, const QString &file, bool recordFromStart, uint flushInterval,
+ bool restrictServices)
{
+ m_recordFromStart = recordFromStart;
+ m_flushInterval = flushInterval;
+ m_isComplete = false;
+
// ### Still using qmlscene due to QTBUG-33377
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2%3%4")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(block ? QStringLiteral(",block") : QString())
- .arg(restrictServices ? QStringLiteral(",services:CanvasFrameRate") : QString())
- << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlProfilerTestClient(m_connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
- QVERIFY(m_client);
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QQmlDebuggingEnabler::profilerServices().join(',') : QString(),
+ testFile(file), block);
+}
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+void tst_QQmlProfilerService::checkProcessTerminated()
+{
+ // If the process ends before connect(), we get a non-success value from connect()
+ // That's not a problem as we will still receive the trace. We check that process has terminated
+ // cleanly here.
+
+ // Wait for the process to finish by itself, if that hasn't happened already
+ QVERIFY(m_client);
+ QVERIFY(m_client->client);
+ QTRY_COMPARE(m_client->client->state(), QQmlDebugClient::NotConnected);
+ QVERIFY(m_process);
+ QTRY_COMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlProfilerService::checkTraceReceived()
{
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())),
- "No trace received in time.");
+ QTRY_VERIFY2(m_isComplete, "No trace received in time.");
+
+ QVector<qint64> numbers;
// must start with "StartTrace"
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace);
- VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType);
+ QQmlProfilerEventType expected(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::StartTrace);
+ VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType, numbers);
// must end with "EndTrace"
- expected.detailType = QQmlProfilerDefinitions::EndTrace;
+ expected = QQmlProfilerEventType(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::EndTrace);
VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected,
- CheckMessageType | CheckDetailType);
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::checkJsHeap()
@@ -373,33 +294,35 @@ void tst_QQmlProfilerService::checkJsHeap()
qint64 allocated = 0;
qint64 used = 0;
qint64 lastTimestamp = -1;
- foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
- switch (message.detailType) {
+ foreach (const QQmlProfilerEvent &message, m_client->jsHeapMessages) {
+ const qint64 amount = message.number<qint64>(0);
+ const QQmlProfilerEventType &type = m_client->types.at(message.typeIndex());
+ switch (type.detailType()) {
case QV4::Profiling::HeapPage:
- allocated += message.amount;
+ allocated += amount;
seen_alloc = true;
break;
case QV4::Profiling::SmallItem:
- used += message.amount;
+ used += amount;
seen_small = true;
break;
case QV4::Profiling::LargeItem:
- allocated += message.amount;
- used += message.amount;
+ allocated += amount;
+ used += amount;
seen_large = true;
break;
}
- QVERIFY(message.time >= lastTimestamp);
+ QVERIFY(message.timestamp() >= lastTimestamp);
// The heap will only be consistent after all events of the same timestamp are processed.
if (lastTimestamp == -1) {
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
continue;
- } else if (message.time == lastTimestamp) {
+ } else if (message.timestamp() == lastTimestamp) {
continue;
}
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1")
.arg(used).toUtf8().constData());
@@ -418,10 +341,10 @@ void tst_QQmlProfilerService::checkJsHeap()
}
bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType type,
- int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks)
+ int expectedPosition, const QQmlProfilerEventType &expected,
+ quint32 checks, const QVector<qint64> &expectedNumbers)
{
- QVector<QQmlProfilerData> *target = 0;
+ const QVector<QQmlProfilerEvent> *target = 0;
switch (type) {
case MessageListQML: target = &(m_client->qmlMessages); break;
case MessageListJavaScript: target = &(m_client->javascriptMessages); break;
@@ -437,41 +360,81 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
}
uint position = expectedPosition;
- qint64 timestamp = target->at(expectedPosition).time;
- while (position > 0 && target->at(position - 1).time == timestamp)
+ qint64 timestamp = target->at(expectedPosition).timestamp();
+ while (position > 0 && target->at(position - 1).timestamp() == timestamp)
--position;
QStringList warnings;
do {
- const QQmlProfilerData &actual = target->at(position);
- if ((checks & CheckMessageType) && actual.messageType != expected.messageType) {
- warnings << QString::fromLatin1("%1: unexpected messageType. actual: %2 - expected: %3")
- .arg(position).arg(actual.messageType).arg(expected.messageType);
+ const QQmlProfilerEvent &event = target->at(position);
+ const QQmlProfilerEventType &actual = m_client->types.at(event.typeIndex());
+ if ((checks & CheckMessageType) &&
+ (actual.message() != expected.message()
+ || actual.rangeType() != expected.rangeType())) {
+ warnings << QString::fromLatin1("%1: unexpected messageType or rangeType. "
+ "actual: %2, %3 - expected: %4, %5")
+ .arg(position).arg(actual.message()).arg(actual.rangeType())
+ .arg(expected.message()).arg(expected.rangeType());
continue;
}
- if ((checks & CheckDetailType) && actual.detailType != expected.detailType) {
+ if ((checks & CheckDetailType) && actual.detailType() != expected.detailType()) {
warnings << QString::fromLatin1("%1: unexpected detailType. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailType).arg(expected.detailType);
+ .arg(position).arg(actual.detailType()).arg(expected.detailType());
continue;
}
- if ((checks & CheckLine) && actual.line != expected.line) {
+
+ const QQmlProfilerEventLocation expectedLocation = expected.location();
+ const QQmlProfilerEventLocation actualLocation = actual.location();
+
+ if ((checks & CheckLine) && actualLocation.line() != expectedLocation.line()) {
warnings << QString::fromLatin1("%1: unexpected line. actual: %2 - expected: %3")
- .arg(position).arg(actual.line).arg(expected.line);
+ .arg(position).arg(actualLocation.line())
+ .arg(expectedLocation.line());
continue;
}
- if ((checks & CheckColumn) && actual.column != expected.column) {
+ if ((checks & CheckColumn) && actualLocation.column() != expectedLocation.column()) {
warnings << QString::fromLatin1("%1: unexpected column. actual: %2 - expected: %3")
- .arg(position).arg(actual.column).arg(expected.column);
+ .arg(position).arg(actualLocation.column())
+ .arg(expectedLocation.column());
+ continue;
+ }
+ if ((checks & CheckFileEndsWith) &&
+ !actualLocation.filename().endsWith(expectedLocation.filename())) {
+ warnings << QString::fromLatin1("%1: unexpected fileName. actual: %2 - expected: %3")
+ .arg(position).arg(actualLocation.filename())
+ .arg(expectedLocation.filename());
continue;
}
- if ((checks & CheckDataEndsWith) && !actual.detailData.endsWith(expected.detailData)) {
+
+ if ((checks & CheckDataEndsWith) && !actual.data().endsWith(expected.data())) {
warnings << QString::fromLatin1("%1: unexpected detailData. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailData).arg(expected.detailData);
+ .arg(position).arg(actual.data()).arg(expected.data());
continue;
}
+
+ if (checks & CheckNumbers) {
+ const QVector<qint64> actualNumbers = event.numbers<QVector<qint64>>();
+ if (actualNumbers != expectedNumbers) {
+
+ QStringList expectedList;
+ for (qint64 number : expectedNumbers)
+ expectedList.append(QString::number(number));
+ QStringList actualList;
+ for (qint64 number : actualNumbers)
+ actualList.append(QString::number(number));
+
+ warnings << QString::fromLatin1(
+ "%1: unexpected numbers. actual [%2] - expected: [%3]")
+ .arg(position)
+ .arg(actualList.join(QLatin1String(", ")))
+ .arg(expectedList.join(QLatin1String(", ")));
+ continue;
+ }
+ }
+
return true;
- } while (target->at(++position).time == timestamp);
+ } while (target->at(++position).timestamp() == timestamp);
foreach (const QString &message, warnings)
qWarning() << message.toLocal8Bit().constData();
@@ -479,54 +442,62 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
return false;
}
+QList<QQmlDebugClient *> tst_QQmlProfilerService::createClients()
+{
+ m_client.reset(new QQmlProfilerTestClient(m_connection));
+ m_client->client->setRecording(m_recordFromStart);
+ m_client->client->setFlushInterval(m_flushInterval);
+ QObject::connect(m_client->client, &QQmlProfilerClient::complete,
+ this, [this](){ m_isComplete = true; });
+ return QList<QQmlDebugClient *>({m_client->client});
+}
+
void tst_QQmlProfilerService::cleanup()
{
+ auto log = [this](const QQmlProfilerEvent &data, int i) {
+ const QQmlProfilerEventType &type = m_client->types.at(data.typeIndex());
+ const QQmlProfilerEventLocation location = type.location();
+ qDebug() << i << data.timestamp() << type.message() << type.rangeType() << type.detailType()
+ << location.filename() << location.line() << location.column()
+ << data.numbers<QVector<qint64>>();
+ };
+
if (m_client && QTest::currentTestFailed()) {
qDebug() << "QML Messages:" << m_client->qmlMessages.count();
int i = 0;
- foreach (const QQmlProfilerData &data, m_client->qmlMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->qmlMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "JavaScript Messages:" << m_client->javascriptMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->javascriptMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->javascriptMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Asynchronous Messages:" << m_client->asynchronousMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->asynchronousMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.framerate << data.animationcount << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->asynchronousMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Pixmap Cache Messages:" << m_client->pixmapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->pixmapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->pixmapMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Javascript Heap Messages:" << m_client->jsHeapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->jsHeapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->jsHeapMessages))
+ log(data, i++);
+
qDebug() << " ";
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+
+ m_client.reset();
+ QQmlDebugTest::cleanup();
}
void tst_QQmlProfilerService::connect_data()
@@ -550,67 +521,62 @@ void tst_QQmlProfilerService::connect()
QFETCH(bool, restrictMode);
QFETCH(bool, traceEnabled);
- connect(blockMode, "test.qml", restrictMode);
+ QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
- // if the engine is waiting, then the first message determines if it starts with trace enabled
if (!traceEnabled)
- m_client->sendRecordingStatus(false);
- m_client->sendRecordingStatus(true);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(true);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::pixmapCacheData()
{
- connect(true, "pixmapCacheTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
- m_client->sendRecordingStatus(true);
- QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
+ QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess);
+ // Don't wait for readyReadStandardOutput before the loop. It may have already arrived.
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
m_process->output().indexOf(QLatin1String("image error")) == -1)
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent);
+ auto createType = [](QQmlProfilerDefinitions::PixmapEventType type) {
+ return QQmlProfilerEventType(QQmlProfilerDefinitions::PixmapCacheEvent,
+ QQmlProfilerDefinitions::MaximumRangeType, type);
+ };
+
+ QVector<qint64> numbers;
// image starting to load
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted;
- VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 0, createType(QQmlProfilerDefinitions::PixmapLoadingStarted),
+ CheckMessageType | CheckDetailType, numbers);
// image size
- expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown;
- expected.line = expected.column = 2; // width and height, in fact
- VERIFY(MessageListPixmap, 1, expected,
- CheckMessageType | CheckDetailType | CheckLine | CheckColumn);
+ numbers = QVector<qint64>({2, 2, 1});
+ VERIFY(MessageListPixmap, 1, createType(QQmlProfilerDefinitions::PixmapSizeKnown),
+ CheckMessageType | CheckDetailType | CheckNumbers, numbers);
// image loaded
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished;
- VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 2, createType(QQmlProfilerDefinitions::PixmapLoadingFinished),
+ CheckMessageType | CheckDetailType, numbers);
// cache size
- expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged;
- VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 3, createType(QQmlProfilerDefinitions::PixmapCacheCountChanged),
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::scenegraphData()
{
- connect(true, "scenegraphTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
@@ -625,34 +591,39 @@ void tst_QQmlProfilerService::scenegraphData()
qint64 contextFrameTime = -1;
qint64 renderFrameTime = -1;
#if QT_CONFIG(opengl) //Software renderer doesn't have context frames
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
- contextFrameTime = msg.time;
- break;
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.message() == QQmlProfilerDefinitions::SceneGraphFrame) {
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphContextFrame) {
+ contextFrameTime = msg.timestamp();
+ break;
+ }
}
}
- }
- QVERIFY(contextFrameTime != -1);
+ QVERIFY(contextFrameTime != -1);
+ }
#endif
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
- QVERIFY(msg.time >= contextFrameTime);
- renderFrameTime = msg.time;
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
+ QVERIFY(msg.timestamp() >= contextFrameTime);
+ renderFrameTime = msg.timestamp();
break;
}
}
QVERIFY(renderFrameTime != -1);
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
- if (msg.time >= contextFrameTime) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
+ if (msg.timestamp() >= contextFrameTime) {
// Make sure SceneGraphRenderLoopFrame is not between SceneGraphContextFrame and
// SceneGraphRendererFrame. A SceneGraphRenderLoopFrame before everything else is
// OK as the scene graph might decide to do an initial rendering.
- QVERIFY(msg.time >= renderFrameTime);
+ QVERIFY(msg.timestamp() >= renderFrameTime);
break;
}
}
@@ -662,10 +633,7 @@ void tst_QQmlProfilerService::scenegraphData()
void tst_QQmlProfilerService::profileOnExit()
{
connect(true, "exit.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
@@ -673,104 +641,108 @@ void tst_QQmlProfilerService::profileOnExit()
void tst_QQmlProfilerService::controlFromJS()
{
- connect(true, "controlFromJS.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::signalSourceLocation()
{
- connect(true, "signalSourceLocation.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation,
- QQmlProfilerDefinitions::HandlingSignal,
- QLatin1String("signalSourceLocation.qml"));
- expected.line = 8;
- expected.column = 28;
- VERIFY(MessageListQML, 9, expected, CheckAll);
+ auto createType = [](int line, int column) {
+ return QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::HandlingSignal, -1,
+ QQmlProfilerEventLocation(QLatin1String("signalSourceLocation.qml"), line,
+ column));
+ };
- expected.line = 7;
- expected.column = 21;
- VERIFY(MessageListQML, 11, expected, CheckAll);
+ VERIFY(MessageListQML, 4, createType(8, 28), CheckType | CheckNumbers, m_rangeStart);
+ VERIFY(MessageListQML, 6, createType(7, 21), CheckType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::javascript()
{
- connect(true, "javascript.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart,
- QQmlProfilerDefinitions::Javascript);
- VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 2, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeLocation;
- expected.detailData = QLatin1String("javascript.qml");
- expected.line = 4;
- expected.column = 5;
- VERIFY(MessageListJavaScript, 7, expected, CheckAll);
+ VERIFY(MessageListJavaScript, 3,
+ QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(QLatin1String("javascript.qml"), 4, 5)),
+ CheckType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeData;
- expected.detailData = QLatin1String("something");
- VERIFY(MessageListJavaScript, 8, expected,
- CheckMessageType | CheckDetailType | CheckDataEndsWith);
+ VERIFY(MessageListJavaScript, 4, QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage, QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(), QLatin1String("something")),
+ CheckMessageType | CheckDetailType | CheckDataEndsWith | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeEnd;
- VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 10, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::flushInterval()
{
- connect(true, "timer.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true, -1, 1);
+ QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
QVERIFY(m_client->qmlMessages.length() < 100);
QTRY_VERIFY(m_client->qmlMessages.length() > 100);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
+void tst_QQmlProfilerService::translationBinding()
+{
+ connect(true, "qstr.qml");
+ checkProcessTerminated();
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ const QQmlProfilerEventType type(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Binding);
+
+ VERIFY(MessageListQML, 4, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeStart);
+ VERIFY(MessageListQML, 5, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeEnd);
+}
+
void tst_QQmlProfilerService::memory()
{
connect(true, "memory.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
int smallItems = 0;
for (auto message : m_client->jsHeapMessages) {
- if (message.detailType == QV4::Profiling::SmallItem)
+ const QQmlProfilerEventType &type = m_client->types[message.typeIndex()];
+ if (type.detailType() == QV4::Profiling::SmallItem)
++smallItems;
}
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 441f8c113f..b569ad6b3c 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -38,7 +38,6 @@
#include <private/qv4debugging_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4string_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugservice_p.h>
@@ -46,7 +45,7 @@
using namespace QV4;
using namespace QV4::Debugging;
-typedef void (*InjectedFunction)(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int);
Q_DECLARE_METATYPE(InjectedFunction)
static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
@@ -79,7 +78,7 @@ public:
emit evaluateFinished();
}
- QV4::ExecutionEngine *v4Engine() { return QV8Engine::getV4(this); }
+ QV4::ExecutionEngine *v4Engine() { return handle(); }
Q_INVOKABLE void injectFunction(const QString &functionName, InjectedFunction injectedFunction)
{
@@ -88,7 +87,7 @@ public:
QV4::ScopedString name(scope, v4->newString(functionName));
QV4::ScopedContext ctx(scope, v4->rootContext());
- QV4::ScopedValue function(scope, BuiltinFunction::create(ctx, name, injectedFunction));
+ QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(ctx, name, injectedFunction));
v4->globalObject->put(name, function);
}
@@ -343,7 +342,6 @@ void tst_qv4debugger::init()
m_javaScriptThread = new QThread;
m_engine = new TestEngine;
m_v4 = m_engine->v4Engine();
- m_v4->iselFactory.reset(new QV4::Moth::ISelFactory);
m_v4->setDebugger(new QV4Debugger(m_v4));
m_engine->moveToThread(m_javaScriptThread);
m_javaScriptThread->start();
@@ -438,9 +436,9 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QCOMPARE(state.lineNumber, 2);
}
-static void someCall(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+static QV4::ReturnedValue someCall(const FunctionObject *function, const QV4::Value *, const QV4::Value *, int)
{
- static_cast<QV4Debugger *>(scope.engine->debugger())
+ static_cast<QV4Debugger *>(function->engine()->debugger())
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
RETURN_UNDEFINED();
}
@@ -464,7 +462,7 @@ void tst_qv4debugger::conditionalBreakPoint()
{
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function test() {\n"
+ "var test = function() {\n"
" for (var i = 0; i < 15; ++i) {\n"
" var x = i;\n"
" }\n"
@@ -489,9 +487,8 @@ void tst_qv4debugger::conditionalBreakPoint()
void tst_qv4debugger::conditionalBreakPointInQml()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 = engine.handle();
QV4Debugger *v4Debugger = new QV4Debugger(v4);
- v4->iselFactory.reset(new QV4::Moth::ISelFactory);
v4->setDebugger(v4Debugger);
QScopedPointer<QThread> debugThread(new QThread);
@@ -531,7 +528,7 @@ void tst_qv4debugger::readArguments()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b, c, d) {\n"
+ "var f = function(a, b, c, d) {\n"
" return a === b\n"
"}\n"
"var four;\n"
@@ -557,7 +554,7 @@ void tst_qv4debugger::readLocals()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b) {\n"
+ "var f = function(a, b) {\n"
" var c = a + b\n"
" var d = a - b\n" // breakpoint, c should be set, d should be undefined
" return c === d\n"
@@ -583,7 +580,7 @@ void tst_qv4debugger::readObject()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a) {\n"
+ "var f = function(a) {\n"
" var b = a\n"
" return b\n"
"}\n"
@@ -630,7 +627,7 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf"));
QJsonObject b_tail_tail = b_tail_props.at(1).toObject();
QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail"));
- QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null"));
+ QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_tail.value("value").isNull());
}
@@ -641,7 +638,7 @@ void tst_qv4debugger::readContextInAllFrames()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function fact(n) {\n"
+ "var fact = function(n) {\n"
" if (n > 1) {\n"
" var n_1 = n - 1;\n"
" n_1 = fact(n_1);\n"
@@ -814,13 +811,13 @@ void tst_qv4debugger::lastLineOfConditional_data()
QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7;
QTest::newRow("if true {block}") << "if (true) {\n" << "}"
- << 4 << 7;
+ << 4 << 8;
QTest::newRow("if false {block}") << "if (false) {\n" << "}"
<< 2 << 8;
QTest::newRow("if true else {block}") << "if (true) {\n" << "} else {\n ret += 8;\n}"
- << 4 << 7;
+ << 4 << 10;
QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}"
- << 8 << 9;
+ << 8 << 10;
QTest::newRow("for statement") << "for (var i = 0; i < 10; ++i)\n" << "" << 4 << 2;
QTest::newRow("for..in statement") << "for (var i in [0, 1, 2, 3, 4])\n" << "" << 4 << 2;
@@ -829,11 +826,11 @@ void tst_qv4debugger::lastLineOfConditional_data()
// For two nested if statements without blocks, we need to map the jump from the inner to the
// outer one on the outer "if". There is just no better place.
- QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 2;
+ QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 8;
QTest::newRow("if false statement") << "if (false)\n" << "" << 2 << 8;
// Also two nested ifs without blocks.
- QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 2;
+ QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 9;
QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9;
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index d31efc84cf..8ecbe53822 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -27,13 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtCore/qeventloop.h>
#include <QtCore/qtimer.h>
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -116,192 +117,114 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
emit serverMessage(ba);
}
-QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
- : QObject(parent)
- , m_executable(executable)
- , m_started(false)
- , m_port(0)
- , m_maximumBindErrors(0)
- , m_receivedBindErrors(0)
-{
- m_process.setProcessChannelMode(QProcess::MergedChannels);
- m_timer.setSingleShot(true);
- m_timer.setInterval(15000);
- connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
- connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)),
- this, SLOT(processError(QProcess::ProcessError)));
- connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
-}
+template<typename F>
+struct Finalizer {
+ F m_lambda;
+ Finalizer(F &&lambda) : m_lambda(std::forward<F>(lambda)) {}
+ ~Finalizer() { m_lambda(); }
+};
-QQmlDebugProcess::~QQmlDebugProcess()
+template<typename F>
+static Finalizer<F> defer(F &&lambda)
{
- stop();
+ return Finalizer<F>(std::forward<F>(lambda));
}
-QString QQmlDebugProcess::state()
+QQmlDebugTest::ConnectResult QQmlDebugTest::connect(
+ const QString &executable, const QString &services, const QString &extraArgs,
+ bool block)
{
- QString stateStr;
- switch (m_process.state()) {
- case QProcess::NotRunning: {
- stateStr = "not running";
- if (m_process.exitStatus() == QProcess::CrashExit)
- stateStr += " (crashed!)";
- else
- stateStr += ", return value " + QString::number(m_process.exitCode());
- break;
- }
- case QProcess::Starting: stateStr = "starting"; break;
- case QProcess::Running: stateStr = "running"; break;
- }
- return stateStr;
-}
+ QStringList arguments;
+ arguments << QString::fromLatin1("-qmljsdebugger=port:13773,13783%3%4")
+ .arg(block ? QStringLiteral(",block") : QString())
+ .arg(services.isEmpty() ? services : (QStringLiteral(",services:") + services))
+ << extraArgs;
-void QQmlDebugProcess::start(const QStringList &arguments)
-{
-#ifdef Q_OS_MAC
- // make sure m_executable points to the actual binary even if it's inside an app bundle
- QFileInfo binFile(m_executable);
- if (!binFile.isExecutable()) {
- QDir bundleDir(m_executable + ".app");
- if (bundleDir.exists()) {
- m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
- //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
- }
- }
-#endif
- m_mutex.lock();
- m_port = 0;
- m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
- m_process.start(m_executable, arguments);
- 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();
-}
+ m_process = createProcess(executable);
+ if (!m_process)
+ return ProcessFailed;
-void QQmlDebugProcess::stop()
-{
- if (m_process.state() != QProcess::NotRunning) {
- m_process.kill();
- m_process.waitForFinished(5000);
- }
-}
+ m_process->start(QStringList() << arguments);
+ if (!m_process->waitForSessionStart())
+ return SessionFailed;
-void QQmlDebugProcess::setMaximumBindErrors(int ignore)
-{
- m_maximumBindErrors = ignore;
-}
+ m_connection = createConnection();
+ if (!m_connection)
+ return ConnectionFailed;
-void QQmlDebugProcess::timeout()
-{
- qWarning() << "Timeout while waiting for QML debugging messages "
- "in application output. Process is in state" << m_process.state() << ", Output:" << m_output << ".";
- m_eventLoop.quit();
-}
+ m_clients = createClients();
+ if (m_clients.contains(nullptr))
+ return ClientsFailed;
-bool QQmlDebugProcess::waitForSessionStart()
-{
- if (m_process.state() != QProcess::Running) {
- qWarning() << "Could not start up " << m_executable;
- return false;
- } else if (m_started) {
+ auto allEnabled = [this]() {
+ for (QQmlDebugClient *client : m_clients) {
+ if (client->state() != QQmlDebugClient::Enabled)
+ return false;
+ }
return true;
+ };
+
+ QList<QQmlDebugClient *> 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())
+ return EnableFailed;
+
+ const QQmlDebugClient::State expectedState = services.isEmpty() ? QQmlDebugClient::Enabled
+ : QQmlDebugClient::Unavailable;
+ for (QQmlDebugClient *other : others) {
+ if (other->state() != expectedState)
+ return RestrictFailed;
}
- m_eventLoop.exec();
-
- return m_started;
+ return ConnectSuccess;
}
-int QQmlDebugProcess::debugPort() const
+QList<QQmlDebugClient *> QQmlDebugTest::createClients()
{
- return m_port;
+ return QList<QQmlDebugClient *>();
}
-bool QQmlDebugProcess::waitForFinished()
+QQmlDebugProcess *QQmlDebugTest::createProcess(const QString &executable)
{
- return m_process.waitForFinished();
+ return new QQmlDebugProcess(executable, this);
}
-QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+QQmlDebugConnection *QQmlDebugTest::createConnection()
{
- return m_process.exitStatus();
+ return new QQmlDebugConnection(this);
}
-void QQmlDebugProcess::addEnvironment(const QString &environment)
+void QQmlDebugTest::cleanup()
{
- m_environment.append(environment);
-}
+ if (QTest::currentTestFailed()) {
+ const QString null = QStringLiteral("null");
-QString QQmlDebugProcess::output() const
-{
- return m_output;
-}
-
-void QQmlDebugProcess::processAppOutput()
-{
- m_mutex.lock();
-
- bool outputFromAppItself = false;
-
- QString newOutput = m_process.readAll();
- m_output.append(newOutput);
- m_outputBuffer.append(newOutput);
-
- while (true) {
- const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
- if (nlIndex < 0) // no further complete lines
- break;
- const QString line = m_outputBuffer.left(nlIndex);
- m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
-
- if (line.contains("QML Debugger:")) {
- const QRegExp portRx("Waiting for connection on port (\\d+)");
- if (portRx.indexIn(line) != -1) {
- m_port = portRx.cap(1).toInt();
- m_timer.stop();
- m_started = true;
- m_eventLoop.quit();
- continue;
- }
- if (line.contains("Unable to listen")) {
- if (++m_receivedBindErrors >= m_maximumBindErrors) {
- if (m_maximumBindErrors == 0)
- qWarning() << "App was unable to bind to port!";
- m_timer.stop();
- m_eventLoop.quit();
- }
- continue;
- }
- } else {
- // set to true if there is output not coming from the debugger
- outputFromAppItself = true;
+ qDebug() << "Process State:" << (m_process ? m_process->state() : null);
+ qDebug() << "Application Output:" << (m_process ? m_process->output() : null);
+ qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
+ for (QQmlDebugClient *client : m_clients) {
+ if (client)
+ qDebug() << client->name() << "State:" << QQmlDebugTest::clientStateString(client);
+ else
+ qDebug() << "Failed Client:" << null;
}
}
- m_mutex.unlock();
- if (outputFromAppItself)
- emit readyReadStandardOutput();
-}
+ qDeleteAll(m_clients);
+ m_clients.clear();
-void QQmlDebugProcess::processError(QProcess::ProcessError error)
-{
- if (!m_eventLoop.isRunning())
- return;
-
- qDebug() << "An error occurred while waiting for debug process to become available:";
- switch (error) {
- case QProcess::FailedToStart: qDebug() << "Process failed to start."; break;
- case QProcess::Crashed: qDebug() << "Process crashed."; break;
- case QProcess::Timedout: qDebug() << "Process timed out."; break;
- case QProcess::WriteError: qDebug() << "Error while writing to process."; break;
- case QProcess::ReadError: qDebug() << "Error while reading from process."; break;
- case QProcess::UnknownError: qDebug() << "Unknown process error."; break;
- }
+ delete m_connection;
+ m_connection = nullptr;
- m_eventLoop.exit();
+ if (m_process) {
+ m_process->stop();
+ delete m_process;
+ m_process = nullptr;
+ }
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index 1983f3583e..13dcdb91d8 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,4 +1,11 @@
QT += qmldebug-private
-HEADERS += $$PWD/debugutil_p.h
-SOURCES += $$PWD/debugutil.cpp
+INCLUDEPATH += $$PWD
+include($$PWD/../../../shared/util.pri)
+
+HEADERS += \
+ $$PWD/debugutil_p.h \
+ $$PWD/qqmldebugprocess_p.h
+SOURCES += \
+ $$PWD/debugutil.cpp \
+ $$PWD/qqmldebugprocess.cpp
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 1ec0a6513d..94ad83bfce 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -41,23 +40,43 @@
// We mean it.
//
+#include <../../../shared/util.h>
#include <private/qqmldebugclient_p.h>
-#include <QtCore/qeventloop.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qprocess.h>
-#include <QtCore/qmutex.h>
-#include <QtTest/qtest.h>
-#include <QtQml/qqmlengine.h>
-
-class QQmlDebugTest
+class QQmlDebugProcess;
+class QQmlDebugTest : public QQmlDataTest
{
+ Q_OBJECT
public:
static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000);
static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection);
static QString clientStateString(const QQmlDebugClient *client);
static QString connectionStateString(const QQmlDebugConnection *connection);
+
+protected:
+ enum ConnectResult {
+ ConnectSuccess,
+ ProcessFailed,
+ SessionFailed,
+ ConnectionFailed,
+ ClientsFailed,
+ EnableFailed,
+ RestrictFailed
+ };
+
+ ConnectResult connect(const QString &executable, const QString &services,
+ const QString &extraArgs, bool block);
+
+ virtual QQmlDebugProcess *createProcess(const QString &executable);
+ virtual QQmlDebugConnection *createConnection();
+ virtual QList<QQmlDebugClient *> createClients();
+
+ QQmlDebugProcess *m_process = nullptr;
+ QQmlDebugConnection *m_connection = nullptr;
+ QList<QQmlDebugClient *> m_clients;
+
+protected slots:
+ virtual void cleanup();
};
class QQmlDebugTestClient : public QQmlDebugClient
@@ -80,51 +99,6 @@ private:
QByteArray lastMsg;
};
-class QQmlDebugProcess : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugProcess(const QString &executable, QObject *parent = 0);
- ~QQmlDebugProcess();
-
- QString state();
-
- void addEnvironment(const QString &environment);
-
- void start(const QStringList &arguments);
- bool waitForSessionStart();
- int debugPort() const;
-
- bool waitForFinished();
- QProcess::ExitStatus exitStatus() const;
-
- QString output() const;
- void stop();
- void setMaximumBindErrors(int numErrors);
-
-signals:
- void readyReadStandardOutput();
-
-private slots:
- void timeout();
- void processAppOutput();
- void processError(QProcess::ProcessError error);
-
-private:
- QString m_executable;
- QProcess m_process;
- QString m_outputBuffer;
- QString m_output;
- QTimer m_timer;
- QEventLoop m_eventLoop;
- QMutex m_mutex;
- bool m_started;
- QStringList m_environment;
- int m_port;
- int m_maximumBindErrors;
- int m_receivedBindErrors;
-};
-
class QQmlInspectorResultRecipient : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
new file mode 100644
index 0000000000..201a6b1a76
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugprocess_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+
+QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
+ : QObject(parent)
+ , m_executable(executable)
+ , m_state(SessionUnknown)
+ , m_port(0)
+ , m_maximumBindErrors(0)
+ , m_receivedBindErrors(0)
+{
+ m_process.setProcessChannelMode(QProcess::MergedChannels);
+ m_timer.setSingleShot(true);
+ m_timer.setInterval(15000);
+ connect(&m_process, &QProcess::readyReadStandardOutput,
+ this, &QQmlDebugProcess::processAppOutput);
+ connect(&m_process, &QProcess::errorOccurred,
+ this, &QQmlDebugProcess::processError);
+ connect(&m_process, QOverload<int>::of(&QProcess::finished),
+ this, [this]() {
+ m_timer.stop();
+ m_eventLoop.quit();
+ });
+ connect(&m_timer, &QTimer::timeout,
+ this, &QQmlDebugProcess::timeout);
+}
+
+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 " + QString::number(m_process.exitCode());
+ break;
+ }
+ case QProcess::Starting:
+ stateStr = "starting";
+ break;
+ case QProcess::Running:
+ stateStr = "running";
+ break;
+ }
+ return stateStr;
+}
+
+void QQmlDebugProcess::start(const QStringList &arguments)
+{
+#ifdef Q_OS_MAC
+ // make sure m_executable points to the actual binary even if it's inside an app bundle
+ QFileInfo binFile(m_executable);
+ if (!binFile.isExecutable()) {
+ QDir bundleDir(m_executable + ".app");
+ if (bundleDir.exists()) {
+ m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
+ //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
+ }
+ }
+#endif
+ m_mutex.lock();
+ m_port = 0;
+ m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
+ m_process.start(m_executable, arguments);
+ if (!m_process.waitForStarted()) {
+ qWarning() << "QML Debug Client: Could not launch app " << m_executable
+ << ": " << m_process.errorString();
+ m_eventLoop.quit();
+ }
+ m_mutex.unlock();
+}
+
+void QQmlDebugProcess::stop()
+{
+ if (m_process.state() != QProcess::NotRunning) {
+ disconnect(&m_process, &QProcess::errorOccurred, this, &QQmlDebugProcess::processError);
+ m_process.kill();
+ m_process.waitForFinished(5000);
+ }
+}
+
+void QQmlDebugProcess::setMaximumBindErrors(int ignore)
+{
+ m_maximumBindErrors = ignore;
+}
+
+void QQmlDebugProcess::timeout()
+{
+ qWarning() << "Timeout while waiting for QML debugging messages "
+ "in application output. Process is in state" << m_process.state()
+ << ", Output:" << m_output << ".";
+ m_eventLoop.quit();
+}
+
+bool QQmlDebugProcess::waitForSessionStart()
+{
+ if (m_process.state() != QProcess::Running) {
+ qWarning() << "Could not start up " << m_executable;
+ return false;
+ } else if (m_state == SessionStarted) {
+ return true;
+ } else if (m_state == SessionFailed) {
+ return false;
+ }
+
+ m_timer.start();
+ m_eventLoop.exec();
+
+ return m_state == SessionStarted;
+}
+
+int QQmlDebugProcess::debugPort() const
+{
+ return m_port;
+}
+
+bool QQmlDebugProcess::waitForFinished()
+{
+ return m_process.waitForFinished();
+}
+
+QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+{
+ return m_process.exitStatus();
+}
+
+void QQmlDebugProcess::addEnvironment(const QString &environment)
+{
+ m_environment.append(environment);
+}
+
+QString QQmlDebugProcess::output() const
+{
+ return m_output;
+}
+
+void QQmlDebugProcess::processAppOutput()
+{
+ m_mutex.lock();
+
+ bool outputFromAppItself = false;
+
+ QString newOutput = m_process.readAll();
+ m_output.append(newOutput);
+ m_outputBuffer.append(newOutput);
+
+ while (true) {
+ const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
+ if (nlIndex < 0) // no further complete lines
+ break;
+ const QString line = m_outputBuffer.left(nlIndex);
+ m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
+
+ if (line.contains("QML Debugger:")) {
+ const QRegExp portRx("Waiting for connection on port (\\d+)");
+ if (portRx.indexIn(line) != -1) {
+ m_port = portRx.cap(1).toInt();
+ m_timer.stop();
+ m_state = SessionStarted;
+ m_eventLoop.quit();
+ continue;
+ }
+ if (line.contains("Unable to listen")) {
+ if (++m_receivedBindErrors >= m_maximumBindErrors) {
+ if (m_maximumBindErrors == 0)
+ qWarning() << "App was unable to bind to port!";
+ m_timer.stop();
+ m_state = SessionFailed;
+ m_eventLoop.quit();
+ }
+ continue;
+ }
+ }
+
+ // set to true if there is output not coming from the debugger or we don't understand it
+ outputFromAppItself = true;
+ }
+ m_mutex.unlock();
+
+ if (outputFromAppItself)
+ emit readyReadStandardOutput();
+}
+
+void QQmlDebugProcess::processError(QProcess::ProcessError error)
+{
+ qDebug() << "An error occurred while waiting for debug process to become available:";
+ switch (error) {
+ case QProcess::FailedToStart:
+ qDebug() << "Process failed to start.";
+ break;
+ case QProcess::Crashed:
+ qDebug() << "Process crashed.";
+ break;
+ case QProcess::Timedout:
+ qDebug() << "Process timed out.";
+ break;
+ case QProcess::WriteError:
+ qDebug() << "Error while writing to process.";
+ break;
+ case QProcess::ReadError:
+ qDebug() << "Error while reading from process.";
+ break;
+ case QProcess::UnknownError:
+ qDebug() << "Unknown process error.";
+ break;
+ }
+}
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
new file mode 100644
index 0000000000..fd2c89bb41
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGPROCESS_P_H
+#define QQMLDEBUGPROCESS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qeventloop.h>
+#include <QtCore/qmutex.h>
+
+class QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+public:
+ QQmlDebugProcess(const QString &executable, QObject *parent = 0);
+ ~QQmlDebugProcess();
+
+ QString state();
+
+ void addEnvironment(const QString &environment);
+
+ void start(const QStringList &arguments);
+ bool waitForSessionStart();
+ int debugPort() const;
+
+ bool waitForFinished();
+ QProcess::ExitStatus exitStatus() const;
+
+ QString output() const;
+ void stop();
+ void setMaximumBindErrors(int numErrors);
+
+signals:
+ void readyReadStandardOutput();
+
+private slots:
+ void timeout();
+ void processAppOutput();
+ void processError(QProcess::ProcessError error);
+
+private:
+ enum SessionState {
+ SessionUnknown,
+ SessionStarted,
+ SessionFailed
+ };
+
+ QString m_executable;
+ QProcess m_process;
+ QString m_outputBuffer;
+ QString m_output;
+ QTimer m_timer;
+ QEventLoop m_eventLoop;
+ QMutex m_mutex;
+ SessionState m_state;
+ QStringList m_environment;
+ int m_port;
+ int m_maximumBindErrors;
+ int m_receivedBindErrors;
+};
+
+#endif // QQMLDEBUGPROCESS_P_H
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index c0252a0290..7e736ec400 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -385,7 +385,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
case QmlObjectProperty::Object:
{
QmlDebugObjectReference obj;
- obj.debugId = prop.value.toInt();
+ obj.name = data.value.toString();
obj.className = prop.valueTypeName;
prop.value = qVariantFromValue(obj);
break;