testing: syncing of parent/child items (for BMC #22329)

Client::Source::*::testLinkedItems* tested local storage operations
for events sharing the same UID. For syncing, only testItems had
a little bit like it. This commit adds more tests specifically
designed to exercise corner cases of syncing such linked items:
- sync parent, then sync with child and other event added on different
  sides (corner case in CalDAV change tracking, BMC #22329)
- sync child
- sync child, sync parent later
This commit is contained in:
Patrick Ohly 2011-08-05 08:33:45 +02:00
parent 3799ddf1d8
commit fef657a7da
2 changed files with 159 additions and 1 deletions

View File

@ -1684,6 +1684,16 @@ void SyncTests::addTests(bool isFirstSource) {
ADD_TEST(SyncTests, testComplexRefreshFromServerSemantic);
ADD_TEST(SyncTests, testDeleteBothSides);
if (config.parentItem &&
config.childItem) {
ADD_TEST(SyncTests, testLinkedItemsParentChild);
if (config.linkedItemsRelaxedSemantic) {
ADD_TEST(SyncTests, testLinkedItemsChild);
ADD_TEST(SyncTests, testLinkedItemsChildParent);
}
}
if (config.updateItem) {
ADD_TEST(SyncTests, testUpdate);
}
@ -2941,6 +2951,151 @@ void SyncTests::testDeleteBothSides()
}
}
/**
* - adds parent on client A
* - syncs A
* - adds unrelated item via client B (necessary to trigger corner cases in
* change tracking, see BMC #22329)
* - syncs B
* - adds child on client A
* - syncs A and B
* - compares
*/
void SyncTests::testLinkedItemsParentChild()
{
source_it it;
// clean server, client A and client B
deleteAll();
accessClientB->refreshClient();
// create and copy parent item
for (it = sources.begin(); it != sources.end(); ++it) {
CPPUNIT_ASSERT(it->second->config.parentItem);
TestingSyncSourcePtr source;
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.parentItem,
it->second->config.itemType));
}
doSync("send-parent",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(0,0,0, 1,0,0, true, SYNC_TWO_WAY)));
// create independent item, refresh client B and server
for (it = accessClientB->sources.begin(); it != accessClientB->sources.end(); ++it) {
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.insertItem,
it->second->config.itemType));
}
accessClientB->doSync("recv-parent",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,0,0, 1,0,0, true, SYNC_TWO_WAY)));
// add child on client A
for (it = sources.begin(); it != sources.end(); ++it) {
CPPUNIT_ASSERT(it->second->config.childItem);
TestingSyncSourcePtr source;
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.childItem,
it->second->config.itemType));
}
// parent may or may not be considered updated
doSync("send-child",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,0,0, 1,-1,0, true, SYNC_TWO_WAY)));
// parent may or may not be considered updated here
accessClientB->doSync("recv-child",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,-1,0, 0,0,0, true, SYNC_TWO_WAY)));
// final comparison
compareDatabases();
}
/**
* - adds child on client A
* - syncs A
* - syncs B
* - compare
*/
void SyncTests::testLinkedItemsChild()
{
source_it it;
// clean server, client A and client B
deleteAll();
accessClientB->refreshClient();
// create and copy child item
for (it = sources.begin(); it != sources.end(); ++it) {
CPPUNIT_ASSERT(it->second->config.childItem);
TestingSyncSourcePtr source;
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.childItem,
it->second->config.itemType));
}
doSync("send",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(0,0,0, 1,0,0, true, SYNC_TWO_WAY)));
accessClientB->doSync("recv",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,0,0, 0,0,0, true, SYNC_TWO_WAY)));
// final comparison
compareDatabases();
}
/**
* - adds child on client A
* - syncs A and B
* - adds parent on client A
* - syncs A and B
* - compares
*/
void SyncTests::testLinkedItemsChildParent()
{
source_it it;
// clean server, client A and client B
deleteAll();
accessClientB->refreshClient();
// create and copy child item
for (it = sources.begin(); it != sources.end(); ++it) {
CPPUNIT_ASSERT(it->second->config.childItem);
TestingSyncSourcePtr source;
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.childItem,
it->second->config.itemType));
}
doSync("send-child",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(0,0,0, 1,0,0, true, SYNC_TWO_WAY)));
accessClientB->doSync("recv-child",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,0,0, 0,0,0, true, SYNC_TWO_WAY)));
// add parent on client A
for (it = sources.begin(); it != sources.end(); ++it) {
CPPUNIT_ASSERT(it->second->config.parentItem);
TestingSyncSourcePtr source;
CPPUNIT_ASSERT_NO_THROW(it->second->insert(it->second->createSourceA,
it->second->config.parentItem,
it->second->config.itemType));
}
// child may or may not be considered updated
doSync("send-parent",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(0,0,0, 1,-1,0, true, SYNC_TWO_WAY)));
// child may or may not be considered updated here
accessClientB->doSync("recv-parent",
SyncOptions(SYNC_TWO_WAY,
CheckSyncReport(1,-1,0, 0,0,0, true, SYNC_TWO_WAY)));
// final comparison
compareDatabases();
}
/**
* implements testMaxMsg(), testLargeObject(), testLargeObjectEncoded()
@ -4419,7 +4574,7 @@ void ClientTest::getTestData(const char *type, Config &config)
"SUMMARY:Recurring\n"
"DESCRIPTION:recurs each Monday\\, 10 times\n"
"CLASS:PUBLIC\n"
"RRULE:FREQ=WEEKLY;COUNT=10;INTERVAL=1;BYDAY=SU\n"
"RRULE:FREQ=WEEKLY;UNTIL=20080608T070000Z;INTERVAL=1;BYDAY=SU\n"
"CREATED:20080407T193241\n"
"LAST-MODIFIED:20080407T193241Z\n"
"END:VEVENT\n"

View File

@ -751,6 +751,9 @@ protected:
virtual void testSlowSyncSemantic();
virtual void testComplexRefreshFromServerSemantic();
virtual void testDeleteBothSides();
virtual void testLinkedItemsParentChild();
virtual void testLinkedItemsChild();
virtual void testLinkedItemsChildParent();
virtual void doInterruptResume(int changes,
boost::shared_ptr<TransportWrapper> wrapper);