From 3346a77474e1b21990b049b824d621413ab9b80f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 9 Nov 2011 14:58:53 +0100 Subject: [PATCH] Debugger: Fix trace service for tracing on startup in block mode Don't call QDeclarativeDebugTrace::instance() inside messageReceived, since messageReceived() will be called for the first message while the constructor is still running. Also add proper autotests for qdeclarativedebugtrace. Change-Id: Ic37d077d93ad4957fb21035abe40b2d281278314 Reviewed-by: Christiaan Janssen --- .../debugger/qdeclarativedebugtrace.cpp | 4 +- .../debugger/qdeclarativedebugtrace_p.h | 2 +- tests/auto/declarative/debugger/debugger.pro | 1 + .../debugger/qdeclarativedebugtrace/data/test.qml | 5 + .../qdeclarativedebugtrace.pro | 14 + .../tst_qdeclarativedebugtrace.cpp | 252 ++++++++++++++++++++ .../auto/declarative/debugger/shared/debugutil.cpp | 21 +- .../auto/declarative/debugger/shared/debugutil_p.h | 1 + 8 files changed, 289 insertions(+), 11 deletions(-) create mode 100644 tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml create mode 100644 tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro create mode 100644 tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp index aed7866..c7987d7 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace.cpp +++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp @@ -275,9 +275,9 @@ void QDeclarativeDebugTrace::messageReceived(const QByteArray &message) if (m_enabled != enabled) { if (enabled) { m_enabled = true; - addEvent(StartTrace); + addEventImpl(StartTrace); } else { - addEvent(EndTrace); + addEventImpl(EndTrace); m_enabled = false; sendMessages(); } diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h index 81bcf5d..51f3e60 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace_p.h +++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h @@ -62,7 +62,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -struct QDeclarativeDebugData +struct Q_AUTOTEST_EXPORT QDeclarativeDebugData { qint64 time; int messageType; diff --git a/tests/auto/declarative/debugger/debugger.pro b/tests/auto/declarative/debugger/debugger.pro index 869b3a8..90c5d4b 100644 --- a/tests/auto/declarative/debugger/debugger.pro +++ b/tests/auto/declarative/debugger/debugger.pro @@ -6,6 +6,7 @@ PRIVATETESTS += \ qdeclarativedebugservice \ qdeclarativedebugjs \ qdeclarativeinspector \ + qdeclarativedebugtrace \ qpacketprotocol contains(QT_CONFIG, private_tests) { diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml b/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml new file mode 100644 index 0000000..9c36e13 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + +} diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro b/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro new file mode 100644 index 0000000..9ddb51c --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qdeclarativedebugtrace +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h + +SOURCES += tst_qdeclarativedebugtrace.cpp \ + ../shared/debugutil.cpp + +OTHER_FILES += data/test.qml + +CONFIG += parallel_test declarative_debug + +QT += core-private gui-private v8-private declarative-private network testlib diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp new file mode 100644 index 0000000..5227147 --- /dev/null +++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "QtDeclarative/private/qdeclarativedebugtrace_p.h" +#include "../shared/debugutil_p.h" +#include "../../shared/util.h" + +#define PORT 13773 +#define STR_PORT "13773" + +class QDeclarativeDebugTraceClient : public QDeclarativeDebugClient +{ + Q_OBJECT + +public: + QDeclarativeDebugTraceClient(QDeclarativeDebugConnection *connection) + : QDeclarativeDebugClient(QLatin1String("CanvasFrameRate"), connection) + { + } + + QList traceMessages; + + void setTraceStatus(bool enabled) { + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream << enabled; + sendMessage(message); + } + +signals: + void complete(); + +protected: + void messageReceived(const QByteArray &message); +}; + +class tst_QDeclarativeDebugTrace : public QObject +{ + Q_OBJECT + +public: + tst_QDeclarativeDebugTrace() + : m_process(0) + , m_connection(0) + , m_client(0) + { + } + +private: + QDeclarativeDebugProcess *m_process; + QDeclarativeDebugConnection *m_connection; + QDeclarativeDebugTraceClient *m_client; + +private slots: + void init(); + void cleanup(); + + void connectWithTraceEnabled(); + void connectWithTraceDisabled(); +}; + +void QDeclarativeDebugTraceClient::messageReceived(const QByteArray &message) +{ + QByteArray msg = message; + QDataStream stream(&msg, QIODevice::ReadOnly); + + + QDeclarativeDebugData data; + data.time = -2; + data.messageType = -1; + data.detailType = -1; + data.line = -1; + data.framerate = -1; + data.animationcount = -1; + + stream >> data.time >> data.messageType; + + QVERIFY(data.time >= -1); + + switch (data.messageType) { + case (QDeclarativeDebugTrace::Event): { + stream >> data.detailType; + + switch (data.detailType) { + case QDeclarativeDebugTrace::AnimationFrame: { + stream >> data.framerate >> data.animationcount; + QVERIFY(data.framerate != -1); + QVERIFY(data.animationcount != -1); + break; + } + case QDeclarativeDebugTrace::FramePaint: + case QDeclarativeDebugTrace::Mouse: + case QDeclarativeDebugTrace::Key: + case QDeclarativeDebugTrace::StartTrace: + case QDeclarativeDebugTrace::EndTrace: + break; + default: { + QString failMsg = QString("Unknown event type:") + data.detailType; + QFAIL(qPrintable(failMsg)); + break; + } + } + break; + } + case QDeclarativeDebugTrace::Complete: { + emit complete(); + QVERIFY(stream.atEnd()); + return; + } + case QDeclarativeDebugTrace::RangeStart: { + stream >> data.detailType; + QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType); + break; + } + case QDeclarativeDebugTrace::RangeEnd: { + stream >> data.detailType; + QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType); + break; + } + case QDeclarativeDebugTrace::RangeData: { + stream >> data.detailType >> data.detailData; + QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType); + break; + } + case QDeclarativeDebugTrace::RangeLocation: { + stream >> data.detailType >> data.detailData >> data.line; + QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType); + QVERIFY(data.line >= -2); + break; + } + default: + QString failMsg = QString("Unknown message type:") + data.messageType; + QFAIL(qPrintable(failMsg)); + break; + } + QVERIFY(stream.atEnd()); + traceMessages.append(data); +} + +void tst_QDeclarativeDebugTrace::init() +{ + const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"; + QStringList arguments; + arguments << QString("-qmljsdebugger=port:"STR_PORT",block"); + arguments << QString(TESTDATA(QLatin1String("test.qml"))); + + m_process = new QDeclarativeDebugProcess(executable); + m_process->start(QStringList() << arguments); + if (!m_process->waitForSessionStart()) { + QString failMsg = QString("Could not launch app '%1'.\nApplication output:\n%2").arg( + executable, m_process->output()); + QFAIL(qPrintable(failMsg)); + } + + QDeclarativeDebugConnection *m_connection = new QDeclarativeDebugConnection(); + m_client = new QDeclarativeDebugTraceClient(m_connection); + + m_connection->connectToHost(QLatin1String("127.0.0.1"), PORT); +} + +void tst_QDeclarativeDebugTrace::cleanup() +{ + delete m_process; + delete m_connection; + delete m_client; +} + +void tst_QDeclarativeDebugTrace::connectWithTraceEnabled() +{ + QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled); + m_client->setTraceStatus(true); + m_client->setTraceStatus(false); + if (!QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(complete()))) { + QString failMsg + = QString("No trace received in time. App output: \n\n").arg(m_process->output()); + QFAIL(qPrintable(failMsg)); + } + + // must start with "StartTrace" + QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event); + QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace); + + // must end with "EndTrace" + QCOMPARE(m_client->traceMessages.last().messageType, (int)QDeclarativeDebugTrace::Event); + QCOMPARE(m_client->traceMessages.last().detailType, (int)QDeclarativeDebugTrace::EndTrace); +} + +void tst_QDeclarativeDebugTrace::connectWithTraceDisabled() +{ + QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled); + m_client->setTraceStatus(false); + m_client->setTraceStatus(true); + m_client->setTraceStatus(false); + if (!QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(complete()))) { + QString failMsg + = QString("No trace received in time. App output: \n\n").arg(m_process->output()); + QFAIL(qPrintable(failMsg)); + } + + // must start with "StartTrace" + QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event); + QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace); + + // must end with "EndTrace" + QCOMPARE(m_client->traceMessages.last().messageType, (int)QDeclarativeDebugTrace::Event); + QCOMPARE(m_client->traceMessages.last().detailType, (int)QDeclarativeDebugTrace::EndTrace); +} + +QTEST_MAIN(tst_QDeclarativeDebugTrace) + +#include "tst_qdeclarativedebugtrace.moc" diff --git a/tests/auto/declarative/debugger/shared/debugutil.cpp b/tests/auto/declarative/debugger/shared/debugutil.cpp index 6ab15f3..5abafd2 100644 --- a/tests/auto/declarative/debugger/shared/debugutil.cpp +++ b/tests/auto/declarative/debugger/shared/debugutil.cpp @@ -149,18 +149,24 @@ bool QDeclarativeDebugProcess::waitForSessionStart() QString QDeclarativeDebugProcess::output() const { - return m_outputBuffer; + return m_output; } void QDeclarativeDebugProcess::processAppOutput() { m_mutex.lock(); - const QString appOutput = m_process.readAll(); - static QRegExp newline("[\n\r]{1,2}"); - QStringList lines = appOutput.split(newline); - foreach (const QString &line, lines) { - if (line.isEmpty()) - continue; + + 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.startsWith("Qml debugging is enabled")) // ignore continue; if (line.startsWith("QDeclarativeDebugServer:")) { @@ -173,7 +179,6 @@ void QDeclarativeDebugProcess::processAppOutput() continue; } } - m_outputBuffer.append(appOutput); } m_mutex.unlock(); } diff --git a/tests/auto/declarative/debugger/shared/debugutil_p.h b/tests/auto/declarative/debugger/shared/debugutil_p.h index 99a482c..24b7e25 100644 --- a/tests/auto/declarative/debugger/shared/debugutil_p.h +++ b/tests/auto/declarative/debugger/shared/debugutil_p.h @@ -113,6 +113,7 @@ private: QString m_executable; QProcess m_process; QString m_outputBuffer; + QString m_output; QTimer m_timer; QEventLoop m_eventLoop; QMutex m_mutex; -- 1.7.2.5