improove RuleAction logic

add tests
fix documentation
This commit is contained in:
Simon Stürz 2015-03-14 21:06:39 +01:00 committed by Michael Zanetti
parent f26ec0fa47
commit 90622e5edb
10 changed files with 294 additions and 59 deletions

View File

@ -36,16 +36,18 @@
RuleActionParam::RuleActionParam(const Param &param) :
m_name(param.name()),
m_value(param.value()),
m_eventTypeId(EventTypeId())
m_eventTypeId(EventTypeId()),
m_eventParamName(QString())
{
}
/*! Constructs a \l{RuleActionParam} with the given \a name, \a value and \a eventTypeId.
/*! Constructs a \l{RuleActionParam} with the given \a name, \a value, \a eventTypeId and \a eventParamName.
* \sa Param, Event, */
RuleActionParam::RuleActionParam(const QString &name, const QVariant &value, const EventTypeId &eventTypeId) :
RuleActionParam::RuleActionParam(const QString &name, const QVariant &value, const EventTypeId &eventTypeId, const QString &eventParamName) :
m_name(name),
m_value(value),
m_eventTypeId(eventTypeId)
m_eventTypeId(eventTypeId),
m_eventParamName(eventParamName)
{
}
@ -61,6 +63,18 @@ void RuleActionParam::setName(const QString &name)
m_name = name;
}
/*! Returns the name of the eventParam for this RuleActionParam. */
QString RuleActionParam::eventParamName() const
{
return m_eventParamName;
}
/*! Sets the \a eventParamName of this RuleActionParam. */
void RuleActionParam::setEventParamName(const QString &eventParamName)
{
m_eventParamName = eventParamName;
}
/*! Returns the value of this RuleActionParam. */
QVariant RuleActionParam::value() const
{
@ -73,10 +87,12 @@ void RuleActionParam::setValue(const QVariant &value)
m_value = value;
}
/*! Returns true if the name and the value of this RuleActionParam are set.*/
/*! Returns true if the name and value or the name, eventTypeId and eventParamName of this RuleActionParam are set.*/
bool RuleActionParam::isValid() const
{
return !m_name.isEmpty() && m_value.isValid();
bool validValue = (!m_name.isEmpty() && m_value.isValid() && m_eventTypeId == EventTypeId() && m_eventParamName.isEmpty());
bool validEvent = (!m_name.isEmpty() && m_eventTypeId != EventTypeId() && !m_eventParamName.isEmpty() && !m_value.isValid());
return validValue ^ validEvent;
}
/*! Return the EventTypeId of the \l{Event} with the \l{Param} which will be taken over in the \l{RuleAction}. */
@ -91,10 +107,10 @@ void RuleActionParam::setEventTypeId(const EventTypeId &eventTypeId)
m_eventTypeId = eventTypeId;
}
/*! Writes the name, value and eventId of the given \a ruleActionParam to \a dbg. */
/*! Writes the name, value, eventId and eventParamName of the given \a ruleActionParam to \a dbg. */
QDebug operator<<(QDebug dbg, const RuleActionParam &ruleActionParam)
{
dbg.nospace() << "RuleActionParam(Name: " << ruleActionParam.name() << ", Value:" << ruleActionParam.value() << ", EventTypeId:" << ruleActionParam.eventTypeId().toString() << ")";
dbg.nospace() << "RuleActionParam(Name: " << ruleActionParam.name() << ", Value:" << ruleActionParam.value() << ", EventTypeId:" << ruleActionParam.eventTypeId().toString() << ", EventParamName:" << ruleActionParam.eventParamName() << ")";
return dbg.space();
}

View File

@ -26,15 +26,18 @@
#include "param.h"
#include "typeutils.h"
class RuleActionParam : public Param
class RuleActionParam
{
public:
RuleActionParam(const Param &param);
RuleActionParam(const QString &name = QString(), const QVariant &value = QVariant(), const EventTypeId &eventTypeId = EventTypeId());
RuleActionParam(const QString &name = QString(), const QVariant &value = QVariant(), const EventTypeId &eventTypeId = EventTypeId(), const QString &eventParamName = QString());
QString name() const;
void setName(const QString &name);
QString eventParamName() const;
void setEventParamName(const QString &eventParamName);
QVariant value() const;
void setValue(const QVariant &value);
@ -47,11 +50,12 @@ private:
QString m_name;
QVariant m_value;
EventTypeId m_eventTypeId;
QString m_eventParamName;
};
Q_DECLARE_METATYPE(RuleActionParam)
QDebug operator<<(QDebug dbg, const RuleActionParam &ruleActionParams);
Q_DECLARE_METATYPE(RuleActionParam)
QDebug operator<<(QDebug dbg, const RuleActionParam &ruleActionParam);
class RuleActionParamList: public QList<RuleActionParam>
{

View File

@ -396,18 +396,24 @@ void GuhCore::gotEvent(const Event &event)
}
}
// Convert event based RuleActions to normal action, depending on the event value
foreach (const RuleAction &ruleAction, eventBasedActions) {
// Set action params, depending on the event value
foreach (RuleAction ruleAction, eventBasedActions) {
RuleActionParamList newParams;
foreach (RuleActionParam ruleActionParam, ruleAction.ruleActionParams()) {
// if this event param should be taken over in this action
if (event.eventTypeId() == ruleActionParam.eventTypeId()) {
QVariant eventValue = event.param(ruleActionParam.name()).value();
QVariant eventValue = event.params().first().value();
// TODO: get param names...
// TODO: limits / scale calculation -> actionValue = eventValue * x
ruleActionParam.setValue(eventValue);
qDebug() << ruleActionParam.value();
}
newParams.append(ruleActionParam);
}
ruleAction.setRuleActionParams(newParams);
actions.append(ruleAction);
}

View File

@ -44,7 +44,7 @@
#include <QJsonDocument>
#include <QStringList>
#define JSON_PROTOCOL_VERSION 17
#define JSON_PROTOCOL_VERSION 18
JsonRPCServer::JsonRPCServer(QObject *parent):
JsonHandler(parent),

View File

@ -105,6 +105,7 @@ void JsonTypes::init()
s_ruleActionParam.insert("name", basicTypeToString(String));
s_ruleActionParam.insert("o:value", basicTypeRef());
s_ruleActionParam.insert("o:eventTypeId", basicTypeToString(Uuid));
s_ruleActionParam.insert("o:eventParamName", basicTypeToString(String));
// ParamDescriptor
s_paramDescriptor.insert("name", basicTypeToString(String));
@ -355,10 +356,10 @@ QVariantMap JsonTypes::packRuleActionParam(const RuleActionParam &ruleActionPara
{
QVariantMap variantMap;
variantMap.insert("name", ruleActionParam.name());
// if this ruleaction param has a valid EventTypeId, there is no value
if (ruleActionParam.eventTypeId() != EventTypeId()) {
variantMap.insert("eventTypeId", ruleActionParam.eventTypeId());
variantMap.insert("eventParamName", ruleActionParam.eventParamName());
} else {
variantMap.insert("value", ruleActionParam.value());
}
@ -635,10 +636,12 @@ RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionPa
if (ruleActionParamMap.keys().count() == 0) {
return RuleActionParam();
}
QString name = ruleActionParamMap.value("name").toString();
QVariant value = ruleActionParamMap.value("value");
EventTypeId eventTypeId(ruleActionParamMap.value("eventTypeId").toString());
return RuleActionParam(name, value, eventTypeId);
EventTypeId eventTypeId = EventTypeId(ruleActionParamMap.value("eventTypeId").toString());
QString eventParamName = ruleActionParamMap.value("eventParamName").toString();
return RuleActionParam(name, value, eventTypeId, eventParamName);
}
RuleActionParamList JsonTypes::unpackRuleActionParams(const QVariantList &ruleActionParamList)

View File

@ -133,7 +133,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
if (params.contains("eventDescriptor") || params.contains("eventDescriptorList")) {
if (params.contains("exitActions")) {
QVariantMap returns;
qWarning() << "The exitActions will never executed if this rule contains any eventDescriptor.";
qWarning() << "The exitActions will never be executed if the rule contains any eventDescriptor.";
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleFormat));
return createReply(returns);
}
@ -156,11 +156,23 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
QList<RuleAction> actions;
QVariantList actionList = params.value("actions").toList();
qDebug() << "unpacking actions:" << actionList;
foreach (const QVariant &actionVariant, actionList) {
QVariantMap actionMap = actionVariant.toMap();
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
qDebug() << "params from json" << actionMap.value("ruleActionParams");
action.setRuleActionParams(JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList()));
qDebug() << "actionParams from json" << actionMap.value("ruleActionParams");
RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList());
qDebug() << "unpacked actionParamList:" << actionParamList;
foreach (const RuleActionParam &ruleActionParam, actionParamList) {
if (!ruleActionParam.isValid()) {
qWarning() << "ERROR: got actionParam with value AND eventTypeId!";
QVariantMap returns;
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
}
action.setRuleActionParams(actionParamList);
qDebug() << "params in action" << action.ruleActionParams();
actions.append(action);
}
@ -174,21 +186,25 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
if (eventDescriptorList.isEmpty()) {
QVariantMap returns;
qWarning() << "RuleAction" << ruleAction.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors.";
returns.insert("ruleErorr", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
// now check if this eventType is in the eventDescriptorList of this rule
foreach (const EventDescriptor eventDescriptor, eventDescriptorList) {
if (eventDescriptor.eventTypeId() == ruleActionParam.eventTypeId()) {
// TODO: check if they match
continue;
} else {
// the given eventTypeId is not in the eventDescriptorList
QVariantMap returns;
qWarning() << "eventTypeId from RuleAction" << ruleAction.actionTypeId() << "missing in eventDescriptors.";
returns.insert("ruleErorr", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
if (!checkEventDescriptors(eventDescriptorList, ruleActionParam.eventTypeId())) {
QVariantMap returns;
qWarning() << "eventTypeId from RuleAction" << ruleAction.actionTypeId() << "missing in eventDescriptors.";
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
// check if the param type of the event and the action match
QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamName());
QVariant::Type actionParamType = getActionParamType(ruleAction.actionTypeId(), ruleActionParam.name());
if (eventParamType != actionParamType) {
QVariantMap returns;
qWarning() << "RuleActionParam" << ruleActionParam.name() << " and given event param have not the same type.";
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
}
}
@ -198,7 +214,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
QVariantMap returns;
if (actions.count() == 0) {
returns.insert("ruleErorr", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorMissingParameter));
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorMissingParameter));
return createReply(returns);
}
@ -208,7 +224,13 @@ JsonReply* RulesHandler::AddRule(const QVariantMap &params)
foreach (const QVariant &actionVariant, exitActionList) {
QVariantMap actionMap = actionVariant.toMap();
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
qDebug() << "params from json" << actionMap.value("ruleActionParams");
qDebug() << "params from json" << actionMap.value("ruleActionParams");
if (action.isEventBased()) {
qWarning() << "ERROR: got exitAction with a param value containing an eventTypeId!";
QVariantMap returns;
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
return createReply(returns);
}
action.setRuleActionParams(JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList()));
qDebug() << "params in action" << action.ruleActionParams();
exitActions.append(action);
@ -261,3 +283,46 @@ JsonReply *RulesHandler::DisableRule(const QVariantMap &params)
{
return createReply(statusToReply(GuhCore::instance()->disableRule(RuleId(params.value("ruleId").toString()))));
}
QVariant::Type RulesHandler::getActionParamType(const ActionTypeId &actionTypeId, const QString &paramName)
{
foreach (const DeviceClass &deviceClass, GuhCore::instance()->supportedDevices()) {
foreach (const ActionType &actionType, deviceClass.actionTypes()) {
if (actionType.id() == actionTypeId) {
foreach (const ParamType &paramType, actionType.paramTypes()) {
if (paramType.name() == paramName) {
return paramType.type();
}
}
}
}
}
return QVariant::Invalid;
}
QVariant::Type RulesHandler::getEventParamType(const EventTypeId &eventTypeId, const QString &paramName)
{
foreach (const DeviceClass &deviceClass, GuhCore::instance()->supportedDevices()) {
foreach (const EventType &eventType, deviceClass.eventTypes()) {
if (eventType.id() == eventTypeId) {
foreach (const ParamType &paramType, eventType.paramTypes()) {
// get ParamType of Event
if (paramType.name() == paramName) {
return paramType.type();
}
}
}
}
}
return QVariant::Invalid;
}
bool RulesHandler::checkEventDescriptors(const QList<EventDescriptor> eventDescriptors, const EventTypeId &eventTypeId)
{
foreach (const EventDescriptor eventDescriptor, eventDescriptors) {
if (eventDescriptor.eventTypeId() == eventTypeId) {
return true;
}
}
return false;
}

View File

@ -39,6 +39,10 @@ public:
Q_INVOKABLE JsonReply* EnableRule(const QVariantMap &params);
Q_INVOKABLE JsonReply* DisableRule(const QVariantMap &params);
private:
QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const QString &paramName);
QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const QString &paramName);
bool checkEventDescriptors(const QList<EventDescriptor> eventDescriptors, const EventTypeId &eventTypeId);
};
#endif // RULESHANDLER_H

View File

@ -141,7 +141,7 @@ RuleEngine::RuleEngine(QObject *parent) :
foreach (QString paramNameString, settings.childGroups()) {
if (paramNameString.startsWith("RuleActionParam-")) {
settings.beginGroup(paramNameString);
RuleActionParam param(paramNameString.remove(QRegExp("^RuleActionParam-")), settings.value("value",QVariant()), EventTypeId(settings.value("eventTypeId", EventTypeId()).toString()));
RuleActionParam param(paramNameString.remove(QRegExp("^RuleActionParam-")), settings.value("value",QVariant()), EventTypeId(settings.value("eventTypeId", EventTypeId()).toString()), settings.value("eventParamName", QString()).toString());
params.append(param);
settings.endGroup();
}
@ -326,6 +326,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
appendRule(rule);
emit ruleAdded(rule.id());
// Save Events / EventDescriptors
QSettings settings(m_settingsFile);
settings.beginGroup(rule.id().toString());
settings.setValue("name", name);
@ -347,8 +348,10 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
}
settings.endGroup();
// Save StateEvaluator
stateEvaluator.dumpToSettings(settings, "stateEvaluator");
// Save ruleActions
settings.beginGroup("ruleActions");
foreach (const RuleAction &action, rule.actions()) {
settings.beginGroup(action.actionTypeId().toString());
@ -357,6 +360,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
foreach (const RuleActionParam &param, action.ruleActionParams()) {
settings.beginGroup("RuleActionParam-" + param.name());
settings.setValue("eventTypeId", param.eventTypeId());
settings.setValue("eventParamName", param.eventParamName());
settings.setValue("value", param.value());
settings.endGroup();
}
@ -365,6 +369,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
settings.endGroup();
// Save ruleExitActions
settings.beginGroup("ruleExitActions");
foreach (const RuleAction &action, rule.exitActions()) {
settings.beginGroup(action.actionTypeId().toString());

View File

@ -1,4 +1,4 @@
17
18
{
"methods": {
"Actions.ExecuteAction": {
@ -594,6 +594,7 @@
},
"RuleActionParam": {
"name": "String",
"o:eventParamName": "String",
"o:eventTypeId": "Uuid",
"o:value": "$ref:BasicType"
},

View File

@ -123,6 +123,7 @@ void TestRules::verifyRuleNotExecuted()
void TestRules::addRemoveRules_data()
{
// RuleAction
QVariantMap validActionNoParams;
validActionNoParams.insert("actionTypeId", mockActionIdNoParams);
validActionNoParams.insert("deviceId", m_mockDeviceId);
@ -133,6 +134,7 @@ void TestRules::addRemoveRules_data()
invalidAction.insert("deviceId", m_mockDeviceId);
invalidAction.insert("ruleActionParams", QVariantList());
// RuleExitAction
QVariantMap validExitActionNoParams;
validExitActionNoParams.insert("actionTypeId", mockActionIdNoParams);
validExitActionNoParams.insert("deviceId", m_mockDeviceId);
@ -143,12 +145,14 @@ void TestRules::addRemoveRules_data()
invalidExitAction.insert("deviceId", m_mockDeviceId);
invalidExitAction.insert("ruleActionParams", QVariantList());
// StateDescriptor
QVariantMap stateDescriptor;
stateDescriptor.insert("stateTypeId", mockIntStateId);
stateDescriptor.insert("deviceId", m_mockDeviceId);
stateDescriptor.insert("operator", JsonTypes::valueOperatorToString(Types::ValueOperatorLess));
stateDescriptor.insert("value", "20");
// StateEvaluator
QVariantMap validStateEvaluator;
validStateEvaluator.insert("stateDescriptor", stateDescriptor);
validStateEvaluator.insert("operator", JsonTypes::stateOperatorToString(Types::StateOperatorAnd));
@ -157,6 +161,7 @@ void TestRules::addRemoveRules_data()
stateDescriptor.remove("deviceId");
invalidStateEvaluator.insert("stateDescriptor", stateDescriptor);
// EventDescriptor
QVariantMap validEventDescriptor1;
validEventDescriptor1.insert("eventTypeId", mockEvent1Id);
validEventDescriptor1.insert("deviceId", m_mockDeviceId);
@ -173,6 +178,13 @@ void TestRules::addRemoveRules_data()
params.append(param1);
validEventDescriptor2.insert("paramDescriptors", params);
QVariantMap validEventDescriptor3;
validEventDescriptor3.insert("eventTypeId", mockEvent2Id);
validEventDescriptor3.insert("deviceId", m_mockDeviceId);
validEventDescriptor3.insert("paramDescriptors", QVariantList());
// EventDescriptorList
QVariantList eventDescriptorList;
eventDescriptorList.append(validEventDescriptor1);
eventDescriptorList.append(validEventDescriptor2);
@ -182,6 +194,39 @@ void TestRules::addRemoveRules_data()
invalidEventDescriptor.insert("deviceId", DeviceId());
invalidEventDescriptor.insert("paramDescriptors", QVariantList());
// RuleAction event based
QVariantMap validActionEventBased;
validActionEventBased.insert("actionTypeId", mockActionIdWithParams);
validActionEventBased.insert("deviceId", m_mockDeviceId);
QVariantMap validActionEventBasedParam1;
validActionEventBasedParam1.insert("name", "mockActionParam1");
validActionEventBasedParam1.insert("eventTypeId", mockEvent2Id);
validActionEventBasedParam1.insert("eventParamName", "mockParamInt");
QVariantMap validActionEventBasedParam2;
validActionEventBasedParam2.insert("name", "mockActionParam2");
validActionEventBasedParam2.insert("value", false);
validActionEventBased.insert("ruleActionParams", QVariantList() << validActionEventBasedParam1 << validActionEventBasedParam2);
QVariantMap invalidActionEventBased;
invalidActionEventBased.insert("actionTypeId", mockActionIdNoParams);
invalidActionEventBased.insert("deviceId", m_mockDeviceId);
validActionEventBasedParam1.insert("value", 10);
invalidActionEventBased.insert("ruleActionParams", QVariantList() << validActionEventBasedParam1);
QVariantMap invalidActionEventBased2;
invalidActionEventBased2.insert("actionTypeId", mockActionIdWithParams);
invalidActionEventBased2.insert("deviceId", m_mockDeviceId);
QVariantMap invalidActionEventBasedParam2;
invalidActionEventBasedParam2.insert("name", "mockActionParam1");
invalidActionEventBasedParam2.insert("eventTypeId", mockEvent1Id);
invalidActionEventBasedParam2.insert("eventParamName", "value");
QVariantMap invalidActionEventBasedParam3;
invalidActionEventBasedParam3.insert("name", "mockActionParam2");
invalidActionEventBasedParam3.insert("value", 2);
invalidActionEventBased2.insert("ruleActionParams", QVariantList() << invalidActionEventBasedParam2 << invalidActionEventBasedParam3);
QTest::addColumn<bool>("enabled");
QTest::addColumn<QVariantMap>("action1");
QTest::addColumn<QVariantMap>("exitAction1");
@ -192,20 +237,29 @@ void TestRules::addRemoveRules_data()
QTest::addColumn<bool>("jsonError");
QTest::addColumn<QString>("name");
QTest::newRow("valid rule. enabled, 1 Action, 1 Exit Action, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << false << "TestRule";
QTest::newRow("valid rule. disabled, 1 Action, 1 Exit Action, 1 StateEvaluator, name") << false << validActionNoParams << validExitActionNoParams << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << false << "TestRule";
QTest::newRow("valid rule. disabled, 1 Action, 1 invalid Exit Action, 1 StateEvaluator, name") << false << validActionNoParams << invalidExitAction << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound << false << "TestRule";
QTest::newRow("invalid rule. 1 Action, 1 Exit Action, 1 EventDescriptor, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
QTest::newRow("invalid rule. 1 Action, 1 Exit Action, eventDescriptorList, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
// Rules with event based actions
QTest::newRow("valid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << validActionEventBased << QVariantMap() << validEventDescriptor3 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorNoError << true << "ActionEventRule1";
QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased2 << QVariantMap() << validEventDescriptor3 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter << false << "TestRule";
QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased << QVariantMap() << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter << false << "TestRule";
QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 StateEvaluator, name") << true << validActionEventBased << QVariantMap() << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleActionParameter << false << "TestRule";
QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << validActionEventBased << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
QTest::newRow("invalid rule. enabled, 1 Action, 1 ExitAction (EventBased), name") << true << validActionNoParams << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
// Rules with exit actions
QTest::newRow("valid rule. enabled, 1 Action, 1 Exit Action, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule";
QTest::newRow("valid rule. disabled, 1 Action, 1 Exit Action, 1 StateEvaluator, name") << false << validActionNoParams << validExitActionNoParams << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule";
QTest::newRow("invalid rule. disabled, 1 Action, 1 invalid Exit Action, 1 StateEvaluator, name") << false << validActionNoParams << invalidExitAction << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound << false << "TestRule";
QTest::newRow("invalid rule. 1 Action, 1 Exit Action, 1 EventDescriptor, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
QTest::newRow("invalid rule. 1 Action, 1 Exit Action, eventDescriptorList, 1 StateEvaluator, name") << true << validActionNoParams << validExitActionNoParams << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule";
QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << false << "TestRule";
QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << false << "TestRule";
QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError << false << "TestRule";
QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter << false << "TestRule";
QTest::newRow("invalid action") << true << invalidAction << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound << false << "TestRule";
QTest::newRow("invalid event descriptor") << true << validActionNoParams << QVariantMap() << invalidEventDescriptor << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorDeviceNotFound << false << "TestRule";
QTest::newRow("invalid StateDescriptor") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << invalidStateEvaluator << RuleEngine::RuleErrorInvalidParameter << true << "TestRule";
// Rules without exit actions
QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule";
QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule";
QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule";
QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter << false << "TestRule";
QTest::newRow("invalid action") << true << invalidAction << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound << false << "TestRule";
QTest::newRow("invalid event descriptor") << true << validActionNoParams << QVariantMap() << invalidEventDescriptor << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorDeviceNotFound << false << "TestRule";
QTest::newRow("invalid StateDescriptor") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << invalidStateEvaluator << RuleEngine::RuleErrorInvalidParameter << true << "TestRule";
}
void TestRules::addRemoveRules()
@ -380,7 +434,28 @@ void TestRules::loadStoreConfig()
action2Params.append(action2Param2);
action2.insert("ruleActionParams", action2Params);
// First rule
// RuleAction event based
QVariantMap validActionEventBased;
validActionEventBased.insert("actionTypeId", mockActionIdWithParams);
validActionEventBased.insert("deviceId", m_mockDeviceId);
QVariantMap validActionEventBasedParam1;
validActionEventBasedParam1.insert("name", "mockActionParam1");
validActionEventBasedParam1.insert("eventTypeId", mockEvent2Id);
validActionEventBasedParam1.insert("eventParamName", "mockParamInt");
QVariantMap validActionEventBasedParam2;
validActionEventBasedParam2.insert("name", "mockActionParam2");
validActionEventBasedParam2.insert("value", false);
validActionEventBased.insert("ruleActionParams", QVariantList() << validActionEventBasedParam1 << validActionEventBasedParam2);
QVariantList validEventDescriptors3;
QVariantMap validEventDescriptor3;
validEventDescriptor3.insert("eventTypeId", mockEvent2Id);
validEventDescriptor3.insert("deviceId", m_mockDeviceId);
validEventDescriptor3.insert("paramDescriptors", QVariantList());
validEventDescriptors3.append(validEventDescriptor3);
// rule 1
QVariantMap params;
QVariantList actions;
actions.append(action1);
@ -394,7 +469,7 @@ void TestRules::loadStoreConfig()
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
verifyRuleError(response);
// Second rule
// rule 2
QVariantMap params2;
QVariantList actions2;
actions2.append(action1);
@ -409,19 +484,33 @@ void TestRules::loadStoreConfig()
RuleId newRuleId2 = RuleId(response2.toMap().value("params").toMap().value("ruleId").toString());
verifyRuleError(response2);
// rule 3
QVariantMap params3;
QVariantList actions3;
actions3.append(validActionEventBased);
params3.insert("actions", actions3);
params3.insert("eventDescriptorList", validEventDescriptors3);
params3.insert("name", "TestRule3");
QVariant response3 = injectAndWait("Rules.AddRule", params3);
RuleId newRuleId3 = RuleId(response3.toMap().value("params").toMap().value("ruleId").toString());
verifyRuleError(response3);
restartServer();
response = injectAndWait("Rules.GetRules");
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
QVERIFY2(rules.count() == 2, "There should be exactly two rule.");
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.");
// Rule 1
params.clear();
params.insert("ruleId", newRuleId);
response.clear();
response = injectAndWait("Rules.GetRuleDetails", params);
QVariantMap rule1 = response.toMap().value("params").toMap().value("rule").toMap();
@ -454,10 +543,6 @@ void TestRules::loadStoreConfig()
}
QVariantList replyActions = rule1.value("actions").toList();
qDebug() << "----------------------------------------------";
qDebug() << rule1;
qDebug() << "----------------------------------------------";
foreach (const QVariant &actionVariant, actions) {
bool found = false;
foreach (const QVariant &replyActionVariant, replyActions) {
@ -474,9 +559,10 @@ void TestRules::loadStoreConfig()
QVERIFY2(found, "Action not found after loading from config.");
}
// Rule 2
params.clear();
params.insert("ruleId", newRuleId2);
response.clear();
response = injectAndWait("Rules.GetRuleDetails", params);
QVariantMap rule2 = response.toMap().value("params").toMap().value("rule").toMap();
@ -530,16 +616,61 @@ void TestRules::loadStoreConfig()
QVERIFY2(found, "Exit Action not found after loading from config.");
}
// Rule 3
params.clear();
params.insert("ruleId", newRuleId3);
response.clear();
response = injectAndWait("Rules.GetRuleDetails", params);
QVariantMap rule3 = response.toMap().value("params").toMap().value("rule").toMap();
qDebug() << rule3;
QVariantList eventDescriptors3 = rule3.value("eventDescriptors").toList();
QVERIFY2(eventDescriptors3.count() == 1, "There shoud be exactly 1 eventDescriptor");
QVariantMap eventDescriptor = eventDescriptors3.first().toMap();
QVERIFY2(eventDescriptor.value("eventTypeId").toString() == mockEvent2Id.toString(), "Loaded the wrong eventTypeId in rule 3");
QVERIFY2(eventDescriptor.value("deviceId").toString() == m_mockDeviceId.toString(), "Loaded the wrong deviceId from eventDescriptor in rule 3");
QVariantList replyExitActions3 = rule3.value("exitActions").toList();
QVERIFY2(replyExitActions3.isEmpty(), "Rule 3 should not have any exitAction");
QVariantList replyActions3 = rule3.value("actions").toList();
QVERIFY2(replyActions3.count() == 1, "Rule 3 should have exactly 1 action");
foreach (const QVariant &actionVariant, actions3) {
bool found = false;
foreach (const QVariant &replyActionVariant, replyActions3) {
if (actionVariant.toMap().value("actionTypeId") == replyActionVariant.toMap().value("actionTypeId") &&
actionVariant.toMap().value("deviceId") == replyActionVariant.toMap().value("deviceId")) {
found = true;
QJsonDocument bDoc = QJsonDocument::fromVariant(actionVariant);
QString bString = bDoc.toJson();
QJsonDocument aDoc = QJsonDocument::fromVariant(replyActionVariant);
QString aString = aDoc.toJson();
QVERIFY2(actionVariant == replyActionVariant, QString("Action doesn't match after loading from config.\nBefore storing: %1\nAfter storing:%2").arg(bString).arg(aString).toUtf8().data());
}
}
QVERIFY2(found, "Action not found after loading from config.");
}
// Remove Rule1
params.clear();
params.insert("ruleId", newRuleId);
response = injectAndWait("Rules.RemoveRule", params);
verifyRuleError(response);
// Remove Rule2
params2.clear();
params2.insert("ruleId", newRuleId2);
response = injectAndWait("Rules.RemoveRule", params2);
verifyRuleError(response);
// Remove Rule2
params3.clear();
params3.insert("ruleId", newRuleId3);
response = injectAndWait("Rules.RemoveRule", params3);
verifyRuleError(response);
restartServer();
response = injectAndWait("Rules.GetRules");