diff options
10 files changed, 170 insertions, 26 deletions
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp index fbdb201b04..86e1a70841 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp +++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp @@ -54,7 +54,8 @@ class QTcpServerConnectionPrivate { public: QTcpServerConnectionPrivate(); - int port; + int portFrom; + int portTo; bool block; QString hostaddress; QTcpSocket *socket; @@ -65,7 +66,8 @@ public: }; QTcpServerConnectionPrivate::QTcpServerConnectionPrivate() : - port(0), + portFrom(0), + portTo(0), block(false), socket(0), protocol(0), @@ -135,10 +137,12 @@ bool QTcpServerConnection::waitForMessage() return d->protocol->waitForReadyRead(-1); } -void QTcpServerConnection::setPort(int port, bool block, const QString &hostaddress) +void QTcpServerConnection::setPortRange(int portFrom, int portTo, bool block, + const QString &hostaddress) { Q_D(QTcpServerConnection); - d->port = port; + d->portFrom = portFrom; + d->portTo = portTo; d->block = block; d->hostaddress = hostaddress; @@ -163,10 +167,20 @@ void QTcpServerConnection::listen() } else { hostaddress = QHostAddress::Any; } - if (d->tcpServer->listen(hostaddress, d->port)) - qDebug("QML Debugger: Waiting for connection on port %d...", d->port); - else - qWarning("QML Debugger: Unable to listen to port %d.", d->port); + int port = d->portFrom; + do { + if (d->tcpServer->listen(hostaddress, port)) { + qDebug("QML Debugger: Waiting for connection on port %d...", port); + break; + } + ++port; + } while (port <= d->portTo); + if (port > d->portTo) { + if (d->portFrom == d->portTo) + qWarning("QML Debugger: Unable to listen to port %d.", d->portFrom); + else + qWarning("QML Debugger: Unable to listen to ports %d - %d.", d->portFrom, d->portTo); + } } diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h index 33157906c8..525ed50e51 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h +++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h @@ -61,7 +61,7 @@ public: ~QTcpServerConnection(); void setServer(QQmlDebugServer *server); - void setPort(int port, bool bock, const QString &hostaddress); + void setPortRange(int portFrom, int portTo, bool bock, const QString &hostaddress); bool isConnected() const; void send(const QList<QByteArray> &messages); diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index 7c9928c43c..27e3d226cd 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -123,8 +123,9 @@ public: m_pluginName = pluginName; } - void setPort(int port, bool block, QString &hostAddress) { - m_port = port; + void setPortRange(int portFrom, int portTo, bool block, QString &hostAddress) { + m_portFrom = portFrom; + m_portTo = portTo; m_block = block; m_hostAddress = hostAddress; } @@ -133,7 +134,8 @@ public: private: QString m_pluginName; - int m_port; + int m_portFrom; + int m_portTo; bool m_block; QString m_hostAddress; }; @@ -225,7 +227,7 @@ void QQmlDebugServerThread::run() = server->d_func()->loadConnectionPlugin(m_pluginName); if (connection) { connection->setServer(QQmlDebugServer::instance()); - connection->setPort(m_port, m_block, m_hostAddress); + connection->setPortRange(m_portFrom, m_portTo, m_block, m_hostAddress); } else { QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp)); qWarning() << QString(QLatin1String("QML Debugger: Ignoring \"-qmljsdebugger=%1\". " @@ -272,12 +274,13 @@ QQmlDebugServer *QQmlDebugServer::instance() QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp)); #ifndef QT_QML_NO_DEBUGGER // ### remove port definition when protocol is changed - int port = 0; + int portFrom = 0; + int portTo = 0; bool block = false; bool ok = false; QString hostAddress; - // format: qmljsdebugger=port:3768[,host:<ip address>][,block] OR qmljsdebugger=ost[,block] + // format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block] if (!appD->qmljsDebugArgumentsString().isEmpty()) { if (!QQmlEnginePrivate::qml_debugging_enabled) { qWarning() << QString(QLatin1String( @@ -290,9 +293,21 @@ QQmlDebugServer *QQmlDebugServer::instance() QString pluginName; QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString() .split(QLatin1Char(',')); - foreach (const QString &strArgument, lstjsDebugArguments) { + QStringList::const_iterator argsItEnd = lstjsDebugArguments.end(); + QStringList::const_iterator argsIt = lstjsDebugArguments.begin(); + for (; argsIt != argsItEnd; ++argsIt) { + const QString strArgument = *argsIt; if (strArgument.startsWith(QLatin1String("port:"))) { - port = strArgument.mid(5).toInt(&ok); + portFrom = strArgument.mid(5).toInt(&ok); + portTo = portFrom; + QStringList::const_iterator argsNext = argsIt + 1; + if (argsNext == argsItEnd) + break; + const QString nextArgument = *argsNext; + if (ok && nextArgument.contains(QRegExp(QStringLiteral("^\\s*\\d+\\s*$")))) { + portTo = nextArgument.toInt(&ok); + ++argsIt; + } pluginName = QLatin1String("qmldbg_tcp"); } else if (strArgument.startsWith(QLatin1String("host:"))) { hostAddress = strArgument.mid(5); @@ -311,7 +326,7 @@ QQmlDebugServer *QQmlDebugServer::instance() qQmlDebugServer->d_func()->thread = thread; qQmlDebugServer->moveToThread(thread); thread->setPluginName(pluginName); - thread->setPort(port, block, hostAddress); + thread->setPortRange(portFrom, portTo, block, hostAddress); QQmlDebugServerPrivate *d = qQmlDebugServer->d_func(); d->blockingMode = block; @@ -325,8 +340,8 @@ QQmlDebugServer *QQmlDebugServer::instance() } else { qWarning() << QString(QLatin1String( "QML Debugger: Ignoring \"-qmljsdebugger=%1\". " - "Format is -qmljsdebugger=port:<port>[,block]")).arg( - appD->qmljsDebugArgumentsString()); + "Format is qmljsdebugger=port:<port_from>[,port_to],host:" + "<ip address>][,block]")).arg(appD->qmljsDebugArgumentsString()); } } #else diff --git a/src/qml/debugger/qqmldebugserverconnection_p.h b/src/qml/debugger/qqmldebugserverconnection_p.h index 82a02bb29e..a7c35c2d2f 100644 --- a/src/qml/debugger/qqmldebugserverconnection_p.h +++ b/src/qml/debugger/qqmldebugserverconnection_p.h @@ -67,7 +67,7 @@ public: virtual ~QQmlDebugServerConnection() {} virtual void setServer(QQmlDebugServer *server) = 0; - virtual void setPort(int port, bool bock, const QString &hostaddress) = 0; + virtual void setPortRange(int portFrom, int portTo, bool bock, const QString &hostaddress) = 0; virtual bool isConnected() const = 0; virtual void send(const QList<QByteArray> &messages) = 0; virtual void disconnect() = 0; diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 3d5d4d5243..9c2ba5bcde 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -124,8 +124,8 @@ const char *UNCAUGHT = "uncaught"; //const char *PAUSE = "pause"; //const char *RESUME = "resume"; -const char *BLOCKMODE = "-qmljsdebugger=port:3771,block"; -const char *NORMALMODE = "-qmljsdebugger=port:3771"; +const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block"; +const char *NORMALMODE = "-qmljsdebugger=port:3771,3800"; const char *TEST_QMLFILE = "test.qml"; const char *TEST_JSFILE = "test.js"; const char *TIMER_QMLFILE = "timer.qml"; @@ -1015,7 +1015,8 @@ bool tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode) return false; } - connection->connectToHost("127.0.0.1", 3771); + const int port = process->debugPort(); + connection->connectToHost("127.0.0.1", port); if (!connection->waitForConnected()) { qDebug() << "could not connect to host!"; return false; diff --git a/tests/auto/qml/debugger/qqmldebugservice/data/test.qml b/tests/auto/qml/debugger/qqmldebugservice/data/test.qml new file mode 100644 index 0000000000..e019ba8b17 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugservice/data/test.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Component.onCompleted: { + var a = [1, 2] + var b = {a: "hello", d: 1 } + var c + var d = 12 + } + function foo() { + var a = [1, 2] + var b = {a: "hello", d: 1 } + var c + var d = 12 + } +} + diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro index 57b0019dfa..5879506a58 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro +++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro @@ -11,6 +11,11 @@ INCLUDEPATH += ../shared include(../../../shared/util.pri) include(../shared/debugutil.pri) +TESTDATA = data/* + +OTHER_FILES += \ + data/test.qml + DEFINES += QT_QML_DEBUG_NO_WARNING QT += qml-private testlib gui-private diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index a895f16dc5..dd4dd003ec 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -44,6 +44,7 @@ #include <QHostAddress> #include <QDebug> #include <QThread> +#include <QLibraryInfo> #include <QtQml/qqmlengine.h> @@ -55,7 +56,7 @@ #define PORT 3769 #define STR_PORT "3769" -class tst_QQmlDebugService : public QObject +class tst_QQmlDebugService : public QQmlDataTest { Q_OBJECT private: @@ -65,6 +66,7 @@ private: private slots: void initTestCase(); + void checkPortRange(); void name(); void version(); void state(); @@ -78,6 +80,7 @@ private slots: void tst_QQmlDebugService::initTestCase() { + QQmlDataTest::initTestCase(); const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); new QQmlEngine(this); @@ -96,6 +99,41 @@ void tst_QQmlDebugService::initTestCase() QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); } +void tst_QQmlDebugService::checkPortRange() +{ + QQmlDebugConnection *connection1 = new QQmlDebugConnection(); + QQmlDebugProcess *process1 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); + + process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3772, 3774 ") << testFile("test.qml")); + + if (!process1->waitForSessionStart()) + QFAIL("could not launch application, or did not get 'Waiting for connection'."); + + const int port1 = process1->debugPort(); + connection1->connectToHost("127.0.0.1", port1); + if (!connection1->waitForConnected()) + QFAIL("could not connect to host!"); + + // Second instance + QQmlDebugConnection *connection2 = new QQmlDebugConnection(); + QQmlDebugProcess *process2 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); + + process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3772,3774") << testFile("test.qml")); + + if (!process2->waitForSessionStart()) + QFAIL("could not launch application, or did not get 'Waiting for connection'."); + + const int port2 = process2->debugPort(); + 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() { QString name = "tst_QQmlDebugService::name()"; diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 7df753df03..6585f7eca2 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -89,6 +89,7 @@ QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent) : QObject(parent) , m_executable(executable) , m_started(false) + , m_port(0) { m_process.setProcessChannelMode(QProcess::MergedChannels); m_timer.setSingleShot(true); @@ -123,6 +124,7 @@ QString QQmlDebugProcess::state() void QQmlDebugProcess::start(const QStringList &arguments) { m_mutex.lock(); + m_port = 0; m_process.setEnvironment(m_environment); m_process.start(m_executable, arguments); if (!m_process.waitForStarted()) { @@ -161,6 +163,11 @@ bool QQmlDebugProcess::waitForSessionStart() return m_started; } +int QQmlDebugProcess::debugPort() const +{ + return m_port; +} + void QQmlDebugProcess::setEnvironment(const QStringList &environment) { m_environment = environment; @@ -187,7 +194,9 @@ void QQmlDebugProcess::processAppOutput() m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1); if (line.contains("QML Debugger:")) { - if (line.contains("Waiting for connection ")) { + 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(); diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index 5b272749ae..363aabbf39 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -93,6 +93,7 @@ public: void start(const QStringList &arguments); bool waitForSessionStart(); + int debugPort() const; QString output() const; void stop(); @@ -111,6 +112,7 @@ private: QMutex m_mutex; bool m_started; QStringList m_environment; + int m_port; }; #endif // DEBUGUTIL_H |