diff --git a/plugins/mock/devicepluginmock.cpp b/plugins/mock/devicepluginmock.cpp index 0317ad6f..25873def 100644 --- a/plugins/mock/devicepluginmock.cpp +++ b/plugins/mock/devicepluginmock.cpp @@ -110,6 +110,8 @@ DeviceManager::DeviceSetupStatus DevicePluginMock::setupDevice(Device *device) connect(daemon, &HttpDaemon::triggerEvent, this, &DevicePluginMock::triggerEvent); connect(daemon, &HttpDaemon::setState, this, &DevicePluginMock::setState); + // Keep this queued or it might happen that the HttpDaemon is deleted before it is able to reply to the caller + connect(daemon, &HttpDaemon::disappear, this, &DevicePluginMock::onDisappear, Qt::QueuedConnection); if (device->paramValue(asyncParamTypeId).toBool()) { m_asyncSetupDevices.append(device); @@ -296,6 +298,17 @@ void DevicePluginMock::triggerEvent(const EventTypeId &id) emit emitEvent(event); } +void DevicePluginMock::onDisappear() +{ + HttpDaemon *daemon = qobject_cast(sender()); + if (!daemon) { + return; + } + Device *device = m_daemons.key(daemon); + qCDebug(dcMockDevice) << "Emitting autoDeviceDisappeared for device" << device->id(); + emit autoDeviceDisappeared(device->id()); +} + void DevicePluginMock::emitDevicesDiscovered() { QList deviceDescriptors; diff --git a/plugins/mock/devicepluginmock.h b/plugins/mock/devicepluginmock.h index ba6cab2c..ab598641 100644 --- a/plugins/mock/devicepluginmock.h +++ b/plugins/mock/devicepluginmock.h @@ -59,6 +59,7 @@ public slots: private slots: void setState(const StateTypeId &stateTypeId, const QVariant &value); void triggerEvent(const EventTypeId &id); + void onDisappear(); void emitDevicesDiscovered(); void emitPushButtonDevicesDiscovered(); void emitDisplayPinDevicesDiscovered(); diff --git a/plugins/mock/httpdaemon.cpp b/plugins/mock/httpdaemon.cpp index 85bb6efa..a9ccfc7e 100644 --- a/plugins/mock/httpdaemon.cpp +++ b/plugins/mock/httpdaemon.cpp @@ -102,6 +102,9 @@ void HttpDaemon::readClient() } else if (url.path() == "/clearactionhistory") { qCDebug(dcMockDevice) << "Clear action history"; m_actionList.clear(); + } else if (url.path() == "/disappear") { + qCDebug(dcMockDevice) << "Should disappear"; + emit disappear(); } if (tokens[0] == "GET") { diff --git a/plugins/mock/httpdaemon.h b/plugins/mock/httpdaemon.h index 4c53ad73..467be297 100644 --- a/plugins/mock/httpdaemon.h +++ b/plugins/mock/httpdaemon.h @@ -46,6 +46,7 @@ public: signals: void setState(const StateTypeId &stateTypeId, const QVariant &value); void triggerEvent(const EventTypeId &eventTypeId); + void disappear(); private slots: void readClient(); diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index 198c7ee3..0eb80b7b 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -98,10 +98,10 @@ private slots: void reconfigureByDiscovery_data(); void reconfigureByDiscovery(); - // Keep this the last one! It'll remove the configured mock device void removeDevice_data(); void removeDevice(); + void removeAutoDevice(); }; void TestDevices::getPlugins() @@ -1204,6 +1204,46 @@ void TestDevices::removeDevice() } } +void TestDevices::removeAutoDevice() +{ + // Setup connection to mock client + QNetworkAccessManager *nam = new QNetworkAccessManager(this); + QSignalSpy spy(nam, SIGNAL(finished(QNetworkReply*))); + + // First try to make a manually created device disappear. It must not go away + + QList devices = GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId); + QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); + Device *device = devices.first(); + + // trigger disappear signal in mock device + int port = device->paramValue(httpportParamTypeId).toInt(); + QNetworkRequest request(QUrl(QString("http://localhost:%1/disappear").arg(port))); + QNetworkReply *reply = nam->get(request); + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); + QVERIFY2(GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId).count() == 1, "Mock device has disappeared even though it shouldn't"); + + // Ok, now do the same with an autocreated one. It should go away + + devices = GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceAutoClassId); + QVERIFY2(devices.count() > 0, "There needs to be at least one auto-created Mock Device for this test"); + device = devices.first(); + + // trigger disappear signal in mock device + spy.clear(); + port = device->paramValue(httpportParamTypeId).toInt(); + request.setUrl(QUrl(QString("http://localhost:%1/disappear").arg(port))); + reply = nam->get(request); + + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); + + QVERIFY2(GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceAutoClassId).count() == 0, "Mock device has not disappeared even though it should have."); +} + #include "testdevices.moc" QTEST_MAIN(TestDevices) diff --git a/tests/auto/guhtestbase.cpp b/tests/auto/guhtestbase.cpp index c1f229e1..34804b4c 100644 --- a/tests/auto/guhtestbase.cpp +++ b/tests/auto/guhtestbase.cpp @@ -185,26 +185,9 @@ void GuhTestBase::initTestCase() m_mockTcpServer = MockTcpServer::servers().first(); m_clientId = QUuid::createUuid(); - // Lets add one instance of the mockdevice - QVariantMap params; - params.insert("name", "Test Mock Device"); - params.insert("deviceClassId", "{753f0d32-0468-4d08-82ed-1964aab03298}"); + createMockDevice(); - QVariantList deviceParams; - QVariantMap httpPortParam; - httpPortParam.insert("paramTypeId", httpportParamTypeId.toString()); - httpPortParam.insert("value", m_mockDevice1Port); - deviceParams.append(httpPortParam); - params.insert("deviceParams", deviceParams); - - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - - verifyDeviceError(response); - - m_mockDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY2(!m_mockDeviceId.isNull(), "Newly created mock device must not be null."); - - response = injectAndWait("Devices.GetConfiguredDevices", {}); + QVariant response = injectAndWait("Devices.GetConfiguredDevices", {}); foreach (const QVariant &device, response.toMap().value("params").toMap().value("devices").toList()) { if (device.toMap().value("deviceClassId").toUuid() == mockDeviceAutoClassId) { m_mockDeviceAutoId = DeviceId(device.toMap().value("id").toString()); @@ -217,6 +200,14 @@ void GuhTestBase::cleanupTestCase() GuhCore::instance()->destroy(); } +void GuhTestBase::cleanup() +{ + // In case a test deleted the mock device, lets recreate it. + if (GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId).count() == 0) { + createMockDevice(); + } +} + QVariant GuhTestBase::injectAndWait(const QString &method, const QVariantMap ¶ms) { QVariantMap call; @@ -500,3 +491,24 @@ void GuhTestBase::clearLoggingDatabase() GuhCore::instance()->logEngine()->clearDatabase(); } +void GuhTestBase::createMockDevice() +{ + QVariantMap params; + params.insert("name", "Test Mock Device"); + params.insert("deviceClassId", "{753f0d32-0468-4d08-82ed-1964aab03298}"); + + QVariantList deviceParams; + QVariantMap httpPortParam; + httpPortParam.insert("paramTypeId", httpportParamTypeId.toString()); + httpPortParam.insert("value", m_mockDevice1Port); + deviceParams.append(httpPortParam); + params.insert("deviceParams", deviceParams); + + QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); + + verifyDeviceError(response); + + m_mockDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); + QVERIFY2(!m_mockDeviceId.isNull(), "Newly created mock device must not be null."); +} + diff --git a/tests/auto/guhtestbase.h b/tests/auto/guhtestbase.h index 21a4044c..fdae7a27 100644 --- a/tests/auto/guhtestbase.h +++ b/tests/auto/guhtestbase.h @@ -101,6 +101,7 @@ public: protected slots: void initTestCase(); void cleanupTestCase(); + void cleanup(); protected: QVariant injectAndWait(const QString &method, const QVariantMap ¶ms = QVariantMap()); @@ -176,6 +177,9 @@ protected: void restartServer(); void clearLoggingDatabase(); +private: + void createMockDevice(); + protected: PluginId mockPluginId = PluginId("727a4a9a-c187-446f-aadf-f1b2220607d1"); VendorId guhVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6");