New DB schema version

* Store plaintext values in log db again
* Use msecs precision instead of secs
* rename column deviceId to thingId
This commit is contained in:
Michael Zanetti 2020-04-20 13:04:13 +02:00
parent 9af820b696
commit bb30a451b3
7 changed files with 243 additions and 243 deletions

View File

@ -46,7 +46,7 @@
#include <QTime> #include <QTime>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#define DB_SCHEMA_VERSION 3 #define DB_SCHEMA_VERSION 4
namespace nymeaserver { namespace nymeaserver {
@ -136,13 +136,13 @@ LogEntriesFetchJob *LogEngine::fetchLogEntries(const LogFilter &filter)
foreach (const QSqlRecord &result, job->results()) { foreach (const QSqlRecord &result, job->results()) {
LogEntry entry( LogEntry entry(
QDateTime::fromTime_t(result.value("timestamp").toUInt()), QDateTime::fromMSecsSinceEpoch(result.value("timestamp").toLongLong()),
static_cast<Logging::LoggingLevel>(result.value("loggingLevel").toInt()), static_cast<Logging::LoggingLevel>(result.value("loggingLevel").toInt()),
static_cast<Logging::LoggingSource>(result.value("sourceType").toInt()), static_cast<Logging::LoggingSource>(result.value("sourceType").toInt()),
result.value("errorCode").toInt()); result.value("errorCode").toInt());
entry.setTypeId(result.value("typeId").toUuid()); entry.setTypeId(result.value("typeId").toUuid());
entry.setThingId(ThingId(result.value("deviceId").toString())); entry.setThingId(ThingId(result.value("thingId").toString()));
entry.setValue(LogValueTool::convertVariantToString(LogValueTool::deserializeValue(result.value("value").toString()))); entry.setValue(result.value("value").toString());
entry.setEventType(static_cast<Logging::LoggingEventType>(result.value("loggingEventType").toInt())); entry.setEventType(static_cast<Logging::LoggingEventType>(result.value("loggingEventType").toInt()));
entry.setActive(result.value("active").toBool()); entry.setActive(result.value("active").toBool());
@ -157,9 +157,9 @@ LogEntriesFetchJob *LogEngine::fetchLogEntries(const LogFilter &filter)
return fetchJob; return fetchJob;
} }
ThingsFetchJob *LogEngine::fetchDevices() ThingsFetchJob *LogEngine::fetchThings()
{ {
QString queryString = QString("SELECT deviceId FROM entries WHERE deviceId != \"%1\" GROUP BY deviceId;").arg(QUuid().toString()); QString queryString = QString("SELECT thingId FROM entries WHERE thingId != \"%1\" GROUP BY thingId;").arg(QUuid().toString());
DatabaseJob *job = new DatabaseJob(m_db, queryString); DatabaseJob *job = new DatabaseJob(m_db, queryString);
ThingsFetchJob *fetchJob = new ThingsFetchJob(this); ThingsFetchJob *fetchJob = new ThingsFetchJob(this);
@ -172,7 +172,7 @@ ThingsFetchJob *LogEngine::fetchDevices()
} }
foreach (const QSqlRecord &result, job->results()) { foreach (const QSqlRecord &result, job->results()) {
fetchJob->m_results.append(ThingId(result.value("deviceId").toUuid())); fetchJob->m_results.append(ThingId(result.value("thingId").toUuid()));
} }
fetchJob->finished(); fetchJob->finished();
}); });
@ -192,10 +192,9 @@ void LogEngine::setMaxLogEntries(int maxLogEntries, int trimSize)
trim(); trim();
} }
/*! Removes all entries from the database. This method will be used for the tests. */
void LogEngine::clearDatabase() void LogEngine::clearDatabase()
{ {
qCWarning(dcLogEngine) << "Clear logging database."; qCWarning(dcLogEngine) << "Clearing logging database.";
QString queryDeleteString = QString("DELETE FROM entries;"); QString queryDeleteString = QString("DELETE FROM entries;");
@ -203,7 +202,7 @@ void LogEngine::clearDatabase()
connect(job, &DatabaseJob::finished, this, [this, job](){ connect(job, &DatabaseJob::finished, this, [this, job](){
if (job->error().type() != QSqlError::NoError) { if (job->error().type() != QSqlError::NoError) {
qCWarning(dcLogEngine) << "Could not clear logging database. Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText(); qCWarning(dcLogEngine) << "Error clearing log database. Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText();
return; return;
} }
m_entryCount = 0; m_entryCount = 0;
@ -329,11 +328,11 @@ void LogEngine::logRuleExitActionsExecuted(const Rule &rule)
appendLogEntry(entry); appendLogEntry(entry);
} }
void LogEngine::removeDeviceLogs(const ThingId &thingId) void LogEngine::removeThingLogs(const ThingId &thingId)
{ {
qCDebug(dcLogEngine) << "Deleting log entries from device" << thingId.toString(); qCDebug(dcLogEngine) << "Deleting log entries from device" << thingId.toString();
QString queryDeleteString = QString("DELETE FROM entries WHERE deviceId = '%1';").arg(thingId.toString()); QString queryDeleteString = QString("DELETE FROM entries WHERE thingId = '%1';").arg(thingId.toString());
DatabaseJob *job = new DatabaseJob(m_db, queryDeleteString); DatabaseJob *job = new DatabaseJob(m_db, queryDeleteString);
connect(job, &DatabaseJob::finished, this, [this, job, thingId](){ connect(job, &DatabaseJob::finished, this, [this, job, thingId](){
@ -373,14 +372,14 @@ void LogEngine::removeRuleLogs(const RuleId &ruleId)
void LogEngine::appendLogEntry(const LogEntry &entry) void LogEngine::appendLogEntry(const LogEntry &entry)
{ {
QString queryString = QString("INSERT INTO entries (timestamp, loggingEventType, loggingLevel, sourceType, typeId, deviceId, value, active, errorCode) values ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9');") QString queryString = QString("INSERT INTO entries (timestamp, loggingEventType, loggingLevel, sourceType, typeId, thingId, value, active, errorCode) values ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9');")
.arg(entry.timestamp().toTime_t()) .arg(entry.timestamp().toMSecsSinceEpoch())
.arg(entry.eventType()) .arg(entry.eventType())
.arg(entry.level()) .arg(entry.level())
.arg(entry.source()) .arg(entry.source())
.arg(entry.typeId().toString()) .arg(entry.typeId().toString())
.arg(entry.thingId().toString()) .arg(entry.thingId().toString())
.arg(LogValueTool::serializeValue(entry.value())) .arg(entry.value().toString())
.arg(entry.active()) .arg(entry.active())
.arg(entry.errorCode()); .arg(entry.errorCode());
@ -428,7 +427,7 @@ void LogEngine::checkDBSize()
{ {
DatabaseJob *job = new DatabaseJob(m_db, "SELECT COUNT(*) FROM entries;"); DatabaseJob *job = new DatabaseJob(m_db, "SELECT COUNT(*) FROM entries;");
connect(job, &DatabaseJob::finished, this, [this, job](){ connect(job, &DatabaseJob::finished, this, [this, job](){
if (job->error().type() != QSqlError::NoError) { if (job->error().type() != QSqlError::NoError || job->results().count() == 0) {
qCWarning(dcLogEngine()) << "Error fetching log DB size. Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText(); qCWarning(dcLogEngine()) << "Error fetching log DB size. Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText();
m_entryCount = 0; m_entryCount = 0;
return; return;
@ -477,6 +476,10 @@ void LogEngine::enqueJob(DatabaseJob *job, bool priority)
void LogEngine::processQueue() void LogEngine::processQueue()
{ {
if (!m_initialized) {
return;
}
if (m_jobQueue.isEmpty()) { if (m_jobQueue.isEmpty()) {
emit jobsRunningChanged(); emit jobsRunningChanged();
return; return;
@ -506,7 +509,7 @@ void LogEngine::processQueue()
query.prepare(job->m_queryString); query.prepare(job->m_queryString);
foreach (const QString &value, job->m_bindValues) { foreach (const QString &value, job->m_bindValues) {
query.addBindValue(LogValueTool::serializeValue(value)); query.addBindValue(value);
} }
query.exec(); query.exec();
@ -552,84 +555,141 @@ void LogEngine::rotate(const QString &dbName)
} }
} }
bool LogEngine::migrateDatabaseVersion2to3() bool LogEngine::migrateDatabaseVersion3to4()
{ {
// Changelog: serialize values of logentries in order to prevent typecast errors QSqlQuery renameQuery = m_db.exec("ALTER TABLE entries RENAME TO _entries_v3;");
qCDebug(dcLogEngine()) << "Start migration of log database from version 2 to version 3";
QDateTime startTime = QDateTime::currentDateTime();
int migrationCounter = 0;
int migrationProgress = 0;
int entryCount = 0;
// Count entries we have to migrate
QString queryString = "SELECT COUNT(*) FROM entries WHERE value != '';";
QSqlQuery countQuery = m_db.exec(queryString);
if (m_db.lastError().type() != QSqlError::NoError) {
qCWarning(dcLogEngine()) << "Failed to query entry count in db:" << m_db.lastError().databaseText();
return false;
}
if (!countQuery.first()) {
qCWarning(dcLogEngine()) << "Migration: Failed retrieving entry count.";
return false;
}
entryCount = countQuery.value(0).toInt();
qCDebug(dcLogEngine()) << "Found" << entryCount << "entries to migrate.";
// Select all entries
QSqlQuery selectQuery = m_db.exec("SELECT * FROM entries;");
if (m_db.lastError().isValid()) { if (m_db.lastError().isValid()) {
qCWarning(dcLogEngine) << "Error migrating database verion 2 -> 3. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText(); qCWarning(dcLogEngine) << "Error migrating database verion 3 -> 4 (renaming table). Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false; return false;
} }
qCDebug(dcLogEngine()) << "Renamed entries table to entries_v3:" << m_db.lastError().text();
m_db.close();
m_db.open(m_username, m_password);
// Migrate all selected entries QSqlQuery createQuery = m_db.exec("CREATE TABLE entries "
while (selectQuery.next()) { "("
QString oldValue = selectQuery.value("value").toString(); "timestamp BIGINT,"
QString newValue = LogValueTool::serializeValue(QVariant(oldValue)); "loggingLevel INT,"
if (oldValue.isEmpty()) "sourceType INT,"
continue; "typeId VARCHAR(38),"
"thingId VARCHAR(38),"
QString updateCall = QString("UPDATE entries SET value = '%1' WHERE timestamp = '%2' AND loggingLevel = '%3' AND sourceType = '%4' AND errorCode = '%5' AND typeId = '%6' AND deviceId = '%7' AND value = '%8' AND loggingEventType = '%9'AND active = '%10';") "value VARCHAR(100),"
.arg(newValue) "loggingEventType INT,"
.arg(selectQuery.value("timestamp").toLongLong()) "active BOOL,"
.arg(selectQuery.value("loggingLevel").toInt()) "errorCode INT,"
.arg(selectQuery.value("sourceType").toInt()) "FOREIGN KEY(sourceType) REFERENCES sourceTypes(id),"
.arg(selectQuery.value("errorCode").toInt()) "FOREIGN KEY(loggingEventType) REFERENCES loggingEventTypes(id)"
.arg(selectQuery.value("typeId").toUuid().toString()) ");");
.arg(selectQuery.value("deviceId").toString()) if (m_db.lastError().isValid()) {
.arg(selectQuery.value("value").toString()) qCWarning(dcLogEngine) << "Error migrating database verion 3 -> 4 (creating new table). Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
.arg(selectQuery.value("loggingEventType").toInt()) return false;
.arg(selectQuery.value("active").toBool());
m_db.exec(updateCall);
if (m_db.lastError().isValid()) {
qCWarning(dcLogEngine) << "Error migrating database verion 2 -> 3. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false;
}
migrationCounter++;
double percentage = migrationCounter * 100.0 / entryCount;
if (qRound(percentage) != migrationProgress) {
migrationProgress = qRound(percentage);
qCDebug(dcLogEngine()) << QString("Migration progress: %1\%").arg(migrationProgress).toLatin1().data();
}
} }
qCDebug(dcLogEngine()) << "Created new entries table:" << m_db.lastError().text();
QTime runTime = QTime(0,0,0,0).addMSecs(startTime.msecsTo(QDateTime::currentDateTime()));
qCDebug(dcLogEngine()) << "Migration of" << migrationCounter << "done in" << runTime.toString("mm:ss.zzz");
qCDebug(dcLogEngine()) << "Updating database version to" << DB_SCHEMA_VERSION; qCDebug(dcLogEngine()) << "Updating database version to" << DB_SCHEMA_VERSION;
m_db.exec(QString("UPDATE metadata SET data = %1 WHERE key = 'version';").arg(DB_SCHEMA_VERSION)); m_db.exec(QString("UPDATE metadata SET data = %1 WHERE `key` = 'version';").arg(DB_SCHEMA_VERSION));
if (m_db.lastError().isValid()) { if (m_db.lastError().isValid()) {
qCWarning(dcLogEngine) << "Error updating database verion 2 -> 3. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText(); qCWarning(dcLogEngine) << "Error updating database verion 3 -> 4. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false; return false;
} }
qCDebug(dcLogEngine()) << "Migrated" << migrationCounter << "entries from database verion 2 -> 3 successfully."; qCDebug(dcLogEngine()) << "Migrated database schema from version 3 to 4.";
return true; return true;
}
void LogEngine::migrateEntries3to4()
{
QString selectQuery = QString("SELECT * FROM _entries_v3;");
DatabaseJob *job = new DatabaseJob(m_db, selectQuery);
connect(job, &DatabaseJob::finished, this, [this, job](){
if (job->error().type() != QSqlError::NoError) {
qCWarning(dcLogEngine) << "Error fetching entries to migrate. Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText();
m_dbMalformed = true;
return;
}
if (job->results().isEmpty()) {
qCDebug(dcLogEngine()) << "No items to migrate from schema 3 to 4 remaining.";
finalizeMigration3To4();
return;
}
int count = job->results().count();
QSqlRecord result = job->results().first();
QString encodedValue = result.value("value").toByteArray();
QString decodedValue = LogValueTool::convertVariantToString(LogValueTool::deserializeValue(encodedValue));
QString insertCall = QString("INSERT INTO entries (timestamp, loggingEventType, loggingLevel, sourceType, typeId, thingId, value, active, errorCode) values ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9');")
.arg(result.value("timestamp").toLongLong() * 1000)
.arg(result.value("loggingEventType").toInt())
.arg(result.value("loggingLevel").toInt())
.arg(result.value("sourceType").toInt())
.arg(result.value("typeId").toString())
.arg(result.value("deviceId").toString())
.arg(decodedValue)
.arg(result.value("active").toBool())
.arg(result.value("errorCode").toInt());
DatabaseJob *insertJob = new DatabaseJob(m_db, insertCall);
connect(insertJob, &DatabaseJob::finished, this, [this, insertJob, count, result](){
if (insertJob->error().type() != QSqlError::NoError) {
qCWarning(dcLogEngine) << "Error fetching entries to migrate. Driver error:" << insertJob->error().driverText() << "Database error:" << insertJob->error().databaseText();
m_dbMalformed = true;
return;
}
QString deleteCall = QString("DELETE FROM _entries_v3 WHERE timestamp = '%1' AND loggingEventType = '%2' AND loggingLevel = '%3' AND sourceType = '%4' AND typeId = '%5' AND deviceId = '%6' AND value = '%7' AND active = '%8' AND errorCode = '%9';")
.arg(result.value("timestamp").toLongLong())
.arg(result.value("loggingEventType").toInt())
.arg(result.value("loggingLevel").toInt())
.arg(result.value("sourceType").toInt())
.arg(result.value("typeId").toString())
.arg(result.value("deviceId").toString())
.arg(result.value("value").toString())
.arg(result.value("active").toBool())
.arg(result.value("errorCode").toInt());
DatabaseJob *deleteJob = new DatabaseJob(m_db, deleteCall);
connect(deleteJob, &DatabaseJob::finished, this, [this, deleteJob, count, result](){
if (deleteJob->error().type() != QSqlError::NoError) {
qCWarning(dcLogEngine) << "Error deleting old entry during migration. Driver error:" << deleteJob->error().driverText() << "Database error:" << deleteJob->error().databaseText();
finalizeMigration3To4();
return;
}
qCDebug(dcLogEngine()) << "Migrated log entry from version 3 to 4." << (count - 1) << "items left to migrate";
if (count - 1 > 0) {
migrateEntries3to4();
} else {
finalizeMigration3To4();
}
});
enqueJob(deleteJob);
});
enqueJob(insertJob);
});
enqueJob(job);
}
void LogEngine::finalizeMigration3To4()
{
qCDebug(dcLogEngine()) << "Finalizing migration of database version 3 to 4.";
QString selectQuery = QString("DROP TABLE _entries_v3;");
DatabaseJob *job = new DatabaseJob(m_db, selectQuery);
enqueJob(job);
connect(job, &DatabaseJob::finished, this, [job](){
if (job->error().type() != QSqlError::NoError) {
qCWarning(dcLogEngine) << "Error finalizing migration from 3 to 4 (drop entries_v3). Driver error:" << job->error().driverText() << "Database error:" << job->error().databaseText();
return;
}
});
} }
bool LogEngine::initDB(const QString &username, const QString &password) bool LogEngine::initDB(const QString &username, const QString &password)
@ -655,21 +715,27 @@ bool LogEngine::initDB(const QString &username, const QString &password)
if (query.next()) { if (query.next()) {
int version = query.value("data").toInt(); int version = query.value("data").toInt();
// Migration from 2 -> 3 (serialize values in order to store QVariant information) // Migration from 3 -> 4
if (DB_SCHEMA_VERSION == 3 && version == 2) { if (version == 3) {
if (!migrateDatabaseVersion2to3()) { if (!migrateDatabaseVersion3to4()) {
qCWarning(dcLogEngine()) << "Migration process failed."; qCWarning(dcLogEngine()) << "Migration process failed.";
return false; return false;
} else { } else {
// Successfully migrated // Successfully migrated
version = DB_SCHEMA_VERSION; version = 4;
} }
} }
if (version != DB_SCHEMA_VERSION) { if (version != DB_SCHEMA_VERSION) {
qCWarning(dcLogEngine) << "Log schema version not matching! Schema upgrade not implemented yet. Logging might fail."; qCWarning(dcLogEngine) << "Log schema version not matching! Schema upgrade not implemented for this version change.";
return false;
} else { } else {
qCDebug(dcLogEngine) << QString("Log database schema version \"%1\" matches").arg(DB_SCHEMA_VERSION).toLatin1().data(); qCDebug(dcLogEngine) << QString("Log database schema version \"%1\" matches").arg(DB_SCHEMA_VERSION).toLatin1().data();
// If there is still a deviceId column, schedule items to be migrated in the
// background with low priority as this might take hours
if (m_db.tables().contains("_entries_v3")) {
migrateEntries3to4();
}
} }
} else { } else {
qCWarning(dcLogEngine) << "Broken log database. Version not found in metadata table."; qCWarning(dcLogEngine) << "Broken log database. Version not found in metadata table.";
@ -703,15 +769,15 @@ bool LogEngine::initDB(const QString &username, const QString &password)
qCDebug(dcLogEngine()) << "No \"entries\" table in database. Creating it."; qCDebug(dcLogEngine()) << "No \"entries\" table in database. Creating it.";
m_db.exec("CREATE TABLE entries " m_db.exec("CREATE TABLE entries "
"(" "("
"timestamp int," "timestamp BIGINT,"
"loggingLevel int," "loggingLevel INT,"
"sourceType int," "sourceType INT,"
"typeId varchar(38)," "typeId VARCHAR(38),"
"deviceId varchar(38)," "thingId VARCHAR(38),"
"value varchar(100)," "value VARCHAR(100),"
"loggingEventType int," "loggingEventType INT,"
"active bool," "active BOOL,"
"errorCode int," "errorCode INT,"
"FOREIGN KEY(sourceType) REFERENCES sourceTypes(id)," "FOREIGN KEY(sourceType) REFERENCES sourceTypes(id),"
"FOREIGN KEY(loggingEventType) REFERENCES loggingEventTypes(id)" "FOREIGN KEY(loggingEventType) REFERENCES loggingEventTypes(id)"
");"); ");");
@ -725,6 +791,7 @@ bool LogEngine::initDB(const QString &username, const QString &password)
} }
qCDebug(dcLogEngine) << "Initialized logging DB successfully. (maximum DB size:" << m_dbMaxSize << ")"; qCDebug(dcLogEngine) << "Initialized logging DB successfully. (maximum DB size:" << m_dbMaxSize << ")";
m_initialized = true;
return true; return true;
} }

View File

@ -61,7 +61,7 @@ public:
~LogEngine(); ~LogEngine();
LogEntriesFetchJob *fetchLogEntries(const LogFilter &filter = LogFilter()); LogEntriesFetchJob *fetchLogEntries(const LogFilter &filter = LogFilter());
ThingsFetchJob *fetchDevices(); ThingsFetchJob *fetchThings();
bool jobsRunning() const; bool jobsRunning() const;
@ -78,7 +78,7 @@ public:
void logRuleEnabledChanged(const Rule &rule, const bool &enabled); void logRuleEnabledChanged(const Rule &rule, const bool &enabled);
void logRuleActionsExecuted(const Rule &rule); void logRuleActionsExecuted(const Rule &rule);
void logRuleExitActionsExecuted(const Rule &rule); void logRuleExitActionsExecuted(const Rule &rule);
void removeDeviceLogs(const ThingId &thingId); void removeThingLogs(const ThingId &thingId);
void removeRuleLogs(const RuleId &ruleId); void removeRuleLogs(const RuleId &ruleId);
signals: signals:
@ -92,8 +92,9 @@ private:
void appendLogEntry(const LogEntry &entry); void appendLogEntry(const LogEntry &entry);
void rotate(const QString &dbName); void rotate(const QString &dbName);
bool migrateDatabaseVersion3to4();
bool migrateDatabaseVersion2to3(); void migrateEntries3to4();
void finalizeMigration3To4();
private slots: private slots:
void checkDBSize(); void checkDBSize();
@ -110,6 +111,7 @@ private:
int m_dbMaxSize; int m_dbMaxSize;
int m_trimSize; int m_trimSize;
int m_entryCount = 0; int m_entryCount = 0;
bool m_initialized = false;
bool m_dbMalformed = false; bool m_dbMalformed = false;
// When maxQueueLength is exceeded, jobs will be flagged and discarded if this source logs more events // When maxQueueLength is exceeded, jobs will be flagged and discarded if this source logs more events

View File

@ -85,7 +85,7 @@ QString LogFilter::queryString() const
if (!query.isEmpty() && !thingIds().isEmpty()) { if (!query.isEmpty() && !thingIds().isEmpty()) {
query.append("AND "); query.append("AND ");
} }
query.append(createDeviceIdString()); query.append(createThingIdString());
if (!query.isEmpty() && !values().isEmpty()) { if (!query.isEmpty() && !values().isEmpty()) {
query.append("AND "); query.append("AND ");
@ -161,7 +161,7 @@ QList<QUuid> LogFilter::typeIds() const
return m_typeIds; return m_typeIds;
} }
/*! Add a new \a deviceId to this \l{LogFilter}. */ /*! Add a new \a thingId to this \l{LogFilter}. */
void LogFilter::addThingId(const ThingId &thingId) void LogFilter::addThingId(const ThingId &thingId)
{ {
if (!m_thingIds.contains(thingId)) if (!m_thingIds.contains(thingId))
@ -366,16 +366,16 @@ QString LogFilter::createTypeIdsString() const
return query; return query;
} }
QString LogFilter::createDeviceIdString() const QString LogFilter::createThingIdString() const
{ {
QString query; QString query;
if (!m_thingIds.isEmpty()) { if (!m_thingIds.isEmpty()) {
if (m_thingIds.count() == 1) { if (m_thingIds.count() == 1) {
query.append(QString("deviceId = '%1' ").arg(m_thingIds.first().toString())); query.append(QString("thingId = '%1' ").arg(m_thingIds.first().toString()));
} else { } else {
query.append("( "); query.append("( ");
foreach (const ThingId &thingId, m_thingIds) { foreach (const ThingId &thingId, m_thingIds) {
query.append(QString("deviceId = '%1' ").arg(thingId.toString())); query.append(QString("thingId = '%1' ").arg(thingId.toString()));
if (thingId != m_thingIds.last()) if (thingId != m_thingIds.last())
query.append("OR "); query.append("OR ");
} }
@ -387,8 +387,6 @@ QString LogFilter::createDeviceIdString() const
QString LogFilter::createValuesString() const QString LogFilter::createValuesString() const
{ {
// FIXME: check how to filter for serialized values
QString query; QString query;
if (!m_values.isEmpty()) { if (!m_values.isEmpty()) {
if (m_values.count() == 1) { if (m_values.count() == 1) {

View File

@ -96,7 +96,7 @@ private:
QString createLevelsString() const; QString createLevelsString() const;
QString createEventTypesString() const; QString createEventTypesString() const;
QString createTypeIdsString() const; QString createTypeIdsString() const;
QString createDeviceIdString() const; QString createThingIdString() const;
QString createValuesString() const; QString createValuesString() const;
}; };

View File

@ -284,14 +284,14 @@ QPair<Thing::ThingError, QList<RuleId> > NymeaCore::removeConfiguredThing(const
foreach (Thing *d, childs) { foreach (Thing *d, childs) {
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id()); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id());
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(d->id()); m_logger->removeThingLogs(d->id());
} }
} }
// delete the things // delete the things
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId);
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(thingId); m_logger->removeThingLogs(thingId);
} }
return QPair<Thing::ThingError, QList<RuleId> > (Thing::ThingErrorNoError, QList<RuleId>()); return QPair<Thing::ThingError, QList<RuleId> > (Thing::ThingErrorNoError, QList<RuleId>());
@ -358,14 +358,14 @@ Thing::ThingError NymeaCore::removeConfiguredThing(const ThingId &thingId, const
foreach (Thing *d, childs) { foreach (Thing *d, childs) {
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id()); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id());
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(d->id()); m_logger->removeThingLogs(d->id());
} }
} }
// delete the things // delete the things
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId);
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(thingId); m_logger->removeThingLogs(thingId);
} }
return removeError; return removeError;
@ -837,14 +837,14 @@ void NymeaCore::onThingDisappeared(const ThingId &thingId)
foreach (Thing *d, childs) { foreach (Thing *d, childs) {
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id()); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(d->id());
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(d->id()); m_logger->removeThingLogs(d->id());
} }
} }
// delete the thing // delete the thing
Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId); Thing::ThingError removeError = m_thingManager->removeConfiguredThing(thingId);
if (removeError == Thing::ThingErrorNoError) { if (removeError == Thing::ThingErrorNoError) {
m_logger->removeDeviceLogs(thingId); m_logger->removeThingLogs(thingId);
} }
} }
@ -859,12 +859,12 @@ void NymeaCore::thingManagerLoaded()
// Do some houskeeping... // Do some houskeeping...
qCDebug(dcApplication()) << "Starting housekeeping..."; qCDebug(dcApplication()) << "Starting housekeeping...";
QDateTime startTime = QDateTime::currentDateTime(); QDateTime startTime = QDateTime::currentDateTime();
ThingsFetchJob *job = m_logger->fetchDevices(); ThingsFetchJob *job = m_logger->fetchThings();
connect(job, &ThingsFetchJob::finished, m_thingManager, [this, job, startTime](){ connect(job, &ThingsFetchJob::finished, m_thingManager, [this, job, startTime](){
foreach (const ThingId &thingId, job->results()) { foreach (const ThingId &thingId, job->results()) {
if (!m_thingManager->findConfiguredThing(thingId)) { if (!m_thingManager->findConfiguredThing(thingId)) {
qCDebug(dcApplication()) << "Cleaning stale thing entries from log DB for thing id" << thingId; qCDebug(dcApplication()) << "Cleaning stale thing entries from log DB for thing id" << thingId;
m_logger->removeDeviceLogs(thingId); m_logger->removeThingLogs(thingId);
} }
} }
qCDebug(dcApplication()) << "Housekeeping done in" << startTime.msecsTo(QDateTime::currentDateTime()) << "ms."; qCDebug(dcApplication()) << "Housekeeping done in" << startTime.msecsTo(QDateTime::currentDateTime()) << "ms.";

View File

@ -75,7 +75,7 @@ private slots:
void actionLog(); void actionLog();
void deviceLogs(); void thingLogs();
void testDoubleValues(); void testDoubleValues();
@ -84,7 +84,7 @@ private slots:
void testLimits(); void testLimits();
// this has to be the last test // this has to be the last test
void removeDevice(); void removeThing();
}; };
void TestLogging::initTestCase() void TestLogging::initTestCase()
@ -294,7 +294,7 @@ void TestLogging::eventLogs()
qDebug() << "got" << loggEntryAddedVariants.count() << "Logging.LogEntryAdded"; qDebug() << "got" << loggEntryAddedVariants.count() << "Logging.LogEntryAdded";
foreach (const QVariant &loggEntryAddedVariant, loggEntryAddedVariants) { foreach (const QVariant &loggEntryAddedVariant, loggEntryAddedVariants) {
QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap(); QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap();
if (logEntry.value("deviceId").toUuid() == device->id()) { if (logEntry.value("thingId").toUuid() == device->id()) {
found = true; found = true;
// Make sure the notification contains all the stuff we expect // Make sure the notification contains all the stuff we expect
QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockEvent1EventTypeId.toString()); QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockEvent1EventTypeId.toString());
@ -311,7 +311,7 @@ void TestLogging::eventLogs()
// get this logentry with filter // get this logentry with filter
QVariantMap params; QVariantMap params;
params.insert("deviceIds", QVariantList() << device->id()); params.insert("thingIds", QVariantList() << device->id());
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceEvents)); params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceEvents));
params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger)); params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger));
params.insert("typeIds", QVariantList() << mockEvent1EventTypeId); params.insert("typeIds", QVariantList() << mockEvent1EventTypeId);
@ -367,7 +367,7 @@ void TestLogging::actionLog()
bool found = false; bool found = false;
foreach (const QVariant &loggEntryAddedVariant, logEntryAddedVariants) { foreach (const QVariant &loggEntryAddedVariant, logEntryAddedVariants) {
QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap(); QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap();
if (logEntry.value("deviceId").toUuid() == m_mockThingId) { if (logEntry.value("thingId").toUuid() == m_mockThingId) {
found = true; found = true;
// Make sure the notification contains all the stuff we expect // Make sure the notification contains all the stuff we expect
QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockWithParamsActionTypeId.toString()); QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockWithParamsActionTypeId.toString());
@ -383,9 +383,9 @@ void TestLogging::actionLog()
// EXECUTE without params // EXECUTE without params
params.clear(); clientSpy.clear(); params.clear(); clientSpy.clear();
params.insert("actionTypeId", mockWithoutParamsActionTypeId); params.insert("actionTypeId", mockWithoutParamsActionTypeId);
params.insert("deviceId", m_mockThingId); params.insert("thingId", m_mockThingId);
response = injectAndWait("Actions.ExecuteAction", params); response = injectAndWait("Integrations.ExecuteAction", params);
verifyDeviceError(response); verifyThingError(response);
clientSpy.wait(200); clientSpy.wait(200);
@ -394,7 +394,7 @@ void TestLogging::actionLog()
// get this logentry with filter // get this logentry with filter
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions)); params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions));
params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger)); params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger));
@ -410,9 +410,9 @@ void TestLogging::actionLog()
// EXECUTE broken action // EXECUTE broken action
params.clear(); clientSpy.clear(); params.clear(); clientSpy.clear();
params.insert("actionTypeId", mockFailingActionTypeId); params.insert("actionTypeId", mockFailingActionTypeId);
params.insert("deviceId", m_mockThingId); params.insert("thingId", m_mockThingId);
response = injectAndWait("Actions.ExecuteAction", params); response = injectAndWait("Integrations.ExecuteAction", params);
verifyDeviceError(response, Thing::ThingErrorSetupFailed); verifyThingError(response, Thing::ThingErrorSetupFailed);
clientSpy.wait(200); clientSpy.wait(200);
@ -422,7 +422,7 @@ void TestLogging::actionLog()
found = false; found = false;
foreach (const QVariant &loggEntryAddedVariant, logEntryAddedVariants) { foreach (const QVariant &loggEntryAddedVariant, logEntryAddedVariants) {
QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap(); QVariantMap logEntry = loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap();
if (logEntry.value("deviceId").toUuid() == m_mockThingId) { if (logEntry.value("thingId").toUuid() == m_mockThingId) {
found = true; found = true;
// Make sure the notification contains all the stuff we expect // Make sure the notification contains all the stuff we expect
QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockFailingActionTypeId.toString()); QCOMPARE(logEntry.value("typeId").toUuid().toString(), mockFailingActionTypeId.toString());
@ -438,7 +438,7 @@ void TestLogging::actionLog()
// get this logentry with filter // get this logentry with filter
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions)); params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions));
params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger)); params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger));
@ -453,7 +453,7 @@ void TestLogging::actionLog()
// check different filters // check different filters
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions)); params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions));
params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger)); params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger));
params.insert("typeIds", QVariantList() << mockWithoutParamsActionTypeId); params.insert("typeIds", QVariantList() << mockWithoutParamsActionTypeId);
@ -465,7 +465,7 @@ void TestLogging::actionLog()
QVERIFY2(!logEntries.isEmpty(), "No logs received"); QVERIFY2(!logEntries.isEmpty(), "No logs received");
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions)); params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions));
params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger)); params.insert("eventTypes", QVariantList() << enumValueName(Logging::LoggingEventTypeTrigger));
params.insert("typeIds", QVariantList() << mockWithoutParamsActionTypeId << mockWithParamsActionTypeId << mockFailingActionTypeId); params.insert("typeIds", QVariantList() << mockWithoutParamsActionTypeId << mockWithParamsActionTypeId << mockFailingActionTypeId);
@ -480,21 +480,21 @@ void TestLogging::actionLog()
QCOMPARE(disableNotifications(), true); QCOMPARE(disableNotifications(), true);
} }
void TestLogging::deviceLogs() void TestLogging::thingLogs()
{ {
QVariantMap params; QVariantMap params;
params.insert("deviceClassId", parentMockThingClassId); params.insert("thingClassId", parentMockThingClassId);
params.insert("name", "Parent device"); params.insert("name", "Parent thing");
QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); QVariant response = injectAndWait("Integrations.AddThing", params);
verifyDeviceError(response); verifyThingError(response);
ThingId deviceId = ThingId(response.toMap().value("params").toMap().value("deviceId").toString()); ThingId thingId = ThingId(response.toMap().value("params").toMap().value("thingId").toString());
QVERIFY(!deviceId.isNull()); QVERIFY(!thingId.isNull());
// get this logentry with filter // get this logentry with filter
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId << deviceId); params.insert("thingIds", QVariantList() << m_mockThingId << thingId);
params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions) params.insert("loggingSources", QVariantList() << enumValueName(Logging::LoggingSourceActions)
<< enumValueName(Logging::LoggingSourceEvents) << enumValueName(Logging::LoggingSourceEvents)
<< enumValueName(Logging::LoggingSourceStates)); << enumValueName(Logging::LoggingSourceStates));
@ -530,21 +530,21 @@ void TestLogging::testDoubleValues()
discoveryParams.append(resultCountParam); discoveryParams.append(resultCountParam);
QVariantMap params; QVariantMap params;
params.insert("deviceClassId", displayPinMockThingClassId); params.insert("thingClassId", displayPinMockThingClassId);
params.insert("discoveryParams", discoveryParams); params.insert("discoveryParams", discoveryParams);
QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); QVariant response = injectAndWait("Integrations.DiscoverThings", params);
verifyDeviceError(response, Thing::ThingErrorNoError); verifyThingError(response, Thing::ThingErrorNoError);
// Pair device // Pair device
ThingDescriptorId descriptorId = ThingDescriptorId(response.toMap().value("params").toMap().value("deviceDescriptors").toList().first().toMap().value("id").toString()); ThingDescriptorId descriptorId = ThingDescriptorId(response.toMap().value("params").toMap().value("thingDescriptors").toList().first().toMap().value("id").toString());
params.clear(); params.clear();
params.insert("deviceClassId", displayPinMockThingClassId); params.insert("thingClassId", displayPinMockThingClassId);
params.insert("name", "Display pin mock device"); params.insert("name", "Display pin mock device");
params.insert("deviceDescriptorId", descriptorId.toString()); params.insert("thingDescriptorId", descriptorId.toString());
response = injectAndWait("Devices.PairDevice", params); response = injectAndWait("Integrations.PairThing", params);
verifyDeviceError(response); verifyThingError(response);
PairingTransactionId pairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString()); PairingTransactionId pairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString());
QString displayMessage = response.toMap().value("params").toMap().value("displayMessage").toString(); QString displayMessage = response.toMap().value("params").toMap().value("displayMessage").toString();
@ -554,11 +554,11 @@ void TestLogging::testDoubleValues()
params.clear(); params.clear();
params.insert("pairingTransactionId", pairingTransactionId.toString()); params.insert("pairingTransactionId", pairingTransactionId.toString());
params.insert("secret", "243681"); params.insert("secret", "243681");
response = injectAndWait("Devices.ConfirmPairing", params); response = injectAndWait("Integrations.ConfirmPairing", params);
verifyDeviceError(response); verifyThingError(response);
ThingId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); ThingId thingId(response.toMap().value("params").toMap().value("thingId").toString());
QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray)));
@ -569,12 +569,12 @@ void TestLogging::testDoubleValues()
actionParam.insert("value", value); actionParam.insert("value", value);
params.clear(); response.clear(); params.clear(); response.clear();
params.insert("deviceId", deviceId); params.insert("thingId", thingId);
params.insert("actionTypeId", displayPinMockDoubleActionTypeId.toString()); params.insert("actionTypeId", displayPinMockDoubleActionTypeId.toString());
params.insert("params", QVariantList() << actionParam); params.insert("params", QVariantList() << actionParam);
response = injectAndWait("Actions.ExecuteAction", params); response = injectAndWait("Integrations.ExecuteAction", params);
verifyDeviceError(response); verifyThingError(response);
notificationSpy.wait(); notificationSpy.wait();
QVariantList logNotificationsList = checkNotifications(notificationSpy, "Logging.LogEntryAdded"); QVariantList logNotificationsList = checkNotifications(notificationSpy, "Logging.LogEntryAdded");
@ -606,25 +606,25 @@ void TestLogging::testDoubleValues()
// Remove device // Remove device
params.clear(); params.clear();
params.insert("deviceId", deviceId.toString()); params.insert("thingId", thingId.toString());
response = injectAndWait("Devices.RemoveConfiguredDevice", params); response = injectAndWait("Integrations.RemoveThing", params);
verifyDeviceError(response); verifyThingError(response);
} }
void TestLogging::testHouseKeeping() void TestLogging::testHouseKeeping()
{ {
QVariantMap params; QVariantMap params;
params.insert("deviceClassId", mockThingClassId); params.insert("thingClassId", mockThingClassId);
params.insert("name", "TestDeviceToBeRemoved"); params.insert("name", "TestDeviceToBeRemoved");
QVariantList deviceParams; QVariantList thingParams;
QVariantMap httpParam; QVariantMap httpParam;
httpParam.insert("paramTypeId", mockThingHttpportParamTypeId); httpParam.insert("paramTypeId", mockThingHttpportParamTypeId);
httpParam.insert("value", 6667); httpParam.insert("value", 6667);
deviceParams.append(httpParam); thingParams.append(httpParam);
params.insert("deviceParams", deviceParams); params.insert("thingParams", thingParams);
QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); QVariant response = injectAndWait("Integrations.AddThing", params);
ThingId deviceId = ThingId(response.toMap().value("params").toMap().value("deviceId").toUuid()); ThingId thingId = ThingId(response.toMap().value("params").toMap().value("thingId").toUuid());
QVERIFY2(!deviceId.isNull(), "Something went wrong creating the device for testing."); QVERIFY2(!thingId.isNull(), "Something went wrong creating the thing for testing.");
// Trigger something that creates a logging entry // Trigger something that creates a logging entry
QNetworkAccessManager nam; QNetworkAccessManager nam;
@ -637,14 +637,14 @@ void TestLogging::testHouseKeeping()
waitForDBSync(); waitForDBSync();
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << deviceId); params.insert("thingIds", QVariantList() << thingId);
response = injectAndWait("Logging.GetLogEntries", params); response = injectAndWait("Logging.GetLogEntries", params);
QVERIFY2(response.toMap().value("params").toMap().value("logEntries").toList().count() > 0, "Couldn't find state change event in log..."); QVERIFY2(response.toMap().value("params").toMap().value("logEntries").toList().count() > 0, "Couldn't find state change event in log...");
// Manually delete this device from config // Manually delete this device from config
NymeaSettings settings(NymeaSettings::SettingsRoleThings); NymeaSettings settings(NymeaSettings::SettingsRoleThings);
settings.beginGroup("ThingConfig"); settings.beginGroup("ThingConfig");
settings.remove(deviceId.toString()); settings.remove(thingId.toString());
settings.endGroup(); settings.endGroup();
restartServer(); restartServer();
@ -652,7 +652,7 @@ void TestLogging::testHouseKeeping()
waitForDBSync(); waitForDBSync();
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << deviceId); params.insert("thingIds", QVariantList() << thingId);
response = injectAndWait("Logging.GetLogEntries", params); response = injectAndWait("Logging.GetLogEntries", params);
qCDebug(dcTests()) << qUtf8Printable(QJsonDocument::fromVariant(response).toJson()); qCDebug(dcTests()) << qUtf8Printable(QJsonDocument::fromVariant(response).toJson());
QVERIFY2(response.toMap().value("status").toString() == QString("success"), "GetLogEntries failed"); QVERIFY2(response.toMap().value("status").toString() == QString("success"), "GetLogEntries failed");
@ -676,12 +676,12 @@ void TestLogging::testLimits()
QVariantMap params; QVariantMap params;
params.insert("actionTypeId", mockWithParamsActionTypeId); params.insert("actionTypeId", mockWithParamsActionTypeId);
params.insert("deviceId", m_mockThingId); params.insert("thingId", m_mockThingId);
params.insert("params", actionParams); params.insert("params", actionParams);
// EXECUTE with params // EXECUTE with params
QVariant response = injectAndWait("Actions.ExecuteAction", params); QVariant response = injectAndWait("Integrations.ExecuteAction", params);
verifyDeviceError(response); verifyThingError(response);
} }
waitForDBSync(); waitForDBSync();
@ -711,14 +711,14 @@ void TestLogging::testLimits()
QCOMPARE(response.value("params").toMap().value("logEntries").toList().count(), 10); QCOMPARE(response.value("params").toMap().value("logEntries").toList().count(), 10);
} }
void TestLogging::removeDevice() void TestLogging::removeThing()
{ {
// enable notifications // enable notifications
enableNotifications({"Logging"}); enableNotifications({"Logging"});
// get this logentry with filter // get this logentry with filter
QVariantMap params; QVariantMap params;
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
QVariant response = injectAndWait("Logging.GetLogEntries", params); QVariant response = injectAndWait("Logging.GetLogEntries", params);
verifyLoggingError(response); verifyLoggingError(response);
QVariantList logEntries = response.toMap().value("params").toMap().value("logEntries").toList(); QVariantList logEntries = response.toMap().value("params").toMap().value("logEntries").toList();
@ -728,9 +728,9 @@ void TestLogging::removeDevice()
// Remove the device // Remove the device
params.clear(); params.clear();
params.insert("deviceId", m_mockThingId); params.insert("thingId", m_mockThingId);
response = injectAndWait("Devices.RemoveConfiguredDevice", params); response = injectAndWait("Integrations.RemoveThing", params);
verifyDeviceError(response); verifyThingError(response);
clientSpy.wait(200); clientSpy.wait(200);
QVariant notification = checkNotification(clientSpy, "Logging.LogDatabaseUpdated"); QVariant notification = checkNotification(clientSpy, "Logging.LogDatabaseUpdated");
@ -738,7 +738,7 @@ void TestLogging::removeDevice()
// verify that the logs from this device where removed from the db // verify that the logs from this device where removed from the db
params.clear(); params.clear();
params.insert("deviceIds", QVariantList() << m_mockThingId); params.insert("thingIds", QVariantList() << m_mockThingId);
response = injectAndWait("Logging.GetLogEntries", params); response = injectAndWait("Logging.GetLogEntries", params);
verifyLoggingError(response); verifyLoggingError(response);
logEntries = response.toMap().value("params").toMap().value("logEntries").toList(); logEntries = response.toMap().value("params").toMap().value("logEntries").toList();

View File

@ -45,11 +45,7 @@ protected slots:
void initTestCase(); void initTestCase();
private slots: private slots:
void testLogMigration();
void testLogfileRotation(); void testLogfileRotation();
void databaseSerializationTest_data();
void databaseSerializationTest();
}; };
TestLoggingLoading::TestLoggingLoading(QObject *parent): QObject(parent) TestLoggingLoading::TestLoggingLoading(QObject *parent): QObject(parent)
@ -65,28 +61,6 @@ void TestLoggingLoading::initTestCase()
QCoreApplication::instance()->setOrganizationName("nymea-test"); QCoreApplication::instance()->setOrganizationName("nymea-test");
} }
void TestLoggingLoading::testLogMigration()
{
// Create LogEngine with log db from resource file
QString temporaryDbName = "/tmp/nymea-test/nymead-v2.sqlite";
if (QFile::exists(temporaryDbName))
QVERIFY(QFile(temporaryDbName).remove());
// Copy v2 log db from resources to default settings path and set permissions
qDebug() << "Copy logdb v2 to" << temporaryDbName;
QVERIFY(QFile::copy(":/nymead-v2.sqlite", temporaryDbName));
QVERIFY(QFile::setPermissions(temporaryDbName, QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther));
LogEngine *logEngine = new LogEngine("QSQLITE", temporaryDbName);
// Check there is no rotated logfile
QVERIFY(!QFile::exists(temporaryDbName + ".1"));
delete logEngine;
QVERIFY(QFile(temporaryDbName).remove());
}
void TestLoggingLoading::testLogfileRotation() void TestLoggingLoading::testLogfileRotation()
{ {
// Create LogEngine with log db from resource file // Create LogEngine with log db from resource file
@ -115,46 +89,5 @@ void TestLoggingLoading::testLogfileRotation()
QVERIFY(QFile(rotatedDbName).remove()); QVERIFY(QFile(rotatedDbName).remove());
} }
void TestLoggingLoading::databaseSerializationTest_data()
{
QUuid uuid = QUuid("3782732b-61b4-48e8-8d6d-b5205159d7cd");
QVariantMap variantMap;
variantMap.insert("string", "value");
variantMap.insert("int", 5);
variantMap.insert("double", 3.14);
variantMap.insert("uuid", uuid);
QVariantList variantList;
variantList.append(variantMap);
variantList.append("String");
variantList.append(3.14);
variantList.append(uuid);
QTest::addColumn<QVariant>("value");
QTest::newRow("QString") << QVariant(QString("Hello"));
QTest::newRow("Integer") << QVariant((int)2);
QTest::newRow("Double") << QVariant((double)2.34);
QTest::newRow("Float") << QVariant((float)2.34);
QTest::newRow("QColor") << QVariant(QColor(0,255,128));
QTest::newRow("QByteArray") << QVariant(QByteArray::fromHex("01FF332F762A"));
QTest::newRow("QUuid") << QVariant(uuid);
QTest::newRow("QVariantMap") << QVariant(variantMap);
QTest::newRow("QVariantList") << QVariant(variantList);
}
void TestLoggingLoading::databaseSerializationTest()
{
QFETCH(QVariant, value);
QString serializedValue = LogValueTool::serializeValue(value);
QVariant deserializedValue = LogValueTool::deserializeValue(serializedValue);
qDebug() << "Stored:" << value;
qDebug() << "Loaded:" << deserializedValue;
QCOMPARE(deserializedValue, value);
}
#include "testloggingloading.moc" #include "testloggingloading.moc"
QTEST_MAIN(TestLoggingLoading) QTEST_MAIN(TestLoggingLoading)