From e8e8184add6d11f5783e3b305025237bdcb54264 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 14:23:36 +0100 Subject: [PATCH] unittest: data driven testing for tokens and prepareData ( failing ) --- src/colnod/syncmanager.cpp | 108 +-------------------- src/colnod/syncmanager.h | 8 +- test/auto/syncmanager/tst_syncmanager.cpp | 109 +++++++++++++++++++++- 3 files changed, 114 insertions(+), 111 deletions(-) diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 148a311..58e9ac3 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -92,7 +92,7 @@ bool SyncManager::startSynchronization() connect(this, &SyncManager::dataReady, [=](){ - prepareData(); + //prepareData(); connect(this, &SyncManager::dataProcessFinished, [=](){ @@ -305,7 +305,7 @@ std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared // Prepare data auto preparedData = std::make_unique(); preparedData->colnodData = cloneColnodDataToProcess; - preparedData->databaseData = databaseDataToProcess; + preparedData->databaseData = cloneDatabaseDataToProcess; return preparedData; } @@ -319,7 +319,7 @@ bool SyncManager::downloadData() qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; qInfo(syncmanager) << dash; - connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); + //connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); //connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); //database->downloadData(); //colnod->downloadData(); @@ -327,96 +327,6 @@ bool SyncManager::downloadData() return res; } -// finds conflicts -> changes on both sides (colnod and DB), apply newer change -bool SyncManager::prepareData() -{ - qInfo(syncmanager) << equals; - qInfo(syncmanager) << "PREPARING DATA -> BEGIN"; - qInfo(syncmanager) << dash; - qInfo(syncmanager) << "Resolve conflicts ( changes on same item on both Colnod and DB ):"; - qInfo(syncmanager) << dash; - - - Q_ASSERT(colnodData); - Q_ASSERT(databaseData); - - - // TODO: why copy data? - colnodDataToProcess = std::make_shared(*colnodData); - databaseDataToProcess = std::make_shared(*databaseData); - - QList conflicts; - QList alreadySynced; - - // check modifed tokens from colnod, dont want update token, if it was edited in db after or has been already synced - for (const auto &colnodToken : colnodDataToProcess->updatedTokens) { - if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) { - // updated in db later - if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) { - conflicts.append(colnodToken->id()); - } - continue; - } - auto token = database->getToken(colnodToken->id()); - if ( token ) - // alredy synced ( tokens are same ) - if (token == colnodToken) - alreadySynced.append(colnodToken->id()); - } - // remove tokens which should be not updated - for (const auto &id : conflicts) - colnodDataToProcess->updatedTokens.remove(id); - for (const auto &id : alreadySynced) - colnodDataToProcess->updatedTokens.remove(id); - - qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE TOO"; - qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; - - - - conflicts.clear(); - - // chech for already deleted ( in previous synced tokens were deleted from colnod, so it come to this sync but we dont want to sync it again - for (const auto &id : colnodDataToProcess->deletedTokens) { - if (database->isAlreadyDeleted(id)) { - conflicts.append(id); - } - } - for (const auto &id : conflicts) { - colnodDataToProcess->deletedTokens.removeOne(id); - } - - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ALREADY DELETED"; - qInfo(syncmanager) << dash; - - conflicts.clear(); - - // chech modified from db, remove token if it was edited in colnod later - for (const auto &databaseToken : databaseDataToProcess->updatedTokens) { - if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) { - if (databaseToken < colnodDataToProcess->updatedTokens.value(databaseToken->id())) - conflicts.append(databaseToken->id()); - } - else { - // restriction cauesed by colnod rest api - if (databaseToken->description() != "mobile") { - qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; - conflicts.append(databaseToken->id()); - } - } - } - for (const auto &id : conflicts) - colnodDataToProcess->updatedTokens.remove(id); - - qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN IN COLNOD TOO"; - qInfo(syncmanager) << dash; - - qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; - qInfo(syncmanager) << equals; - return true; -} bool SyncManager::processData() { @@ -454,15 +364,3 @@ void SyncManager::areDataReady() emit dataReady(); } } - -void SyncManager::saveColnodData(const std::shared_ptr &data) -{ - colnodData = data; - areDataReady(); -} - -void SyncManager::saveDatabaseData(const std::shared_ptr &data) -{ - databaseData = data; - areDataReady(); -} diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 267efc0..4276d7e 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -32,14 +32,12 @@ private: void initNewToken(const std::shared_ptr& token); bool downloadData(); - bool prepareData(); + //bool prepareData(); bool processData(); void updateLastUpdate(qint64 syncBegin); private: - Q_SLOT void saveColnodData(const std::shared_ptr &data); - Q_SLOT void saveDatabaseData(const std::shared_ptr &data); Q_SLOT void areDataReady(); signals: @@ -56,8 +54,8 @@ private: serversdk::DatabaseManager dbMan; Timestamp mlastSync; - std::shared_ptr colnodData; - std::shared_ptr databaseData; +// std::shared_ptr colnodData; +// std::shared_ptr databaseData; std::shared_ptr colnodDataToProcess; std::shared_ptr databaseDataToProcess; diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index 95a43ce..ff45e89 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -6,12 +6,37 @@ class SyncManagerTest : public QObject { Q_OBJECT +private: + std::shared_ptr tokenFromString(const QString &text); private slots: + void tokenFromString_test(); void sync_init_test(); void prepareData_test(); + void prepareData_tokens(); + void prepareData_tokens_data(); }; +std::shared_ptr SyncManagerTest::tokenFromString(const QString &text) +{ + auto split = text.split(","); + if (split.count() != 2) + return nullptr; + + auto token = std::make_shared(); + token->setId(split.first()); + token->setDescription("mobile"); + token->setLastUpdate(QDateTime::fromString(split.last(), "yyyyMMdd:HHmmss")); + return token; +} + +void SyncManagerTest::tokenFromString_test() +{ + auto token = tokenFromString("id1,20191010:232300"); + QCOMPARE(token->id(), QStringLiteral("id1")); + QCOMPARE(token->lastUpdate(), QDateTime::fromString("20191010:232300", "yyyyMMdd:HHmmss")); +} + void SyncManagerTest::sync_init_test() { SyncManager sync(true); @@ -22,14 +47,15 @@ void SyncManagerTest::sync_init_test() void SyncManagerTest::prepareData_test() { SyncManager sync(true); + QVERIFY(sync.databaseInitialization()); auto dbData = std::make_shared(); auto colnodData = std::make_shared(); auto token = std::make_shared(); + token->setDescription("mobile"); token->setId("id1"); dbData->updatedTokens.insert("id1", token); - auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); QVERIFY(oldPreparedData->databaseData->updatedTokens.contains("id1")); @@ -42,6 +68,87 @@ void SyncManagerTest::prepareData_test() QVERIFY(newPreparedData->databaseData->deletedSubjects.isEmpty()); } +void SyncManagerTest::prepareData_tokens() +{ + SyncManager sync(true); + QVERIFY(sync.databaseInitialization()); + + + + QFETCH(QString, db_token_updated); + QFETCH(QString, db_token_deleted); + QFETCH(QString, colnod_token_updated); + QFETCH(QString, colnod_token_deleted); + QFETCH(QString, expected_db_tokens_toupdate); + QFETCH(QString, expected_db_tokens_todelete); + QFETCH(QString, expected_colnod_tokens_toupdate); + QFETCH(QString, expected_colnod_tokens_todelete); + + // fake data + auto dbData = std::make_shared(); + auto colnodData = std::make_shared(); + + // Database + auto utoken = tokenFromString(db_token_updated); + if ( utoken ) + dbData->updatedTokens.insert(utoken->id(), utoken); + auto dtoken = tokenFromString(db_token_deleted); + if ( dtoken ) + dbData->deletedTokens.append(dtoken->id()); + + // Colnod + auto colnod_utoken = tokenFromString(colnod_token_updated); + if ( colnod_utoken ) + colnodData->updatedTokens.insert(colnod_utoken->id(), colnod_utoken); + auto colnod_dtoken = tokenFromString(colnod_token_deleted); + if ( colnod_dtoken ) + colnodData->deletedTokens.append(colnod_dtoken->id()); + + auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); + auto newPreparedData = sync.prepareDataNew(dbData, colnodData); + + QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); + QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); + QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); + QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + + QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); + QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); + QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); + QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + +} + +void SyncManagerTest::prepareData_tokens_data() +{ + QTest::addColumn("db_token_updated"); + QTest::addColumn("db_token_deleted"); + QTest::addColumn("colnod_token_updated"); + QTest::addColumn("colnod_token_deleted"); + QTest::addColumn("expected_db_tokens_toupdate"); + QTest::addColumn("expected_db_tokens_todelete"); + QTest::addColumn("expected_colnod_tokens_toupdate"); + QTest::addColumn("expected_colnod_tokens_todelete"); + + // in: db 1 new token + // out: 1 db token must be updated in colnod + QTest::newRow("db 1 update") << "id1,20191010:23:23:00" << "" + << "" << "" + // expected database: toupdate << todelete + << "id1" << "" + // expected colnod: toupdate << todelete + << "" << ""; + // in: id1 in database new/updated + // in: id1 deleted in colnod + // out: 1 colnod token must be deleted from database + QTest::newRow("delete 1 existing token in database") << "id1,20191010:23:23:00" << "" + << "" << "id1,20191010:23:23:00" + // expected database: toupdate << todelete + << "" << "id1" + // expected colnod: toupdate << todelete + << "" << ""; +} + QTEST_MAIN(SyncManagerTest) #include "tst_syncmanager.moc"