allow calling AddRule with a single eventDescriptor but also with a list

This commit is contained in:
Michael Zanetti 2014-06-15 00:53:37 +02:00
parent 373af5bde5
commit 9d21f32366
12 changed files with 105 additions and 35 deletions

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
guh (0.1.8) utopic; urgency=medium
* allow calling AddRule with a single eventDescriptor but also with a list
-- Michael Zanetti <micha@noneyet> Sun, 15 Jun 2014 00:33:36 +0200
guh (0.1.7) utopic; urgency=medium
* implement StateEvaluators

View File

@ -478,6 +478,15 @@ QList<ParamDescriptor> JsonTypes::unpackParamDescriptors(const QVariantList &par
return params;
}
EventDescriptor JsonTypes::unpackEventDescriptor(const QVariantMap &eventDescriptorMap)
{
EventTypeId eventTypeId(eventDescriptorMap.value("eventTypeId").toString());
DeviceId eventDeviceId(eventDescriptorMap.value("deviceId").toString());
QList<ParamDescriptor> eventParams = JsonTypes::unpackParamDescriptors(eventDescriptorMap.value("paramDescriptors").toList());
EventDescriptor eventDescriptor(EventDescriptorId::createEventDescriptorId(), eventTypeId, eventDeviceId, eventParams);
return eventDescriptor;
}
QPair<bool, QString> JsonTypes::validateMap(const QVariantMap &templateMap, const QVariantMap &map)
{
s_lastError.clear();

View File

@ -110,6 +110,7 @@ public:
static QList<Param> unpackParams(const QVariantList &paramList);
static ParamDescriptor unpackParamDescriptor(const QVariantMap &paramDescriptorMap);
static QList<ParamDescriptor> unpackParamDescriptors(const QVariantList &paramDescriptorList);
static EventDescriptor unpackEventDescriptor(const QVariantMap &eventDescriptorMap);
static QPair<bool, QString> validateMap(const QVariantMap &templateMap, const QVariantMap &map);
static QPair<bool, QString> validateProperty(const QVariant &templateValue, const QVariant &value);

View File

@ -81,12 +81,23 @@ JsonReply* RulesHandler::GetRules(const QVariantMap &params)
JsonReply* RulesHandler::AddRule(const QVariantMap &params)
{
QVariantMap eventMap = params.value("eventDescriptor").toMap();
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
QVariantMap returns;
returns.insert("success", false);
returns.insert("errorMessage", "Only one of \"eventDescriptor\" and \"eventDescriptorList\" may be used.");
return createReply(returns);
}
EventTypeId eventTypeId(eventMap.value("eventTypeId").toString());
DeviceId eventDeviceId(eventMap.value("deviceId").toString());
QList<ParamDescriptor> eventParams = JsonTypes::unpackParamDescriptors(eventMap.value("paramDescriptors").toList());
EventDescriptor eventDescriptor(EventDescriptorId::createEventDescriptorId(), eventTypeId, eventDeviceId, eventParams);
QList<EventDescriptor> eventDescriptorList;
if (params.contains("eventDescriptor")) {
QVariantMap eventMap = params.value("eventDescriptor").toMap();
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
} else if (params.contains("eventDescriptorList")) {
foreach (const QVariant &eventVariant, params.value("eventDescriptorList").toList()) {
QVariantMap eventMap = eventVariant.toMap();
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
}
}
QList<Action> actions;
QVariantList actionList = params.value("actions").toList();
@ -105,7 +116,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
}
RuleId newRuleId = RuleId::createRuleId();
switch(GuhCore::instance()->ruleEngine()->addRule(newRuleId, eventDescriptor, actions)) {
switch(GuhCore::instance()->ruleEngine()->addRule(newRuleId, eventDescriptorList, actions)) {
case RuleEngine::RuleErrorNoError:
returns.insert("success", true);
returns.insert("errorMessage", "");

View File

@ -160,12 +160,10 @@ QList<Action> RuleEngine::evaluateEvent(const Event &event)
return actions;
}
/*! Add a new \l{Rule} with the given \a event and \a actions to the engine.
/*! Add a new \l{Rule} with the given \a EventDescriptorList and \a actions to the engine.
For convenience, this creates a Rule without any \l{State} comparison. */
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const EventDescriptor &eventDescriptor, const QList<Action> &actions)
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions)
{
QList<EventDescriptor> eventDescriptorList;
eventDescriptorList.append(eventDescriptor);
return addRule(ruleId, eventDescriptorList, StateEvaluator(StateEvaluatorId::createStateEvaluatorId()), actions);
}

View File

@ -44,7 +44,7 @@ public:
QList<Action> evaluateEvent(const Event &event);
RuleError addRule(const RuleId &ruleId, const EventDescriptor &eventDescriptor, const QList<Action> &actions);
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions);
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions);
QList<Rule> rules() const;

View File

@ -1,4 +1,4 @@
0.1.7
0.1.8
{
"methods": {
"Actions.ExecuteAction": {
@ -214,12 +214,15 @@
}
},
"Rules.AddRule": {
"description": "Add a rule",
"description": "Add a rule.",
"params": {
"actions": [
"$ref:Action"
],
"eventDescriptor": "$ref:EventDescriptor"
"o:eventDescriptor": "$ref:EventDescriptor",
"o:eventDescriptorList": [
"$ref:EventDescriptor"
]
},
"returns": {
"errorMessage": "string",

View File

@ -245,7 +245,7 @@ void TestDevices::removeDevice()
QFETCH(DeviceId, deviceId);
QFETCH(bool, success);
QSettings settings;
QSettings settings(m_deviceSettings);
settings.beginGroup("DeviceConfig");
if (success) {
settings.beginGroup(m_mockDeviceId.toString());

View File

@ -38,15 +38,17 @@ GuhTestBase::GuhTestBase(QObject *parent) :
m_mockDevice2Port = 7331;
QCoreApplication::instance()->setOrganizationName("guh-test");
m_rulesSettings = QCoreApplication::instance()->organizationName() + "/rules";
m_deviceSettings = QCoreApplication::instance()->organizationName() + "/devices";
}
void GuhTestBase::initTestCase()
{
// If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers
QSettings rulesSettings(QCoreApplication::instance()->organizationName() + "/rules");
QSettings rulesSettings(m_rulesSettings);
rulesSettings.clear();
QSettings deviceSettings(QCoreApplication::instance()->organizationName() + "/devices");
QSettings deviceSettings(m_deviceSettings);
deviceSettings.clear();
GuhCore::instance();

View File

@ -41,6 +41,7 @@ extern ActionTypeId mockActionIdAsync;
extern ActionTypeId mockActionIdFailing;
extern ActionTypeId mockActionIdAsyncFailing;
extern EventTypeId mockEvent1Id;
extern EventTypeId mockEvent2Id;
extern StateTypeId mockIntStateId;
class MockTcpServer;
@ -70,6 +71,8 @@ protected:
DeviceId m_mockDeviceId;
QString m_deviceSettings;
QString m_rulesSettings;
};
#endif // GUHTESTBASE_H

View File

@ -52,10 +52,19 @@ void TestRules::addRules_data()
invalidAction.insert("deviceId", m_mockDeviceId);
invalidAction.insert("params", QVariantList());
QVariantMap validEventDescriptor;
validEventDescriptor.insert("eventTypeId", mockEvent1Id);
validEventDescriptor.insert("deviceId", m_mockDeviceId);
validEventDescriptor.insert("paramDescriptors", QVariantList());
QVariantMap validEventDescriptor1;
validEventDescriptor1.insert("eventTypeId", mockEvent1Id);
validEventDescriptor1.insert("deviceId", m_mockDeviceId);
validEventDescriptor1.insert("paramDescriptors", QVariantList());
QVariantMap validEventDescriptor2;
validEventDescriptor2.insert("eventTypeId", mockEvent2Id);
validEventDescriptor2.insert("deviceId", m_mockDeviceId);
validEventDescriptor2.insert("paramDescriptors", QVariantList());
QVariantList eventDescriptorList;
eventDescriptorList.append(validEventDescriptor1);
eventDescriptorList.append(validEventDescriptor2);
QVariantMap invalidEventDescriptor;
invalidEventDescriptor.insert("eventTypeId", mockEvent1Id);
@ -63,26 +72,37 @@ void TestRules::addRules_data()
invalidEventDescriptor.insert("paramDescriptors", QVariantList());
QTest::addColumn<QVariantMap>("action1");
QTest::addColumn<QVariantMap>("eventDescriptor1");
QTest::addColumn<QVariantMap>("eventDescriptor");
QTest::addColumn<QVariantList>("eventDescriptorList");
QTest::addColumn<bool>("success");
QTest::newRow("valid rule") << validAction << validEventDescriptor << true;
QTest::newRow("invalid action") << invalidAction << validEventDescriptor << false;
QTest::newRow("invalid event descriptor") << validAction << invalidEventDescriptor << false;
QTest::newRow("valid rule. 1 EventDescriptor, 1 Action") << validAction << validEventDescriptor1 << QVariantList() << true;
QTest::newRow("valid rule. 2 EventDescriptors, 1 Action") << validAction << QVariantMap() << eventDescriptorList << true;
QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << validAction << validEventDescriptor1 << eventDescriptorList << false;
QTest::newRow("invalid action") << invalidAction << validEventDescriptor1 << QVariantList() << false;
QTest::newRow("invalid event descriptor") << validAction << invalidEventDescriptor << QVariantList() << false;
}
void TestRules::addRules()
{
QFETCH(QVariantMap, action1);
QFETCH(QVariantMap, eventDescriptor1);
QFETCH(QVariantMap, eventDescriptor);
QFETCH(QVariantList, eventDescriptorList);
QFETCH(bool, success);
QVariantMap params;
QVariantList actions;
actions.append(action1);
params.insert("actions", actions);
params.insert("eventDescriptor", eventDescriptor1);
if (!eventDescriptor.isEmpty()) {
params.insert("eventDescriptor", eventDescriptor);
}
if (!eventDescriptorList.isEmpty()) {
params.insert("eventDescriptorList", eventDescriptorList);
}
QVariant response = injectAndWait("Rules.AddRule", params);
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
@ -99,9 +119,24 @@ void TestRules::addRules()
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor1, "Event descriptor doesn't match");
if (!eventDescriptor.isEmpty()) {
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor, "Event descriptor doesn't match");
} else if (eventDescriptorList.isEmpty()){
QVERIFY2(eventDescriptors.count() == eventDescriptorList.count(), QString("There shoud be exactly %1 eventDescriptor").arg(eventDescriptorList.count()).toLatin1().data());
foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) {
bool found = false;
foreach (const QVariant &replyEventDescriptorVariant, eventDescriptors) {
if (eventDescriptorVariant.toMap().value("deviceId") == replyEventDescriptorVariant.toMap().value("deviceId") &&
eventDescriptorVariant.toMap().value("eventTypeId") == replyEventDescriptorVariant.toMap().value("eventTypeId")) {
found = true;
QVERIFY2(eventDescriptorVariant == replyEventDescriptorVariant, "Event descriptor doesn't match");
}
}
}
}
QVariantList replyActions = rules.first().toMap().value("actions").toList();
QVERIFY2(actions == replyActions, "Actions don't match");

View File

@ -79,10 +79,6 @@ void TestVersioning::apiChangeBumpsVersion()
return;
}
if (oldVersion == newVersionStripped && 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) {
@ -94,9 +90,15 @@ void TestVersioning::apiChangeBumpsVersion()
newApiFile.flush();
QProcess p;
p.execute("diff", QStringList() << "-u" << oldFilePath << newFilePath);
p.start("diff", QStringList() << "-u" << oldFilePath << newFilePath);
p.waitForFinished();
qDebug() << p.readAll();
QByteArray apiDiff = p.readAll();
qDebug() << "API Differences:" << endl << apiDiff;
if (oldVersion == newVersionStripped && oldApi != newApi) {
QVERIFY2(false, "JSONRPC API has changed but version is still the same. You need to bump the API version.");
}
if (oldVersion != newVersionStripped && oldApi == newApi) {
QVERIFY2(false, QString("Version has changed. Update %1.").arg(oldFilePath).toLatin1().data());