cleanup, fix last tests

This commit is contained in:
Michael Zanetti 2019-11-16 00:44:08 +01:00
parent 73812df269
commit c7dd26d525
7 changed files with 92 additions and 43 deletions

View File

@ -140,11 +140,11 @@ JsonReply* LoggingHandler::GetLogEntries(const QVariantMap &params) const
{ {
LogFilter filter = unpackLogFilter(params); LogFilter filter = unpackLogFilter(params);
LogEngineFetchJob *job = NymeaCore::instance()->logEngine()->logEntries(filter); LogEntriesFetchJob *job = NymeaCore::instance()->logEngine()->fetchLogEntries(filter);
JsonReply *reply = createAsyncReply("GetLogEntries"); JsonReply *reply = createAsyncReply("GetLogEntries");
connect(job, &LogEngineFetchJob::finished, reply, [this, reply, job, filter](){ connect(job, &LogEntriesFetchJob::finished, reply, [reply, job, filter](){
QVariantList entries; QVariantList entries;
foreach (const LogEntry &entry, job->results()) { foreach (const LogEntry &entry, job->results()) {

View File

@ -180,23 +180,19 @@ LogEngine::LogEngine(const QString &driver, const QString &dbName, const QString
/*! Destructs the \l{LogEngine}. */ /*! Destructs the \l{LogEngine}. */
LogEngine::~LogEngine() LogEngine::~LogEngine()
{ {
qWarning() << "Destroying logEngine";
// Process the job queue before allowing to shut down // Process the job queue before allowing to shut down
while (m_currentJob) { while (m_currentJob) {
qWarning() << "Waiting for job to finish... (" << m_jobQueue.count() << "jobs left in queue)"; qCDebug(dcLogEngine()) << "Waiting for job to finish... (" << m_jobQueue.count() << "jobs left in queue)";
m_jobWatcher.waitForFinished(); m_jobWatcher.waitForFinished();
// Make sure that the job queue is processes
// We can't call processQueue ourselves because thread synchronisation is done via queued connections
qApp->processEvents(); qApp->processEvents();
} }
qWarning() << "Done waiting";
qCDebug(dcLogEngine()) << "Closing Database"; qCDebug(dcLogEngine()) << "Closing Database";
m_db.close(); m_db.close();
} }
/*! Returns the list of \l{LogEntry}{LogEntries} of the database matching the given \a filter. LogEntriesFetchJob *LogEngine::fetchLogEntries(const LogFilter &filter)
\sa LogEntry, LogFilter
*/
LogEngineFetchJob* LogEngine::logEntries(const LogFilter &filter)
{ {
QList<LogEntry> results; QList<LogEntry> results;
QSqlQuery query(m_db); QSqlQuery query(m_db);
@ -224,7 +220,7 @@ LogEngineFetchJob* LogEngine::logEntries(const LogFilter &filter)
} }
DatabaseJob *job = new DatabaseJob(query); DatabaseJob *job = new DatabaseJob(query);
LogEngineFetchJob *fetchJob = new LogEngineFetchJob(this); LogEntriesFetchJob *fetchJob = new LogEntriesFetchJob(this);
connect(job, &DatabaseJob::finished, this, [this, job, fetchJob](){ connect(job, &DatabaseJob::finished, this, [this, job, fetchJob](){
fetchJob->deleteLater(); fetchJob->deleteLater();
@ -246,7 +242,7 @@ LogEngineFetchJob* LogEngine::logEntries(const LogFilter &filter)
entry.setEventType((Logging::LoggingEventType)job->query().value("loggingEventType").toInt()); entry.setEventType((Logging::LoggingEventType)job->query().value("loggingEventType").toInt());
entry.setActive(job->query().value("active").toBool()); entry.setActive(job->query().value("active").toBool());
fetchJob->addResult(entry); fetchJob->m_results.append(entry);
} }
qCDebug(dcLogEngine) << "Fetched" << fetchJob->results().count() << "entries for db query:" << job->query().executedQuery(); qCDebug(dcLogEngine) << "Fetched" << fetchJob->results().count() << "entries for db query:" << job->query().executedQuery();
fetchJob->finished(); fetchJob->finished();
@ -257,6 +253,32 @@ LogEngineFetchJob* LogEngine::logEntries(const LogFilter &filter)
return fetchJob; return fetchJob;
} }
DevicesFetchJob *LogEngine::fetchDevices()
{
QString queryString = QString("SELECT deviceId FROM entries WHERE deviceId != \"%1\" GROUP BY deviceId;").arg(QUuid().toString());
DatabaseJob *job = new DatabaseJob(queryString, m_db);
DevicesFetchJob *fetchJob = new DevicesFetchJob(this);
connect(job, &DatabaseJob::finished, this, [this, job, fetchJob](){
fetchJob->deleteLater();
if (job->query().lastError().type() != QSqlError::NoError) {
qCWarning(dcLogEngine()) << "Error fetching device entries from log database:" << m_db.lastError().driverText() << m_db.lastError().databaseText();
fetchJob->finished();
return;
}
if (!job->query().first()) {
fetchJob->finished();
return;
}
do {
fetchJob->m_results.append(DeviceId::fromUuid(job->query().value("deviceId").toUuid()));
} while (job->query().next());
fetchJob->finished();
});
return fetchJob;
}
void LogEngine::setMaxLogEntries(int maxLogEntries, int overflow) void LogEngine::setMaxLogEntries(int maxLogEntries, int overflow)
{ {
m_dbMaxSize = maxLogEntries; m_dbMaxSize = maxLogEntries;

View File

@ -39,7 +39,8 @@
namespace nymeaserver { namespace nymeaserver {
class DatabaseJob; class DatabaseJob;
class LogEngineFetchJob; class LogEntriesFetchJob;
class DevicesFetchJob;
class LogEngine: public QObject class LogEngine: public QObject
{ {
@ -48,7 +49,8 @@ public:
LogEngine(const QString &driver, const QString &dbName, const QString &hostname = QString("127.0.0.1"), const QString &username = QString(), const QString &password = QString(), int maxDBSize = 50000, QObject *parent = nullptr); LogEngine(const QString &driver, const QString &dbName, const QString &hostname = QString("127.0.0.1"), const QString &username = QString(), const QString &password = QString(), int maxDBSize = 50000, QObject *parent = nullptr);
~LogEngine(); ~LogEngine();
LogEngineFetchJob *logEntries(const LogFilter &filter = LogFilter()); LogEntriesFetchJob *fetchLogEntries(const LogFilter &filter = LogFilter());
DevicesFetchJob *fetchDevices();
void setMaxLogEntries(int maxLogEntries, int overflow); void setMaxLogEntries(int maxLogEntries, int overflow);
void clearDatabase(); void clearDatabase();
@ -122,24 +124,32 @@ private:
QSqlQuery m_query; QSqlQuery m_query;
}; };
class LogEngineFetchJob: public QObject class LogEntriesFetchJob: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
LogEngineFetchJob(QObject *parent): QObject(parent) {} LogEntriesFetchJob(QObject *parent): QObject(parent) {}
QList<LogEntry> results() { return m_results; } QList<LogEntry> results() { return m_results; }
signals: signals:
void finished(); void finished();
private: private:
void addResult(const LogEntry &entry) { m_results.append(entry); }
QList<LogEntry> m_results; QList<LogEntry> m_results;
friend class LogEngine; friend class LogEngine;
}; };
class DevicesFetchJob: public QObject
{
Q_OBJECT
public:
DevicesFetchJob(QObject *parent): QObject(parent) {}
QList<DeviceId> results() { return m_results; }
signals:
void finished();
private:
QList<DeviceId> m_results;
friend class LogEngine;
};
} }
#endif #endif

View File

@ -920,6 +920,29 @@ void NymeaCore::deviceManagerLoaded()
onDateTimeChanged(m_timeManager->currentDateTime()); onDateTimeChanged(m_timeManager->currentDateTime());
emit initialized(); emit initialized();
// Do some houskeeping...
qCDebug(dcApplication()) << "Starting housekeeping...";
QDateTime startTime = QDateTime::currentDateTime();
DevicesFetchJob *job = m_logger->fetchDevices();
connect(job, &DevicesFetchJob::finished, this, [this, job, startTime](){
foreach (const DeviceId &deviceId, job->results()) {
if (!m_deviceManager->findConfiguredDevice(deviceId)) {
qCDebug(dcApplication()) << "Cleaning stale device entries from log DB for device id" << deviceId;
m_logger->removeDeviceLogs(deviceId);
}
}
qCDebug(dcApplication()) << "Housekeeping done in" << startTime.msecsTo(QDateTime::currentDateTime()) << "ms.";
});
foreach (const DeviceId &deviceId, m_ruleEngine->devicesInRules()) {
if (!m_deviceManager->findConfiguredDevice(deviceId)) {
qCDebug(dcApplication()) << "Cleaning stale rule entries for device id" << deviceId;
foreach (const RuleId &ruleId, m_ruleEngine->findRules(deviceId)) {
m_ruleEngine->removeDeviceFromRule(ruleId, deviceId);
}
}
}
} }
} }

View File

@ -991,18 +991,16 @@ void TestJSONRPC::stateChangeEmitsNotifications()
break; break;
} }
} }
if (!found)
qDebug() << QJsonDocument::fromVariant(stateChangedVariants).toJson();
QVERIFY2(found, "Could not find the correct Devices.StateChanged notification"); QVERIFY2(found, "Could not find the correct Devices.StateChanged notification");
clientSpy.wait();
// Make sure the logg notification contains all the stuff we expect // Make sure the logg notification contains all the stuff we expect
QVariantList loggEntryAddedVariants = checkNotifications(clientSpy, "Logging.LogEntryAdded"); QVariantList logEntryAddedVariants = checkNotifications(clientSpy, "Logging.LogEntryAdded");
QVERIFY2(!loggEntryAddedVariants.isEmpty(), "Did not get Logging.LogEntryAdded notification."); QVERIFY2(!logEntryAddedVariants.isEmpty(), "Did not get Logging.LogEntryAdded notification.");
qDebug() << "got" << loggEntryAddedVariants.count() << "Logging.LogEntryAdded notifications";
found = false; found = false;
foreach (const QVariant &loggEntryAddedVariant, loggEntryAddedVariants) { foreach (const QVariant &loggEntryAddedVariant, logEntryAddedVariants) {
if (loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap().value("typeId").toUuid() == stateTypeId) { if (loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap().value("typeId").toUuid() == stateTypeId) {
found = true; found = true;
QCOMPARE(loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap().value("source").toString(), QString("LoggingSourceStates")); QCOMPARE(loggEntryAddedVariant.toMap().value("params").toMap().value("logEntry").toMap().value("source").toString(), QString("LoggingSourceStates"));
@ -1010,8 +1008,6 @@ void TestJSONRPC::stateChangeEmitsNotifications()
break; break;
} }
} }
if (!found)
qDebug() << QJsonDocument::fromVariant(loggEntryAddedVariants).toJson();
QVERIFY2(found, "Could not find the corresponding Logging.LogEntryAdded notification"); QVERIFY2(found, "Could not find the corresponding Logging.LogEntryAdded notification");
@ -1020,7 +1016,6 @@ void TestJSONRPC::stateChangeEmitsNotifications()
QVariantList eventTriggeredVariants = checkNotifications(clientSpy, "Events.EventTriggered"); QVariantList eventTriggeredVariants = checkNotifications(clientSpy, "Events.EventTriggered");
QVERIFY2(!eventTriggeredVariants.isEmpty(), "Did not get Events.EventTriggered notification."); QVERIFY2(!eventTriggeredVariants.isEmpty(), "Did not get Events.EventTriggered notification.");
found = false; found = false;
qDebug() << "got" << eventTriggeredVariants.count() << "Events.EventTriggered notifications";
foreach (const QVariant &eventTriggeredVariant, eventTriggeredVariants) { foreach (const QVariant &eventTriggeredVariant, eventTriggeredVariants) {
if (eventTriggeredVariant.toMap().value("params").toMap().value("event").toMap().value("eventTypeId").toUuid() == stateTypeId) { if (eventTriggeredVariant.toMap().value("params").toMap().value("event").toMap().value("eventTypeId").toUuid() == stateTypeId) {
found = true; found = true;
@ -1028,8 +1023,6 @@ void TestJSONRPC::stateChangeEmitsNotifications()
break; break;
} }
} }
if (!found)
qDebug() << QJsonDocument::fromVariant(eventTriggeredVariants).toJson();
QVERIFY2(found, "Could not find the corresponding Events.EventTriggered notification"); QVERIFY2(found, "Could not find the corresponding Events.EventTriggered notification");
@ -1108,6 +1101,7 @@ void TestJSONRPC::testPushButtonAuth()
void TestJSONRPC::testPushButtonAuthInterrupt() void TestJSONRPC::testPushButtonAuthInterrupt()
{ {
enableNotifications({});
PushButtonAgent pushButtonAgent; PushButtonAgent pushButtonAgent;
pushButtonAgent.init(); pushButtonAgent.init();

View File

@ -82,8 +82,8 @@ void TestLoggingDirect::benchmarkDB()
engine->setMaxLogEntries(prefill, overflow); engine->setMaxLogEntries(prefill, overflow);
engine->setMaxLogEntries(maxSize, overflow); engine->setMaxLogEntries(maxSize, overflow);
LogEngineFetchJob *job = engine->logEntries(); LogEntriesFetchJob *job = engine->fetchLogEntries();
QSignalSpy fetchSpy(job, &LogEngineFetchJob::finished); QSignalSpy fetchSpy(job, &LogEntriesFetchJob::finished);
fetchSpy.wait(); fetchSpy.wait();
QList<LogEntry> entries = job->results(); QList<LogEntry> entries = job->results();
@ -93,8 +93,8 @@ void TestLoggingDirect::benchmarkDB()
engine->logSystemEvent(QDateTime::currentDateTime(), true); engine->logSystemEvent(QDateTime::currentDateTime(), true);
} }
job = engine->logEntries(); job = engine->fetchLogEntries();
QSignalSpy fetchSpy2(job, &LogEngineFetchJob::finished); QSignalSpy fetchSpy2(job, &LogEntriesFetchJob::finished);
fetchSpy2.wait(); fetchSpy2.wait();
entries = job->results(); entries = job->results();
@ -106,8 +106,8 @@ void TestLoggingDirect::benchmarkDB()
} }
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
job = engine->logEntries(); job = engine->fetchLogEntries();
QSignalSpy fetchSpy3(job, &LogEngineFetchJob::finished); QSignalSpy fetchSpy3(job, &LogEntriesFetchJob::finished);
fetchSpy3.wait(); fetchSpy3.wait();
entries = job->results(); entries = job->results();

View File

@ -2313,8 +2313,8 @@ void TestRules::testStateBasedAction()
filter.addDeviceId(m_mockDeviceId); filter.addDeviceId(m_mockDeviceId);
filter.addTypeId(mockWithParamsActionTypeId); filter.addTypeId(mockWithParamsActionTypeId);
LogEngineFetchJob *job = NymeaCore::instance()->logEngine()->logEntries(filter); LogEntriesFetchJob *job = NymeaCore::instance()->logEngine()->fetchLogEntries(filter);
QSignalSpy fetchSpy(job, &LogEngineFetchJob::finished); QSignalSpy fetchSpy(job, &LogEntriesFetchJob::finished);
fetchSpy.wait(); fetchSpy.wait();
QList<LogEntry> entries = job->results(); QList<LogEntry> entries = job->results();
qCDebug(dcTests()) << "Log entries:" << entries; qCDebug(dcTests()) << "Log entries:" << entries;
@ -2335,8 +2335,8 @@ void TestRules::testStateBasedAction()
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 1);
reply->deleteLater(); reply->deleteLater();
job = NymeaCore::instance()->logEngine()->logEntries(filter); job = NymeaCore::instance()->logEngine()->fetchLogEntries(filter);
QSignalSpy fetchSpy2(job, &LogEngineFetchJob::finished); QSignalSpy fetchSpy2(job, &LogEntriesFetchJob::finished);
fetchSpy2.wait(); fetchSpy2.wait();
entries = job->results(); entries = job->results();