From 299052d2f7ccc9666b6ec30bdbfcfd16a1f55fe7 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 7 Apr 2019 23:15:13 +0200 Subject: [PATCH] Fix processing of rule action params and make tests pass again --- libnymea-core/ruleengine.cpp | 308 ++++++++++++----------------- libnymea-core/ruleengine.h | 4 +- libnymea/types/actiontype.h | 2 +- libnymea/types/eventdescriptor.cpp | 5 + libnymea/types/eventdescriptor.h | 1 + tests/auto/rules/testrules.cpp | 32 ++- 6 files changed, 164 insertions(+), 188 deletions(-) diff --git a/libnymea-core/ruleengine.cpp b/libnymea-core/ruleengine.cpp index be772004..e73752de 100644 --- a/libnymea-core/ruleengine.cpp +++ b/libnymea-core/ruleengine.cpp @@ -383,184 +383,18 @@ RuleEngine::RuleError RuleEngine::addRule(const Rule &rule, bool fromEdit) // Check actions - foreach (const RuleAction &action, rule.actions()) { - if (!action.isValid()) { - qWarning(dcRuleEngine()) << "Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction"; - return RuleErrorActionTypeNotFound; - } - if (action.type() == RuleAction::TypeDevice) { - Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(action.deviceId()); - if (!device) { - qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for action with actionTypeId" << action.actionTypeId(); - return RuleErrorDeviceNotFound; - } - - DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); - if (!deviceClass.hasActionType(action.actionTypeId())) { - qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << action.actionTypeId(); - return RuleErrorActionTypeNotFound; - } - - } else { // Is TypeInterface - Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(action.interface()); - if (!iface.isValid()) { - qCWarning(dcRuleEngine()) << "Cannot create rule. No such interface:" << action.interface(); - return RuleError::RuleErrorInterfaceNotFound; - } - ActionType ifaceActionType = iface.actionTypes().findByName(action.interfaceAction()); - if (ifaceActionType.name().isEmpty()) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << action.interfaceAction(); - return RuleError::RuleErrorActionTypeNotFound; - } - foreach (const ParamType &ifaceActionParamType, ifaceActionType.paramTypes()) { - if (!action.ruleActionParams().hasParam(ifaceActionParamType.name())) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action" << iface.name() << ":" << action.interfaceAction() << "requires a" << ifaceActionParamType.name() << "param of type" << QVariant::typeToName(static_cast(ifaceActionParamType.type())); - return RuleError::RuleErrorMissingParameter; - } - if (!action.ruleActionParam(ifaceActionParamType.name()).value().canConvert(static_cast(ifaceActionParamType.type()))) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << action.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(static_cast(ifaceActionParamType.type())); - return RuleError::RuleErrorInvalidParameter; - } - } - } - - foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) { - if (ruleActionParam.isEventBased()) { - // We have an eventTypeId, see if the rule actually has such a event - if (rule.eventDescriptors().isEmpty() || !checkEventDescriptors(rule.eventDescriptors(), ruleActionParam.eventTypeId())) { - qCWarning(dcRuleEngine) << "Cannot create rule. EventTypeId from RuleAction" << action.actionTypeId() << "not in eventDescriptors."; - return RuleErrorInvalidRuleActionParameter; - } - - // check if the param type of the event and the action match - QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamTypeId()); - QVariant v(eventParamType); - QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId()); - if (eventParamType != actionParamType && !v.canConvert(static_cast(actionParamType))) { - qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given event param " << ruleActionParam.eventParamTypeId().toString() << "have not the same type:"; - qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType; - qCWarning(dcRuleEngine) << " -> eventParamType:" << eventParamType; - return RuleErrorTypesNotMatching; - } - } else if (ruleActionParam.isStateBased()) { - Device *d = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleActionParam.stateDeviceId()); - if (!d) { - qCWarning(dcRuleEngine()) << "Cannot create Rule. DeviceId from RuleAction" << action.actionTypeId() << "not found in system."; - return RuleErrorDeviceNotFound; - } - DeviceClass stateDeviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(d->deviceClassId()); - StateType stateType = stateDeviceClass.stateTypes().findById(ruleActionParam.stateTypeId()); - QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId()); - QVariant v(stateType.type()); - if (actionParamType != stateType.type() && !v.canConvert(static_cast(actionParamType))) { - qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:"; - qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType; - qCWarning(dcRuleEngine) << " -> stateType:" << stateType.type(); - return RuleErrorTypesNotMatching; - } - } else { - if (ruleActionParam.value().isNull()) { - qCDebug(dcRuleEngine()) << "Cannot create rule. No param value given for action:" << ruleActionParam.paramTypeId().toString(); - return RuleErrorInvalidRuleActionParameter; - } - QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId()); - if (ruleActionParam.value().type() != actionParamType && !ruleActionParam.value().canConvert(static_cast(actionParamType))) { - qCDebug(dcRuleEngine()) << "Cannot create rule. Given param value for action" << ruleActionParam.paramTypeId().toString() << "does not match type"; - return RuleErrorInvalidRuleActionParameter; - } - } - } - - foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) { - if (!ruleActionParam.isValid()) { - qCWarning(dcRuleEngine) << "Cannot create rule. There must be only one out of \"value\", \"eventTypeId/eventParamTypeID\" or \"deviceId/stateTypeId\"."; - return RuleEngine::RuleErrorInvalidRuleActionParameter; - } + foreach (const RuleAction &ruleAction, rule.actions()) { + RuleError ruleActionError = checkRuleAction(ruleAction, rule); + if (ruleActionError != RuleErrorNoError) { + return ruleActionError; } } // Check exit actions foreach (const RuleAction &ruleExitAction, rule.exitActions()) { - if (!ruleExitAction.isValid()) { - qWarning(dcRuleEngine()) << "Exit Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction"; - return RuleErrorActionTypeNotFound; - } - - if (ruleExitAction.type() == RuleAction::TypeDevice) { - Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleExitAction.deviceId()); - if (!device) { - qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for exit action with actionTypeId" << ruleExitAction.actionTypeId(); - return RuleErrorDeviceNotFound; - } - - DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); - if (!deviceClass.hasActionType(ruleExitAction.actionTypeId())) { - qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << ruleExitAction.actionTypeId(); - return RuleErrorActionTypeNotFound; - } - - } else { // Is TypeInterface - Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(ruleExitAction.interface()); - if (!iface.isValid()) { - qCWarning(dcRuleEngine()) << "Cannot create rule. No such interface:" << ruleExitAction.interface(); - return RuleError::RuleErrorInterfaceNotFound; - } - ActionType ifaceActionType = iface.actionTypes().findByName(ruleExitAction.interfaceAction()); - if (ifaceActionType.name().isEmpty()) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << ruleExitAction.interfaceAction(); - return RuleError::RuleErrorActionTypeNotFound; - } - foreach (const ParamType &ifaceActionParamType, ifaceActionType.paramTypes()) { - if (!ruleExitAction.ruleActionParams().hasParam(ifaceActionParamType.name())) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action" << iface.name() << ":" << ruleExitAction.interfaceAction() << "requires a" << ifaceActionParamType.name() << "param of type" << QVariant::typeToName(static_cast(ifaceActionParamType.type())); - return RuleError::RuleErrorMissingParameter; - } - if (!ruleExitAction.ruleActionParam(ifaceActionParamType.name()).value().canConvert(static_cast(ifaceActionParamType.type()))) { - qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << ruleExitAction.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(static_cast(ifaceActionParamType.type())); - return RuleError::RuleErrorInvalidParameter; - } - } - } - - foreach (const RuleActionParam &ruleActionParam, ruleExitAction.ruleActionParams()) { - if (ruleActionParam.isEventBased()) { - // We have an eventTypeId, see if the rule actually has such a event - qCWarning(dcRuleEngine) << "Cannot create rule. Exit actions cannot be event based."; - return RuleErrorInvalidRuleActionParameter; - } else if (ruleActionParam.isStateBased()) { - Device *d = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleActionParam.stateDeviceId()); - if (!d) { - qCWarning(dcRuleEngine()) << "Cannot create Rule. DeviceId from RuleAction" << ruleExitAction.actionTypeId() << "not found in system."; - return RuleErrorDeviceNotFound; - } - DeviceClass stateDeviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(d->deviceClassId()); - StateType stateType = stateDeviceClass.stateTypes().findById(ruleActionParam.stateTypeId()); - QVariant::Type actionParamType = getActionParamType(ruleExitAction.actionTypeId(), ruleActionParam.paramTypeId()); - QVariant v(stateType.type()); - if (actionParamType != stateType.type() && !v.canConvert(static_cast(actionParamType))) { - qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:"; - qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType; - qCWarning(dcRuleEngine) << " -> stateType:" << stateType.type(); - return RuleErrorTypesNotMatching; - } - } else { - if (ruleActionParam.value().isNull()) { - qCDebug(dcRuleEngine()) << "Cannot create rule. No param value given for action:" << ruleActionParam.paramTypeId().toString(); - return RuleErrorInvalidRuleActionParameter; - } - QVariant::Type actionParamType = getActionParamType(ruleExitAction.actionTypeId(), ruleActionParam.paramTypeId()); - if (ruleActionParam.value().type() != actionParamType && !ruleActionParam.value().canConvert(static_cast(actionParamType))) { - qCDebug(dcRuleEngine()) << "Cannot create rule. Given param value for action" << ruleActionParam.paramTypeId().toString() << "does not match type"; - return RuleErrorInvalidRuleActionParameter; - } - } - } - - foreach (const RuleActionParam &ruleActionParam, ruleExitAction.ruleActionParams()) { - if (!ruleActionParam.isValid()) { - qCWarning(dcRuleEngine) << "Cannot create rule. There must be only one out of \"value\", \"eventTypeId/eventParamTypeID\" or \"deviceId/stateTypeId\"."; - return RuleEngine::RuleErrorInvalidRuleActionParameter; - } + RuleError ruleActionError = checkRuleAction(ruleExitAction, rule); + if (ruleActionError != RuleErrorNoError) { + return ruleActionError; } } @@ -1074,15 +908,133 @@ bool RuleEngine::containsState(const StateEvaluator &stateEvaluator, const Event return false; } -bool RuleEngine::checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId) +RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction, const Rule &rule) { - foreach (const EventDescriptor eventDescriptor, eventDescriptors) { - if (eventDescriptor.eventTypeId() == eventTypeId) { - return true; + if (!ruleAction.isValid()) { + qWarning(dcRuleEngine()) << "Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction"; + return RuleErrorActionTypeNotFound; + } + + ActionType actionType; + if (ruleAction.type() == RuleAction::TypeDevice) { + Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleAction.deviceId()); + if (!device) { + qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for action with actionTypeId" << ruleAction.actionTypeId(); + return RuleErrorDeviceNotFound; + } + + DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); + if (!deviceClass.hasActionType(ruleAction.actionTypeId())) { + qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << ruleAction.actionTypeId(); + return RuleErrorActionTypeNotFound; + } + + actionType = deviceClass.actionTypes().findById(ruleAction.actionTypeId()); + } else if (ruleAction.type() == RuleAction::TypeInterface) { + Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(ruleAction.interface()); + if (!iface.isValid()) { + qCWarning(dcRuleEngine()) << "Cannot create rule. No such interface:" << ruleAction.interface(); + return RuleError::RuleErrorInterfaceNotFound; + } + actionType = iface.actionTypes().findByName(ruleAction.interfaceAction()); + if (actionType.name().isEmpty()) { + qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << ruleAction.interfaceAction(); + return RuleError::RuleErrorActionTypeNotFound; + } + } else { + return RuleErrorActionTypeNotFound; + } + + // Verify given params + foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) { + RuleError ruleActionParamError = checkRuleActionParam(ruleActionParam, actionType, rule); + if (ruleActionParamError != RuleErrorNoError) { + return ruleActionParamError; } } - return false; + // Verify all required params are given + foreach (const ParamType ¶mType, actionType.paramTypes()) { + bool found = false; + foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) { + if (ruleActionParam.paramTypeId() == paramType.id() + || ruleActionParam.paramName() == paramType.name()) { + found = true; + break; + } + } + if (!found) { + return RuleErrorMissingParameter; + } + } + + return RuleErrorNoError; +} + +RuleEngine::RuleError RuleEngine::checkRuleActionParam(const RuleActionParam &ruleActionParam, const ActionType &actionType, const Rule &rule) +{ + // Check param identifier (either paramTypeId or paramName) + ParamType paramType; + if (!ruleActionParam.paramTypeId().isNull()) { + paramType = actionType.paramTypes().findById(ruleActionParam.paramTypeId()); + } else if (!ruleActionParam.paramName().isEmpty()) { + paramType = actionType.paramTypes().findByName(ruleActionParam.paramName()); + } else { + return RuleErrorInvalidRuleActionParameter; + } + + if (ruleActionParam.isEventBased()) { + // We have an eventTypeId, see if the rule actually has such a event + bool found = false; + foreach (const EventDescriptor &ed, rule.eventDescriptors()) { + if (ed.eventTypeId() == ruleActionParam.eventTypeId()) { + found = true; + } + } + if (!found) { + qCWarning(dcRuleEngine) << "Cannot create rule. EventTypeId" << ruleActionParam.eventTypeId() << "not found in rule's eventDescriptors."; + return RuleErrorInvalidRuleActionParameter; + } + + // check if the param type of the event and the action match + QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamTypeId()); + QVariant v(eventParamType); + if (eventParamType != paramType.type() && !v.canConvert(static_cast(paramType.type()))) { + qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given event param " << ruleActionParam.eventParamTypeId().toString() << "have not the same type:"; + qCWarning(dcRuleEngine) << " -> actionParamType:" << paramType.type(); + qCWarning(dcRuleEngine) << " -> eventParamType:" << eventParamType; + return RuleErrorTypesNotMatching; + } + } else if (ruleActionParam.isStateBased()) { + Device *d = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleActionParam.stateDeviceId()); + if (!d) { + qCWarning(dcRuleEngine()) << "Cannot create Rule. DeviceId from RuleActionParam" << ruleActionParam.paramTypeId() << "not found in system."; + return RuleErrorDeviceNotFound; + } + DeviceClass stateDeviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(d->deviceClassId()); + StateType stateType = stateDeviceClass.stateTypes().findById(ruleActionParam.stateTypeId()); + QVariant::Type actionParamType = getActionParamType(actionType.id(), ruleActionParam.paramTypeId()); + QVariant v(stateType.type()); + if (actionParamType != stateType.type() && !v.canConvert(static_cast(actionParamType))) { + qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:"; + qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType; + qCWarning(dcRuleEngine) << " -> stateType:" << stateType.type(); + return RuleErrorTypesNotMatching; + } + } else { // Is value based + if (ruleActionParam.value().isNull()) { + qCDebug(dcRuleEngine()) << "Cannot create rule. No param value given for action:" << ruleActionParam.paramTypeId().toString(); + return RuleErrorInvalidRuleActionParameter; + } + if (paramType.type() != ruleActionParam.value().type() && !ruleActionParam.value().canConvert(static_cast(paramType.type()))) { + qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:"; + qCWarning(dcRuleEngine) << " -> actionParamType:" << paramType.type(); + qCWarning(dcRuleEngine) << " -> stateType:" << ruleActionParam.value().type(); + return RuleErrorTypesNotMatching; + } + } + + return RuleErrorNoError; } QVariant::Type RuleEngine::getActionParamType(const ActionTypeId &actionTypeId, const ParamTypeId ¶mTypeId) diff --git a/libnymea-core/ruleengine.h b/libnymea-core/ruleengine.h index a5aa8219..40369712 100644 --- a/libnymea-core/ruleengine.h +++ b/libnymea-core/ruleengine.h @@ -104,7 +104,9 @@ private: bool containsEvent(const Rule &rule, const Event &event, const DeviceClassId &deviceClassId); bool containsState(const StateEvaluator &stateEvaluator, const Event &stateChangeEvent); - bool checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId); + RuleError checkRuleAction(const RuleAction &ruleAction, const Rule &rule); + RuleError checkRuleActionParam(const RuleActionParam &ruleActionParam, const ActionType &actionType, const Rule &rule); + QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const ParamTypeId ¶mTypeId); QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const ParamTypeId ¶mTypeId); diff --git a/libnymea/types/actiontype.h b/libnymea/types/actiontype.h index 09eb7a25..09853a36 100644 --- a/libnymea/types/actiontype.h +++ b/libnymea/types/actiontype.h @@ -33,7 +33,7 @@ class LIBNYMEA_EXPORT ActionType { public: - ActionType(const ActionTypeId &id); + ActionType(const ActionTypeId &id = ActionTypeId()); ActionTypeId id() const; diff --git a/libnymea/types/eventdescriptor.cpp b/libnymea/types/eventdescriptor.cpp index 690f69b1..f0a2b117 100644 --- a/libnymea/types/eventdescriptor.cpp +++ b/libnymea/types/eventdescriptor.cpp @@ -49,6 +49,11 @@ #include "eventdescriptor.h" +EventDescriptor::EventDescriptor() +{ + +} + /*! Constructs an EventDescriptor describing an \l{Event} with the given \a eventTypeId, \a deviceId and the given \a paramDescriptors. */ EventDescriptor::EventDescriptor(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList ¶mDescriptors): m_eventTypeId(eventTypeId), diff --git a/libnymea/types/eventdescriptor.h b/libnymea/types/eventdescriptor.h index e1e88294..97e98f79 100644 --- a/libnymea/types/eventdescriptor.h +++ b/libnymea/types/eventdescriptor.h @@ -41,6 +41,7 @@ public: TypeInterface }; + EventDescriptor(); EventDescriptor(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList ¶mDescriptors = QList()); EventDescriptor(const QString &interface, const QString &interfaceEvent, const QList ¶mDescriptors = QList()); diff --git a/tests/auto/rules/testrules.cpp b/tests/auto/rules/testrules.cpp index ced4bc1e..f86d3a0d 100644 --- a/tests/auto/rules/testrules.cpp +++ b/tests/auto/rules/testrules.cpp @@ -1149,7 +1149,6 @@ void TestRules::loadStoreConfig() QVariantMap action2; action2.insert("actionTypeId", mockActionIdWithParams); - qDebug() << "got action id" << mockActionIdWithParams; action2.insert("deviceId", m_mockDeviceId); QVariantList action2Params; QVariantMap action2Param1; @@ -1221,6 +1220,7 @@ void TestRules::loadStoreConfig() actionsInterfaces.append(actionInterfaces); // rule 1 + qCDebug(dcTests()) << "Adding rule 1"; QVariantMap params; QVariantList actions; actions.append(action1); @@ -1235,6 +1235,7 @@ void TestRules::loadStoreConfig() verifyRuleError(response); // rule 2 + qCDebug(dcTests()) << "Adding rule 2"; QVariantMap params2; QVariantList actions2; actions2.append(action1); @@ -1250,6 +1251,7 @@ void TestRules::loadStoreConfig() verifyRuleError(response2); // rule 3 + qCDebug(dcTests()) << "Adding rule 3"; QVariantMap params3; QVariantList actions3; actions3.append(validActionEventBased); @@ -1262,6 +1264,7 @@ void TestRules::loadStoreConfig() verifyRuleError(response3); // rule 4, interface based + qCDebug(dcTests()) << "Adding rule 4"; QVariantMap params4; params4.insert("name", "TestRule4 - Interface based"); params4.insert("eventDescriptors", eventDescriptorsInterfaces); @@ -1272,10 +1275,12 @@ void TestRules::loadStoreConfig() RuleId newRuleId4 = RuleId(response4.toMap().value("params").toMap().value("ruleId").toString()); verifyRuleError(response4); + qCDebug(dcTests()) << "Getting rules"; response = injectAndWait("Rules.GetRules"); QVariantList rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList(); qDebug() << "GetRules before server shutdown:" << response; + qCDebug(dcTests()) << "Restarting server"; restartServer(); response = injectAndWait("Rules.GetRules"); @@ -2249,11 +2254,11 @@ void TestRules::testStateBasedAction() QVariantList ruleActionParams; QVariantMap param1; param1.insert("paramTypeId", mockActionParam1ParamTypeId); - param1.insert("deviceId", m_mockDeviceId); + param1.insert("stateDeviceId", m_mockDeviceId); param1.insert("stateTypeId", mockIntStateId); QVariantMap param2; param2.insert("paramTypeId", mockActionParam2ParamTypeId); - param2.insert("deviceId", m_mockDeviceId); + param2.insert("stateDeviceId", m_mockDeviceId); param2.insert("stateTypeId", mockBoolStateId); ruleActionParams.append(param1); ruleActionParams.append(param2); @@ -2265,7 +2270,7 @@ void TestRules::testStateBasedAction() actions.append(action); addRuleParams.insert("actions", actions); - qDebug() << addRuleParams; + qCDebug(dcTests) << "Adding rule"; QVariant response = injectAndWait("Rules.AddRule", addRuleParams); verifyRuleError(response); @@ -2469,6 +2474,7 @@ void TestRules::removePolicyUpdateRendersUselessRule() params.insert("deviceClassId", mockParentDeviceClassId); params.insert("name", "Parent device"); + qCDebug(dcTests()) << "Adding device"; QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); verifyDeviceError(response); @@ -2476,6 +2482,7 @@ void TestRules::removePolicyUpdateRendersUselessRule() QVERIFY(!parentDeviceId.isNull()); // find child device + qCDebug(dcTests()) << "Gettin devices"; response = injectAndWait("Devices.GetConfiguredDevices"); QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); @@ -2506,26 +2513,34 @@ void TestRules::removePolicyUpdateRendersUselessRule() QVariantMap action; action.insert("deviceId", childDeviceId); action.insert("actionTypeId", mockParentChildActionId); + QVariantMap ruleActionParam; + ruleActionParam.insert("paramTypeId", mockParentChildActionId); + ruleActionParam.insert("value", true); + action.insert("ruleActionParams", QVariantList() << ruleActionParam); params.insert("actions", QVariantList() << action); + qCDebug(dcTests()) << "Adding Rule"; response = injectAndWait("Rules.AddRule", params); verifyRuleError(response); RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString()); QVERIFY2(!ruleId.isNull(), "Could not get ruleId"); // Try to remove child device + qCDebug(dcTests()) << "Removing device (expecing failure - device is child)"; params.clear(); response.clear(); params.insert("deviceId", childDeviceId); response = injectAndWait("Devices.RemoveConfiguredDevice", params); verifyDeviceError(response, DeviceManager::DeviceErrorDeviceIsChild); // Try to remove child device + qCDebug(dcTests()) << "Removing device (expeciting failure - device in use)"; params.clear(); response.clear(); params.insert("deviceId", parentDeviceId); response = injectAndWait("Devices.RemoveConfiguredDevice", params); verifyDeviceError(response, DeviceManager::DeviceErrorDeviceInRule); // Remove policy + qCDebug(dcTests()) << "Removing device with update policy"; params.clear(); response.clear(); params.insert("deviceId", parentDeviceId); params.insert("removePolicy", "RemovePolicyUpdate"); @@ -2533,6 +2548,7 @@ void TestRules::removePolicyUpdateRendersUselessRule() verifyDeviceError(response); // get updated rule. It should've been deleted given it ended up with no actions + qCDebug(dcTests()) << "Getting details"; params.clear(); params.insert("ruleId", ruleId); response = injectAndWait("Rules.GetRuleDetails", params); @@ -2572,10 +2588,10 @@ void TestRules::testRuleActionParams_data() QTest::newRow("valid action params") << action << QVariantMap() << RuleEngine::RuleErrorNoError; QTest::newRow("valid action and exit action params") << action << action << RuleEngine::RuleErrorNoError; - QTest::newRow("invalid action params1") << invalidAction1 << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter; - QTest::newRow("invalid action params2") << invalidAction2 << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter; - QTest::newRow("valid action and invalid exit action params1") << action << invalidAction1 << RuleEngine::RuleErrorInvalidRuleActionParameter; - QTest::newRow("valid action and invalid exit action params2") << action << invalidAction2 << RuleEngine::RuleErrorInvalidRuleActionParameter; + QTest::newRow("invalid action params1") << invalidAction1 << QVariantMap() << RuleEngine::RuleErrorMissingParameter; + QTest::newRow("invalid action params2") << invalidAction2 << QVariantMap() << RuleEngine::RuleErrorMissingParameter; + QTest::newRow("valid action and invalid exit action params1") << action << invalidAction1 << RuleEngine::RuleErrorMissingParameter; + QTest::newRow("valid action and invalid exit action params2") << action << invalidAction2 << RuleEngine::RuleErrorMissingParameter; } void TestRules::testRuleActionParams()