@@ -15,6 +15,8 @@ private Q_SLOTS:
1515
1616 void testPrepareData ();
1717 void testAddAccount ();
18+ void testLiveSync ();
19+ void testPassiveSync ();
1820
1921Q_SIGNALS:
2022 void unlock ();
@@ -33,6 +35,8 @@ private Q_SLOTS:
3335
3436void IntegrationTest::initTestCase ()
3537{
38+ // QLoggingCategory::setFilterRules(QStringLiteral("qtdatasync.*.debug=true"));
39+
3640 QByteArray confPath { SETUP_FILE };
3741 QVERIFY (QFile::exists (QString::fromUtf8 (confPath)));
3842 qputenv (" QDSAPP_CONFIG_FILE" , confPath);
@@ -99,13 +103,15 @@ void IntegrationTest::cleanupTestCase()
99103 sync1 = nullptr ;
100104 delete acc1;
101105 acc1 = nullptr ;
106+ Setup::removeSetup (QStringLiteral (" setup1" ), true );
107+
102108 delete store2;
103109 store2 = nullptr ;
104110 delete sync2;
105111 sync2 = nullptr ;
106112 delete acc2;
107113 acc2 = nullptr ;
108- Setup::removeSetup (DefaultSetup , true );
114+ Setup::removeSetup (QStringLiteral ( " setup2 " ) , true );
109115
110116 // send a signal to stop
111117#ifdef Q_OS_UNIX
@@ -262,6 +268,202 @@ void IntegrationTest::testAddAccount()
262268 }
263269}
264270
271+ void IntegrationTest::testLiveSync ()
272+ {
273+ try {
274+ QSignalSpy error1Spy (sync1, &SyncManager::lastErrorChanged);
275+ QSignalSpy error2Spy (sync2, &SyncManager::lastErrorChanged);
276+ QSignalSpy dataSpy (store2, &DataTypeStoreBase::dataChanged);
277+ QSignalSpy sync1Spy (sync1, &SyncManager::syncStateChanged);
278+ QSignalSpy sync2Spy (sync2, &SyncManager::syncStateChanged);
279+ QSignalSpy unlockSpy (this , &IntegrationTest::unlock);
280+
281+ // sync data from 1
282+ for (auto i = 20 ; i < 40 ; i++)
283+ store1->save (TestLib::generateData (i));
284+ sync1->runOnSynchronized ([this ](SyncManager::SyncState s) {
285+ emit unlock ();
286+ QCOMPARE (s, SyncManager::Synchronized);
287+ }, false );
288+ QVERIFY (sync1Spy.wait ());
289+ QVERIFY (sync1Spy.size () > 0 );
290+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Uploading);
291+ QVERIFY (unlockSpy.wait ());
292+ QCOMPARE (sync1Spy.size (), 1 );
293+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Synchronized);
294+
295+ // sync data to 2
296+ sync2->runOnDownloaded ([this ](SyncManager::SyncState s) {
297+ emit unlock ();
298+ QCOMPARE (s, SyncManager::Synchronized);
299+ }, false );
300+ if (sync2Spy.isEmpty ())
301+ QVERIFY (sync2Spy.wait ());
302+ QVERIFY (sync2Spy.size () > 0 );
303+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Downloading);
304+ QVERIFY (unlockSpy.wait ());
305+ QVERIFY (sync2Spy.size () > 0 );
306+ QCOMPARE (sync2Spy.last ()[0 ].toInt (), SyncManager::Synchronized);
307+
308+ // verify data changes
309+ QCOMPARE (dataSpy.size (), 20 );
310+ QStringList keys;
311+ foreach (auto sig, QList<QList<QVariant>>(dataSpy))
312+ keys.append (sig[0 ].toString ());
313+ QCOMPAREUNORDERED (keys, TestLib::generateDataKeys (20 , 39 ));
314+
315+ QVERIFY (!unlockSpy.wait ());
316+ QVERIFY (error1Spy.isEmpty ());
317+ QVERIFY (error2Spy.isEmpty ());
318+ } catch (std::exception &e) {
319+ QFAIL (e.what ());
320+ }
321+ }
322+
323+ void IntegrationTest::testPassiveSync ()
324+ {
325+ try {
326+ QSignalSpy error1Spy (sync1, &SyncManager::lastErrorChanged);
327+ QSignalSpy error2Spy (sync2, &SyncManager::lastErrorChanged);
328+ QSignalSpy data1Spy (store1, &DataTypeStoreBase::dataChanged);
329+ QSignalSpy data2Spy (store2, &DataTypeStoreBase::dataChanged);
330+ QSignalSpy enabled1Spy (sync1, &SyncManager::syncEnabledChanged);
331+ QSignalSpy enabled2Spy (sync2, &SyncManager::syncEnabledChanged);
332+ QSignalSpy sync1Spy (sync1, &SyncManager::syncStateChanged);
333+ QSignalSpy sync2Spy (sync2, &SyncManager::syncStateChanged);
334+ QSignalSpy unlockSpy (this , &IntegrationTest::unlock);
335+
336+ // disable 1
337+ sync1->setSyncEnabled (false );
338+ QVERIFY (enabled1Spy.wait ());
339+ QCOMPARE (enabled1Spy.size (), 1 );
340+ QCOMPARE (enabled1Spy.takeFirst ()[0 ].toBool (), false );
341+ // wait for disconnected
342+ if (sync1Spy.isEmpty ())
343+ QVERIFY (sync1Spy.wait ());
344+ QCOMPARE (sync1Spy.size (), 1 );
345+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Disconnected);
346+ // disable 2
347+ sync2->setSyncEnabled (false );
348+ QVERIFY (enabled2Spy.wait ());
349+ QCOMPARE (enabled2Spy.size (), 1 );
350+ QCOMPARE (enabled2Spy.takeFirst ()[0 ].toBool (), false );
351+ // wait for disconnected
352+ if (sync2Spy.isEmpty ())
353+ QVERIFY (sync2Spy.wait ());
354+ QCOMPARE (sync2Spy.size (), 1 );
355+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Disconnected);
356+
357+ // sync data from 2
358+ for (auto i = 20 ; i < 30 ; i++)
359+ store2->remove (TestLib::generateDataKey (i));
360+ sync2->runOnSynchronized ([this ](SyncManager::SyncState s) {
361+ emit unlock ();
362+ QCOMPARE (s, SyncManager::Disconnected);
363+ }, false );
364+ QVERIFY (unlockSpy.wait ());
365+
366+ // enable sync
367+ sync2->setSyncEnabled (true );
368+ QVERIFY (enabled2Spy.wait ());
369+ QCOMPARE (enabled2Spy.size (), 1 );
370+ QCOMPARE (enabled2Spy.takeFirst ()[0 ].toBool (), true );
371+ // wait for init
372+ QVERIFY (sync2Spy.wait ());
373+ QVERIFY (sync2Spy.size () > 0 );
374+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Initializing);
375+ // wait for uploading
376+ if (sync2Spy.isEmpty ())
377+ QVERIFY (sync2Spy.wait ());
378+ QVERIFY (sync2Spy.size () > 0 );
379+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Uploading);
380+ // wait for synced
381+ sync2->runOnSynchronized ([this ](SyncManager::SyncState s) {
382+ emit unlock ();
383+ QCOMPARE (s, SyncManager::Synchronized);
384+ }, false );
385+ QVERIFY (unlockSpy.wait ());
386+ QCOMPARE (sync2Spy.size (), 1 );
387+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Synchronized);
388+
389+ // sync data from and to 1
390+ for (auto i = 30 ; i < 40 ; i++)
391+ store1->remove (TestLib::generateDataKey (i));
392+ sync1->runOnSynchronized ([this ](SyncManager::SyncState s) {
393+ emit unlock ();
394+ QCOMPARE (s, SyncManager::Disconnected);
395+ }, false );
396+ QVERIFY (unlockSpy.wait ());
397+
398+ // enable sync
399+ sync1->setSyncEnabled (true );
400+ QVERIFY (enabled1Spy.wait ());
401+ QCOMPARE (enabled1Spy.size (), 1 );
402+ QCOMPARE (enabled1Spy.takeFirst ()[0 ].toBool (), true );
403+ // wait for init
404+ QVERIFY (sync1Spy.wait ());
405+ QVERIFY (sync1Spy.size () > 0 );
406+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Initializing);
407+ // wait for downloading
408+ if (sync1Spy.isEmpty ())
409+ QVERIFY (sync1Spy.wait ());
410+ QVERIFY (sync1Spy.size () > 0 );
411+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Downloading);
412+ unlockSpy.clear ();
413+ sync1->runOnDownloaded ([this ](SyncManager::SyncState s) {
414+ emit unlock ();
415+ QCOMPARE (s, SyncManager::Uploading);
416+ }, false );
417+ sync1->runOnSynchronized ([this ](SyncManager::SyncState s) {
418+ emit unlock ();
419+ QCOMPARE (s, SyncManager::Synchronized);
420+ }, false );
421+ // wait for uploading
422+ if (sync1Spy.isEmpty ())
423+ QVERIFY (sync1Spy.wait ());
424+ QVERIFY (sync1Spy.size () > 0 );
425+ QCOMPARE (sync1Spy.takeFirst ()[0 ].toInt (), SyncManager::Uploading);
426+ // wait for synced
427+ QVERIFY (unlockSpy.wait ());
428+ if (unlockSpy.size () != 2 )
429+ QVERIFY (unlockSpy.wait ());
430+ QVERIFY (sync1Spy.size () > 0 );
431+ QCOMPARE (sync1Spy.last ()[0 ].toInt (), SyncManager::Synchronized);
432+
433+ // sync data to 2 again
434+ sync2->runOnSynchronized ([this ](SyncManager::SyncState s) {
435+ emit unlock ();
436+ QCOMPARE (s, SyncManager::Synchronized);
437+ }, false );
438+ if (sync2Spy.isEmpty ())
439+ QVERIFY (sync2Spy.wait ());
440+ QVERIFY (sync2Spy.size () > 0 );
441+ QCOMPARE (sync2Spy.takeFirst ()[0 ].toInt (), SyncManager::Downloading);
442+ QVERIFY (unlockSpy.wait ());
443+ QVERIFY (sync2Spy.size () > 0 );
444+ QCOMPARE (sync2Spy.last ()[0 ].toInt (), SyncManager::Synchronized);
445+
446+ // verify data changes on 1
447+ QCOMPARE (data1Spy.size (), 20 );
448+ QStringList keys;
449+ foreach (auto sig, QList<QList<QVariant>>(data1Spy))
450+ keys.append (sig[0 ].toString ());
451+ QCOMPAREUNORDERED (keys, TestLib::generateDataKeys (20 , 39 ));
452+ // and on 2
453+ QCOMPARE (data2Spy.size (), 20 );
454+ keys.clear ();
455+ foreach (auto sig, QList<QList<QVariant>>(data2Spy))
456+ keys.append (sig[0 ].toString ());
457+ QCOMPAREUNORDERED (keys, TestLib::generateDataKeys (20 , 39 ));
458+
459+ QVERIFY (!unlockSpy.wait ());
460+ QVERIFY (error1Spy.isEmpty ());
461+ QVERIFY (error2Spy.isEmpty ());
462+ } catch (std::exception &e) {
463+ QFAIL (e.what ());
464+ }
465+ }
466+
265467QTEST_MAIN (IntegrationTest)
266468
267469#include " tst_integration.moc"
0 commit comments