From af4516ac866cc877c3a033d6b837b30445ee8f1a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 26 Aug 2016 18:19:37 +0200 Subject: QmlDebug: Allow specifying debug connectors on the command line With this change arbitrary debug connector plugins can be loaded by specifying them in the "-qmljsdebugger=..." argument. It was already possible to load them by using startDebugConnector(...), but that requires source code modification. Change-Id: I06ec7f54ec65add7cff2846ed4083ea878a04765 Reviewed-by: Simon Hausmann --- .../qmldbg_native/qqmlnativedebugconnector.cpp | 4 +- .../qmltooling/qmldbg_server/qqmldebugserver.cpp | 4 +- src/qml/debugger/qqmldebugconnector.cpp | 10 +++ .../qqmldebuggingenabler/data/test.qml | 1 + .../tst_qqmldebuggingenabler.cpp | 96 ++++++++++++++-------- .../qqmldebuggingenablerserver.cpp | 23 +++++- 6 files changed, 97 insertions(+), 41 deletions(-) diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp index 9eeb285951..1a318b3ca2 100644 --- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp +++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp @@ -183,7 +183,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector() : m_blockingMode(false) { const QString args = commandLineArguments(); - const auto lstjsDebugArguments = args.splitRef(QLatin1Char(',')); + const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts); QStringList services; for (const QStringRef &strArgument : lstjsDebugArguments) { if (strArgument == QLatin1String("block")) { @@ -195,7 +195,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector() services.append(strArgument.mid(9).toString()); } else if (!services.isEmpty()) { services.append(strArgument.toString()); - } else { + } else if (!strArgument.startsWith(QLatin1String("connector:"))) { qWarning("QML Debugger: Invalid argument \"%s\" detected. Ignoring the same.", strArgument.toUtf8().constData()); } diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index f449989598..f6f48e43a4 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -346,7 +346,7 @@ void QQmlDebugServerImpl::parseArguments() QString fileName; QStringList services; - const auto lstjsDebugArguments = args.splitRef(QLatin1Char(',')); + const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts); for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) { const QStringRef &strArgument = *argsIt; if (strArgument.startsWith(QLatin1String("port:"))) { @@ -377,7 +377,7 @@ void QQmlDebugServerImpl::parseArguments() services.append(strArgument.mid(9).toString()); } else if (!services.isEmpty()) { services.append(strArgument.toString()); - } else { + } else if (!strArgument.startsWith(QLatin1String("connector:"))) { const QString message = tr("QML Debugger: Invalid argument \"%1\" detected." " Ignoring the same.").arg(strArgument.toString()); qWarning("%s", qPrintable(message)); diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index 029df1e748..3adf335ffd 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -126,6 +126,16 @@ QQmlDebugConnector *QQmlDebugConnector::instance() params->instance = loadQQmlDebugConnector(params->pluginKey); } else if (params->arguments.isEmpty()) { return 0; // no explicit class name given and no command line arguments + } else if (params->arguments.startsWith(QLatin1String("connector:"))) { + static const int connectorBegin = int(strlen("connector:")); + + int connectorEnd = params->arguments.indexOf(QLatin1Char(','), connectorBegin); + if (connectorEnd == -1) + connectorEnd = params->arguments.length(); + + params->instance = loadQQmlDebugConnector(params->arguments.mid( + connectorBegin, + connectorEnd - connectorBegin)); } else { params->instance = loadQQmlDebugConnector( params->arguments.startsWith(QLatin1String("native")) ? diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/data/test.qml b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/data/test.qml index a36d0cae91..0fa9f1ffd8 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/data/test.qml +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/data/test.qml @@ -36,6 +36,7 @@ Item { var b = {a: "hello", d: 1 } var c var d = 12 + console.log("Component.onCompleted"); } function foo() { var a = [1, 2] diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp index 8d1a165243..3aa3a5c87e 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp @@ -142,24 +142,36 @@ void tst_QQmlDebuggingEnabler::cleanup() void tst_QQmlDebuggingEnabler::data() { + QTest::addColumn("connector"); QTest::addColumn("blockMode"); QTest::addColumn("services"); - QTest::newRow("noblock,all") << false << QStringList(); - QTest::newRow("block,all") << true << QStringList(); - QTest::newRow("noblock,debugger") << false << QQmlDebuggingEnabler::debuggerServices(); - QTest::newRow("block,debugger") << true << QQmlDebuggingEnabler::debuggerServices(); - QTest::newRow("noblock,inspector") << false << QQmlDebuggingEnabler::inspectorServices(); - QTest::newRow("block,inspector") << true << QQmlDebuggingEnabler::inspectorServices(); - QTest::newRow("noblock,profiler") << false << QQmlDebuggingEnabler::profilerServices(); - QTest::newRow("block,profiler") << true << QQmlDebuggingEnabler::profilerServices(); - QTest::newRow("noblock,debugger+inspector") - << false << QQmlDebuggingEnabler::debuggerServices() + - QQmlDebuggingEnabler::inspectorServices(); - QTest::newRow("block,debugger+inspector") - << true << QQmlDebuggingEnabler::debuggerServices() + - QQmlDebuggingEnabler::inspectorServices(); - + QStringList connectors({ + QLatin1String("QQmlDebugServer"), + QLatin1String("QQmlNativeDebugConnector") + }); + + QList blockModes({ true, false }); + + QList serviceLists({ + QStringList(), + QQmlDebuggingEnabler::nativeDebuggerServices(), + QQmlDebuggingEnabler::debuggerServices(), + QQmlDebuggingEnabler::inspectorServices(), + QQmlDebuggingEnabler::profilerServices(), + QQmlDebuggingEnabler::debuggerServices() + QQmlDebuggingEnabler::inspectorServices() + }); + + foreach (const QString &connector, connectors) { + foreach (bool blockMode, blockModes) { + foreach (const QStringList &serviceList, serviceLists) { + QString name = connector + QLatin1Char(',') + + QLatin1String(blockMode ? "block" : "noblock") + QLatin1Char(',') + + serviceList.join(QLatin1Char('-')); + QTest::newRow(name.toUtf8().constData()) << connector << blockMode << serviceList; + } + } + } } void tst_QQmlDebuggingEnabler::qmlscene_data() @@ -169,27 +181,36 @@ void tst_QQmlDebuggingEnabler::qmlscene_data() void tst_QQmlDebuggingEnabler::qmlscene() { + QFETCH(QString, connector); QFETCH(bool, blockMode); QFETCH(QStringList, services); - connection = new QQmlDebugConnection(); - QList clients = QQmlDebugTest::createOtherClients(connection); process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); process->setMaximumBindErrors(1); process->start(QStringList() - << QString::fromLatin1("-qmljsdebugger=port:5555,5565%1%2%3") + << 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"))); - QVERIFY(process->waitForSessionStart()); - connection->connectToHost("127.0.0.1", process->debugPort()); - QVERIFY(connection->waitForConnected()); - foreach (QQmlDebugClient *client, clients) - QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? - QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); + if (connector == QLatin1String("QQmlDebugServer")) { + QVERIFY(process->waitForSessionStart()); + connection = new QQmlDebugConnection(); + QList clients = QQmlDebugTest::createOtherClients(connection); + connection->connectToHost("127.0.0.1", process->debugPort()); + QVERIFY(connection->waitForConnected()); + foreach (QQmlDebugClient *client, clients) + QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? + QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); + } + + QCOMPARE(process->state(), QLatin1String("running")); + if (!blockMode) + QTRY_VERIFY(process->output().contains(QLatin1String("qml: Component.onCompleted"))); } void tst_QQmlDebuggingEnabler::custom_data() @@ -199,13 +220,12 @@ void tst_QQmlDebuggingEnabler::custom_data() void tst_QQmlDebuggingEnabler::custom() { + QFETCH(QString, connector); QFETCH(bool, blockMode); QFETCH(QStringList, services); const int portFrom = 5555; const int portTo = 5565; - connection = new QQmlDebugConnection(); - QList clients = QQmlDebugTest::createOtherClients(connection); process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebuggingenablerserver"), this); process->setMaximumBindErrors(portTo - portFrom); @@ -214,18 +234,28 @@ void tst_QQmlDebuggingEnabler::custom() if (blockMode) args << QLatin1String("-block"); - args << QString::number(portFrom) << QString::number(portTo); + args << QLatin1String("-connector") << connector + << QString::number(portFrom) << QString::number(portTo); + if (!services.isEmpty()) args << QLatin1String("-services") << services; process->start(args); - QVERIFY(process->waitForSessionStart()); - connection->connectToHost("127.0.0.1", process->debugPort()); - QVERIFY(connection->waitForConnected()); - foreach (QQmlDebugClient *client, clients) - QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? - QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); + if (connector == QLatin1String("QQmlDebugServer")) { + QVERIFY(process->waitForSessionStart()); + connection = new QQmlDebugConnection(); + QList clients = QQmlDebugTest::createOtherClients(connection); + connection->connectToHost("127.0.0.1", process->debugPort()); + QVERIFY(connection->waitForConnected()); + foreach (QQmlDebugClient *client, clients) + QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? + QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); + } + + QCOMPARE(process->state(), QLatin1String("running")); + if (!blockMode) + QTRY_VERIFY(process->output().contains(QLatin1String("QQmlEngine created"))); } QTEST_MAIN(tst_QQmlDebuggingEnabler) diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp index cfbb31f9e1..a064bbbacc 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -40,12 +41,18 @@ int main(int argc, char *argv[]) QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); arguments.removeFirst(); + QString connector = QLatin1String("QQmlDebugServer"); if (arguments.size() && arguments.first() == QLatin1String("-block")) { block = QQmlDebuggingEnabler::WaitForClient; arguments.removeFirst(); } + if (arguments.size() >= 2 && arguments.first() == QLatin1String("-connector")) { + arguments.removeFirst(); + connector = arguments.takeFirst(); + } + if (arguments.size() >= 2) { portFrom = arguments.takeFirst().toInt(); portTo = arguments.takeFirst().toInt(); @@ -54,12 +61,20 @@ int main(int argc, char *argv[]) if (arguments.size() && arguments.takeFirst() == QLatin1String("-services")) QQmlDebuggingEnabler::setServices(arguments); - if (!portFrom || !portTo) - qFatal("Port range has to be specified."); + if (connector == QLatin1String("QQmlDebugServer")) { + if (!portFrom || !portTo) + qFatal("Port range has to be specified."); + + while (portFrom <= portTo) + QQmlDebuggingEnabler::startTcpDebugServer(portFrom++, block); + } else if (connector == QLatin1String("QQmlNativeDebugConnector")) { + QVariantHash configuration; + configuration[QLatin1String("block")] = (block == QQmlDebuggingEnabler::WaitForClient); + QQmlDebuggingEnabler::startDebugConnector(connector, configuration); + } - while (portFrom <= portTo) - QQmlDebuggingEnabler::startTcpDebugServer(portFrom++, block); QQmlEngine engine; + qDebug() << "QQmlEngine created\n"; Q_UNUSED(engine); return app.exec(); } -- cgit v1.2.3