testing: cleaned up ClientTestConfig

The memset/memcpy of the embedded boost::function instances inside the
old ClientTestConfig was causing segfaults at the end of a client-test
run if compiled with optimization.

Therefore this commit turns ClientTestConfig into a proper class
containing members which initialize themselves (Bool wrapper class,
std::string), thus memset is no longer needed and used. Also added the
standard m_ prefix.

m_numItems is gone, was never set by any backend anyway and even
expected to be consistent in one test. Now CLIENT_TEST_NUM_ITEMS is
read by defNumItems() each time it is needed.

Removed "const char *" strings from method parameters. This revealed
that config.itemType (a const char *) was incorrectly passed to
insert() where the boolean "relax" parameter should have been given.
Replaced by "false" (= strict checking) even though the old code
must have run with an implicit "true" (= relaxed checking). Let's see
whether any tests fail now.
This commit is contained in:
Patrick Ohly 2011-09-02 09:42:19 +02:00
parent 8c92178965
commit 6399bd8181
20 changed files with 458 additions and 551 deletions

View File

@ -142,10 +142,10 @@ namespace {
* operation. Using the cached information implies that we won't find bugs in
* the handling of that information.
*/
static int DumpItems(ClientTest &client, TestingSyncSource &source, const char *file)
static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::string &file)
{
ActiveSyncSource &eassource = static_cast<ActiveSyncSource &>(source);
ofstream out(file);
ofstream out(file.c_str());
// find all ActiveSync server IDs: in ActiveSyncCalendarSource,
// each server ID might appear multiple times, once for each
@ -204,17 +204,17 @@ static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
// cannot run tests involving a second database:
// wrap orginal source creation, set default database for
// database #0 and refuse to return a source for database #1
config.createSourceA = boost::bind(createEASSource, config.createSourceA,
_1, _2, _3);
config.createSourceB = boost::bind(createEASSource, config.createSourceB,
_1, _2, _3);
config.m_createSourceA = boost::bind(createEASSource, config.m_createSourceA,
_1, _2, _3);
config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB,
_1, _2, _3);
config.dump = DumpItems;
config.sourceLUIDsAreVolatile = true;
config.m_dump = DumpItems;
config.m_sourceLUIDsAreVolatile = true;
// TODO: find out how ActiveSync/Exchange handle children without parent;
// at the moment, the child is stored as if it was a stand-alone event
// and the RECURRENCE-ID is lost (BMC #22831).
config.linkedItemsRelaxedSemantic = false;
config.m_linkedItemsRelaxedSemantic = false;
}
static class ActiveSyncContactTest : public RegisterSyncSourceTest {
@ -227,7 +227,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
// override default eds_contact test config
config.type = "eas-contacts";
config.m_type = "eas-contacts";
// TODO: provide comprehensive set of vCard 3.0 contacts as they are understood by the ActiveSync library
// config.testcases = "testcases/eas_contact.vcf";
@ -243,7 +243,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "eas-events";
config.m_type = "eas-events";
updateConfigEAS(this, config);
}
} ActiveSyncEventTest;
@ -256,7 +256,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "eas-todos";
config.m_type = "eas-todos";
updateConfigEAS(this, config);
}
} ActiveSyncTodoTest;
@ -269,7 +269,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "eas-memos";
config.m_type = "eas-memos";
updateConfigEAS(this, config);
}
} ActiveSyncMemoTest;

View File

@ -101,7 +101,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "apple-contacts:text/x-vcard";
config.m_type = "apple-contacts:text/x-vcard";
}
} vCard21Test;
@ -111,7 +111,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "apple-contacts:text/vcard";
config.m_type = "apple-contacts:text/vcard";
}
} vCard30Test;

View File

@ -348,7 +348,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "kde-calendar";
config.m_type = "kde-calendar";
}
} iCal20Test;
@ -358,7 +358,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "kde-tasks";
config.m_type = "kde-tasks";
}
} iTodo20Test;
@ -368,7 +368,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "KDE Memos"; // use an alias here to test that
config.m_type = "KDE Memos"; // use an alias here to test that
}
} memoTest;

View File

@ -317,7 +317,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "evolution-calendar";
config.m_type = "evolution-calendar";
}
} iCal20Test;
@ -327,7 +327,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "evolution-tasks";
config.m_type = "evolution-tasks";
}
} iTodo20Test;
@ -337,8 +337,8 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "virtual:text/x-vcalendar";
config.subConfigs = "eds_event,eds_task";
config.m_type = "virtual:text/x-vcalendar";
config.m_subConfigs = "eds_event,eds_task";
}
} superTest;
@ -349,7 +349,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "Evolution Memos"; // use an alias here to test that
config.m_type = "Evolution Memos"; // use an alias here to test that
}
} memoTest;

View File

@ -152,8 +152,8 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "evolution-contacts:text/vcard";
config.update = config.genericUpdate;
config.m_type = "evolution-contacts:text/vcard";
config.m_update = config.m_genericUpdate;
}
} vCard30Test;

View File

@ -121,7 +121,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "file:text/vcard:3.0";
config.m_type = "file:text/vcard:3.0";
}
} VCard30Test;
@ -131,7 +131,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "file:text/calendar:2.0";
config.m_type = "file:text/calendar:2.0";
// A sync source which supports linked items (= recurring
// event with detached exception) is expected to handle
@ -143,7 +143,7 @@ public:
// Client::Source::file_event::testLinkedItemsInsertChildTwice
//
// Disable linked item testing to avoid this.
config.sourceKnowsItemSemantic = false;
config.m_sourceKnowsItemSemantic = false;
}
} ICal20Test;
@ -153,7 +153,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "file:text/calendar:2.0";
config.m_type = "file:text/calendar:2.0";
}
} ITodo20Test;
@ -163,8 +163,8 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "virtual:text/x-vcalendar";
config.subConfigs = "file_event,file_task";
config.m_type = "virtual:text/x-vcalendar";
config.m_subConfigs = "file_event,file_task";
}
} superTest;

View File

@ -93,10 +93,10 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "KCalExtended:text/calendar";
config.m_type = "KCalExtended:text/calendar";
// after fixing BMC #6061, mKCal is able to delete individual
// VEVENTs, without enforcing the "each child must have parent" rule
config.linkedItemsRelaxedSemantic = true;
config.m_linkedItemsRelaxedSemantic = true;
}
} iCal20Test;

View File

@ -137,7 +137,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "maemo-events";
config.m_type = "maemo-events";
}
} iCal20Test;
@ -147,7 +147,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "maemo-tasks";
config.m_type = "maemo-tasks";
}
} iTodo20Test;
@ -157,7 +157,7 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "maemo-notes";
config.m_type = "maemo-notes";
}
} memoTest;

View File

@ -202,8 +202,8 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "qt-contacts:text/vcard";
config.testcases = "testcases/qt_contact.vcf";
config.m_type = "qt-contacts:text/vcard";
config.m_testcases = "testcases/qt_contact.vcf";
}
} vCard30Test;

View File

@ -99,8 +99,8 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = "sqlite-contacts:text/x-vcard";
config.testcases = "testcases/sqlite_vcard21.vcf";
config.m_type = "sqlite-contacts:text/x-vcard";
config.m_testcases = "testcases/sqlite_vcard21.vcf";
}
} VCard21Test;

View File

@ -229,13 +229,13 @@ public:
virtual void updateConfig(ClientTestConfig &config) const
{
config.type = m_type.c_str();
config.createSourceA = boost::bind(&WebDAVTest::createSource, this, _3);
config.createSourceB = boost::bind(&WebDAVTest::createSource, this, _3);
config.m_type = m_type.c_str();
config.m_createSourceA = boost::bind(&WebDAVTest::createSource, this, _3);
config.m_createSourceB = boost::bind(&WebDAVTest::createSource, this, _3);
ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
if (it != m_props.end() ||
(it = m_props.find("testcases")) != m_props.end()) {
config.testcases = it->second.c_str();
config.m_testcases = it->second.c_str();
}
}

View File

@ -65,46 +65,6 @@ public:
virtual void addTests() {
LocalTests::addTests();
#ifdef ENABLE_MAEMO
if (config.createSourceA &&
config.createSourceB &&
config.templateItem &&
strstr(config.templateItem, "BEGIN:VCARD") &&
config.uniqueProperties) {
ADD_TEST(EvolutionLocalTests, testOssoDelete);
}
#endif
}
private:
// insert am item,
// overwrite it with an additional X-OSSO-CONTACT-STATE:DELETED as Maemoe address book does,
// iterate again and check that our own code deleted the item
void testOssoDelete() {
// get into clean state with one template item added
deleteAll(createSourceA);
insert(createSourceA, config.templateItem, config.itemType);
// add X-OSSO-CONTACT-STATE:DELETED
string item = config.templateItem;
const char *comma = strchr(config.uniqueProperties, ':');
size_t offset = item.find(config.uniqueProperties, 0,
comma ? comma - config.uniqueProperties : strlen(config.uniqueProperties));
CPPUNIT_ASSERT(offset != item.npos);
item.insert(offset, "X-OSSO-CONTACT-STATE:DELETED\n");
update(createSourceA, item.c_str(), false);
// opening and preparing the source should delete the item
std::auto_ptr<TestingSyncSource> source;
SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceA()));
SOURCE_ASSERT_NO_FAILURE(source.get(), source->open());
SOURCE_ASSERT_NO_FAILURE(source.get(), source->beginSync("", "") );
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::ANY));
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::NEW));
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::UPDATED));
CPPUNIT_ASSERT_EQUAL(1, countItemsOfType(source.get(), SyncSourceChanges::DELETED));
}
};
@ -233,9 +193,9 @@ public:
ClientTest::Config conf;
BOOST_FOREACH (string source, sources) {
getSourceConfig (source, conf);
if (conf.subConfigs) {
if (!conf.m_subConfigs.empty()) {
vector<string> subs;
boost::split (subs, conf.subConfigs, boost::is_any_of(","));
boost::split (subs, conf.m_subConfigs, boost::is_any_of(","));
BOOST_FOREACH (string sub, subs) {
pushLocalSource2Config(sub);
}
@ -264,17 +224,17 @@ public:
BOOST_FOREACH(const RegisterSyncSourceTest *test, m_configs) {
ClientTest::Config testconfig;
getSourceConfig(test, testconfig);
CPPUNIT_ASSERT(testconfig.type);
CPPUNIT_ASSERT(!testconfig.m_type.empty());
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.sourceName);
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName);
if (!sc || !sc->exists()) {
// no configuration yet
config->setSourceDefaults(testconfig.sourceName);
sc = config->getSyncSourceConfig(testconfig.sourceName);
config->setSourceDefaults(testconfig.m_sourceName);
sc = config->getSyncSourceConfig(testconfig.m_sourceName);
CPPUNIT_ASSERT(sc);
sc->setURI(testconfig.uri);
if(from && testconfig.sourceNameServerTemplate){
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.sourceNameServerTemplate);
sc->setURI(testconfig.m_uri);
if(from && !testconfig.m_sourceNameServerTemplate.empty()) {
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate);
sc->setURI(scServerTemplate->getURI());
}
}
@ -284,7 +244,7 @@ public:
sc->setDatabaseID(database);
sc->setUser(m_evoUser);
sc->setPassword(m_evoPassword);
sc->setBackend(SourceType(testconfig.type).m_backend);
sc->setBackend(SourceType(testconfig.m_type).m_backend);
}
config->flush();
}
@ -331,9 +291,9 @@ public:
static void getSourceConfig(const RegisterSyncSourceTest *test, Config &config) {
ClientTest::getTestData(test->m_testCaseName.c_str(), config);
config.createSourceA = createSource;
config.createSourceB = createSource;
config.sourceName = test->m_configName.c_str();
config.m_createSourceA = createSource;
config.m_createSourceB = createSource;
config.m_sourceName = test->m_configName.c_str();
test->updateConfig(config);
}
@ -538,7 +498,7 @@ private:
getSourceConfig(test, testConfig);
PersistentSyncSourceConfig sourceConfig(params.m_name, params.m_nodes);
sourceConfig.setSourceType(SourceType(testConfig.type));
sourceConfig.setSourceType(SourceType(testConfig.m_type));
// downcasting here: anyone who registers his sources for testing
// must ensure that they are indeed TestingSyncSource instances

View File

@ -106,21 +106,6 @@ public:
/** the run() call modified configurations (added, updated, removed) */
bool configWasModified() const { return m_configModified; }
/**
* Acts like a boolean, but in addition, can also tell whether the
* value was explicitly set.
*/
class Bool {
public:
Bool(bool val = false) : m_value(val), m_wasSet(false) {}
operator bool () const { return m_value; }
Bool & operator = (bool val) { m_value = val; m_wasSet = true; return *this; }
bool wasSet() const { return m_wasSet; }
private:
bool m_value;
bool m_wasSet;
};
Bool useDaemon() { return m_useDaemon; }
/** whether '--monitor' is set */

View File

@ -1915,16 +1915,16 @@ void SyncContext::startLoopThread()
#endif
}
SyncSource *SyncContext::findSource(const char *name)
SyncSource *SyncContext::findSource(const std::string &name)
{
if (!m_activeContext || !m_activeContext->m_sourceListPtr) {
return NULL;
}
const char *realname = strrchr(name, m_findSourceSeparator);
const char *realname = strrchr(name.c_str(), m_findSourceSeparator);
if (realname) {
realname++;
} else {
realname = name;
realname = name.c_str();
}
return (*m_activeContext->m_sourceListPtr)[realname];
}
@ -3269,7 +3269,7 @@ SyncMLStatus SyncContext::doSync()
target;
target = m_engine.OpenSubkey(targets, sysync::KEYVAL_ID_NEXT, true)) {
s = m_engine.GetStrValue(target, "dbname");
SyncSource *source = findSource(s.c_str());
SyncSource *source = findSource(s);
if (source) {
m_engine.SetInt32Value(target, "enabled", 1);
int slow = 0;

View File

@ -451,7 +451,7 @@ class SyncContext : public SyncConfig, public ConfigUserInterface {
* @TODO: roll SourceList into SyncContext and
* make this non-static
*/
static SyncSource *findSource(const char *name);
static SyncSource *findSource(const std::string &name);
static const char m_findSourceSeparator = '@';
/**

View File

@ -163,49 +163,22 @@ class TestingSyncSource;
* information.
*/
struct ClientTestConfig {
ClientTestConfig() {
/*
* brute-force old-style initialization - must not embed C++ classes!
* TODO: replace old-style C values with self-initializing C++ classes
*/
memset(this, 0, sizeof(*this));
}
ClientTestConfig(const ClientTestConfig &other) {
memcpy(this, &other, sizeof(*this));
if (other.linkedItems) {
linkedItems = new std::vector<LinkedItems_t>(*other.linkedItems);
}
}
~ClientTestConfig() {
delete linkedItems;
}
ClientTestConfig &operator = (const ClientTestConfig &other) {
if (this != &other) {
delete linkedItems;
memcpy(this, &other, sizeof(*this));
if (other.linkedItems) {
linkedItems = new std::vector<LinkedItems_t>(*other.linkedItems);
}
}
return *this;
}
/**
* The name is used in test names and has to be set.
*/
const char *sourceName;
std::string m_sourceName;
/**
* A default URI to be used when creating a client config.
*/
const char *uri;
std::string m_uri;
/**
* A corresponding source name in the default server template,
* this is used to copy corresponding uri set in the server template
* instead of the uri field above (which is the same for all servers).
*/
const char *sourceNameServerTemplate;
std::string m_sourceNameServerTemplate;
/**
* A member function of a subclass which is called to create a
@ -237,7 +210,7 @@ struct ClientTestConfig {
* it may report the same changes as the sync source used during
* sync tests.
*/
createsource_t createSourceA;
createsource_t m_createSourceA;
/**
* A second sync source also referencing the primary data
@ -255,7 +228,7 @@ struct ClientTestConfig {
* - check that the total number and number of
* added/updated/deleted items is as expected
*/
createsource_t createSourceB;
createsource_t m_createSourceB;
/**
* The framework can generate vCard and vCalendar/iCalendar items
@ -266,24 +239,19 @@ struct ClientTestConfig {
* It must contain the string <<REVISION>> which will be replaced
* with the revision parameter of the createItem() method.
*/
const char *templateItem;
std::string m_templateItem;
/**
* This is a colon (:) separated list of properties which need
* to be modified in templateItem.
*/
const char *uniqueProperties;
/**
* the number of items to create during stress tests
*/
int numItems;
std::string m_uniqueProperties;
/**
* This is a single property in templateItem which can be extended
* to increase the size of generated items.
*/
const char *sizeProperty;
std::string m_sizeProperty;
/**
* Type to be set when importing any of the items into the
@ -293,7 +261,7 @@ struct ClientTestConfig {
* Not currently used! All items are assumed to be in the raw,
* internal format (see SyncSourceRaw and SyncSourceSerialize).
*/
const char *itemType;
std::string m_itemType;
/**
* callback which is invoked with a specific item as paramter
@ -303,33 +271,33 @@ struct ClientTestConfig {
* @param update modify item content so that it can be
* used as an update of the old data
*/
std::string (*mangleItem)(const std::string &data, bool update);
boost::function<std::string (const std::string &, bool)> m_mangleItem;
/**
* A very simple item that is inserted during basic tests. Ideally
* it only contains properties supported by all servers.
*/
const char *insertItem;
std::string m_insertItem;
/**
* A slightly modified version of insertItem. If the source has UIDs
* embedded into the item data, then both must have the same UID.
* Again all servers should better support these modified properties.
*/
const char *updateItem;
std::string m_updateItem;
/**
* A more heavily modified version of insertItem. Same UID if necessary,
* but can test changes to items only supported by more advanced
* servers.
*/
const char *complexUpdateItem;
std::string m_complexUpdateItem;
/**
* To test merge conflicts two different updates of insertItem are
* needed. This is the first such update.
*/
const char *mergeItem1;
std::string m_mergeItem1;
/**
* The second merge update item. To avoid true conflicts it should
@ -337,7 +305,7 @@ struct ClientTestConfig {
* usually have problems perfectly merging items. Therefore the
* test is run without expecting a certain merge result.
*/
const char *mergeItem2;
std::string m_mergeItem2;
/**
* The items in the inner vector are related: the first one the is
@ -361,26 +329,28 @@ struct ClientTestConfig {
/**
* The linked items may exist in different variations (outer vector).
*/
std::vector<LinkedItems_t> *linkedItems;
typedef std::vector<LinkedItems_t> MultipleLinkedItems_t;
MultipleLinkedItems_t m_linkedItems;
/**
* Backends atomic modification tests
*/
bool atomicModification;
Bool m_atomicModification;
/**
* set to false to disable tests which slightly violate the
* semantic of linked items by inserting children
* before/without their parent
*/
bool linkedItemsRelaxedSemantic;
Bool m_linkedItemsRelaxedSemantic;
/**
* setting this to false disables tests which depend
* on the source's support for linked item semantic
* (testLinkedItemsInsertParentTwice, testLinkedItemsInsertChildTwice)
*/
bool sourceKnowsItemSemantic;
Bool m_sourceKnowsItemSemantic;
/**
* Set this to true if the backend does not have IDs which are the
@ -389,7 +359,7 @@ struct ClientTestConfig {
* because items are renumbered as 1:x with x = 1, 2, ... for each
* clients when a sync anchor is assigned to it.
*/
bool sourceLUIDsAreVolatile;
Bool m_sourceLUIDsAreVolatile;
/**
* called to dump all items into a file, required by tests which need
@ -402,7 +372,7 @@ struct ClientTestConfig {
* @param file a file name
* @return error code, 0 for success
*/
int (*dump)(ClientTest &client, TestingSyncSource &source, const char *file);
boost::function<int (ClientTest &, TestingSyncSource &, const std::string &)> m_dump;
/**
* import test items: which these are is determined entirely by
@ -418,8 +388,8 @@ struct ClientTestConfig {
* this may depend on the current server that is being tested
* @return error string, empty for success
*/
std::string (*import)(ClientTest &client, TestingSyncSource &source, const ClientTestConfig &config,
const char *file, std::string &realfile);
boost::function<std::string (ClientTest &, TestingSyncSource &, const ClientTestConfig &,
const std::string &, std::string &)> m_import;
/**
* a function which compares two files with items in the format used by "dump"
@ -428,7 +398,7 @@ struct ClientTestConfig {
* @param fileB second file name
* @return true if the content of the files is considered equal
*/
bool (*compare)(ClientTest &client, const char *fileA, const char *fileB);
boost::function<bool (ClientTest &, const std::string &, const std::string &)> m_compare;
/**
* A file with test cases in the format expected by import and compare.
@ -447,27 +417,27 @@ struct ClientTestConfig {
* That file then will be used in testItems instead of the base
* version. See the src/Makefile.am for rules that maintain such files.
*/
const char *testcases;
std::string m_testcases;
/**
* the item type normally used by the source (not used by the tests
* themselves; client-test.cpp uses it to initialize source configs)
*/
const char *type;
std::string m_type;
/**
* a list of sub configs separated via , if this is a super datastore
*/
const char *subConfigs;
std::string m_subConfigs;
/**
* TRUE if the source supports recovery from an interrupted
* synchronization. Enables the Client::Sync::*::Retry group
* of tests.
*/
bool retrySync;
bool suspendSync;
bool resendSync;
Bool m_retrySync;
Bool m_suspendSync;
Bool m_resendSync;
/**
* Set this to test if the source supports preserving local data extensions.
@ -480,8 +450,8 @@ struct ClientTestConfig {
* genericUpdate works for vCard and iCalendar by updating FN, N, resp. SUMMARY
* and can be used as implementation of update.
*/
void (*update)(std::string &item);
void (*genericUpdate)(std::string &item);
boost::function<void (std::string &)> m_update;
boost::function<void (std::string &)> m_genericUpdate;
};
/**

View File

@ -380,7 +380,21 @@ class Timespec : public timespec
static Timespec monotonic() { Timespec res; clock_gettime(CLOCK_MONOTONIC, &res); return res; }
static Timespec system() { Timespec res; clock_gettime(CLOCK_REALTIME, &res); return res; }
};
/**
* Acts like a boolean, but in addition, can also tell whether the
* value was explicitly set. Defaults to false.
*/
class Bool {
public:
Bool(bool val = false) : m_value(val), m_wasSet(false) {}
operator bool () const { return m_value; }
Bool & operator = (bool val) { m_value = val; m_wasSet = true; return *this; }
bool wasSet() const { return m_wasSet; }
private:
bool m_value;
bool m_wasSet;
};
/**
* an exception which records the source file and line

View File

@ -508,7 +508,7 @@ int main( int argc, char **argv )
return 0;
}
Cmdline::Bool useDaemon = cmdline.useDaemon();
Bool useDaemon = cmdline.useDaemon();
if(cmdline.monitor()) {

File diff suppressed because it is too large Load Diff

View File

@ -286,7 +286,7 @@ class ClientTest {
/**
* utility function for dumping items which are C strings with blank lines as separator
*/
static int dump(ClientTest &client, TestingSyncSource &source, const char *file);
static int dump(ClientTest &client, TestingSyncSource &source, const std::string &file);
/**
* utility function for splitting file into items with blank lines as separator
@ -295,20 +295,20 @@ class ClientTest {
* of the generic version. The caller gets the name of the
* file that was opened here.
*/
static void getItems(const char *file, std::list<std::string> &items, std::string &realfile);
static void getItems(const std::string &file, std::list<std::string> &items, std::string &realfile);
/**
* utility function for importing items with blank lines as separator
*/
static std::string import(ClientTest &client, TestingSyncSource &source,
const ClientTestConfig &config,
const char *file, std::string &realfile);
const std::string &file, std::string &realfile);
/**
* utility function for comparing vCard and iCal files with the external
* synccompare.pl Perl script
*/
static bool compare(ClientTest &client, const char *fileA, const char *fileB);
static bool compare(ClientTest &client, const std::string &fileA, const std::string &fileB);
/**
* utility function: update a vCard or iCalendar item by inserting "MOD-" into
@ -429,7 +429,7 @@ class ClientTest {
*/
class CreateSource {
public:
CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
CreateSource(const ClientTest::Config::createsource_t &createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
createSource(createSourceParam),
client(clientParam),
source(sourceParam),
@ -473,8 +473,8 @@ public:
client(cl),
source(sourceParam),
config(co),
createSourceA(co.createSourceA, cl, sourceParam, true),
createSourceB(co.createSourceB, cl, sourceParam, false)
createSourceA(co.m_createSourceA, cl, sourceParam, true),
createSourceB(co.m_createSourceB, cl, sourceParam, false)
{}
/** set up before running a test */