add tests for loading/storing rules to disk

pull/135/head
Michael Zanetti 2014-06-14 23:29:16 +02:00
parent eec2461622
commit 373af5bde5
9 changed files with 106 additions and 39 deletions

View File

@ -86,6 +86,7 @@
#include <QDebug>
#include <QSettings>
#include <QStringList>
#include <QCoreApplication>
/*! Constructs the DeviceManager with the given \a parent. There should only be one DeviceManager in the system created by \l{GuhCore}.
Use \c GuhCore::instance()->deviceManager() instead to access the DeviceManager.
@ -97,6 +98,8 @@ DeviceManager::DeviceManager(QObject *parent) :
m_pluginTimer.setInterval(15000);
connect(&m_pluginTimer, &QTimer::timeout, this, &DeviceManager::timerEvent);
m_settingsFile = QCoreApplication::instance()->organizationName() + "/devices";
// Give hardware a chance to start up before loading plugins etc.
QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "loadConfiguredDevices", Qt::QueuedConnection);
@ -298,7 +301,7 @@ QPair<DeviceManager::DeviceError, QString> DeviceManager::removeConfiguredDevice
device->deleteLater();
QSettings settings;
QSettings settings(m_settingsFile);
settings.beginGroup("DeviceConfig");
settings.beginGroup(deviceId.toString());
settings.remove("");
@ -406,7 +409,7 @@ void DeviceManager::loadPlugins()
m_supportedDevices.insert(deviceClass.id(), deviceClass);
qDebug() << "* Loaded device class:" << deviceClass.name();
}
QSettings settings;
QSettings settings(m_settingsFile);
settings.beginGroup("PluginConfig");
QList<Param> params;
if (settings.childGroups().contains(pluginIface->pluginId().toString())) {
@ -440,7 +443,7 @@ void DeviceManager::loadPlugins()
void DeviceManager::loadConfiguredDevices()
{
QSettings settings;
QSettings settings(m_settingsFile);
settings.beginGroup("DeviceConfig");
qDebug() << "loading devices from" << settings.fileName();
foreach (const QString &idString, settings.childGroups()) {
@ -472,7 +475,7 @@ void DeviceManager::loadConfiguredDevices()
void DeviceManager::storeConfiguredDevices()
{
QSettings settings;
QSettings settings(m_settingsFile);
settings.beginGroup("DeviceConfig");
foreach (Device *device, m_configuredDevices) {
settings.beginGroup(device->id().toString());

View File

@ -132,6 +132,8 @@ private:
QHash<PluginId, DevicePlugin*> m_devicePlugins;
QString m_settingsFile;
// Hardware Resources
Radio433* m_radio433;
QTimer m_pluginTimer;

View File

@ -432,6 +432,9 @@ QVariantMap JsonTypes::packRule(const Rule &rule)
Param JsonTypes::unpackParam(const QVariantMap &paramMap)
{
if (paramMap.keys().count() == 0) {
return Param();
}
QString key = paramMap.keys().first();
return Param(key, paramMap.value(key));
}

View File

@ -38,8 +38,9 @@ RulesHandler::RulesHandler(QObject *parent) :
setReturns("GetRules", returns);
params.clear(); returns.clear();
setDescription("AddRule", "Add a rule");
params.insert("eventDescriptor", JsonTypes::eventDescriptorRef());
setDescription("AddRule", "Add a rule.");
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef());
QVariantList actions;
actions.append(JsonTypes::actionRef());
params.insert("actions", actions);

View File

@ -72,8 +72,8 @@ RuleEngine::RuleEngine(QObject *parent) :
QObject(parent)
{
m_settingsFile = QCoreApplication::instance()->organizationName() + "/rules";
qDebug() << "laoding rules from" << m_settingsFile;
QSettings settings(m_settingsFile);
qDebug() << "laoding rules from" << settings.fileName();
foreach (const QString &idString, settings.childGroups()) {
qDebug() << "found rule" << idString;
@ -133,8 +133,8 @@ RuleEngine::RuleEngine(QObject *parent) :
settings.endGroup();
// Rule rule = Rule(RuleId(idString), eventDescriptorList, states, actions);
// m_rules.append(rule);
Rule rule = Rule(RuleId(idString), eventDescriptorList, stateEvaluator, actions);
m_rules.append(rule);
}
}

View File

@ -278,12 +278,8 @@ void TestDevices::storedDevices()
DeviceId addedDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString());
QVERIFY(!addedDeviceId.isNull());
// Destroy and recreate the core instance to check if settings are loaded at startup
GuhCore::instance()->destroy();
QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded()));
spy.wait();
m_mockTcpServer = MockTcpServer::servers().first();
// Restart the core instance to check if settings are loaded at startup
restartServer();
response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap());

View File

@ -44,8 +44,10 @@ void GuhTestBase::initTestCase()
{
// If testcase asserts cleanup won't do. Lets clear any previous test run settings leftovers
QSettings settings;
settings.clear();
QSettings rulesSettings(QCoreApplication::instance()->organizationName() + "/rules");
rulesSettings.clear();
QSettings deviceSettings(QCoreApplication::instance()->organizationName() + "/devices");
deviceSettings.clear();
GuhCore::instance();
@ -105,3 +107,12 @@ void GuhTestBase::verifySuccess(const QVariant &response, bool success)
QVERIFY2(response.toMap().value("status").toString() == QString("success"), jsonDoc.toJson().data());
QVERIFY2(response.toMap().value("params").toMap().value("success").toBool() == success, jsonDoc.toJson().data());
}
void GuhTestBase::restartServer()
{
// Destroy and recreate the core instance...
GuhCore::instance()->destroy();
QSignalSpy spy(GuhCore::instance()->deviceManager(), SIGNAL(loaded()));
spy.wait();
m_mockTcpServer = MockTcpServer::servers().first();
}

View File

@ -58,6 +58,7 @@ protected slots:
protected:
QVariant injectAndWait(const QString &method, const QVariantMap &params = QVariantMap());
void verifySuccess(const QVariant &response, bool success = true);
void restartServer();
protected:
MockTcpServer *m_mockTcpServer;

View File

@ -36,8 +36,8 @@ class TestRules: public GuhTestBase
private slots:
void addRules_data();
void addRules();
void getStateValue_data();
void getStateValue();
void loadStoreConfig();
};
void TestRules::addRules_data()
@ -117,34 +117,84 @@ void TestRules::addRules()
QVERIFY2(rules.count() == 0, "There should be no rules.");
}
void TestRules::getStateValue_data()
void TestRules::loadStoreConfig()
{
QList<Device*> devices = GuhCore::instance()->deviceManager()->findConfiguredDevices(mockDeviceClassId);
QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test");
Device *device = devices.first();
QVariantMap eventDescriptor1;
eventDescriptor1.insert("eventTypeId", mockEvent1Id);
eventDescriptor1.insert("deviceId", m_mockDeviceId);
eventDescriptor1.insert("paramDescriptors", QVariantList());
QTest::addColumn<DeviceId>("deviceId");
QTest::addColumn<StateTypeId>("stateTypeId");
QTest::addColumn<bool>("success");
QVariantMap eventDescriptor2;
eventDescriptor2.insert("eventTypeId", mockEvent1Id);
eventDescriptor2.insert("deviceId", m_mockDeviceId);
eventDescriptor2.insert("paramDescriptors", QVariantList());
QTest::newRow("existing state") << device->id() << mockIntStateId << true;
QTest::newRow("invalid device") << DeviceId::createDeviceId() << mockIntStateId << false;
QTest::newRow("invalid statetype") << device->id() << StateTypeId::createStateTypeId() << false;
}
QVariantMap action1;
action1.insert("actionTypeId", mockActionIdNoParams);
action1.insert("deviceId", m_mockDeviceId);
action1.insert("params", QVariantList());
QVariantMap action2;
action2.insert("actionTypeId", mockActionIdWithParams);
qDebug() << "got action id" << mockActionIdWithParams;
action2.insert("deviceId", m_mockDeviceId);
QVariantList action2Params;
QVariantMap action2Param1;
action2Param1.insert("mockActionParam1", 5);
action2Params.append(action2Param1);
QVariantMap action2Param2;
action2Param2.insert("mockActionParam2", true);
action2Params.append(action2Param2);
action2.insert("params", action2Params);
void TestRules::getStateValue()
{
QFETCH(DeviceId, deviceId);
QFETCH(StateTypeId, stateTypeId);
QFETCH(bool, success);
QVariantMap params;
params.insert("deviceId", deviceId.toString());
params.insert("stateTypeId", stateTypeId.toString());
QVariantList actions;
actions.append(action1);
actions.append(action2);
params.insert("actions", actions);
params.insert("eventDescriptor", eventDescriptor1);
QVariant response = injectAndWait("Rules.AddRule", params);
QVariant response = injectAndWait("Devices.GetStateValue", params);
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
verifySuccess(response, true);
verifySuccess(response, success);
restartServer();
response = injectAndWait("Rules.GetRules");
QVariantList rules = response.toMap().value("params").toMap().value("rules").toList();
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor1, "Event descriptor doesn't match");
QVariantList replyActions = rules.first().toMap().value("actions").toList();
foreach (const QVariant &actionVariant, actions) {
bool found = false;
foreach (const QVariant &replyActionVariant, replyActions) {
if (actionVariant.toMap().value("actionTypeId") == replyActionVariant.toMap().value("actionTypeId") &&
actionVariant.toMap().value("deviceId") == replyActionVariant.toMap().value("deviceId")) {
found = true;
QVERIFY2(actionVariant == replyActionVariant, "Action doesn't match after loading from config.");
}
}
QVERIFY2(found, "Action not found after loading from config.");
}
params.clear();
params.insert("ruleId", newRuleId);
response = injectAndWait("Rules.RemoveRule", params);
verifySuccess(response, true);
restartServer();
response = injectAndWait("Rules.GetRules");
rules = response.toMap().value("params").toMap().value("rules").toList();
QVERIFY2(rules.count() == 0, "There should be no rules.");
}
#include "testrules.moc"