From ca8717d2a028eed0882338f952e2fcfb9c1cf8f9 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 3 May 2014 23:53:51 +0200 Subject: [PATCH] split tests into different files --- libguh/devicemanager.cpp | 8 + libguh/devicemanager.h | 1 + .../deviceplugins/mock/devicepluginmock.cpp | 6 + plugins/deviceplugins/mock/devicepluginmock.h | 1 + server/guhcore.cpp | 5 + server/guhcore.h | 1 + tests/auto/auto.pro | 24 +- tests/auto/generatedefines.sh | 19 + tests/auto/guhtestbase.cpp | 121 ++++++ tests/auto/guhtestbase.h | 64 ++++ tests/auto/testdevices.cpp | 156 ++++++++ tests/auto/testdevices.h | 32 ++ tests/auto/testjsonrpc.cpp | 352 +----------------- tests/auto/testjsonrpc.h | 43 +++ tests/auto/testversioning.cpp | 89 +++++ tests/auto/testversioning.h | 20 + 16 files changed, 593 insertions(+), 349 deletions(-) create mode 100755 tests/auto/generatedefines.sh create mode 100644 tests/auto/guhtestbase.cpp create mode 100644 tests/auto/guhtestbase.h create mode 100644 tests/auto/testdevices.cpp create mode 100644 tests/auto/testdevices.h create mode 100644 tests/auto/testjsonrpc.h create mode 100644 tests/auto/testversioning.cpp create mode 100644 tests/auto/testversioning.h diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index 4299385e..194e0f6d 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -105,6 +105,14 @@ DeviceManager::DeviceManager(QObject *parent) : QMetaObject::invokeMethod(this, "loaded", Qt::QueuedConnection); } +DeviceManager::~DeviceManager() +{ + qDebug() << "Shutting down DeviceManager"; + foreach (DevicePlugin *plugin, m_devicePlugins) { + delete plugin; + } +} + /*! Returns all the \l{DevicePlugin}{DevicePlugins} loaded in the system. */ QList DeviceManager::plugins() const { diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index 48489a83..b5b9ab22 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -69,6 +69,7 @@ public: }; explicit DeviceManager(QObject *parent = 0); + ~DeviceManager(); QList plugins() const; DevicePlugin* plugin(const PluginId &id) const; diff --git a/plugins/deviceplugins/mock/devicepluginmock.cpp b/plugins/deviceplugins/mock/devicepluginmock.cpp index e3660062..723e35df 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.cpp +++ b/plugins/deviceplugins/mock/devicepluginmock.cpp @@ -37,6 +37,12 @@ ActionTypeId mockAction2Id = ActionTypeId("defd3ed6-1a0d-400b-8879-a0202cf39935" DevicePluginMock::DevicePluginMock() { + qDebug() << "Mock device plugin created"; +} + +DevicePluginMock::~DevicePluginMock() +{ + qDebug() << "shutting down Mock device plugin"; } QList DevicePluginMock::supportedVendors() const diff --git a/plugins/deviceplugins/mock/devicepluginmock.h b/plugins/deviceplugins/mock/devicepluginmock.h index c1eb354d..5d422798 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.h +++ b/plugins/deviceplugins/mock/devicepluginmock.h @@ -34,6 +34,7 @@ class DevicePluginMock : public DevicePlugin public: explicit DevicePluginMock(); + ~DevicePluginMock(); QList supportedVendors() const override; QList supportedDevices() const override; diff --git a/server/guhcore.cpp b/server/guhcore.cpp index 66e52c64..6098906d 100644 --- a/server/guhcore.cpp +++ b/server/guhcore.cpp @@ -47,6 +47,11 @@ GuhCore *GuhCore::instance() return s_instance; } +GuhCore::~GuhCore() +{ + qDebug() << "Shutting down. Bye."; +} + void GuhCore::destroy() { delete s_instance; diff --git a/server/guhcore.h b/server/guhcore.h index 54d4aed2..7fbc9923 100644 --- a/server/guhcore.h +++ b/server/guhcore.h @@ -34,6 +34,7 @@ class GuhCore : public QObject Q_OBJECT public: static GuhCore* instance(); + ~GuhCore(); // Used for testing void destroy(); diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 9ba84496..8a09deaa 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -7,14 +7,28 @@ DEFINES += TESTING_ENABLED DEFINES += TESTS_SOURCE_DIR=\\\"$$top_srcdir/tests/auto/\\\" INCLUDEPATH += $$top_srcdir/server/ $$top_srcdir/server/jsonrpc $$top_srcdir/libguh $$top_srcdir/tests/auto/ -LIBS += -L$$top_builddir/libguh/ -lguh +LIBS += -L$$top_builddir/libguh/ -lguh -L$$top_builddir/plugins/deviceplugins/mock/ -lguh_devicepluginmock QMAKE_LFLAGS += -Wl,--rpath=$$top_builddir/libguh include($$top_srcdir/server/server.pri) -SOURCES += testjsonrpc.cpp \ - mocktcpserver.cpp +testcases="TestJSONRPC TestVersioning TestDevices" -HEADERS += mocktcpserver.h +SOURCES += guhtestbase.cpp \ + mocktcpserver.cpp \ + testjsonrpc.cpp \ + testversioning.cpp \ + testdevices.cpp -LIBS += -L$$top_builddir/plugins/deviceplugins/mock/ -lguh_devicepluginmock +HEADERS += mocktcpserver.h \ + guhtestbase.h \ + testdefines.h \ + testversioning.h \ + testjsonrpc.h \ + testdevices.h + +message("testcases: $${testcases}") +#DEFINES += TESTCASES=\\\"$${testcases}\\\" +#DEFINES += TESTCASES=\\\"TestJSONRPC\\\" + +system(./generatedefines.sh $${testcases}) diff --git a/tests/auto/generatedefines.sh b/tests/auto/generatedefines.sh new file mode 100755 index 00000000..350afd1a --- /dev/null +++ b/tests/auto/generatedefines.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +echo generating defines... $@ +echo \#include \ > testdefines.h +for i in $@; do + echo \#include \"${i,,}.h\" >> testdefines.h +done + +echo >> testdefines.h + +echo \#define REGISTER_METATYPES \\ >> testdefines.h + +for i in $@; do + echo qRegisterMetaType\<$i\>\(\"$i\"\)\; \\ >> testdefines.h +done + +echo >> testdefines.h + +echo \#define TESTCASES \"$@\" >> testdefines.h diff --git a/tests/auto/guhtestbase.cpp b/tests/auto/guhtestbase.cpp new file mode 100644 index 00000000..569237f9 --- /dev/null +++ b/tests/auto/guhtestbase.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + ***************************************************************************/ + +#include "guhtestbase.h" +#include "mocktcpserver.h" +#include "guhcore.h" +#include "devicemanager.h" + +#include +#include +#include +#include +#include +#include +#include "testdefines.h" + +Q_IMPORT_PLUGIN(DevicePluginMock) + +GuhTestBase::GuhTestBase(QObject *parent) : + QObject(parent), + m_commandId(0) +{ + m_mockDevice1Port = 1337; + m_mockDevice2Port = 7331; + QCoreApplication::instance()->setOrganizationName("guh-test"); + +} + +void GuhTestBase::initTestCase() +{ + + // If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers + QSettings settings; + settings.clear(); + + GuhCore::instance(); + + // Wait for the DeviceManager to signal that it has loaded plugins and everything + QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); + QVERIFY(spy.isValid()); + QVERIFY(spy.wait()); + + m_mockTcpServer = MockTcpServer::servers().first(); + m_clientId = QUuid::createUuid(); + + // Lets add one instance of the mockdevice + QVariantMap params; + params.insert("deviceClassId", "{753f0d32-0468-4d08-82ed-1964aab03298}"); + QVariantMap deviceParams; + deviceParams.insert("httpport", m_mockDevice1Port); + params.insert("deviceParams", deviceParams); + QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); + + QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); + + m_mockDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); + QVERIFY2(!m_mockDeviceId.isNull(), "Newly created mock device must not be null."); +} + +void GuhTestBase::cleanupTestCase() +{ + GuhCore::instance()->destroy(); +} + +QVariant GuhTestBase::injectAndWait(const QString &method, const QVariantMap ¶ms) +{ + QVariantMap call; + call.insert("id", m_commandId++); + call.insert("method", method); + call.insert("params", params); + + QJsonDocument jsonDoc = QJsonDocument::fromVariant(call); + QSignalSpy spy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); + + m_mockTcpServer->injectData(m_clientId, jsonDoc.toJson()); + + if (spy.count() == 0) { + spy.wait(); + } + + // Make sure the response it a valid JSON string + QJsonParseError error; + jsonDoc = QJsonDocument::fromJson(spy.takeFirst().last().toByteArray(), &error); + + return jsonDoc.toVariant(); +} + +int main(int argc, char *argv[]) +{ + REGISTER_METATYPES + + QGuiApplication app(argc, argv); + app.setAttribute(Qt::AA_Use96Dpi, true); + bool success = true; + qDebug() << "got testcases" << TESTCASES; + foreach (const QString &testcase, QString(TESTCASES).split(' ')) { + int id = QMetaType::type(testcase.toLatin1().data()); + if (id != -1) { + GuhTestBase *testcase = static_cast(QMetaType::create(id)); + success &= QTest::qExec(testcase, argc, argv); + delete testcase; + QCoreApplication::processEvents(); + } + } + return success; +} diff --git a/tests/auto/guhtestbase.h b/tests/auto/guhtestbase.h new file mode 100644 index 00000000..bdc25980 --- /dev/null +++ b/tests/auto/guhtestbase.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + ***************************************************************************/ + +#ifndef GUHTESTBASE_H +#define GUHTESTBASE_H + +#include "typeutils.h" +#include "mocktcpserver.h" + +#include +#include +#include +#include + +extern VendorId guhVendorId; +extern DeviceClassId mockDeviceClassId; +extern DeviceClassId mockDeviceAutoClassId; +extern ActionTypeId mockAction1Id; +extern EventTypeId mockEvent1Id; +extern StateTypeId mockIntStateId; + +class MockTcpServer; + +class GuhTestBase : public QObject +{ + Q_OBJECT +public: + explicit GuhTestBase(QObject *parent = 0); + +private slots: + void initTestCase(); + void cleanupTestCase(); + +protected: + QVariant injectAndWait(const QString &method, const QVariantMap ¶ms = QVariantMap()); + +protected: + MockTcpServer *m_mockTcpServer; + QUuid m_clientId; + int m_commandId; + + int m_mockDevice1Port; + int m_mockDevice2Port; + + DeviceId m_mockDeviceId; + +}; + +#endif // GUHTESTBASE_H diff --git a/tests/auto/testdevices.cpp b/tests/auto/testdevices.cpp new file mode 100644 index 00000000..4e7df10f --- /dev/null +++ b/tests/auto/testdevices.cpp @@ -0,0 +1,156 @@ +#include "testdevices.h" +#include "guhcore.h" +#include "devicemanager.h" + +#include +#include + +TestDevices::TestDevices(QObject *parent) : + GuhTestBase(parent) +{ +} + +void TestDevices::getSupportedVendors() +{ + QVariant supportedVendors = injectAndWait("Devices.GetSupportedVendors"); + qDebug() << "response" << supportedVendors; + + // Make sure there is exactly 1 supported Vendor named "guh" + QVariantList vendorList = supportedVendors.toMap().value("params").toMap().value("vendors").toList(); + QCOMPARE(vendorList.count(), 1); + VendorId vendorId = VendorId(vendorList.first().toMap().value("id").toString()); + QCOMPARE(vendorId, guhVendorId); +} + +void TestDevices::getSupportedDevices_data() +{ + QTest::addColumn("vendorId"); + QTest::addColumn("resultCount"); + + QTest::newRow("vendor guh") << guhVendorId << 2; + QTest::newRow("no filter") << VendorId() << 2; + QTest::newRow("invalid vendor") << VendorId("93e7d361-8025-4354-b17e-b68406c800bc") << 0; +} + +void TestDevices::getSupportedDevices() +{ + QFETCH(VendorId, vendorId); + QFETCH(int, resultCount); + + QVariantMap params; + if (!vendorId.isNull()) { + params.insert("vendorId", vendorId); + } + QVariant supportedDevices = injectAndWait("Devices.GetSupportedDevices", params); + + // Make sure there is exactly 1 supported device class with the name Mock Wifi Device + QCOMPARE(supportedDevices.toMap().value("params").toMap().value("deviceClasses").toList().count(), resultCount); + if (resultCount > 0) { + QString deviceName = supportedDevices.toMap().value("params").toMap().value("deviceClasses").toList().first().toMap().value("name").toString(); + QVERIFY(deviceName.startsWith(QString("Mock Device"))); + } +} + +void TestDevices::addConfiguredDevice_data() +{ + QTest::addColumn("deviceClassId"); + QTest::addColumn("deviceParams"); + QTest::addColumn("success"); + + QVariantMap deviceParams; + deviceParams.insert("httpport", m_mockDevice1Port - 1); + QTest::newRow("User, JustAdd") << mockDeviceClassId << deviceParams << true; + QTest::newRow("Auto, JustAdd") << mockDeviceAutoClassId << deviceParams << false; +} + +void TestDevices::addConfiguredDevice() +{ + QFETCH(DeviceClassId, deviceClassId); + QFETCH(QVariantMap, deviceParams); + QFETCH(bool, success); + + QVariantMap params; + params.insert("deviceClassId", deviceClassId); + params.insert("deviceParams", deviceParams); + QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); + qDebug() << "response is" << response; + + QCOMPARE(response.toMap().value("status").toString(), QString("success")); + QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), success); + + if (success) { + QUuid deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); + params.clear(); + params.insert("deviceId", deviceId.toString()); + injectAndWait("Devices.RemoveConfiguredDevice", params); + QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); + } +} + +void TestDevices::getConfiguredDevices() +{ + QVariant response = injectAndWait("Devices.GetConfiguredDevices"); + + QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); + qDebug() << "got devices" << devices; + QCOMPARE(devices.count(), 2); // There should be one auto created mock device and the one created in initTestcase() +} + +void TestDevices::removeDevice() +{ + QVERIFY(!m_mockDeviceId.isNull()); + QSettings settings; + settings.beginGroup(m_mockDeviceId.toString()); + // Make sure we have some config values for this device + QVERIFY(settings.allKeys().count() > 0); + + QVariantMap params; + params.insert("deviceId", m_mockDeviceId); + + QVariant response = injectAndWait("Devices.RemoveConfiguredDevice", params); + + QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); + + // Make sure the device is gone from settings too + QCOMPARE(settings.allKeys().count(), 0); +} + +void TestDevices::storedDevices() +{ + QVariantMap params; + params.insert("deviceClassId", mockDeviceClassId); + QVariantMap deviceParams; + deviceParams.insert("httpport", 8888); + params.insert("deviceParams", deviceParams); + QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); + QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); + DeviceId addedDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); + QVERIFY(!addedDeviceId.isNull()); + + // Destroy and recreate the core instance to check if settings are loaded at startup + GuhCore::instance()->destroy(); + QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); + spy.wait(); + m_mockTcpServer = MockTcpServer::servers().first(); + + + response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); + + foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { + qDebug() << "found stored device" << device; + if (DeviceId(device.toMap().value("id").toString()) == addedDeviceId) { +// foreach (const QVariant ¶mVariant, device.toMap().value("params").toList()) { +// if () +// } + + qDebug() << "found added device" << device.toMap().value("params").toList().first().toMap(); + qDebug() << "expected deviceParams:" << deviceParams; + QCOMPARE(device.toMap().value("params").toList().first().toMap(), deviceParams); + } + } + + params.clear(); + params.insert("deviceId", addedDeviceId); + response = injectAndWait("Devices.RemoveConfiguredDevice", params); +} + diff --git a/tests/auto/testdevices.h b/tests/auto/testdevices.h new file mode 100644 index 00000000..35bd875f --- /dev/null +++ b/tests/auto/testdevices.h @@ -0,0 +1,32 @@ +#ifndef TESTDEVICES_H +#define TESTDEVICES_H + +#include "guhtestbase.h" + +class TestDevices : public GuhTestBase +{ + Q_OBJECT +public: + explicit TestDevices(QObject *parent = 0); + TestDevices (const TestDevices &other) {} + TestDevices& operator=(const TestDevices &other) {} + +private slots: + + void getSupportedVendors(); + + void getSupportedDevices_data(); + void getSupportedDevices(); + + void addConfiguredDevice_data(); + void addConfiguredDevice(); + + void getConfiguredDevices(); + + void removeDevice(); + + void storedDevices(); + +}; + +#endif // TESTDEVICES_H diff --git a/tests/auto/testjsonrpc.cpp b/tests/auto/testjsonrpc.cpp index bc6f01f7..5245d9c2 100644 --- a/tests/auto/testjsonrpc.cpp +++ b/tests/auto/testjsonrpc.cpp @@ -16,6 +16,8 @@ * * ***************************************************************************/ +#include "guhtestbase.h" +#include "testjsonrpc.h" #include "guhcore.h" #include "devicemanager.h" #include "mocktcpserver.h" @@ -27,140 +29,7 @@ #include #include #include - -Q_IMPORT_PLUGIN(DevicePluginMock) - -int mockDevice1Port = 1337; -int mockDevice2Port = 7331; - -extern VendorId guhVendorId; -extern DeviceClassId mockDeviceClassId; -extern DeviceClassId mockDeviceAutoClassId; -extern ActionTypeId mockAction1Id; -extern EventTypeId mockEvent1Id; -extern StateTypeId mockIntStateId; - -class TestJSONRPC: public QObject -{ - Q_OBJECT -private slots: - void initTestcase(); - void cleanupTestCase(); - - void testBasicCall(); - void version(); - void introspect(); - - void getSupportedVendors(); - - void getSupportedDevices_data(); - void getSupportedDevices(); - - void addConfiguredDevice_data(); - void addConfiguredDevice(); - - void getConfiguredDevices(); - - void executeAction_data(); - void executeAction(); - - void getActionTypes_data(); - void getActionTypes(); - - void getEventTypes_data(); - void getEventTypes(); - - void getStateTypes_data(); - void getStateTypes(); - - void enableDisableNotifications_data(); - void enableDisableNotifications(); - - void stateChangeEmitsNotifications(); - - void removeDevice(); - - void storedDevices(); - - void getRules(); - - void apiChangeBumpsVersion(); - -private: - QVariant injectAndWait(const QString &method, const QVariantMap ¶ms); - QStringList extractRefs(const QVariant &variant); - -private: - MockTcpServer *m_mockTcpServer; - QUuid m_clientId; - int m_commandId; - DeviceId m_mockDeviceId; -}; - -void TestJSONRPC::initTestcase() -{ - QCoreApplication::instance()->setOrganizationName("guh-test"); - - // If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers - QSettings settings; - settings.clear(); - - m_commandId = 0; - - GuhCore::instance(); - - // Wait for the DeviceManager to signal that it has loaded plugins and everything - QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); - QVERIFY(spy.isValid()); - QVERIFY(spy.wait()); - - // If Guh should create more than one TcpServer at some point, this needs to be updated. - QCOMPARE(MockTcpServer::servers().count(), 1); - m_mockTcpServer = MockTcpServer::servers().first(); - m_clientId = QUuid::createUuid(); - - // Lets add one instance of the mockdevice - QVariantMap params; - params.insert("deviceClassId", "{753f0d32-0468-4d08-82ed-1964aab03298}"); - QVariantMap deviceParams; - deviceParams.insert("httpport", mockDevice1Port); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - - QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); - - m_mockDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY2(!m_mockDeviceId.isNull(), "Newly created mock device must not be null."); -} - -void TestJSONRPC::cleanupTestCase() -{ - QSettings settings; -// settings.clear(); -} - -QVariant TestJSONRPC::injectAndWait(const QString &method, const QVariantMap ¶ms = QVariantMap()) -{ - QVariantMap call; - call.insert("id", m_commandId++); - call.insert("method", method); - call.insert("params", params); - - QJsonDocument jsonDoc = QJsonDocument::fromVariant(call); - QSignalSpy spy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - m_mockTcpServer->injectData(m_clientId, jsonDoc.toJson()); - - if (spy.count() == 0) { - spy.wait(); - } - - // Make sure the response it a valid JSON string - QJsonParseError error; - jsonDoc = QJsonDocument::fromJson(spy.takeFirst().last().toByteArray(), &error); - - return jsonDoc.toVariant(); -} +#include QStringList TestJSONRPC::extractRefs(const QVariant &variant) { @@ -212,17 +81,6 @@ void TestJSONRPC::testBasicCall() QCOMPARE(jsonDoc.toVariant().toMap().value("id").toInt(), 42); } -void TestJSONRPC::version() -{ - QVariant response = injectAndWait("JSONRPC.Version"); - - QString version = response.toMap().value("params").toMap().value("version").toString(); - qDebug() << "Got version:" << version << "( Expected:" << GUH_VERSION_STRING << ")"; - - QVERIFY2(!version.isEmpty(), "Version is empty."); - QCOMPARE(version, QString(GUH_VERSION_STRING)); -} - void TestJSONRPC::introspect() { QVariant response = injectAndWait("JSONRPC.Introspect"); @@ -245,92 +103,6 @@ void TestJSONRPC::introspect() } } -void TestJSONRPC::getSupportedVendors() -{ - QVariant supportedVendors = injectAndWait("Devices.GetSupportedVendors"); - qDebug() << "response" << supportedVendors; - - // Make sure there is exactly 1 supported Vendor named "guh" - QVariantList vendorList = supportedVendors.toMap().value("params").toMap().value("vendors").toList(); - QCOMPARE(vendorList.count(), 1); - VendorId vendorId = VendorId(vendorList.first().toMap().value("id").toString()); - QCOMPARE(vendorId, guhVendorId); -} - -void TestJSONRPC::getSupportedDevices_data() -{ - QTest::addColumn("vendorId"); - QTest::addColumn("resultCount"); - - QTest::newRow("vendor guh") << guhVendorId << 2; - QTest::newRow("no filter") << VendorId() << 2; - QTest::newRow("invalid vendor") << VendorId("93e7d361-8025-4354-b17e-b68406c800bc") << 0; -} - -void TestJSONRPC::getSupportedDevices() -{ - QFETCH(VendorId, vendorId); - QFETCH(int, resultCount); - - QVariantMap params; - if (!vendorId.isNull()) { - params.insert("vendorId", vendorId); - } - QVariant supportedDevices = injectAndWait("Devices.GetSupportedDevices", params); - - // Make sure there is exactly 1 supported device class with the name Mock Wifi Device - QCOMPARE(supportedDevices.toMap().value("params").toMap().value("deviceClasses").toList().count(), resultCount); - if (resultCount > 0) { - QString deviceName = supportedDevices.toMap().value("params").toMap().value("deviceClasses").toList().first().toMap().value("name").toString(); - QVERIFY(deviceName.startsWith(QString("Mock Device"))); - } -} - -void TestJSONRPC::addConfiguredDevice_data() -{ - QTest::addColumn("deviceClassId"); - QTest::addColumn("deviceParams"); - QTest::addColumn("success"); - - QVariantMap deviceParams; - deviceParams.insert("httpport", mockDevice1Port - 1); - QTest::newRow("User, JustAdd") << mockDeviceClassId << deviceParams << true; - QTest::newRow("Auto, JustAdd") << mockDeviceAutoClassId << deviceParams << false; -} - -void TestJSONRPC::addConfiguredDevice() -{ - QFETCH(DeviceClassId, deviceClassId); - QFETCH(QVariantMap, deviceParams); - QFETCH(bool, success); - - QVariantMap params; - params.insert("deviceClassId", deviceClassId); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - qDebug() << "response is" << response; - - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), success); - - if (success) { - QUuid deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - params.clear(); - params.insert("deviceId", deviceId.toString()); - injectAndWait("Devices.RemoveConfiguredDevice", params); - QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); - } -} - -void TestJSONRPC::getConfiguredDevices() -{ - QVariant response = injectAndWait("Devices.GetConfiguredDevices"); - - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - qDebug() << "got devices" << devices; - QCOMPARE(devices.count(), 2); // There should be one auto created mock device and the one created in initTestcase() -} - void TestJSONRPC::executeAction_data() { QTest::addColumn("deviceId"); @@ -363,13 +135,14 @@ void TestJSONRPC::executeAction() params.insert("deviceId", deviceId); params.insert("params", actionParams); QVariant response = injectAndWait("Actions.ExecuteAction", params); + qDebug() << "executeActionresponse" << response; QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), success); // Fetch action execution history from mock device QNetworkAccessManager nam; QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(mockDevice1Port))); + QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port))); QNetworkReply *reply = nam.get(request); spy.wait(); QCOMPARE(spy.count(), 1); @@ -383,7 +156,7 @@ void TestJSONRPC::executeAction() // cleanup for the next run spy.clear(); - request.setUrl(QUrl(QString("http://localhost:%1/clearactionhistory").arg(mockDevice1Port))); + request.setUrl(QUrl(QString("http://localhost:%1/clearactionhistory").arg(m_mockDevice1Port))); reply = nam.get(request); spy.wait(); QCOMPARE(spy.count(), 1); @@ -502,7 +275,7 @@ void TestJSONRPC::stateChangeEmitsNotifications() // trigger state change in mock device int newVal = 1111; QUuid stateTypeId("80baec19-54de-4948-ac46-31eabfaceb83"); - QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(mockDevice1Port).arg(stateTypeId.toString()).arg(newVal))); + QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(stateTypeId.toString()).arg(newVal))); QNetworkReply *reply = nam.get(request); reply->deleteLater(); @@ -525,7 +298,7 @@ void TestJSONRPC::stateChangeEmitsNotifications() // Fire the a statechange once again clientSpy.clear(); newVal = 42; - request.setUrl(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(mockDevice1Port).arg(stateTypeId.toString()).arg(newVal))); + request.setUrl(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(stateTypeId.toString()).arg(newVal))); reply = nam.get(request); reply->deleteLater(); @@ -544,117 +317,8 @@ void TestJSONRPC::stateChangeEmitsNotifications() } -void TestJSONRPC::removeDevice() -{ - QVERIFY(!m_mockDeviceId.isNull()); - QSettings settings; - settings.beginGroup(m_mockDeviceId.toString()); - // Make sure we have some config values for this device - QVERIFY(settings.allKeys().count() > 0); - - QVariantMap params; - params.insert("deviceId", m_mockDeviceId); - - QVariant response = injectAndWait("Devices.RemoveConfiguredDevice", params); - - QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); - - // Make sure the device is gone from settings too - QCOMPARE(settings.allKeys().count(), 0); -} - -void TestJSONRPC::storedDevices() -{ - QVariantMap params; - params.insert("deviceClassId", mockDeviceClassId); - QVariantMap deviceParams; - deviceParams.insert("httpport", 8888); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true); - DeviceId addedDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!addedDeviceId.isNull()); - - // Destroy and recreate the core instance to check if settings are loaded at startup - GuhCore::instance()->destroy(); - QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded())); - spy.wait(); - m_mockTcpServer = MockTcpServer::servers().first(); - - - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - qDebug() << "found stored device" << device; - if (DeviceId(device.toMap().value("id").toString()) == addedDeviceId) { -// foreach (const QVariant ¶mVariant, device.toMap().value("params").toList()) { -// if () -// } - - qDebug() << "found added device" << device.toMap().value("params").toList().first().toMap(); - qDebug() << "expected deviceParams:" << deviceParams; - QCOMPARE(device.toMap().value("params").toList().first().toMap(), deviceParams); - } - } - - params.clear(); - params.insert("deviceId", addedDeviceId); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); -} - void TestJSONRPC::getRules() { QVariant response = injectAndWait("Rules.GetRules", QVariantMap()); qDebug() << "got rules response" << response; } - -void TestJSONRPC::apiChangeBumpsVersion() -{ - QString oldFilePath = QString(TESTS_SOURCE_DIR) + "/api.json"; - QString newFilePath = QString(TESTS_SOURCE_DIR) + "/api.json.new"; - - QVariant response = injectAndWait("JSONRPC.Version", QVariantMap()); - QByteArray newVersion = response.toMap().value("params").toMap().value("version").toByteArray(); - - response = injectAndWait("JSONRPC.Introspect", QVariantMap()); - QJsonDocument jsonDoc = QJsonDocument::fromVariant(response.toMap().value("params")); - QByteArray newApi = jsonDoc.toJson(); - - - QFile oldApiFile(oldFilePath); - QVERIFY(oldApiFile.exists() && oldApiFile.open(QIODevice::ReadOnly)); - - QByteArray oldVersion = oldApiFile.readLine().trimmed(); - QByteArray oldApi = oldApiFile.readAll(); - - qDebug() << "version" << oldVersion << newVersion; - - if (oldVersion == newVersion && oldApi == newApi) { - // All fine. no changes - return; - } - - if (oldVersion == newVersion && oldApi != newApi) { - QVERIFY2(false, "JSONRPC API has changed but version is still the same. You need to bump the API version."); - } - - QFile newApiFile(newFilePath); - QVERIFY(newApiFile.open(QIODevice::ReadWrite)); - if (newApiFile.size() > 0) { - newApiFile.resize(0); - } - - newApiFile.write(newVersion + '\n'); - newApiFile.write(newApi); - newApiFile.flush(); - - QProcess p; - p.execute("diff", QStringList() << "-u" << oldFilePath << newFilePath); - p.waitForFinished(); - qDebug() << p.readAll(); - - QVERIFY2(false, QString("JSONRPC API has changed. Update %1.").arg(oldFilePath).toLatin1().data()); -} - -QTEST_MAIN(TestJSONRPC) -#include "testjsonrpc.moc" diff --git a/tests/auto/testjsonrpc.h b/tests/auto/testjsonrpc.h new file mode 100644 index 00000000..b17d5f4c --- /dev/null +++ b/tests/auto/testjsonrpc.h @@ -0,0 +1,43 @@ +#ifndef TESTJSONRPC_H +#define TESTJSONRPC_H + +#include "guhtestbase.h" + +class TestJSONRPC: public GuhTestBase +{ + Q_OBJECT +public: + TestJSONRPC(QObject *parent=0): GuhTestBase(parent) {} + TestJSONRPC (const TestJSONRPC &other) {} + TestJSONRPC& operator=(const TestJSONRPC &other) {} + +private slots: + void testBasicCall(); + void introspect(); + + void executeAction_data(); + void executeAction(); + + void getActionTypes_data(); + void getActionTypes(); + + void getEventTypes_data(); + void getEventTypes(); + + void getStateTypes_data(); + void getStateTypes(); + + void enableDisableNotifications_data(); + void enableDisableNotifications(); + + void stateChangeEmitsNotifications(); + + void getRules(); + +private: + QStringList extractRefs(const QVariant &variant); + +}; +Q_DECLARE_METATYPE(TestJSONRPC) + +#endif diff --git a/tests/auto/testversioning.cpp b/tests/auto/testversioning.cpp new file mode 100644 index 00000000..5a5d190a --- /dev/null +++ b/tests/auto/testversioning.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + ***************************************************************************/ + +#include "testversioning.h" +#include "guhcore.h" +#include "devicemanager.h" +#include "mocktcpserver.h" + +#include +#include +#include +#include +#include +#include +#include + +void TestVersioning::version() +{ + QVariant response = injectAndWait("JSONRPC.Version"); + + QString version = response.toMap().value("params").toMap().value("version").toString(); + qDebug() << "Got version:" << version << "( Expected:" << GUH_VERSION_STRING << ")"; + + QVERIFY2(!version.isEmpty(), "Version is empty."); + QCOMPARE(version, QString(GUH_VERSION_STRING)); +} + +void TestVersioning::apiChangeBumpsVersion() +{ + QString oldFilePath = QString(TESTS_SOURCE_DIR) + "/api.json"; + QString newFilePath = QString(TESTS_SOURCE_DIR) + "/api.json.new"; + + QVariant response = injectAndWait("JSONRPC.Version", QVariantMap()); + QByteArray newVersion = response.toMap().value("params").toMap().value("version").toByteArray(); + + response = injectAndWait("JSONRPC.Introspect", QVariantMap()); + QJsonDocument jsonDoc = QJsonDocument::fromVariant(response.toMap().value("params")); + QByteArray newApi = jsonDoc.toJson(); + + + QFile oldApiFile(oldFilePath); + QVERIFY(oldApiFile.exists() && oldApiFile.open(QIODevice::ReadOnly)); + + QByteArray oldVersion = oldApiFile.readLine().trimmed(); + QByteArray oldApi = oldApiFile.readAll(); + + qDebug() << "version" << oldVersion << newVersion; + + if (oldVersion == newVersion && oldApi == newApi) { + // All fine. no changes + return; + } + + if (oldVersion == newVersion && oldApi != newApi) { + QVERIFY2(false, "JSONRPC API has changed but version is still the same. You need to bump the API version."); + } + + QFile newApiFile(newFilePath); + QVERIFY(newApiFile.open(QIODevice::ReadWrite)); + if (newApiFile.size() > 0) { + newApiFile.resize(0); + } + + newApiFile.write(newVersion + '\n'); + newApiFile.write(newApi); + newApiFile.flush(); + + QProcess p; + p.execute("diff", QStringList() << "-u" << oldFilePath << newFilePath); + p.waitForFinished(); + qDebug() << p.readAll(); + + QVERIFY2(false, QString("JSONRPC API has changed. Update %1.").arg(oldFilePath).toLatin1().data()); +} diff --git a/tests/auto/testversioning.h b/tests/auto/testversioning.h new file mode 100644 index 00000000..1ba4536a --- /dev/null +++ b/tests/auto/testversioning.h @@ -0,0 +1,20 @@ +#ifndef TESTVERSIONING_H +#define TESTVERSIONING_H + +#include "guhtestbase.h" + +class TestVersioning: public GuhTestBase +{ + Q_OBJECT +public: + TestVersioning () {} + TestVersioning (const TestVersioning &other) {} + TestVersioning& operator=(const TestVersioning &other) {} + +private slots: + void version(); + void apiChangeBumpsVersion(); +}; +Q_DECLARE_METATYPE(TestVersioning); + +#endif //TESTVERSIONING_H