From a1880c1be94bdfa7df8d181f8553d9d9a7aeaba9 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Wed, 7 Feb 2018 13:44:25 +0100 Subject: [PATCH] fix comparison of eventDescriptor params in rule evaluation --- libguh-core/ruleengine.cpp | 17 ++++---- tests/auto/rules/testrules.cpp | 74 ++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/libguh-core/ruleengine.cpp b/libguh-core/ruleengine.cpp index 94808616..92a7570f 100644 --- a/libguh-core/ruleengine.cpp +++ b/libguh-core/ruleengine.cpp @@ -1101,42 +1101,45 @@ bool RuleEngine::containsEvent(const Rule &rule, const Event &event, const Devic } // Ok, either device/eventTypeId or interface/interfaceEvent are matching. Compare the paramdescriptor + bool allOK = true; foreach (const ParamDescriptor ¶mDescriptor, eventDescriptor.paramDescriptors()) { switch (paramDescriptor.operatorType()) { case Types::ValueOperatorEquals: if (event.param(paramDescriptor.paramTypeId()).value() != paramDescriptor.value()) { - continue; + allOK = false; } break; case Types::ValueOperatorNotEquals: if (event.param(paramDescriptor.paramTypeId()).value() == paramDescriptor.value()) { - continue; + allOK = false; } break; case Types::ValueOperatorGreater: if (event.param(paramDescriptor.paramTypeId()).value() <= paramDescriptor.value()) { - continue; + allOK = false; } break; case Types::ValueOperatorGreaterOrEqual: if (event.param(paramDescriptor.paramTypeId()).value() < paramDescriptor.value()) { - continue; + allOK = false; } break; case Types::ValueOperatorLess: if (event.param(paramDescriptor.paramTypeId()).value() >= paramDescriptor.value()) { - continue; + allOK = false; } break; case Types::ValueOperatorLessOrEqual: if (event.param(paramDescriptor.paramTypeId()).value() < paramDescriptor.value()) { - continue; + allOK = false; } break; } } // All matching! - return true; + if (allOK) { + return true; + } } return false; diff --git a/tests/auto/rules/testrules.cpp b/tests/auto/rules/testrules.cpp index bc2c5c93..8c29ad8b 100644 --- a/tests/auto/rules/testrules.cpp +++ b/tests/auto/rules/testrules.cpp @@ -78,6 +78,8 @@ private slots: void evaluateEvent(); + void evaluateEventParams(); + void testStateEvaluator_data(); void testStateEvaluator(); @@ -1403,6 +1405,78 @@ void TestRules::evaluateEvent() verifyRuleExecuted(mockActionIdNoParams); } +void TestRules::evaluateEventParams() +{ + // Init bool state to true + QNetworkAccessManager nam; + QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); + QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg("true"))); + QNetworkReply *reply = nam.get(request); + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); + + + // Add a rule + QVariantMap addRuleParams; + addRuleParams.insert("name", "TestRule"); + + QVariantList params; + QVariantMap boolParam; + boolParam.insert("paramTypeId", mockBoolStateId); + boolParam.insert("operator", "ValueOperatorEquals"); + boolParam.insert("value", true); + params.append(boolParam); + + QVariantMap event1; + event1.insert("eventTypeId", mockBoolStateId); + event1.insert("deviceId", m_mockDeviceId); + event1.insert("paramDescriptors", params); + + QVariantList events; + events.append(event1); + addRuleParams.insert("eventDescriptors", events); + + QVariantList actions; + QVariantMap action; + action.insert("actionTypeId", mockActionIdNoParams); + action.insert("deviceId", m_mockDeviceId); + actions.append(action); + addRuleParams.insert("actions", actions); + QVariant response = injectAndWait("Rules.AddRule", addRuleParams); + verifyRuleError(response); + + + // Trigger a non matching param + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg("false"))); + reply = nam.get(request); + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); + + verifyRuleNotExecuted(); + + // Trigger a matching param + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg("true"))); + reply = nam.get(request); + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); + + verifyRuleExecuted(mockActionIdNoParams); + + // Reset back to false to not mess with other tests + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg("false"))); + reply = nam.get(request); + spy.wait(); + QCOMPARE(spy.count(), 1); + reply->deleteLater(); +} + + void TestRules::testStateChange() { // Add a rule QVariantMap addRuleParams;