From 1688a6b24c77d19c72693c49d5c57ece8416cb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sun, 5 Jul 2015 20:39:29 +0200 Subject: [PATCH] added database updated notification fixed notification tests fixed datetime notification id bump api version --- .../datetime/deviceplugindatetime.json | 2 +- server/guhcore.cpp | 12 +- server/jsonrpc/logginghandler.cpp | 38 +++-- server/jsonrpc/logginghandler.h | 3 + server/logging/logengine.cpp | 84 +++++++++-- server/logging/logengine.h | 15 +- server/main.cpp | 2 +- tests/auto/api.json | 9 +- tests/auto/jsonrpc/testjsonrpc.cpp | 140 +++++------------- 9 files changed, 166 insertions(+), 139 deletions(-) diff --git a/plugins/deviceplugins/datetime/deviceplugindatetime.json b/plugins/deviceplugins/datetime/deviceplugindatetime.json index a1315a5b..06d639b5 100644 --- a/plugins/deviceplugins/datetime/deviceplugindatetime.json +++ b/plugins/deviceplugins/datetime/deviceplugindatetime.json @@ -118,7 +118,7 @@ "name": "dusk" }, { - "id": "792885f3-f505-42db-8c74-3d0460b575a1", + "id": "726acb30-928b-43da-a790-977a821c979e", "idName": "sunrise", "name": "sunrise" }, diff --git a/server/guhcore.cpp b/server/guhcore.cpp index 7161bbbe..dc349269 100644 --- a/server/guhcore.cpp +++ b/server/guhcore.cpp @@ -213,7 +213,11 @@ DeviceManager::DeviceError GuhCore::removeConfiguredDevice(const DeviceId &devic } } - return m_deviceManager->removeConfiguredDevice(deviceId); + DeviceManager::DeviceError removeError = m_deviceManager->removeConfiguredDevice(deviceId); + if (removeError == DeviceManager::DeviceErrorNoError) + m_logger->removeDeviceLogs(deviceId); + + return removeError; } /*! Calls the metheod DeviceManager::pairDevice(\a pairingTransactionId, \a deviceClassId, \a deviceDescriptorId). @@ -357,7 +361,11 @@ RuleEngine::RuleError GuhCore::editRule(const RuleId &id, const QString &name, c * \sa RuleEngine, */ RuleEngine::RuleError GuhCore::removeRule(const RuleId &id) { - return m_ruleEngine->removeRule(id); + RuleEngine::RuleError removeError = m_ruleEngine->removeRule(id); + if (removeError != RuleEngine::RuleErrorNoError) + m_logger->removeRuleLogs(id); + + return removeError; } /*! Calls the metheod RuleEngine::findRules(\a deviceId). diff --git a/server/jsonrpc/logginghandler.cpp b/server/jsonrpc/logginghandler.cpp index acb7446b..1d54bc6f 100644 --- a/server/jsonrpc/logginghandler.cpp +++ b/server/jsonrpc/logginghandler.cpp @@ -33,17 +33,12 @@ LoggingHandler::LoggingHandler(QObject *parent) : QVariantMap params; QVariantMap returns; - // Notifications - params.clear(); returns.clear(); - setDescription("LogEntryAdded", "Emitted whenever an entry is appended to the logging system. " - "The filters can be combinend."); - params.insert("logEntry", JsonTypes::logEntryRef()); - setParams("LogEntryAdded", params); - - params.clear(); returns.clear(); - setDescription("GetLogEntries", "Get the LogEntries matching the given filter."); - QVariantMap timeFilter; + params.clear(); returns.clear(); + setDescription("GetLogEntries", "Get the LogEntries matching the given filter. " + "Each list element of a given filter will be connected with OR " + "to each other. Each of the given filters will be connected with AND " + "to each other."); timeFilter.insert("o:startDate", JsonTypes::basicTypeToString(JsonTypes::Int)); timeFilter.insert("o:endDate", JsonTypes::basicTypeToString(JsonTypes::Int)); params.insert("o:timeFilters", QVariantList() << timeFilter); @@ -53,13 +48,27 @@ LoggingHandler::LoggingHandler(QObject *parent) : params.insert("o:typeIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Uuid)); params.insert("o:deviceIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Uuid)); params.insert("o:values", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Variant)); - setParams("GetLogEntries", params); returns.insert("loggingError", JsonTypes::loggingErrorRef()); returns.insert("o:logEntries", QVariantList() << JsonTypes::logEntryRef()); setReturns("GetLogEntries", returns); + // Notifications + params.clear(); + setDescription("LogEntryAdded", "Emitted whenever an entry is appended to the logging system. "); + params.insert("logEntry", JsonTypes::logEntryRef()); + setParams("LogEntryAdded", params); + + params.clear(); + setDescription("LogDatabaseUpdated", "Emitted whenever the database was updated. " + "The database will be updated when a log entry was deleted. A log " + "entry will be deleted when the corresponding device or a rule will " + "be removed, or when the oldest entry of the database was deleted to " + "keep to database in the size limits."); + setParams("LogDatabaseUpdated", params); + connect(GuhCore::instance()->logEngine(), &LogEngine::logEntryAdded, this, &LoggingHandler::logEntryAdded); + connect(GuhCore::instance()->logEngine(), &LogEngine::logDatabaseUpdated, this, &LoggingHandler::logDatabaseUpdated); } QString LoggingHandler::name() const @@ -69,11 +78,18 @@ QString LoggingHandler::name() const void LoggingHandler::logEntryAdded(const LogEntry &logEntry) { + qCDebug(dcJsonRpc) << "Notify \"Logging.LogEntryAdded\""; QVariantMap params; params.insert("logEntry", JsonTypes::packLogEntry(logEntry)); emit LogEntryAdded(params); } +void LoggingHandler::logDatabaseUpdated() +{ + qCDebug(dcJsonRpc) << "Notify \"Logging.LogDatabaseUpdated\""; + emit LogDatabaseUpdated(QVariantMap()); +} + JsonReply* LoggingHandler::GetLogEntries(const QVariantMap ¶ms) const { qCDebug(dcJsonRpc) << "Asked for log entries" << params; diff --git a/server/jsonrpc/logginghandler.h b/server/jsonrpc/logginghandler.h index 1af6bbb2..39fd0761 100644 --- a/server/jsonrpc/logginghandler.h +++ b/server/jsonrpc/logginghandler.h @@ -37,9 +37,12 @@ public: Q_INVOKABLE JsonReply *GetLogEntries(const QVariantMap ¶ms) const; signals: void LogEntryAdded(const QVariantMap ¶ms); + void LogDatabaseUpdated(const QVariantMap ¶ms); private slots: void logEntryAdded(const LogEntry &entry); + void logDatabaseUpdated(); + }; } diff --git a/server/logging/logengine.cpp b/server/logging/logengine.cpp index 067451bb..0b0a7e46 100644 --- a/server/logging/logengine.cpp +++ b/server/logging/logengine.cpp @@ -24,20 +24,24 @@ #include "logging.h" #include +#include #include +#include #include #include #include #define DB_SCHEMA_VERSION 2 +#define DB_MAX_SIZE 3000 namespace guhserver { LogEngine::LogEngine(QObject *parent): QObject(parent) { + m_db = QSqlDatabase::addDatabase("QSQLITE"); - m_db.setDatabaseName("/tmp/guhd-logs.sqlite"); + m_db.setDatabaseName("/tmp/guhd.log"); if (!m_db.isValid()) { qCWarning(dcLogEngine) << "Database not valid:" << m_db.lastError().driverText() << m_db.lastError().databaseText(); @@ -58,14 +62,19 @@ QList LogEngine::logEntries(const LogFilter &filter) const QList results; QSqlQuery query; - QString queryCall = "SELECT * FROM entries;"; + QString queryCall = "SELECT * FROM entries ORDER BY timestamp;"; if (filter.isEmpty()) { query.exec(queryCall); } else { - queryCall = QString("SELECT * FROM entries WHERE %1;").arg(filter.queryString()); + queryCall = QString("SELECT * FROM entries WHERE %1 ORDER BY timestamp;").arg(filter.queryString()); query.exec(queryCall); } + if (query.lastError().isValid()) { + qCWarning(dcLogEngine) << "Error fetching log entries. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + return QList(); + } + while (query.next()) { LogEntry entry( QDateTime::fromTime_t(query.value("timestamp").toLongLong()), @@ -91,7 +100,6 @@ void LogEngine::logSystemEvent(bool active, Logging::LoggingLevel level) LogEntry entry(level, Logging::LoggingSourceSystem); entry.setActive(active); appendLogEntry(entry); - emit logEntryAdded(entry); } void LogEngine::logEvent(const Event &event) @@ -112,7 +120,6 @@ void LogEngine::logEvent(const Event &event) entry.setDeviceId(event.deviceId()); entry.setValue(valueList.join(", ")); appendLogEntry(entry); - emit logEntryAdded(entry); } void LogEngine::logAction(const Action &action, Logging::LoggingLevel level, int errorCode) @@ -126,7 +133,6 @@ void LogEngine::logAction(const Action &action, Logging::LoggingLevel level, int entry.setDeviceId(action.deviceId()); entry.setValue(valueList.join(", ")); appendLogEntry(entry); - emit logEntryAdded(entry); } void LogEngine::logRuleTriggered(const Rule &rule) @@ -134,7 +140,6 @@ void LogEngine::logRuleTriggered(const Rule &rule) LogEntry entry(Logging::LoggingSourceRules); entry.setTypeId(rule.id()); appendLogEntry(entry); - emit logEntryAdded(entry); } void LogEngine::logRuleActiveChanged(const Rule &rule) @@ -143,11 +148,38 @@ void LogEngine::logRuleActiveChanged(const Rule &rule) entry.setTypeId(rule.id()); entry.setActive(rule.active()); appendLogEntry(entry); - emit logEntryAdded(entry); +} + +void LogEngine::removeDeviceLogs(const DeviceId &deviceId) +{ + qCDebug(dcLogEngine) << "Deleting log entries from device" << deviceId.toString(); + + QSqlQuery query; + QString queryDeleteString = QString("DELETE FROM entries WHERE deviceId = '%1';").arg(deviceId.toString()); + if (!query.exec(queryDeleteString)) { + qCWarning(dcLogEngine) << "Error deleting log entries from device" << deviceId.toString() << ". Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + } else { + emit logDatabaseUpdated(); + } +} + +void LogEngine::removeRuleLogs(const RuleId &ruleId) +{ + qCDebug(dcLogEngine) << "Deleting log entries from rule" << ruleId.toString(); + + QSqlQuery query; + QString queryDeleteString = QString("DELETE FROM entries WHERE typeId = '%1';").arg(ruleId.toString()); + if (!query.exec(queryDeleteString)) { + qCWarning(dcLogEngine) << "Error deleting log entries from rule" << ruleId.toString() << ". Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + } else { + emit logDatabaseUpdated(); + } } void LogEngine::appendLogEntry(const LogEntry &entry) { + checkDBSize(); + QString queryString = QString("INSERT INTO entries (timestamp, loggingEventType, loggingLevel, sourceType, typeId, deviceId, value, active, errorCode) values ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9');") .arg(entry.timestamp().toTime_t()) .arg(entry.eventType()) @@ -160,10 +192,37 @@ void LogEngine::appendLogEntry(const LogEntry &entry) .arg(entry.errorCode()); QSqlQuery query; - query.exec(queryString); - - if (query.lastError().isValid()) { + if (!query.exec(queryString)) { qCWarning(dcLogEngine) << "Error writing log entry. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + return; + } + + emit logEntryAdded(entry); +} + +void LogEngine::checkDBSize() +{ + QString queryString = "SELECT ROWID FROM entries;"; + QSqlQuery query; + query.exec(queryString); + int numRows = 0; + if (m_db.driver()->hasFeature(QSqlDriver::QuerySize)) { + numRows = query.size(); + } else { + // this can be very slow + query.last(); + numRows = query.at() + 1; + } + + if (numRows >= DB_MAX_SIZE) { + // keep only the latest DB_MAX_SIZE entries + qCDebug(dcLogEngine) << "Deleting oldest entries and keep only the latest" << DB_MAX_SIZE << "entries."; + QString queryDeleteString = QString("DELETE FROM entries WHERE ROWID IN (SELECT ROWID FROM entries ORDER BY timestamp DESC LIMIT -1 OFFSET %1);").arg(QString::number(DB_MAX_SIZE)); + if (!query.exec(queryDeleteString)) { + qCWarning(dcLogEngine) << "Error deleting oldest log entries to keep size. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); + } else { + emit logDatabaseUpdated(); + } } } @@ -185,7 +244,7 @@ void LogEngine::initDB() if (version != DB_SCHEMA_VERSION) { qCWarning(dcLogEngine) << "Log schema version not matching! Schema upgrade not implemented yet. Logging might fail."; } else { - qCDebug(dcLogEngine) << "Log database schema version" << DB_SCHEMA_VERSION << "matches"; + qCDebug(dcLogEngine) << QString("Log database schema version \"%1\" matches").arg(DB_SCHEMA_VERSION); } } else { qCWarning(dcLogEngine) << "Broken log database. Version not found in metadata table."; @@ -230,6 +289,7 @@ void LogEngine::initDB() qCWarning(dcLogEngine) << "Error creating log table in database. Driver error:" << query.lastError().driverText() << "Database error:" << query.lastError().databaseText(); } } + qCDebug(dcLogEngine) << "Initialized logging DB successfully."; } } diff --git a/server/logging/logengine.h b/server/logging/logengine.h index 65ede922..4a41b1b0 100644 --- a/server/logging/logengine.h +++ b/server/logging/logengine.h @@ -43,6 +43,14 @@ public: signals: void logEntryAdded(const LogEntry &logEntry); + void logDatabaseUpdated(); + +private: + QSqlDatabase m_db; + + void initDB(); + void appendLogEntry(const LogEntry &entry); + void checkDBSize(); private: // Only GuhCore is allowed to log events. @@ -52,12 +60,9 @@ private: void logAction(const Action &action, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0); void logRuleTriggered(const Rule &rule); void logRuleActiveChanged(const Rule &rule); + void removeDeviceLogs(const DeviceId &deviceId); + void removeRuleLogs(const RuleId &ruleId); -private: - void initDB(); - void appendLogEntry(const LogEntry &entry); - - QSqlDatabase m_db; }; } diff --git a/server/main.cpp b/server/main.cpp index 658dc56e..bd8763d0 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) s_loggingFilters.insert("Warnings", true); s_loggingFilters.insert("DeviceManager", true); s_loggingFilters.insert("RuleEngine", true); - s_loggingFilters.insert("Connection", false); + s_loggingFilters.insert("Connection", true); s_loggingFilters.insert("JsonRpc", false); s_loggingFilters.insert("Hardware", false); s_loggingFilters.insert("LogEngine", false); diff --git a/tests/auto/api.json b/tests/auto/api.json index af2dd1aa..3aecb62f 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -276,7 +276,7 @@ } }, "Logging.GetLogEntries": { - "description": "Get the LogEntries matching the given filter.", + "description": "Get the LogEntries matching the given filter. Each list element of a given filter will be connected with OR to each other. Each of the given filters will be connected with AND to each other.", "params": { "o:deviceIds": [ "Uuid" @@ -457,8 +457,13 @@ "event": "$ref:Event" } }, + "Logging.LogDatabaseUpdated": { + "description": "Emitted whenever the database was updated. The database will be updated when a log entry was deleted. A log entry will be deleted when the corresponding device or a rule will be removed, or when the oldest entry of the database was deleted to keep to database in the size limits.", + "params": { + } + }, "Logging.LogEntryAdded": { - "description": "Emitted whenever an entry is appended to the logging system. The filters can be combinend.", + "description": "Emitted whenever an entry is appended to the logging system. ", "params": { "logEntry": "$ref:LogEntry" } diff --git a/tests/auto/jsonrpc/testjsonrpc.cpp b/tests/auto/jsonrpc/testjsonrpc.cpp index 72c0efc2..0bf0fd35 100644 --- a/tests/auto/jsonrpc/testjsonrpc.cpp +++ b/tests/auto/jsonrpc/testjsonrpc.cpp @@ -412,22 +412,13 @@ void TestJSONRPC::ruleActiveChangedNotifications() QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); response = injectAndWait("Rules.AddRule", params); - clientSpy.wait(500); - qDebug() << "got" << clientSpy.count() << "notifications"; - QCOMPARE(clientSpy.count(), 2); + QVariant notificationVariant = checkNotification(clientSpy, "Rules.RuleAdded"); + verifyRuleError(response); - QJsonDocument jsonDocResponse = QJsonDocument::fromJson(clientSpy.at(1).at(1).toByteArray()); - QJsonDocument jsonDocNotification = QJsonDocument::fromJson(clientSpy.at(0).at(1).toByteArray()); - - verifyRuleError(jsonDocResponse.toVariant()); - RuleId ruleId = RuleId(jsonDocResponse.toVariant().toMap().value("params").toMap().value("ruleId").toString()); + QVariantMap notificationRuleMap = notificationVariant.toMap().value("params").toMap().value("rule").toMap(); + RuleId ruleId = RuleId(notificationRuleMap.value("id").toString()); QVERIFY(!ruleId.isNull()); - - // check the DeviceAdded notification - QCOMPARE(jsonDocNotification.toVariant().toMap().value("notification").toString(), QString("Rules.RuleAdded")); - QVariantMap notificationRuleMap = jsonDocNotification.toVariant().toMap().value("params").toMap().value("rule").toMap(); - QCOMPARE(notificationRuleMap.value("enabled").toBool(), true); QCOMPARE(notificationRuleMap.value("name").toString(), params.value("name").toString()); QCOMPARE(notificationRuleMap.value("id").toString(), ruleId.toString()); @@ -438,31 +429,21 @@ void TestJSONRPC::ruleActiveChangedNotifications() // set the rule active QNetworkAccessManager nam; QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - QSignalSpy clientSpy2(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); // state state to 20 qDebug() << "setting mock int state to 20"; QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockIntStateId.toString()).arg(20))); QNetworkReply *reply = nam.get(request); - spy.wait(500); - QCOMPARE(spy.count(), 1); reply->deleteLater(); - clientSpy2.wait(500); - qDebug() << "got" << clientSpy2.count() << "notifications"; - QCOMPARE(clientSpy2.count(), 6); + clientSpy.wait(500); + notificationVariant = checkNotification(clientSpy, "Rules.RuleActiveChanged"); + verifyRuleError(response); - for (int i = 0; i < clientSpy2.count(); i++) { - QByteArray notification = clientSpy2.at(i).at(1).toByteArray(); - if (notification.contains("Rules.RuleActiveChanged")) { - QVariantMap notificationMap = QJsonDocument::fromJson(notification).toVariant().toMap(); - QCOMPARE(notificationMap.value("notification").toString(), QString("Rules.RuleActiveChanged")); - QCOMPARE(notificationMap.value("params").toMap().value("ruleId").toString(), ruleId.toString()); - QCOMPARE(notificationMap.value("params").toMap().value("active").toBool(), true); - } - } - clientSpy2.clear(); - spy.clear(); + QCOMPARE(notificationVariant.toMap().value("params").toMap().value("ruleId").toString(), ruleId.toString()); + QCOMPARE(notificationVariant.toMap().value("params").toMap().value("active").toBool(), true); + + spy.clear(); clientSpy.clear(); // set the rule inactive qDebug() << "setting mock int state to 42"; @@ -472,39 +453,24 @@ void TestJSONRPC::ruleActiveChangedNotifications() QCOMPARE(spy.count(), 1); reply2->deleteLater(); - clientSpy2.wait(500); - QCOMPARE(clientSpy2.count(), 5); + clientSpy.wait(500); + notificationVariant = checkNotification(clientSpy, "Rules.RuleActiveChanged"); + verifyRuleError(response); - for (int i = 0; i < clientSpy2.count(); i++) { - QByteArray notification = clientSpy2.at(i).at(1).toByteArray(); - if (notification.contains("Rules.RuleActiveChanged")) { - QVariantMap notificationMap = QJsonDocument::fromJson(notification).toVariant().toMap(); - QCOMPARE(notificationMap.value("notification").toString(), QString("Rules.RuleActiveChanged")); - QCOMPARE(notificationMap.value("params").toMap().value("ruleId").toString(), ruleId.toString()); - QCOMPARE(notificationMap.value("params").toMap().value("active").toBool(), false); - } - } - - // Setup connection to mock client - QSignalSpy clientSpy3(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); + QCOMPARE(notificationVariant.toMap().value("params").toMap().value("ruleId").toString(), ruleId.toString()); + QCOMPARE(notificationVariant.toMap().value("params").toMap().value("active").toBool(), false); // now remove the rule and check the RuleRemoved notification params.clear(); response.clear(); params.insert("ruleId", ruleId); response = injectAndWait("Rules.RemoveRule", params); - clientSpy3.wait(500); - qDebug() << "got" << clientSpy3.count() << "notifications"; - QCOMPARE(clientSpy3.count(), 2); // wait for RuleRemoved notification and response + clientSpy.wait(500); + notificationVariant = checkNotification(clientSpy, "Rules.RuleRemoved"); + checkNotification(clientSpy, "Logging.LogDatabaseUpdated"); + verifyRuleError(response); - jsonDocResponse = QJsonDocument::fromJson(clientSpy3.at(1).at(1).toByteArray()); - jsonDocNotification = QJsonDocument::fromJson(clientSpy3.at(0).at(1).toByteArray()); - - verifyRuleError(jsonDocResponse.toVariant()); - - // check the DeviceRemoved notification - QCOMPARE(jsonDocNotification.toVariant().toMap().value("notification").toString(), QString("Rules.RuleRemoved")); - QCOMPARE(jsonDocNotification.toVariant().toMap().value("params").toMap().value("ruleId").toString(), ruleId.toString()); + QCOMPARE(notificationVariant.toMap().value("params").toMap().value("ruleId").toString(), ruleId.toString()); } void TestJSONRPC::deviceParamsChangedNotifications() @@ -519,7 +485,6 @@ void TestJSONRPC::deviceParamsChangedNotifications() QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); // ADD - // add device and wait for notification QVariantList deviceParams; QVariantMap httpportParam; @@ -527,25 +492,15 @@ void TestJSONRPC::deviceParamsChangedNotifications() httpportParam.insert("value", 23234); deviceParams.append(httpportParam); - params.clear(); response.clear(); + params.clear(); response.clear(); clientSpy.clear(); params.insert("deviceClassId", mockDeviceClassId); params.insert("deviceParams", deviceParams); response = injectAndWait("Devices.AddConfiguredDevice", params); - - // Lets wait for the notification - clientSpy.wait(500); - QCOMPARE(clientSpy.count(), 2); // wait for device added notification and response - - QJsonDocument jsonDocResponse = QJsonDocument::fromJson(clientSpy.at(1).at(1).toByteArray()); - QJsonDocument jsonDocNotification = QJsonDocument::fromJson(clientSpy.at(0).at(1).toByteArray()); - - verifyDeviceError(jsonDocResponse.toVariant()); - DeviceId deviceId = DeviceId(jsonDocResponse.toVariant().toMap().value("params").toMap().value("deviceId").toString()); + DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); QVERIFY(!deviceId.isNull()); - - // check the DeviceAdded notification - QCOMPARE(jsonDocNotification.toVariant().toMap().value("notification").toString(), QString("Devices.DeviceAdded")); - QVariantMap notificationDeviceMap = jsonDocNotification.toVariant().toMap().value("params").toMap().value("device").toMap(); + clientSpy.wait(500); + verifyDeviceError(response); + QVariantMap notificationDeviceMap = checkNotification(clientSpy, "Devices.DeviceAdded").toMap().value("params").toMap().value("device").toMap(); QCOMPARE(notificationDeviceMap.value("deviceClassId").toString(), mockDeviceClassId.toString()); QCOMPARE(notificationDeviceMap.value("id").toString(), deviceId.toString()); @@ -556,10 +511,6 @@ void TestJSONRPC::deviceParamsChangedNotifications() } // EDIT - - // Setup connection to mock client - QSignalSpy clientSpy2(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - // now edit the device and check the deviceParamsChanged notification QVariantList newDeviceParams; QVariantMap newHttpportParam; @@ -567,22 +518,13 @@ void TestJSONRPC::deviceParamsChangedNotifications() newHttpportParam.insert("value", 45473); newDeviceParams.append(newHttpportParam); - params.clear(); response.clear(); + params.clear(); response.clear(); clientSpy.clear(); params.insert("deviceId", deviceId); params.insert("deviceParams", newDeviceParams); response = injectAndWait("Devices.EditDevice", params); - - clientSpy2.wait(500); - QCOMPARE(clientSpy2.count(), 2); - - jsonDocResponse = QJsonDocument::fromJson(clientSpy2.at(1).at(1).toByteArray()); - jsonDocNotification = QJsonDocument::fromJson(clientSpy2.at(0).at(1).toByteArray()); - - verifyDeviceError(jsonDocResponse.toVariant()); - - QCOMPARE(jsonDocNotification.toVariant().toMap().value("notification").toString(), QString("Devices.DeviceParamsChanged")); - - QVariantMap editDeviceNotificationMap = jsonDocNotification.toVariant().toMap().value("params").toMap().value("device").toMap(); + clientSpy.wait(500); + verifyDeviceError(response); + QVariantMap editDeviceNotificationMap = checkNotification(clientSpy, "Devices.DeviceParamsChanged").toMap().value("params").toMap().value("device").toMap(); QCOMPARE(editDeviceNotificationMap.value("deviceClassId").toString(), mockDeviceClassId.toString()); QCOMPARE(editDeviceNotificationMap.value("id").toString(), deviceId.toString()); foreach (const QVariant ¶m, editDeviceNotificationMap.value("params").toList()) { @@ -592,26 +534,14 @@ void TestJSONRPC::deviceParamsChangedNotifications() } // REMOVE - - // Setup connection to mock client - QSignalSpy clientSpy3(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - // now remove the device and check the device removed notification - params.clear(); response.clear(); + params.clear(); response.clear(); clientSpy.clear(); params.insert("deviceId", deviceId); response = injectAndWait("Devices.RemoveConfiguredDevice", params); - - clientSpy3.wait(500); - QCOMPARE(clientSpy3.count(), 2); // wait for device removed notification and response - - jsonDocResponse = QJsonDocument::fromJson(clientSpy3.at(1).at(1).toByteArray()); - jsonDocNotification = QJsonDocument::fromJson(clientSpy3.at(0).at(1).toByteArray()); - - verifyDeviceError(jsonDocResponse.toVariant()); - - // check the DeviceRemoved notification - QCOMPARE(jsonDocNotification.toVariant().toMap().value("notification").toString(), QString("Devices.DeviceRemoved")); - QCOMPARE(jsonDocNotification.toVariant().toMap().value("params").toMap().value("deviceId").toString(), deviceId.toString()); + clientSpy.wait(500); + verifyDeviceError(response); + checkNotification(clientSpy, "Devices.DeviceRemoved"); + checkNotification(clientSpy, "Logging.LogDatabaseUpdated"); } #include "testjsonrpc.moc"