Fix processing of rule action params and make tests pass again

pull/148/head
Michael Zanetti 2019-04-07 23:15:13 +02:00
parent 694d78225d
commit 299052d2f7
6 changed files with 164 additions and 188 deletions

View File

@ -383,184 +383,18 @@ RuleEngine::RuleError RuleEngine::addRule(const Rule &rule, bool fromEdit)
// Check actions // Check actions
foreach (const RuleAction &action, rule.actions()) { foreach (const RuleAction &ruleAction, rule.actions()) {
if (!action.isValid()) { RuleError ruleActionError = checkRuleAction(ruleAction, rule);
qWarning(dcRuleEngine()) << "Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction"; if (ruleActionError != RuleErrorNoError) {
return RuleErrorActionTypeNotFound; return ruleActionError;
}
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<int>(ifaceActionParamType.type()));
return RuleError::RuleErrorMissingParameter;
}
if (!action.ruleActionParam(ifaceActionParamType.name()).value().canConvert(static_cast<int>(ifaceActionParamType.type()))) {
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << action.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(static_cast<int>(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<int>(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<int>(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<int>(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;
}
} }
} }
// Check exit actions // Check exit actions
foreach (const RuleAction &ruleExitAction, rule.exitActions()) { foreach (const RuleAction &ruleExitAction, rule.exitActions()) {
if (!ruleExitAction.isValid()) { RuleError ruleActionError = checkRuleAction(ruleExitAction, rule);
qWarning(dcRuleEngine()) << "Exit Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction"; if (ruleActionError != RuleErrorNoError) {
return RuleErrorActionTypeNotFound; return ruleActionError;
}
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<int>(ifaceActionParamType.type()));
return RuleError::RuleErrorMissingParameter;
}
if (!ruleExitAction.ruleActionParam(ifaceActionParamType.name()).value().canConvert(static_cast<int>(ifaceActionParamType.type()))) {
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << ruleExitAction.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(static_cast<int>(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<int>(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<int>(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;
}
} }
} }
@ -1074,15 +908,133 @@ bool RuleEngine::containsState(const StateEvaluator &stateEvaluator, const Event
return false; return false;
} }
bool RuleEngine::checkEventDescriptors(const QList<EventDescriptor> eventDescriptors, const EventTypeId &eventTypeId) RuleEngine::RuleError RuleEngine::checkRuleAction(const RuleAction &ruleAction, const Rule &rule)
{ {
foreach (const EventDescriptor eventDescriptor, eventDescriptors) { if (!ruleAction.isValid()) {
if (eventDescriptor.eventTypeId() == eventTypeId) { qWarning(dcRuleEngine()) << "Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction";
return true; 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 &paramType, 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<int>(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<int>(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<int>(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 &paramTypeId) QVariant::Type RuleEngine::getActionParamType(const ActionTypeId &actionTypeId, const ParamTypeId &paramTypeId)

View File

@ -104,7 +104,9 @@ private:
bool containsEvent(const Rule &rule, const Event &event, const DeviceClassId &deviceClassId); bool containsEvent(const Rule &rule, const Event &event, const DeviceClassId &deviceClassId);
bool containsState(const StateEvaluator &stateEvaluator, const Event &stateChangeEvent); bool containsState(const StateEvaluator &stateEvaluator, const Event &stateChangeEvent);
bool checkEventDescriptors(const QList<EventDescriptor> 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 &paramTypeId); QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const ParamTypeId &paramTypeId);
QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const ParamTypeId &paramTypeId); QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const ParamTypeId &paramTypeId);

View File

@ -33,7 +33,7 @@
class LIBNYMEA_EXPORT ActionType class LIBNYMEA_EXPORT ActionType
{ {
public: public:
ActionType(const ActionTypeId &id); ActionType(const ActionTypeId &id = ActionTypeId());
ActionTypeId id() const; ActionTypeId id() const;

View File

@ -49,6 +49,11 @@
#include "eventdescriptor.h" #include "eventdescriptor.h"
EventDescriptor::EventDescriptor()
{
}
/*! Constructs an EventDescriptor describing an \l{Event} with the given \a eventTypeId, \a deviceId and the given \a paramDescriptors. */ /*! 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<ParamDescriptor> &paramDescriptors): EventDescriptor::EventDescriptor(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList<ParamDescriptor> &paramDescriptors):
m_eventTypeId(eventTypeId), m_eventTypeId(eventTypeId),

View File

@ -41,6 +41,7 @@ public:
TypeInterface TypeInterface
}; };
EventDescriptor();
EventDescriptor(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList<ParamDescriptor> &paramDescriptors = QList<ParamDescriptor>()); EventDescriptor(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList<ParamDescriptor> &paramDescriptors = QList<ParamDescriptor>());
EventDescriptor(const QString &interface, const QString &interfaceEvent, const QList<ParamDescriptor> &paramDescriptors = QList<ParamDescriptor>()); EventDescriptor(const QString &interface, const QString &interfaceEvent, const QList<ParamDescriptor> &paramDescriptors = QList<ParamDescriptor>());

View File

@ -1149,7 +1149,6 @@ void TestRules::loadStoreConfig()
QVariantMap action2; QVariantMap action2;
action2.insert("actionTypeId", mockActionIdWithParams); action2.insert("actionTypeId", mockActionIdWithParams);
qDebug() << "got action id" << mockActionIdWithParams;
action2.insert("deviceId", m_mockDeviceId); action2.insert("deviceId", m_mockDeviceId);
QVariantList action2Params; QVariantList action2Params;
QVariantMap action2Param1; QVariantMap action2Param1;
@ -1221,6 +1220,7 @@ void TestRules::loadStoreConfig()
actionsInterfaces.append(actionInterfaces); actionsInterfaces.append(actionInterfaces);
// rule 1 // rule 1
qCDebug(dcTests()) << "Adding rule 1";
QVariantMap params; QVariantMap params;
QVariantList actions; QVariantList actions;
actions.append(action1); actions.append(action1);
@ -1235,6 +1235,7 @@ void TestRules::loadStoreConfig()
verifyRuleError(response); verifyRuleError(response);
// rule 2 // rule 2
qCDebug(dcTests()) << "Adding rule 2";
QVariantMap params2; QVariantMap params2;
QVariantList actions2; QVariantList actions2;
actions2.append(action1); actions2.append(action1);
@ -1250,6 +1251,7 @@ void TestRules::loadStoreConfig()
verifyRuleError(response2); verifyRuleError(response2);
// rule 3 // rule 3
qCDebug(dcTests()) << "Adding rule 3";
QVariantMap params3; QVariantMap params3;
QVariantList actions3; QVariantList actions3;
actions3.append(validActionEventBased); actions3.append(validActionEventBased);
@ -1262,6 +1264,7 @@ void TestRules::loadStoreConfig()
verifyRuleError(response3); verifyRuleError(response3);
// rule 4, interface based // rule 4, interface based
qCDebug(dcTests()) << "Adding rule 4";
QVariantMap params4; QVariantMap params4;
params4.insert("name", "TestRule4 - Interface based"); params4.insert("name", "TestRule4 - Interface based");
params4.insert("eventDescriptors", eventDescriptorsInterfaces); params4.insert("eventDescriptors", eventDescriptorsInterfaces);
@ -1272,10 +1275,12 @@ void TestRules::loadStoreConfig()
RuleId newRuleId4 = RuleId(response4.toMap().value("params").toMap().value("ruleId").toString()); RuleId newRuleId4 = RuleId(response4.toMap().value("params").toMap().value("ruleId").toString());
verifyRuleError(response4); verifyRuleError(response4);
qCDebug(dcTests()) << "Getting rules";
response = injectAndWait("Rules.GetRules"); response = injectAndWait("Rules.GetRules");
QVariantList rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList(); QVariantList rules = response.toMap().value("params").toMap().value("ruleDescriptions").toList();
qDebug() << "GetRules before server shutdown:" << response; qDebug() << "GetRules before server shutdown:" << response;
qCDebug(dcTests()) << "Restarting server";
restartServer(); restartServer();
response = injectAndWait("Rules.GetRules"); response = injectAndWait("Rules.GetRules");
@ -2249,11 +2254,11 @@ void TestRules::testStateBasedAction()
QVariantList ruleActionParams; QVariantList ruleActionParams;
QVariantMap param1; QVariantMap param1;
param1.insert("paramTypeId", mockActionParam1ParamTypeId); param1.insert("paramTypeId", mockActionParam1ParamTypeId);
param1.insert("deviceId", m_mockDeviceId); param1.insert("stateDeviceId", m_mockDeviceId);
param1.insert("stateTypeId", mockIntStateId); param1.insert("stateTypeId", mockIntStateId);
QVariantMap param2; QVariantMap param2;
param2.insert("paramTypeId", mockActionParam2ParamTypeId); param2.insert("paramTypeId", mockActionParam2ParamTypeId);
param2.insert("deviceId", m_mockDeviceId); param2.insert("stateDeviceId", m_mockDeviceId);
param2.insert("stateTypeId", mockBoolStateId); param2.insert("stateTypeId", mockBoolStateId);
ruleActionParams.append(param1); ruleActionParams.append(param1);
ruleActionParams.append(param2); ruleActionParams.append(param2);
@ -2265,7 +2270,7 @@ void TestRules::testStateBasedAction()
actions.append(action); actions.append(action);
addRuleParams.insert("actions", actions); addRuleParams.insert("actions", actions);
qDebug() << addRuleParams; qCDebug(dcTests) << "Adding rule";
QVariant response = injectAndWait("Rules.AddRule", addRuleParams); QVariant response = injectAndWait("Rules.AddRule", addRuleParams);
verifyRuleError(response); verifyRuleError(response);
@ -2469,6 +2474,7 @@ void TestRules::removePolicyUpdateRendersUselessRule()
params.insert("deviceClassId", mockParentDeviceClassId); params.insert("deviceClassId", mockParentDeviceClassId);
params.insert("name", "Parent device"); params.insert("name", "Parent device");
qCDebug(dcTests()) << "Adding device";
QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); QVariant response = injectAndWait("Devices.AddConfiguredDevice", params);
verifyDeviceError(response); verifyDeviceError(response);
@ -2476,6 +2482,7 @@ void TestRules::removePolicyUpdateRendersUselessRule()
QVERIFY(!parentDeviceId.isNull()); QVERIFY(!parentDeviceId.isNull());
// find child device // find child device
qCDebug(dcTests()) << "Gettin devices";
response = injectAndWait("Devices.GetConfiguredDevices"); response = injectAndWait("Devices.GetConfiguredDevices");
QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); QVariantList devices = response.toMap().value("params").toMap().value("devices").toList();
@ -2506,26 +2513,34 @@ void TestRules::removePolicyUpdateRendersUselessRule()
QVariantMap action; QVariantMap action;
action.insert("deviceId", childDeviceId); action.insert("deviceId", childDeviceId);
action.insert("actionTypeId", mockParentChildActionId); action.insert("actionTypeId", mockParentChildActionId);
QVariantMap ruleActionParam;
ruleActionParam.insert("paramTypeId", mockParentChildActionId);
ruleActionParam.insert("value", true);
action.insert("ruleActionParams", QVariantList() << ruleActionParam);
params.insert("actions", QVariantList() << action); params.insert("actions", QVariantList() << action);
qCDebug(dcTests()) << "Adding Rule";
response = injectAndWait("Rules.AddRule", params); response = injectAndWait("Rules.AddRule", params);
verifyRuleError(response); verifyRuleError(response);
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString()); RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
QVERIFY2(!ruleId.isNull(), "Could not get ruleId"); QVERIFY2(!ruleId.isNull(), "Could not get ruleId");
// Try to remove child device // Try to remove child device
qCDebug(dcTests()) << "Removing device (expecing failure - device is child)";
params.clear(); response.clear(); params.clear(); response.clear();
params.insert("deviceId", childDeviceId); params.insert("deviceId", childDeviceId);
response = injectAndWait("Devices.RemoveConfiguredDevice", params); response = injectAndWait("Devices.RemoveConfiguredDevice", params);
verifyDeviceError(response, DeviceManager::DeviceErrorDeviceIsChild); verifyDeviceError(response, DeviceManager::DeviceErrorDeviceIsChild);
// Try to remove child device // Try to remove child device
qCDebug(dcTests()) << "Removing device (expeciting failure - device in use)";
params.clear(); response.clear(); params.clear(); response.clear();
params.insert("deviceId", parentDeviceId); params.insert("deviceId", parentDeviceId);
response = injectAndWait("Devices.RemoveConfiguredDevice", params); response = injectAndWait("Devices.RemoveConfiguredDevice", params);
verifyDeviceError(response, DeviceManager::DeviceErrorDeviceInRule); verifyDeviceError(response, DeviceManager::DeviceErrorDeviceInRule);
// Remove policy // Remove policy
qCDebug(dcTests()) << "Removing device with update policy";
params.clear(); response.clear(); params.clear(); response.clear();
params.insert("deviceId", parentDeviceId); params.insert("deviceId", parentDeviceId);
params.insert("removePolicy", "RemovePolicyUpdate"); params.insert("removePolicy", "RemovePolicyUpdate");
@ -2533,6 +2548,7 @@ void TestRules::removePolicyUpdateRendersUselessRule()
verifyDeviceError(response); verifyDeviceError(response);
// get updated rule. It should've been deleted given it ended up with no actions // get updated rule. It should've been deleted given it ended up with no actions
qCDebug(dcTests()) << "Getting details";
params.clear(); params.clear();
params.insert("ruleId", ruleId); params.insert("ruleId", ruleId);
response = injectAndWait("Rules.GetRuleDetails", params); 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 params") << action << QVariantMap() << RuleEngine::RuleErrorNoError;
QTest::newRow("valid action and exit action params") << action << action << 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 params1") << invalidAction1 << QVariantMap() << RuleEngine::RuleErrorMissingParameter;
QTest::newRow("invalid action params2") << invalidAction2 << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter; QTest::newRow("invalid action params2") << invalidAction2 << QVariantMap() << RuleEngine::RuleErrorMissingParameter;
QTest::newRow("valid action and invalid exit action params1") << action << invalidAction1 << RuleEngine::RuleErrorInvalidRuleActionParameter; 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::RuleErrorInvalidRuleActionParameter; QTest::newRow("valid action and invalid exit action params2") << action << invalidAction2 << RuleEngine::RuleErrorMissingParameter;
} }
void TestRules::testRuleActionParams() void TestRules::testRuleActionParams()