diff options
Diffstat (limited to 'tests/shared')
-rw-r--r-- | tests/shared/clientwrapper.h | 23 | ||||
-rw-r--r-- | tests/shared/qmltestutil.h | 17 | ||||
-rw-r--r-- | tests/shared/requestwrapper.h | 290 | ||||
-rw-r--r-- | tests/shared/shared.pri | 10 | ||||
-rw-r--r-- | tests/shared/testhelper.cpp | 419 | ||||
-rw-r--r-- | tests/shared/testhelper.h | 123 | ||||
-rw-r--r-- | tests/shared/util.h | 22 |
7 files changed, 877 insertions, 27 deletions
diff --git a/tests/shared/clientwrapper.h b/tests/shared/clientwrapper.h index 32e71db..1fc5b92 100644 --- a/tests/shared/clientwrapper.h +++ b/tests/shared/clientwrapper.h @@ -45,6 +45,10 @@ #include <QEventLoop> #include <QElapsedTimer> #include <QDebug> +#include <QJsonObject> +#include <QJsonArray> +#include <QJsonValue> +#include <QJsonDocument> #include "jsondb-client.h" @@ -81,7 +85,8 @@ QT_USE_NAMESPACE_JSONDB if ((result)->mNotificationId.isNull()) { \ QVERIFY2(false, "we expected notification but did not get it :("); \ } else { \ - QString data = JsonWriter().toString((result)->mNotifications.last().mObject); \ + QJsonValue value = QJsonValue::fromVariant((result)->mNotifications.last().mObject); \ + QString data = QString::fromUtf8(value.isArray() ? QJsonDocument(value.toArray()).toJson() : QJsonDocument(value.toObject()).toJson()); \ QByteArray ba = QString("we didn't expect notification but got it. %1").arg(data).toLatin1(); \ QVERIFY2(false, ba.constData()); \ } \ @@ -96,6 +101,22 @@ QT_USE_NAMESPACE_JSONDB #define waitForResponse3(id, code, notificationId) waitForResponse(mEventLoop, this, id, code, notificationId, 0) #define waitForResponse4(id, code, notificationId, count) waitForResponse(mEventLoop, this, id, code, notificationId, count) +#define waitForCallbackGeneric(eventloop) \ +{ \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ + timer.start(mClientTimeout); \ + mElapsedTimer.start(); \ + mTimedOut = false;\ + callbackError = false; \ + eventloop.exec(QEventLoop::AllEvents); \ + QCOMPARE(false, mTimedOut); \ +} + +#define waitForCallback() waitForCallbackGeneric(mEventLoop) +#define waitForCallback2() waitForCallbackGeneric(mEventLoop2) + class JsonDbTestNotification { public: diff --git a/tests/shared/qmltestutil.h b/tests/shared/qmltestutil.h index 9d9d4d0..0d1b78f 100644 --- a/tests/shared/qmltestutil.h +++ b/tests/shared/qmltestutil.h @@ -50,23 +50,6 @@ #include <QQmlProperty> #include <QDir> -#define waitForCallbackGeneric(eventloop) \ -{ \ - QTimer timer; \ - QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ - QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ - timer.start(mClientTimeout); \ - mElapsedTimer.start(); \ - mTimedOut = false;\ - callbackError = false; \ - eventloop.exec(QEventLoop::AllEvents); \ - QCOMPARE(false, mTimedOut); \ -} - -#define waitForCallback() waitForCallbackGeneric(mEventLoop) -#define waitForCallback2() waitForCallbackGeneric(mEventLoop2) - - inline QVariant createObject(const QString &functionName) { static QStringList greekAlphabets; diff --git a/tests/shared/requestwrapper.h b/tests/shared/requestwrapper.h new file mode 100644 index 0000000..df20de9 --- /dev/null +++ b/tests/shared/requestwrapper.h @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtAddOn.JsonDb module 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$ +** +****************************************************************************/ +#ifndef RequestWrapper_H +#define RequestWrapper_H + +#include <QCoreApplication> +#include <QList> +#include <QTest> +#include <QFile> +#include <QProcess> +#include <QEventLoop> +#include <QDebug> +#include <QLocalSocket> +#include <QTimer> +#include <QQmlEngine> +#include <QQmlComponent> + +#include "qjsondbconnection.h" +#include "qjsondbwriterequest.h" +#include "qjsondbreadrequest.h" + +QT_USE_NAMESPACE_JSONDB + +#define waitForResponse(eventloop_, id_) \ +{ \ + int givenid_ = (id_); \ + lastRequestId = -1; \ + lastResult.clear(); \ + lastErrorCode = 0; \ + lastErrorMessage.clear(); \ + eventLoop = &eventloop_; \ + \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), eventLoop, SLOT(quit())); \ + timer.start(clientTimeout); \ + elapsedTimer.start(); \ + do { \ + eventLoop->exec(QEventLoop::AllEvents); \ + } while (lastRequestId < givenid_); \ + eventLoop = 0; \ + if (givenid_ != -1) QVERIFY2((lastRequestId!=-1), "Failed to receive an answer from the db server"); \ + if (givenid_ != -1) QCOMPARE(lastRequestId, givenid_); \ +} + +#define waitForResponse1(id) waitForResponse(eventLoop1, id) + +#define waitForCallbackGeneric(eventloop) \ +{ \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ + timer.start(clientTimeout); \ + elapsedTimer.start(); \ + mTimedOut = false;\ + callbackError = false; \ + eventloop.exec(QEventLoop::AllEvents); \ + QCOMPARE(false, mTimedOut); \ +} + +//#define waitForCallback() waitForCallbackGeneric(eventLoop) +#define waitForCallback1() waitForCallbackGeneric(eventLoop1) + +class RequestWrapper: public QObject +{ + Q_OBJECT +public: + RequestWrapper() + :clientTimeout(20000) + { + if (qgetenv("JSONDB_CLIENT_TIMEOUT").size()) + clientTimeout = QString::fromLatin1(qgetenv("JSONDB_CLIENT_TIMEOUT")).toLong(); + + connect(this, SIGNAL(response(int,QVariantList)), + this, SLOT(onResponse(int,QVariantList))); + connect(this, SIGNAL(error(int,int,QString)), + this, SLOT(onError(int,int,QString))); + } + + ~RequestWrapper() + { + if (connection) + delete connection; + } + + int create(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return create(list, partitionName); + } + + int create(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbCreateRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + + int update(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return update(list, partitionName); + } + + int update(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbUpdateRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + + int remove(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return remove(list, partitionName); + } + + int remove(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbRemoveRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + + int query(const QString &queryString, const QString &partitionName = QString()) + { + QJsonDbReadRequest *request = new QJsonDbReadRequest; + request->setQuery(queryString); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + +public Q_SLOTS: + void onWriteFinished() + { + QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender()); + if (request) { + QList<QJsonObject> objects = request->takeResults(); + QVariantList list; + for (int i = 0; i<objects.count(); i++) { + list.append(objects[i].toVariantMap()); + } + emit response(request->property("requestId").toInt(), list); + } + } + void onQueryFinished() + { + QtJsonDb::QJsonDbReadRequest *request = qobject_cast<QtJsonDb::QJsonDbReadRequest*>(sender()); + if (request) { + QList<QJsonObject> objects = request->takeResults(); + QVariantList list; + for (int i = 0; i<objects.count(); i++) { + list.append(objects[i].toVariantMap()); + } + emit response(request->property("requestId").toInt(), list); + } + } + void onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) + { + QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender()); + if (request) { + emit error(request->property("requestId").toInt(), int(code), message); + } + } + void onResponse(int id, const QVariantList& list) + { + //qDebug() << "onResponse" << id; + lastRequestId = id; + lastResult = list; + if (eventLoop) + eventLoop->quit(); + } + void onError(int id, int code, const QString &message) + { + qDebug() << "onError" << id << code << message; + lastRequestId = id; + lastErrorCode = code; + lastErrorMessage = message; + if (eventLoop) + eventLoop->quit(); + } + virtual void timeout() + { + qDebug() << "RequestWrapper::timeout() " << elapsedTimer.elapsed(); + } +Q_SIGNALS: + void response(int, const QVariantList&); + void error(int, int, const QString&); +protected: + QPointer<QtJsonDb::QJsonDbConnection> connection; + QPointer<QEventLoop> eventLoop; + int lastRequestId; + QVariantList lastResult; + int lastErrorCode; + QString lastErrorMessage; + QEventLoop eventLoop1; + QElapsedTimer elapsedTimer; + int clientTimeout; + + //Liang is trying + bool callbackError; + int callbackErrorCode; + QString callbackErrorMessage; + QVariant callbackMeta; + QVariant callbackResponse; + bool mCallbackReceived; +}; + +#endif diff --git a/tests/shared/shared.pri b/tests/shared/shared.pri index 4f47a0b..b69a0b8 100644 --- a/tests/shared/shared.pri +++ b/tests/shared/shared.pri @@ -1,12 +1,20 @@ +QT += jsondb jsondb-private + INCLUDEPATH += $$PWD -HEADERS += $$PWD/util.h $$PWD/qmltestutil.h +HEADERS += \ + $$PWD/util.h \ + $$PWD/qmltestutil.h contains(QT, jsondbcompat|jsondbcompat-private) { HEADERS += $$PWD/clientwrapper.h SOURCES += $$PWD/clientwrapper.cpp +} else { + HEADERS += $$PWD/testhelper.h + SOURCES += $$PWD/testhelper.cpp } RESOURCES += \ ../../json.qrc +DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" diff --git a/tests/shared/testhelper.cpp b/tests/shared/testhelper.cpp new file mode 100644 index 0000000..961a533 --- /dev/null +++ b/tests/shared/testhelper.cpp @@ -0,0 +1,419 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtAddOn.JsonDb module 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 "testhelper.h" + +#include <QJsonDbWatcher> + +#include <QCoreApplication> +#include <QDir> +#include <QLocalSocket> +#include <QProcess> +#include <QTest> +#include <QTimer> +#include <QJsonArray> + +QT_USE_NAMESPACE_JSONDB + +TestHelper::TestHelper(QObject *parent) : + QObject(parent) + , mProcess(0) + , mConnection(0) + , mNotificationsReceived(0) + , mNotificationsExpected(0) + , mLastStateChangedExpected(0) + , mLastStateChangedReceived(0) + , mRequestsPending(0) +{ +} + +QJsonDocument TestHelper::readJsonFile(const QString &filename, QJsonParseError *error) +{ + QString filepath = filename; + QFile jsonFile(filepath); + if (!jsonFile.exists()) { + if (error) { + error->error = QJsonParseError::MissingObject; + error->offset = 0; + } + return QJsonDocument(); + } + jsonFile.open(QIODevice::ReadOnly); + QByteArray json = jsonFile.readAll(); + QJsonDocument doc(QJsonDocument::fromJson(json, error)); + return doc; +} + +void TestHelper::launchJsonDbDaemon(const QString &basename, const QStringList &args, const char *sourceFile) +{ + qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8()); + + if (dontLaunch()) + return; + + QString jsondb_app = QDir(QString::fromLocal8Bit(JSONDB_DAEMON_BASE)).absoluteFilePath(QLatin1String("jsondb")); + if (!QFile::exists(jsondb_app)) + jsondb_app = QLatin1String("jsondb"); // rely on the PATH + + mProcess = new QProcess; + mProcess->setProcessChannelMode(QProcess::ForwardedChannels); + connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(processFinished(int,QProcess::ExitStatus))); + + QString socketName = QString("testjsondb_%1").arg(getpid()); + + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("JSONDB_SOCKET", socketName); + mProcess->setProcessEnvironment(env); + ::setenv("JSONDB_SOCKET", qPrintable(socketName), 1); + + QStringList argList = args; + argList << QLatin1String("-base-name") << basename; + + qDebug() << "Starting process" << jsondb_app << argList << "with socket" << socketName; + + if (useValgrind()) { + QStringList args1 = argList; + args1.prepend(jsondb_app); + mProcess->start("valgrind", args1); + } else { + mProcess->start(jsondb_app, argList); + } + + if (!mProcess->waitForStarted()) + qFatal("Unable to start jsondb database process"); + + /* Wait until the jsondb is accepting connections */ + int tries = 0; + bool connected = false; + while (!connected && tries++ < 100) { + QLocalSocket socket; + socket.connectToServer(socketName); + if (socket.waitForConnected()) { + connected = true; + socket.close(); + } + QTest::qWait(250); + } + + if (!connected) + qFatal("Unable to connect to jsondb process"); +} + +inline qint64 TestHelper::launchJsonDbDaemonDetached(const QString &basename, const QStringList &args, const char *sourceFile) +{ + qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8()); + + if (dontLaunch()) + return 0; + + QString jsondb_app = QDir(QString::fromLocal8Bit(JSONDB_DAEMON_BASE)).absoluteFilePath(QLatin1String("jsondb")); + if (!QFile::exists(jsondb_app)) + jsondb_app = QLatin1String("jsondb"); // rely on the PATH + + QString socketName = QString("testjsondb_%1").arg(getpid()); + ::setenv("JSONDB_SOCKET", qPrintable(socketName), 1); + + QStringList argList = args; + argList << QLatin1String("-base-name") << basename; + + qDebug() << "Starting process" << jsondb_app << argList << "with socket" << socketName; + qint64 pid; + if (useValgrind()) { + QStringList args1 = argList; + args1.prepend(jsondb_app); + QProcess::startDetached(jsondb_app, args1, QDir::currentPath(), &pid ); + } else { + QProcess::startDetached(jsondb_app, argList, QDir::currentPath(), &pid); + } + + /* Wait until the jsondb is accepting connections */ + int tries = 0; + bool connected = false; + while (!connected && tries++ < 100) { + QLocalSocket socket; + socket.connectToServer(socketName); + if (socket.waitForConnected()) { + connected = true; + socket.close(); + } + QTest::qWait(250); + } + if (!connected) + qFatal("Unable to connect to jsondb process"); + + return pid; +} + +void TestHelper::stopDaemon() +{ + if (dontLaunch()) + return; + + if (mProcess) { + mProcess->close(); + delete mProcess; + mProcess = 0; + } +} + +void TestHelper::connectToServer() +{ + mConnection = new QJsonDbConnection(this); + connect(mConnection, SIGNAL(error(QtJsonDb::QJsonDbConnection::ErrorCode,QString)), + this, SLOT(connectionError(QtJsonDb::QJsonDbConnection::ErrorCode,QString))); + + mConnection->connectToServer(); +} + +void TestHelper::disconnectFromServer() +{ + connect(mConnection, SIGNAL(disconnected()), &mEventLoop, SLOT(quit()), Qt::QueuedConnection); + mConnection->disconnectFromServer(); + blockWithTimeout(); + + if (mConnection) { + delete mConnection; + mConnection = 0; + } + + mRequestErrors.clear(); +} + +void TestHelper::removeDbFiles(const QStringList &additionalFiles) +{ + if (dontLaunch()) + return; + + QStringList files = QDir().entryList(QStringList() << QLatin1String("*.db")); + files << additionalFiles; + foreach (const QString &fileName, files) + QFile::remove(fileName); +} + +void TestHelper::waitForResponse(QJsonDbRequest *request) +{ + mRequestsPending = 1; + mNotificationsExpected = 0; + mLastStateChangedExpected = 0; + + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + + blockWithTimeout(); + + disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + QVERIFY(!mRequestsPending); +} + +void TestHelper::waitForResponse(QList<QJsonDbRequest *> requests) +{ + mRequestsPending = requests.count(); + mNotificationsExpected = 0; + mLastStateChangedExpected = 0; + + foreach (QJsonDbRequest *request, requests) { + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + } + + blockWithTimeout(); + + foreach (QJsonDbRequest *request, requests) { + disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + } + QVERIFY(!mRequestsPending); +} + +void TestHelper::waitForResponseAndNotifications(QJsonDbRequest *request, + QJsonDbWatcher *watcher, + int notificationsExpected, + int lastStateChangedExpected) +{ + mNotificationsExpected = notificationsExpected; + mNotificationsReceived = 0; + mLastStateChangedExpected = lastStateChangedExpected; + mLastStateChangedReceived = 0; + + if (request) { + mRequestsPending = 1; + + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + } + + connect(watcher, SIGNAL(notificationsAvailable(int)), + this, SLOT(watcherNotificationsAvailable(int))); + connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); + connect(watcher, SIGNAL(lastStateNumberChanged(int)), + this, SLOT(watcherLastStateNumberChanged(int))); + + blockWithTimeout(); + + if (request) { + disconnect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + disconnect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + } + + disconnect(watcher, SIGNAL(notificationsAvailable(int)), + this, SLOT(watcherNotificationsAvailable(int))); + disconnect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); + disconnect(watcher, SIGNAL(lastStateNumberChanged(int)), + this, SLOT(watcherLastStateNumberChanged(int))); + + QVERIFY(!mRequestsPending && mNotificationsReceived >= mNotificationsExpected + && mLastStateChangedReceived >= mLastStateChangedExpected); + + mNotificationsExpected = 0; +} + +void TestHelper::waitForStatus(QJsonDbWatcher *watcher, QJsonDbWatcher::Status status) +{ + mExpectedStatus = status; + connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)), + this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status))); + blockWithTimeout(); + disconnect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)), + this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status))); + QVERIFY(mExpectedStatus == status); +} + +bool TestHelper::dontLaunch() +{ + static const bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1; + return dontlaunch; +} + +bool TestHelper::useValgrind() +{ + static const bool usevalgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1; + return usevalgrind; +} + +void TestHelper::blockWithTimeout() +{ + QTimer t; + connect(&t, SIGNAL(timeout()), &mEventLoop, SLOT(quit())); + connect(&t, SIGNAL(timeout()), this, SLOT(timeout())); + + t.start(10000); + mEventLoop.exec(QEventLoop::AllEvents); + t.stop(); +} + +void TestHelper::connectionError(QtJsonDb::QJsonDbConnection::ErrorCode code, QString msg) +{ + qCritical() << "Error from connection" << code << msg; +} + +void TestHelper::processFinished(int code, QProcess::ExitStatus status) +{ + qDebug() << "jsondb process finished" << code << status; +} + +void TestHelper::requestFinished() +{ + --mRequestsPending; + if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected + && mLastStateChangedReceived >= mLastStateChangedExpected) + mEventLoop.quit(); +} + +void TestHelper::requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, QString msg) +{ + qWarning() << "Request error:" << code << msg; + QJsonDbRequest *request = qobject_cast<QJsonDbRequest*>(sender()); + if (request) + mRequestErrors[request] = code; + + requestFinished(); +} + +void TestHelper::requestStatusChanged(QtJsonDb::QJsonDbRequest::Status status) +{ + Q_UNUSED(status); +} + +void TestHelper::watcherNotificationsAvailable(int count) +{ + mNotificationsReceived = count; + + if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected + && mLastStateChangedReceived >= mLastStateChangedExpected) + mEventLoop.quit(); +} + +void TestHelper::watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status status) +{ + if (status == mExpectedStatus) + mEventLoop.quit(); +} + +void TestHelper::watcherLastStateNumberChanged(int stateNumber) +{ + Q_UNUSED(stateNumber); + mLastStateChangedReceived++; + if (!mRequestsPending && mNotificationsReceived >= mNotificationsExpected + && mLastStateChangedReceived >= mLastStateChangedExpected) + mEventLoop.quit(); +} + +void TestHelper::watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString msg) +{ + qWarning() << "Watcher error:" << code << msg; +} + +void TestHelper::timeout() +{ + qCritical() << "A timeout occurred"; +} + + diff --git a/tests/shared/testhelper.h b/tests/shared/testhelper.h new file mode 100644 index 0000000..1a14825 --- /dev/null +++ b/tests/shared/testhelper.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtAddOn.JsonDb module 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$ +** +****************************************************************************/ + +#ifndef JSONDB_TESTHELPER_H +#define JSONDB_TESTHELPER_H + +#include <QJsonDbConnection> +#include <QJsonDbRequest> +#include <QJsonDbWatcher> + +#include <QEventLoop> +#include <QHash> +#include <QJsonDocument> +#include <QJsonValue> +#include <QObject> +#include <QProcess> +#include <QStringList> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE +class QProcess; +QT_END_NAMESPACE + +class TestHelper : public QObject +{ + Q_OBJECT +public: + explicit TestHelper(QObject *parent = 0); + + QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0); + + void launchJsonDbDaemon(const QString &basename, const QStringList &args, const char *sourceFile); + qint64 launchJsonDbDaemonDetached(const QString &basename, const QStringList &args, const char *sourceFile); + void stopDaemon(); + + void connectToServer(); + void disconnectFromServer(); + + void removeDbFiles(const QStringList &additionalFiles = QStringList()); + + void waitForResponse(QtJsonDb::QJsonDbRequest *request); + void waitForResponse(QList<QtJsonDb::QJsonDbRequest*> requests); + void waitForResponseAndNotifications(QtJsonDb::QJsonDbRequest *request, + QtJsonDb::QJsonDbWatcher *watcher, + int notificationsExpected, + int lastStateChangedExpected = 0); + void waitForStatus(QtJsonDb::QJsonDbWatcher *watcher, + QtJsonDb::QJsonDbWatcher::Status status); + +protected: + QProcess *mProcess; + QtJsonDb::QJsonDbConnection *mConnection; + QEventLoop mEventLoop; + int mNotificationsReceived; + int mNotificationsExpected; + int mLastStateChangedExpected; + int mLastStateChangedReceived; + QHash<QtJsonDb::QJsonDbRequest *, QtJsonDb::QJsonDbRequest::ErrorCode> mRequestErrors; + +protected Q_SLOTS: + void connectionError(QtJsonDb::QJsonDbConnection::ErrorCode code, QString msg); + + void processFinished(int,QProcess::ExitStatus); + + void requestFinished(); + void requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, QString msg); + void requestStatusChanged(QtJsonDb::QJsonDbRequest::Status status); + + void watcherNotificationsAvailable(int count); + void watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status status); + void watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString msg); + void watcherLastStateNumberChanged(int stateNumber); + void timeout(); + +private: + static bool dontLaunch(); + static bool useValgrind(); + void blockWithTimeout(); + + int mRequestsPending; + QtJsonDb::QJsonDbWatcher::Status mExpectedStatus; +}; + +#endif // JSONDB_TESTHELPER_H diff --git a/tests/shared/util.h b/tests/shared/util.h index 90e6535..93b4353 100644 --- a/tests/shared/util.h +++ b/tests/shared/util.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef UTIL_H -#define UTIL_H +#ifndef JSONDB_UTIL_H +#define JSONDB_UTIL_H #include <QFile> #include <QDir> @@ -49,6 +49,8 @@ #include <QLocalSocket> #include <qtestsystem.h> #include <qjsondocument.h> +#include <qjsonarray.h> +#include <qjsonobject.h> inline QString findFile(const QString &filename) { @@ -73,7 +75,7 @@ inline QString findFile(const char *filename) return findFile(QString::fromLocal8Bit(filename)); } -QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0) +inline QJsonValue readJsonFile(const QString &filename, QJsonParseError *error = 0) { QString filepath = filename; QFile jsonFile(filepath); @@ -82,16 +84,18 @@ QJsonDocument readJsonFile(const QString &filename, QJsonParseError *error = 0) error->error = QJsonParseError::MissingObject; error->offset = 0; } - return QJsonDocument(); + return QJsonValue(); } jsonFile.open(QIODevice::ReadOnly); QByteArray json = jsonFile.readAll(); QJsonDocument doc(QJsonDocument::fromJson(json, error)); - return doc; + return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object()); } -inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketName, const QStringList &args) +inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketName, const QStringList &args, const char *sourceFile) { + qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8()); + static bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1; static bool useValgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1; if (dontlaunch) @@ -133,8 +137,10 @@ inline QProcess *launchJsonDbDaemon(const char *prefix, const QString &socketNam return process; } -inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &socketName, const QStringList &args) +inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &socketName, const QStringList &args, const char *sourceFile) { + qputenv("JSONDB_CONFIG_SEARCH_PATH", QFileInfo(QString::fromUtf8(sourceFile)).dir().absolutePath().toUtf8()); + static bool dontlaunch = qgetenv("AUTOTEST_DONT_LAUNCH_JSONDB").toInt() == 1; static bool useValgrind = qgetenv("AUTOTEST_VALGRIND_JSONDB").toInt() == 1; if (dontlaunch) @@ -169,4 +175,4 @@ inline qint64 launchJsonDbDaemonDetached(const char *prefix, const QString &sock return pid; } -#endif // UTIL_H +#endif // JSONDB_UTIL_H |