bump api version

add tests for rule active changed notification
This commit is contained in:
Simon Stürz 2015-06-08 17:21:35 +02:00 committed by Michael Zanetti
parent 01b92e325a
commit 69ca5c4713
4 changed files with 326 additions and 15 deletions

View File

@ -2,7 +2,7 @@
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
# define JSON protocol version
JSON_PROTOCOL_VERSION=22
JSON_PROTOCOL_VERSION=23
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" JSON_PROTOCOL_VERSION=\\\"$${JSON_PROTOCOL_VERSION}\\\"

View File

@ -1,4 +1,4 @@
22
23
{
"methods": {
"Actions.ExecuteAction": {
@ -287,12 +287,13 @@
}
},
"Rules.AddRule": {
"description": "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that onlyone of either eventDescriptor or eventDescriptorList may be passed at a time. A rule can be created but left disabled,meaning it won't actually be executed until set to enabled. If not given, enabled defaults to true.",
"description": "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that only one of either eventDescriptor or eventDescriptorList may be passed at a time. A rule can be created but left disabled, meaning it won't actually be executed until set to enabled. If not given, enabled defaults to true.",
"params": {
"actions": [
"$ref:RuleAction"
],
"name": "String",
"o:active": "Bool",
"o:enabled": "Bool",
"o:eventDescriptor": "$ref:EventDescriptor",
"o:eventDescriptorList": [
@ -348,12 +349,12 @@
}
},
"Rules.GetRules": {
"description": "Get all configured rules",
"description": "Get the descriptions of all configured rules. If you need more information about a specific rule use the method Rules.GetRuleDetails.",
"params": {
},
"returns": {
"ruleIds": [
"Uuid"
"ruleDescriptions": [
"$ref:RuleDescription"
]
}
},
@ -416,6 +417,13 @@
"logEntry": "$ref:LogEntry"
}
},
"Rules.RuleActiveChanged": {
"description": "Emitted whenever the active state of a Rule changed.",
"params": {
"active": "Bool",
"ruleId": "Uuid"
}
},
"Rules.RuleAdded": {
"description": "Emitted whenever a Rule was added.",
"params": {
@ -620,6 +628,7 @@
"actions": [
"$ref:RuleAction"
],
"active": "Bool",
"enabled": "Bool",
"eventDescriptors": [
"$ref:EventDescriptor"
@ -644,6 +653,12 @@
"o:eventTypeId": "Uuid",
"o:value": "$ref:BasicType"
},
"RuleDescription": {
"active": "Bool",
"enabled": "Bool",
"id": "Uuid",
"name": "String"
},
"RuleError": [
"RuleErrorNoError",
"RuleErrorInvalidRuleId",

View File

@ -52,6 +52,8 @@ private slots:
void deviceAddedRemovedNotifications();
void ruleAddedRemovedNotifications();
void ruleActiveChangedNotifications();
void deviceParamsChangedNotifications();
private:
@ -261,6 +263,294 @@ void TestJSONRPC::stateChangeEmitsNotifications()
}
void TestJSONRPC::deviceAddedRemovedNotifications()
{
// enable notificartions
QVariantMap params;
params.insert("enabled", true);
QVariant response = injectAndWait("JSONRPC.SetNotificationStatus", params);
QCOMPARE(response.toMap().value("params").toMap().value("enabled").toBool(), true);
// Setup connection to mock client
QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
// add device and wait for notification
QVariantList deviceParams;
QVariantMap httpportParam;
httpportParam.insert("name", "httpport");
httpportParam.insert("value", 8765);
deviceParams.append(httpportParam);
params.clear(); response.clear();
params.insert("deviceClassId", mockDeviceClassId);
params.insert("deviceParams", deviceParams);
response = injectAndWait("Devices.AddConfiguredDevice", params);
// Lets wait for the notification
clientSpy.wait(500);
qDebug() << "got" << clientSpy.count() << "notifications";
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());
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();
QCOMPARE(notificationDeviceMap.value("deviceClassId").toString(), mockDeviceClassId.toString());
QCOMPARE(notificationDeviceMap.value("id").toString(), deviceId.toString());
foreach (const QVariant &param, notificationDeviceMap.value("params").toList()) {
if (param.toMap().value("name").toString() == "httpport") {
QCOMPARE(param.toMap().value("value").toInt(), httpportParam.value("value").toInt());
}
}
// Setup connection to mock client
QSignalSpy clientSpy2(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
// now remove the device and check the device removed notification
params.clear(); response.clear();
params.insert("deviceId", deviceId);
response = injectAndWait("Devices.RemoveConfiguredDevice", params);
clientSpy2.wait(500);
qDebug() << "got" << clientSpy2.count() << "notifications";
QCOMPARE(clientSpy2.count(), 2); // wait for device removed notification and response
jsonDocResponse = QJsonDocument::fromJson(clientSpy2.at(1).at(1).toByteArray());
jsonDocNotification = QJsonDocument::fromJson(clientSpy2.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());
}
void TestJSONRPC::ruleAddedRemovedNotifications()
{
// enable notificartions
QVariantMap params;
params.insert("enabled", true);
QVariant response = injectAndWait("JSONRPC.SetNotificationStatus", params);
QCOMPARE(response.toMap().value("params").toMap().value("enabled").toBool(), true);
// Add rule and wait for notification
// StateDescriptor
QVariantMap stateDescriptor;
stateDescriptor.insert("stateTypeId", mockIntStateId);
stateDescriptor.insert("deviceId", m_mockDeviceId);
stateDescriptor.insert("operator", JsonTypes::valueOperatorToString(Types::ValueOperatorLess));
stateDescriptor.insert("value", "20");
QVariantMap stateEvaluator;
stateEvaluator.insert("stateDescriptor", stateDescriptor);
// RuleAction
QVariantMap actionNoParams;
actionNoParams.insert("actionTypeId", mockActionIdNoParams);
actionNoParams.insert("deviceId", m_mockDeviceId);
actionNoParams.insert("ruleActionParams", QVariantList());
// EventDescriptor
QVariantMap eventDescriptor;
eventDescriptor.insert("eventTypeId", mockEvent1Id);
eventDescriptor.insert("deviceId", m_mockDeviceId);
eventDescriptor.insert("paramDescriptors", QVariantList());
params.clear(); response.clear();
params.insert("name", "Test Rule notifications");
params.insert("actions", QVariantList() << actionNoParams);
params.insert("eventDescriptor", eventDescriptor);
params.insert("stateEvaluator", stateEvaluator);
// Setup connection to mock client
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);
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());
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());
QCOMPARE(notificationRuleMap.value("actions").toList(), QVariantList() << actionNoParams);
QCOMPARE(notificationRuleMap.value("stateEvaluator").toMap().value("stateDescriptor").toMap(), stateDescriptor);
QCOMPARE(notificationRuleMap.value("eventDescriptors").toList(), QVariantList() << eventDescriptor);
QCOMPARE(notificationRuleMap.value("exitActions").toList(), QVariantList());
// Setup connection to mock client
QSignalSpy clientSpy2(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
// now remove the rule and check the RuleRemoved notification
params.clear(); response.clear();
params.insert("ruleId", ruleId);
response = injectAndWait("Rules.RemoveRule", params);
clientSpy2.wait(500);
qDebug() << "got" << clientSpy2.count() << "notifications";
QCOMPARE(clientSpy2.count(), 2); // wait for RuleRemoved notification and response
jsonDocResponse = QJsonDocument::fromJson(clientSpy2.at(1).at(1).toByteArray());
jsonDocNotification = QJsonDocument::fromJson(clientSpy2.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());
}
void TestJSONRPC::ruleActiveChangedNotifications()
{
// enable notificartions
QVariantMap params;
params.insert("enabled", true);
QVariant response = injectAndWait("JSONRPC.SetNotificationStatus", params);
QCOMPARE(response.toMap().value("params").toMap().value("enabled").toBool(), true);
// Add rule and wait for notification
// StateDescriptor
QVariantMap stateDescriptor;
stateDescriptor.insert("stateTypeId", mockIntStateId);
stateDescriptor.insert("deviceId", m_mockDeviceId);
stateDescriptor.insert("operator", JsonTypes::valueOperatorToString(Types::ValueOperatorEquals));
stateDescriptor.insert("value", "20");
QVariantMap stateEvaluator;
stateEvaluator.insert("stateDescriptor", stateDescriptor);
// RuleAction
QVariantMap actionNoParams;
actionNoParams.insert("actionTypeId", mockActionIdNoParams);
actionNoParams.insert("deviceId", m_mockDeviceId);
actionNoParams.insert("ruleActionParams", QVariantList());
params.clear(); response.clear();
params.insert("name", "Test Rule notifications");
params.insert("actions", QVariantList() << actionNoParams);
params.insert("stateEvaluator", stateEvaluator);
// Setup connection to mock client
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);
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());
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());
QCOMPARE(notificationRuleMap.value("actions").toList(), QVariantList() << actionNoParams);
QCOMPARE(notificationRuleMap.value("stateEvaluator").toMap().value("stateDescriptor").toMap(), stateDescriptor);
QCOMPARE(notificationRuleMap.value("exitActions").toList(), QVariantList());
// 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();
QCOMPARE(spy.count(), 1);
reply->deleteLater();
clientSpy2.wait(500);
qDebug() << "got" << clientSpy2.count() << "notifications";
QCOMPARE(clientSpy2.count(), 6);
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();
// set the rule inactive
qDebug() << "setting mock int state to 42";
QNetworkRequest request2(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockIntStateId.toString()).arg(42)));
QNetworkReply *reply2 = nam.get(request2);
spy.wait();
QCOMPARE(spy.count(), 1);
reply2->deleteLater();
clientSpy2.wait(500);
QCOMPARE(clientSpy2.count(), 5);
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)));
// 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
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());
}
void TestJSONRPC::deviceParamsChangedNotifications()
{
// enable notificartions

View File

@ -81,9 +81,9 @@ void TestRules::cleanupMockHistory() {
void TestRules::cleanupRules() {
QVariant response = injectAndWait("Rules.GetRules");
foreach (const QVariant &ruleId, response.toMap().value("params").toMap().value("ruleIds").toList()) {
foreach (const QVariant &ruleDescription, response.toMap().value("params").toMap().value("ruleDescriptions").toList()) {
QVariantMap params;
params.insert("ruleId", ruleId.toString());
params.insert("ruleId", ruleDescription.toMap().value("id").toString());
verifyRuleError(injectAndWait("Rules.RemoveRule", params));
}
}
@ -319,7 +319,7 @@ void TestRules::addRemoveRules()
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
response = injectAndWait("Rules.GetRules");
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
QVariantList rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList();
if (error != RuleEngine::RuleErrorNoError) {
QVERIFY2(rules.count() == 0, "There should be no rules.");
@ -327,7 +327,7 @@ void TestRules::addRemoveRules()
}
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
QCOMPARE(RuleId(rules.first().toString()), newRuleId);
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
params.clear();
params.insert("ruleId", newRuleId);
@ -369,7 +369,7 @@ void TestRules::addRemoveRules()
verifyRuleError(response);
response = injectAndWait("Rules.GetRules");
rules = response.toMap().value("params").toMap().value("rules").toList();
rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList();
QVERIFY2(rules.count() == 0, "There should be no rules.");
}
@ -518,12 +518,18 @@ void TestRules::loadStoreConfig()
response = injectAndWait("Rules.GetRules");
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
QVariantList rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList();
QVERIFY2(rules.count() == 3, "There should be exactly three rule.");
QVERIFY2(rules.contains(newRuleId.toString()), "Rule 1 should be in ruleIds list.");
QVERIFY2(rules.contains(newRuleId2.toString()), "Rule 2 should be in ruleIds list.");
QVERIFY2(rules.contains(newRuleId3.toString()), "Rule 3 should be in ruleIds list.");
QStringList idList;
foreach (const QVariant &ruleDescription, rules) {
idList.append(ruleDescription.toMap().value("id").toString());
}
QVERIFY2(idList.contains(newRuleId.toString()), "Rule 1 should be in ruleIds list.");
QVERIFY2(idList.contains(newRuleId2.toString()), "Rule 2 should be in ruleIds list.");
QVERIFY2(idList.contains(newRuleId3.toString()), "Rule 3 should be in ruleIds list.");
// Rule 1
params.clear();