testing: added Client::Source::*::testLinkedSources
The WebDAV backend must support different kinds of items in the same collection. The new testLinkedSources covers this by adding, updating and deleting an item of one kind and checking that other sources referencing the same database do not see these changes. This test must be activated for a specific source by adding links to other sources using the same database. A separate commit will do that for WebDAV.
This commit is contained in:
parent
497a9bec74
commit
c1a705169d
|
@ -296,6 +296,7 @@ public:
|
|||
config.m_createSourceA = createSource;
|
||||
config.m_createSourceB = createSource;
|
||||
config.m_sourceName = test->m_configName.c_str();
|
||||
config.m_linkedSources = test->m_linkedSources;
|
||||
|
||||
test->updateConfig(config);
|
||||
}
|
||||
|
|
|
@ -485,6 +485,15 @@ struct ClientTestConfig {
|
|||
*/
|
||||
boost::function<void (std::string &)> m_update;
|
||||
boost::function<void (std::string &)> m_genericUpdate;
|
||||
|
||||
/**
|
||||
* A list of m_sourceName values of other ClientTestConfigs
|
||||
* which share the same database. Normally, sources are tested in
|
||||
* isolation, but for such linked sources we also need to test
|
||||
* interdependencies, in particular regarding change tracking and
|
||||
* item listing.
|
||||
*/
|
||||
std::list<std::string> m_linkedSources;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -561,6 +570,15 @@ class RegisterSyncSourceTest
|
|||
|
||||
const string m_configName;
|
||||
const string m_testCaseName;
|
||||
|
||||
/**
|
||||
* A list of m_configName values of other RegisterSyncSourceTest
|
||||
* which share the same database. Normally, sources are tested in
|
||||
* isolation, but for such linked sources we also need to test
|
||||
* interdependencies, in particular regarding change tracking and
|
||||
* item listing.
|
||||
*/
|
||||
std::list<std::string> m_linkedSources;
|
||||
};
|
||||
|
||||
class TestRegistry : public vector<const RegisterSyncSourceTest *>
|
||||
|
|
|
@ -266,6 +266,9 @@ class TestingSyncSourcePtr : public std::auto_ptr<TestingSyncSource>
|
|||
|
||||
public:
|
||||
TestingSyncSourcePtr() : m_active(false) {}
|
||||
TestingSyncSourcePtr(const TestingSyncSourcePtr &other) : m_active(false) {
|
||||
CPPUNIT_ASSERT(!other.get());
|
||||
}
|
||||
~TestingSyncSourcePtr()
|
||||
{
|
||||
// We can skip the full cleanup if the test has already failed.
|
||||
|
@ -444,6 +447,10 @@ void LocalTests::addTests() {
|
|||
if (config.m_createSourceB) {
|
||||
ADD_TEST(LocalTests, testChanges);
|
||||
ADD_TEST(LocalTests, testChangesMultiCycles);
|
||||
|
||||
if (!config.m_linkedSources.empty()) {
|
||||
ADD_TEST(LocalTests, testLinkedSources);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,6 +1277,115 @@ void LocalTests::testChangesMultiCycles()
|
|||
doChanges(true);
|
||||
}
|
||||
|
||||
// Make changes in one source and verify that other linked
|
||||
// sources do not see and report any changes in their view
|
||||
// of the shared database. Source A of the other sources
|
||||
// is created once and is restarted, source B is created
|
||||
// from scratch after each change.
|
||||
void LocalTests::testLinkedSources()
|
||||
{
|
||||
// make changes in each of the sources (doesn't have t be
|
||||
// the current one)
|
||||
BOOST_FOREACH (LocalTests *main, m_linkedSources) {
|
||||
CLIENT_TEST_LOG("making changes in %s", main->getSourceName().c_str());
|
||||
|
||||
// first delete via *all* sources
|
||||
BOOST_FOREACH (LocalTests *test, m_linkedSources) {
|
||||
CLIENT_TEST_LOG("clean via source A of %s", test->getSourceName().c_str());
|
||||
CT_ASSERT_NO_THROW(test->deleteAll(test->createSourceA));
|
||||
}
|
||||
|
||||
std::map<std::string, TestingSyncSourcePtr> sourcesA;
|
||||
BOOST_FOREACH (LocalTests *test, m_linkedSources) {
|
||||
if (test == main) {
|
||||
continue;
|
||||
}
|
||||
TestingSyncSourcePtr &source = sourcesA[test->getSourceName()];
|
||||
CLIENT_TEST_LOG("creating source A of %s", test->getSourceName().c_str());
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(test->createSourceA()));
|
||||
CT_ASSERT_NO_THROW(source.stopAccess());
|
||||
}
|
||||
|
||||
// insert one item
|
||||
CLIENT_TEST_LOG("inserting into %s", main->getSourceName().c_str());
|
||||
CT_ASSERT_NO_THROW(main->testSimpleInsert());
|
||||
BOOST_FOREACH (LocalTests *test, m_linkedSources) {
|
||||
if (test == main) {
|
||||
continue;
|
||||
}
|
||||
TestingSyncSourcePtr &source = sourcesA[test->getSourceName()];
|
||||
CLIENT_TEST_LOG("checking %s after insertion into %s",
|
||||
test->getSourceName().c_str(),
|
||||
main->getSourceName().c_str());
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.startAccess());
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.stopAccess());
|
||||
|
||||
TestingSyncSourcePtr sourceB;
|
||||
SOURCE_ASSERT_NO_FAILURE(sourceB.get(), sourceB.reset(test->createSourceB()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countNewItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countUpdatedItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countDeletedItems(sourceB.get()));
|
||||
}
|
||||
|
||||
// update one item
|
||||
CLIENT_TEST_LOG("updating in %s", main->getSourceName().c_str());
|
||||
CT_ASSERT_NO_THROW(main->update(main->createSourceA, main->config.m_updateItem));
|
||||
BOOST_FOREACH (LocalTests *test, m_linkedSources) {
|
||||
if (test == main) {
|
||||
continue;
|
||||
}
|
||||
TestingSyncSourcePtr &source = sourcesA[test->getSourceName()];
|
||||
CLIENT_TEST_LOG("checking %s after update into %s",
|
||||
test->getSourceName().c_str(),
|
||||
main->getSourceName().c_str());
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.startAccess());
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.stopAccess());
|
||||
|
||||
TestingSyncSourcePtr sourceB;
|
||||
SOURCE_ASSERT_NO_FAILURE(sourceB.get(), sourceB.reset(test->createSourceB()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countNewItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countUpdatedItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countDeletedItems(sourceB.get()));
|
||||
}
|
||||
|
||||
// delete one item
|
||||
CLIENT_TEST_LOG("deleting in %s", main->getSourceName().c_str());
|
||||
CT_ASSERT_NO_THROW(main->deleteAll(main->createSourceA));
|
||||
BOOST_FOREACH (LocalTests *test, m_linkedSources) {
|
||||
if (test == main) {
|
||||
continue;
|
||||
}
|
||||
TestingSyncSourcePtr &source = sourcesA[test->getSourceName()];
|
||||
CLIENT_TEST_LOG("checking %s after delete in %s",
|
||||
test->getSourceName().c_str(),
|
||||
main->getSourceName().c_str());
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.startAccess());
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
|
||||
SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.stopAccess());
|
||||
|
||||
TestingSyncSourcePtr sourceB;
|
||||
SOURCE_ASSERT_NO_FAILURE(sourceB.get(), sourceB.reset(test->createSourceB()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countNewItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countUpdatedItems(sourceB.get()));
|
||||
SOURCE_ASSERT_EQUAL(sourceB.get(), 0, countDeletedItems(sourceB.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean database, import file, then export again and compare
|
||||
void LocalTests::testImport() {
|
||||
// check additional requirements
|
||||
|
@ -5790,6 +5906,8 @@ public:
|
|||
CppUnit::TestSuite *tests;
|
||||
|
||||
// create local source tests
|
||||
typedef std::map<std::string, LocalTests *> ConfigMap;
|
||||
ConfigMap configs;
|
||||
tests = new CppUnit::TestSuite(alltests->getName() + "::Source");
|
||||
for (source=0; source < client.getNumLocalSources(); source++) {
|
||||
ClientTest::Config config;
|
||||
|
@ -5799,6 +5917,18 @@ public:
|
|||
client.createLocalTests(tests->getName() + "::" + config.m_sourceName, source, config);
|
||||
sourcetests->addTests();
|
||||
tests->addTest(FilterTest(sourcetests));
|
||||
configs[config.m_sourceName] = sourcetests;
|
||||
}
|
||||
}
|
||||
// link configs of sources which share the same database
|
||||
BOOST_FOREACH (const ConfigMap::value_type &entry, configs) {
|
||||
LocalTests *sourcetests = entry.second;
|
||||
const ClientTest::Config &config = sourcetests->config;
|
||||
if (!config.m_linkedSources.empty()) {
|
||||
sourcetests->m_linkedSources.push_back(sourcetests);
|
||||
BOOST_FOREACH (const std::string &source, config.m_linkedSources) {
|
||||
sourcetests->m_linkedSources.push_back(configs[source]);
|
||||
}
|
||||
}
|
||||
}
|
||||
alltests->addTest(FilterTest(tests));
|
||||
|
|
|
@ -476,6 +476,19 @@ public:
|
|||
/** configuration that corresponds to source */
|
||||
const ClientTest::Config config;
|
||||
|
||||
/** shortcut for config.m_sourceName */
|
||||
const std::string &getSourceName() const { return config.m_sourceName; }
|
||||
|
||||
/**
|
||||
* A list of config pointers which share the same
|
||||
* database. Normally, sources are tested in isolation, but for
|
||||
* such linked sources we also need to test interdependencies, in
|
||||
* particular regarding change tracking and item listing.
|
||||
*
|
||||
* This includes *all* configs, not just the other ones.
|
||||
*/
|
||||
std::list<LocalTests *> m_linkedSources;
|
||||
|
||||
/** helper funclets to create sources */
|
||||
CreateSource createSourceA, createSourceB;
|
||||
|
||||
|
@ -617,6 +630,7 @@ public:
|
|||
void doChanges(bool restart);
|
||||
virtual void testChanges();
|
||||
virtual void testChangesMultiCycles();
|
||||
virtual void testLinkedSources();
|
||||
virtual void testImport();
|
||||
virtual void testImportDelete();
|
||||
virtual void testRemoveProperties();
|
||||
|
|
Loading…
Reference in New Issue