QmlProfiler: Unify local and tcp connection mechanism

Use the URL scheme to distinguish between them, check that in
QmlProfilerClientManager and test all possible combinations of URL
parts.

Change-Id: I6583e5bf18eda0344a299a279c12578c4ebc7ffe
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Ulf Hermann
2017-09-21 12:59:44 +02:00
parent 63e2f9ccdb
commit 63a99936ab
8 changed files with 63 additions and 68 deletions

View File

@@ -293,6 +293,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunControl *runControl, const AndroidRu
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6),
qDebug() << tr("No free ports available on host for QML debugging."));
m_qmlServer.setScheme(urlTcpScheme());
m_qmlServer.setHost(server.serverAddress().toString());
m_qmlServer.setPort(server.serverPort());
}

View File

@@ -46,6 +46,7 @@ QUrl urlFromLocalHostAndFreePort()
{
QUrl serverUrl;
QTcpServer server;
serverUrl.setScheme(urlTcpScheme());
if (server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6)) {
serverUrl.setHost(server.serverAddress().toString());
serverUrl.setPort(server.serverPort());
@@ -68,4 +69,9 @@ QString urlSocketScheme()
return QString("socket");
}
QString urlTcpScheme()
{
return QString("tcp");
}
} // namespace ProjectExplorer

View File

@@ -56,5 +56,6 @@ PROJECTEXPLORER_EXPORT bool operator==(const StandardRunnable &r1, const Standar
PROJECTEXPLORER_EXPORT QUrl urlFromLocalHostAndFreePort();
PROJECTEXPLORER_EXPORT QUrl urlFromLocalSocket();
PROJECTEXPLORER_EXPORT QString urlSocketScheme();
PROJECTEXPLORER_EXPORT QString urlTcpScheme();
} // namespace ProjectExplorer

View File

@@ -29,6 +29,7 @@
#include "qmlprofilerstatemanager.h"
#include <utils/qtcassert.h>
#include <projectexplorer/runnables.h>
namespace QmlProfiler {
namespace Internal {
@@ -65,13 +66,19 @@ void QmlProfilerClientManager::setRetryParams(int interval, int maxAttempts)
m_maximumRetries = maxAttempts;
}
void QmlProfilerClientManager::setServerUrl(const QUrl &server)
void QmlProfilerClientManager::connectToServer(const QUrl &server)
{
if (m_server != server) {
m_server = server;
disconnectClient();
stopConnectionTimer();
}
if (server.scheme() == ProjectExplorer::urlTcpScheme())
connectToTcpServer();
else if (server.scheme() == ProjectExplorer::urlSocketScheme())
startLocalServer();
else
QTC_ASSERT(false, emit connectionFailed());
}
void QmlProfilerClientManager::clearConnection()
@@ -166,9 +173,9 @@ void QmlProfilerClientManager::stopRecording()
void QmlProfilerClientManager::retryConnect()
{
if (m_server.scheme() == "socket") {
if (m_server.scheme() == ProjectExplorer::urlSocketScheme()) {
startLocalServer();
} else if (!m_server.host().isEmpty() && m_server.port() > 0) {
} else if (m_server.scheme() == ProjectExplorer::urlTcpScheme()) {
disconnectClient();
connectToTcpServer();
} else {

View File

@@ -47,7 +47,7 @@ public:
~QmlProfilerClientManager();
void setProfilerStateManager(QmlProfilerStateManager *profilerState);
void setServerUrl(const QUrl &server);
void connectToServer(const QUrl &server);
void clearConnection();
void clearBufferedData();
@@ -58,8 +58,6 @@ public:
void setRetryParams(int interval, int maxAttempts);
void retryConnect();
void connectToTcpServer();
void startLocalServer();
void stopRecording();
@@ -69,6 +67,9 @@ signals:
void connectionClosed();
private:
void connectToTcpServer();
void startLocalServer();
QPointer<QmlProfilerStateManager> m_profilerState;
QPointer<QmlProfilerModelManager> m_modelManager;
QScopedPointer<QmlDebug::QmlDebugConnection> m_connection;

View File

@@ -127,17 +127,10 @@ void QmlProfilerRunner::start()
});
infoBox->show();
});
clientManager->setServerUrl(serverUrl);
if (serverUrl.port() != -1) {
clientManager->connectToTcpServer();
} else {
clientManager->startLocalServer();
}
}, Qt::QueuedConnection); // Queue any connection failures after reportStarted()
clientManager->connectToServer(serverUrl);
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
reportStarted();
}
@@ -284,9 +277,13 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q
StandardRunnable debuggee = runnable().as<StandardRunnable>();
QString code = serverUrl.scheme() == "socket"
? QString("file:%1").arg(serverUrl.path())
: QString("port:%1").arg(serverUrl.port());
QString code;
if (serverUrl.scheme() == urlSocketScheme())
code = QString("file:%1").arg(serverUrl.path());
else if (serverUrl.scheme() == urlTcpScheme())
code = QString("port:%1").arg(serverUrl.port());
else
QTC_CHECK(false);
QString arguments = QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlProfilerServices,
code, true);

View File

@@ -56,6 +56,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
debuggee.environment = Utils::Environment::systemEnvironment();
// should not be used anywhere but cannot be empty
serverUrl.setScheme(ProjectExplorer::urlSocketScheme());
serverUrl.setPath("invalid");
runControl = new ProjectExplorer::RunControl(nullptr,

View File

@@ -73,37 +73,31 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data()
QUrl localUrl = urlFromLocalHostAndFreePort();
QTest::addColumn<QUrl>("serverUrl");
QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", localUrl.host()});
QVarLengthArray<int> ports({-1, 5, localUrl.port()});
QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", urlFromLocalSocket().path()});
const QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", localUrl.host()});
const QVarLengthArray<int> ports({-1, 5, localUrl.port()});
const QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", urlFromLocalSocket().path()});
const QVarLengthArray<QString> schemes({"", urlSocketScheme(), urlTcpScheme()});
foreach (QmlProfilerModelManager *modelManager, modelManagers) {
foreach (QmlProfilerStateManager *stateManager, stateManagers) {
foreach (QString host, hosts) {
foreach (int port, ports) {
QString tag = QString::fromLatin1("%1, %2, %3, %4, %5")
.arg(QLatin1String(modelManager ? "modelManager" : "<null>"))
.arg(QLatin1String(stateManager ? "stateManager" : "<null>"))
.arg(host.isEmpty() ? "<empty>" : host)
.arg(Utils::Port(port).isValid() ? port : 0)
.arg("<empty>");
for (QmlProfilerModelManager *modelManager : modelManagers) {
for (QmlProfilerStateManager *stateManager : stateManagers) {
for (const QString &host : hosts) {
for (int port : ports) {
for (const QString &socket : sockets) {
for (const QString &scheme : schemes ) {
QUrl url;
url.setScheme(scheme);
url.setHost(host);
url.setPort(port);
QTest::newRow(tag.toLatin1().constData()) << modelManager << stateManager << url;
}
}
foreach (QString socket, sockets) {
QString tag = QString::fromLatin1("%1, %2, %3, %4, %5")
url.setPath(socket);
QString tag = QString::fromLatin1("%1, %2, %3")
.arg(QLatin1String(modelManager ? "modelManager" : "<null>"))
.arg(QLatin1String(stateManager ? "stateManager" : "<null>"))
.arg("<empty>")
.arg(0)
.arg(socket);
QUrl url;
url.setScheme(urlSocketScheme());
url.setPath(socket);
QTest::newRow(tag.toLatin1().constData()) << modelManager << stateManager << url;
.arg(url.toString());
QTest::newRow(tag.toLatin1().constData()) << modelManager
<< stateManager << url;
}
}
}
}
}
}
@@ -137,24 +131,17 @@ void QmlProfilerClientManagerTest::testConnectionFailure()
clientManager.setModelManager(modelManager);
clientManager.setProfilerStateManager(stateManager);
clientManager.setServerUrl(serverUrl);
QVERIFY(!clientManager.isConnected());
clientManager.connectToTcpServer();
clientManager.connectToServer(serverUrl);
QTRY_COMPARE(failedSpy.count(), 1);
QCOMPARE(closedSpy.count(), 0);
QCOMPARE(openedSpy.count(), 0);
QVERIFY(!clientManager.isConnected());
clientManager.startLocalServer();
QTRY_COMPARE(failedSpy.count(), 2);
QCOMPARE(closedSpy.count(), 0);
QCOMPARE(openedSpy.count(), 0);
QVERIFY(!clientManager.isConnected());
clientManager.retryConnect();
QTRY_COMPARE(failedSpy.count(), 3);
QTRY_COMPARE(failedSpy.count(), 2);
QCOMPARE(closedSpy.count(), 0);
QCOMPARE(openedSpy.count(), 0);
QVERIFY(!clientManager.isConnected());
@@ -181,8 +168,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveTcp()
server.listen(QHostAddress(serverUrl.host()), serverUrl.port());
QSignalSpy connectionSpy(&server, SIGNAL(newConnection()));
clientManager.setServerUrl(serverUrl);
clientManager.connectToTcpServer();
clientManager.connectToServer(serverUrl);
QTRY_VERIFY(connectionSpy.count() > 0);
QTRY_COMPARE(failedSpy.count(), 1);
@@ -208,8 +194,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveLocal()
QLocalSocket socket;
QSignalSpy connectionSpy(&socket, SIGNAL(connected()));
clientManager.setServerUrl(socketUrl);
clientManager.startLocalServer();
clientManager.connectToServer(socketUrl);
socket.connectToServer(socketUrl.path());
QTRY_COMPARE(connectionSpy.count(), 1);
@@ -280,8 +265,7 @@ void QmlProfilerClientManagerTest::testResponsiveTcp()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
clientManager.setServerUrl(serverUrl);
clientManager.connectToTcpServer();
clientManager.connectToServer(serverUrl);
QTRY_COMPARE(openedSpy.count(), 1);
QCOMPARE(closedSpy.count(), 0);
@@ -329,8 +313,7 @@ void QmlProfilerClientManagerTest::testResponsiveLocal()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
clientManager.setServerUrl(socketUrl);
clientManager.startLocalServer();
clientManager.connectToServer(socketUrl);
{
QScopedPointer<QLocalSocket> socket(new QLocalSocket(this));
@@ -397,8 +380,7 @@ void QmlProfilerClientManagerTest::testInvalidData()
server.listen(QHostAddress(serverUrl.host()), serverUrl.port());
clientManager.setServerUrl(serverUrl);
clientManager.connectToTcpServer();
clientManager.connectToServer(serverUrl);
QTRY_VERIFY(dataSent);
QTRY_COMPARE(failedSpy.count(), 1);
@@ -427,8 +409,7 @@ void QmlProfilerClientManagerTest::testStopRecording()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
clientManager.setServerUrl(socketUrl);
clientManager.startLocalServer();
clientManager.connectToServer(socketUrl);
QScopedPointer<QLocalSocket> socket(new QLocalSocket(this));
socket->connectToServer(socketUrl.path());