2 * Copyright (C) 2008 Funambol, Inc.
3 * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
4 * Copyright (C) 2009 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) version 3.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #ifndef INCL_TESTSYNCCLIENT
23 #define INCL_TESTSYNCCLIENT
29 #include <boost/function.hpp>
30 #include <boost/shared_ptr.hpp>
33 #include <TransportAgent.h>
34 #include <SyncSource.h>
38 #ifdef ENABLE_INTEGRATION_TESTS
40 #include <cppunit/TestSuite.h>
41 #include <cppunit/TestAssert.h>
42 #include <cppunit/TestFixture.h>
44 #include <syncevo/declarations.h>
48 class EvolutionSyncSource;
49 class TransportWrapper;
50 class TestingSyncSource;
53 * This class encapsulates logging and checking of a SyncReport.
54 * When constructed with default parameters, no checking will be done.
55 * Otherwise the sync report has to contain exactly the expected result.
56 * When multiple sync sources are active, @b all of them have to behave
57 * alike (which is how the tests are constructed).
59 * No item is ever supposed to fail.
61 class CheckSyncReport {
63 CheckSyncReport(int clAdded = -1, int clUpdated = -1, int clDeleted = -1,
64 int srAdded = -1, int srUpdated = -1, int srDeleted = -1,
65 bool mstSucceed = true, SyncMode mode = SYNC_NONE) :
67 clientUpdated(clUpdated),
68 clientDeleted(clDeleted),
70 serverUpdated(srUpdated),
71 serverDeleted(srDeleted),
72 mustSucceed(mstSucceed),
76 virtual ~CheckSyncReport() {}
78 int clientAdded, clientUpdated, clientDeleted,
79 serverAdded, serverUpdated, serverDeleted;
84 * checks that the sync completed as expected and throws
85 * CPPUnit exceptions if something is wrong
87 * @param res return code from SyncClient::sync()
88 * @param report the sync report stored in the SyncClient
90 virtual void check(SyncMLStatus status, SyncReport &report) const;
94 * parameters for running a sync
97 /** default maximum message size */
98 static const long DEFAULT_MAX_MSG_SIZE = 128 * 1024;
99 /** default maximum object size */
100 static const long DEFAULT_MAX_OBJ_SIZE = 1024 * 1024 * 1024;
101 /** sync mode chosen by client */
104 * has to be called after a successful or unsuccessful sync,
105 * will dump the report and (optionally) check the result;
106 * beware, the later may throw exceptions inside CPPUNIT macros
108 CheckSyncReport m_checkReport;
110 /** maximum message size supported by client */
112 /** maximum object size supported by client */
114 /** enabled large object support */
116 /** enabled WBXML (default) */
123 typedef boost::function<bool (SyncContext &,
124 SyncOptions &)> Callback_t;
126 * Callback to be invoked after setting up local sources, but
127 * before running the engine. May throw exception to indicate
128 * error and return true to stop sync without error.
130 Callback_t m_startCallback;
132 boost::shared_ptr<TransportAgent> m_transport;
134 SyncOptions(SyncMode syncMode = SYNC_NONE,
135 const CheckSyncReport &checkReport = CheckSyncReport(),
136 long maxMsgSize = DEFAULT_MAX_MSG_SIZE, // 128KB = large enough that normal tests should run with a minimal number of messages
137 long maxObjSize = DEFAULT_MAX_OBJ_SIZE, // 1GB = basically unlimited...
138 bool loSupport = false,
139 bool isWBXML = defaultWBXML(),
140 Callback_t startCallback = EmptyCallback,
141 boost::shared_ptr<TransportAgent> transport =
142 boost::shared_ptr<TransportAgent>()) :
143 m_syncMode(syncMode),
144 m_checkReport(checkReport),
145 m_maxMsgSize(maxMsgSize),
146 m_maxObjSize(maxObjSize),
147 m_loSupport(loSupport),
149 m_isSuspended(false),
151 m_startCallback(startCallback),
152 m_transport (transport)
155 SyncOptions &setSyncMode(SyncMode syncMode) { m_syncMode = syncMode; return *this; }
156 SyncOptions &setCheckReport(const CheckSyncReport &checkReport) { m_checkReport = checkReport; return *this; }
157 SyncOptions &setMaxMsgSize(long maxMsgSize) { m_maxMsgSize = maxMsgSize; return *this; }
158 SyncOptions &setMaxObjSize(long maxObjSize) { m_maxObjSize = maxObjSize; return *this; }
159 SyncOptions &setLOSupport(bool loSupport) { m_loSupport = loSupport; return *this; }
160 SyncOptions &setWBXML(bool isWBXML) { m_isWBXML = isWBXML; return *this; }
161 SyncOptions &setStartCallback(const Callback_t &callback) { m_startCallback = callback; return *this; }
162 SyncOptions &setTransportAgent(const boost::shared_ptr<TransportAgent> transport)
163 {m_transport = transport; return *this;}
165 static bool EmptyCallback(SyncContext &,
166 SyncOptions &) { return false; }
168 /** if CLIENT_TEST_XML=1, then XML, otherwise WBXML */
169 static bool defaultWBXML();
176 * This is the interface expected by the testing framework for sync
177 * clients. It defines several methods that a derived class must
178 * implement if it wants to use that framework. Note that this class
179 * itself is not derived from SyncClient. This gives a user of this
180 * framework the freedom to implement it in two different ways:
181 * - implement a class derived from both SyncClient and ClientTest
182 * - add testing of an existing subclass of SyncClient by implementing
183 * a ClientTest which uses that subclass
185 * The client is expected to support change tracking for multiple
186 * servers. Although the framework always always tests against the
187 * same server, for most tests it is necessary to access the database
188 * without affecting the next synchronization with the server. This is
189 * done by asking the client for two different sync sources via
190 * Config::createSourceA and Config::createSourceB which have to
191 * create them in a suitable way - pretty much as if the client was
192 * synchronized against different server. A third, different change
193 * tracking is needed for real synchronizations of the data.
195 * Furthermore the client is expected to support multiple data sources
196 * of the same kind, f.i. two different address books. This is used to
197 * test full client A <-> server <-> client B synchronizations in some
198 * tests or to check server modifications done by client A with a
199 * synchronization against client B. In those tests client A is mapped
200 * to the first data source and client B to the second one.
202 * Handling configuration and creating classes is entirely done by the
203 * subclass of ClientTest, the frameworks makes no assumptions
204 * about how this is done. Instead it queries the ClientTest for
205 * properties (like available sync sources) and then creates several
210 ClientTest(int serverSleepSec = 0, const std::string &serverLog= "");
211 virtual ~ClientTest();
214 * This function registers tests using this instance of ClientTest for
215 * later use during a test run.
217 * The instance must remain valid until after the tests were
218 * run. To run them use a separate test runner, like the one from
219 * client-test-main.cpp.
221 virtual void registerTests();
223 typedef ClientTestConfig Config;
226 * Creates an instance of LocalTests (default implementation) or a
227 * class derived from it. LocalTests provides tests which cover
228 * the SyncSource interface and can be executed without a SyncML
229 * server. It also contains utility functions for working with
232 * A ClientTest implementation can, but doesn't have to extend
233 * these tests by instantiating a derived class here.
235 virtual LocalTests *createLocalTests(const std::string &name, int sourceParam, ClientTest::Config &co);
238 * Creates an instance of SyncTests (default) or a class derived
239 * from it. SyncTests provides tests which cover the actual
240 * interaction with a SyncML server.
242 * A ClientTest implementation can, but doesn't have to extend
243 * these tests by instantiating a derived class here.
245 virtual SyncTests *createSyncTests(const std::string &name, std::vector<int> sourceIndices, bool isClientA = true);
248 * utility function for dumping items which are C strings with blank lines as separator
250 static int dump(ClientTest &client, TestingSyncSource &source, const char *file);
253 * utility function for splitting file into items with blank lines as separator
255 * @retval realfile If <file>.<server>.tem exists, then it is used instead
256 * of the generic version. The caller gets the name of the
257 * file that was opened here.
259 static void getItems(const char *file, std::list<std::string> &items, std::string &realfile);
262 * utility function for importing items with blank lines as separator
264 static int import(ClientTest &client, TestingSyncSource &source, const char *file, std::string &realfile);
267 * utility function for comparing vCard and iCal files with the external
268 * synccompare.pl Perl script
270 static bool compare(ClientTest &client, const char *fileA, const char *fileB);
272 struct ClientTestConfig config;
275 * A derived class can use this call to get default test
276 * cases, but still has to add callbacks which create sources
277 * and execute a sync session.
279 * Some of the test cases are compiled into the library, other
280 * depend on the auxiliary files from the "test" directory.
281 * Currently supported types:
282 * - vcard30 = vCard 3.0 contacts
283 * - vcard21 = vCard 2.1 contacts
284 * - ical20 = iCal 2.0 events
285 * - vcal10 = vCal 1.0 events
286 * - itodo20 = iCal 2.0 tasks
288 static void getTestData(const char *type, Config &config);
291 * Data sources are enumbered from 0 to n-1 for the purpose of
292 * testing. This call returns n.
294 virtual int getNumLocalSources() = 0;
295 virtual int getNumSyncSources() = 0;
298 * Called to fill the given test source config with information
299 * about a sync source identified by its index. It's okay to only
300 * fill in the available pieces of information and set everything
302 * Two kinds of source config indexs are maintained, used for localSources
303 * and SyncSources, this is because virtual datasoures should be visible as
304 * a whole to the synccontext while should be viewed as a list of sub
305 * datasoures for Localtests.
307 virtual void getLocalSourceConfig(int source, Config &config) = 0;
308 virtual void getSyncSourceConfig(int source, Config &config) = 0;
311 * Find the correspoding test source config via config name.
313 virtual void getSourceConfig(const string &configName, Config &config) =0;
315 * Give me a test source config name, return the index in localSyncSources.
317 virtual int getLocalSourcePosition (const string &configName) =0;
320 * The instance to use as second client. Returning NULL disables
321 * all checks which require a second client. The returned pointer
322 * must remain valid throughout the life time of the tests.
324 * The second client must be configured to access the same server
325 * and have data sources which match the ones from the primary
328 virtual ClientTest *getClientB() = 0;
331 * Execute a synchronization with the selected sync sources
332 * and the selected synchronization options. The log file
333 * in LOG has been set up already for the synchronization run
334 * and should not be changed by the client.
336 * @param activeSources a -1 terminated array of sync source indices
337 * @param logbase basename for logging: can be used for directory or as file (by adding .log suffix)
338 * @param options sync options to be used
339 * @return return code of SyncClient::sync()
341 virtual SyncMLStatus doSync(
342 const int *activeSources,
343 const std::string &logbase,
344 const SyncOptions &options) = 0;
348 * This is called after successful sync() calls (res == 0) as well
349 * as after unsuccessful ones (res != 1). The default implementation
350 * sleeps for the number of seconds specified when constructing this
351 * instance and copies the server log if one was named.
353 * @param res result of sync()
354 * @param logname base name of the current sync log (without ".client.[AB].log" suffix)
356 virtual void postSync(int res, const std::string &logname);
360 * time to sleep in postSync()
362 int serverSleepSeconds;
365 * server log file which is copied by postSync() and then
366 * truncated (Unix only, Windows does not allow such access
369 std::string serverLogFileName;
373 * really a CppUnit::TestFactory, but declared as void * to avoid
374 * dependencies on the CPPUnit header files: created by
375 * registerTests() and remains valid until the client is deleted
381 * helper class to encapsulate ClientTest::Config::createsource_t
382 * pointer and the corresponding parameters
386 CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
387 createSource(createSourceParam),
390 isSourceA(isSourceAParam) {}
392 TestingSyncSource *operator() () {
393 CPPUNIT_ASSERT(createSource);
394 return createSource(client, source, isSourceA);
397 const ClientTest::Config::createsource_t createSource;
400 const bool isSourceA;
405 * local test of one sync source and utility functions also used by
408 class LocalTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
410 /** the client we are testing */
413 /** number of the source we are testing in that client */
416 /** configuration that corresponds to source */
417 const ClientTest::Config config;
419 /** helper funclets to create sources */
420 CreateSource createSourceA, createSourceB;
422 LocalTests(const std::string &name, ClientTest &cl, int sourceParam, ClientTest::Config &co) :
423 CppUnit::TestSuite(name),
427 createSourceA(co.createSourceA, cl, sourceParam, true),
428 createSourceB(co.createSourceB, cl, sourceParam, false)
432 * adds the supported tests to the instance itself;
433 * this is the function that a derived class can override
434 * to add additional tests
436 virtual void addTests();
439 * opens source and inserts the given item; can be called
440 * regardless whether the data source already contains items or not
442 * @param relaxed if true, then disable some of the additional checks after adding the item
443 * @return the LUID of the inserted item
445 virtual std::string insert(CreateSource createSource, const char *data, bool relaxed = false);
448 * assumes that exactly one element is currently inserted and updates it with the given item
450 * @param check if true, then reopen the source and verify that the reported items are as expected
452 virtual void update(CreateSource createSource, const char *data, bool check = true);
455 * updates one item identified by its LUID with the given item
457 * The type of the item is cleared, as in insert() above.
459 virtual void update(CreateSource createSource, const char *data, const std::string &luid);
461 /** deletes all items locally via sync source */
462 virtual void deleteAll(CreateSource createSource);
465 * takes two databases, exports them,
466 * then compares them using synccompare
468 * @param refFile existing file with source reference items, NULL uses a dump of sync source A instead
469 * @param copy a sync source which contains the copied items, begin/endSync will be called
470 * @param raiseAssert raise assertion if comparison yields differences (defaults to true)
471 * @return true if the two databases are equal
473 virtual bool compareDatabases(const char *refFile, TestingSyncSource ©, bool raiseAssert = true);
476 * insert artificial items, number of them determined by TEST_EVOLUTION_NUM_ITEMS
477 * unless passed explicitly
479 * @param createSource a factory for the sync source that is to be used
480 * @param startIndex IDs are generated starting with this value
481 * @param numItems number of items to be inserted if non-null, otherwise TEST_EVOLUTION_NUM_ITEMS is used
482 * @param size minimum size for new items
483 * @return number of items inserted
485 virtual std::list<std::string> insertManyItems(CreateSource createSource, int startIndex = 1, int numItems = 0, int size = -1);
488 * create an artificial item for the current database
490 * @param item item number: items with different number should be
491 * recognized as different by SyncML servers
492 * @param revision differentiates items with the same item number (= updates of an older item)
493 * @param size if > 0, then create items at least that large (in bytes)
494 * @return created item
496 std::string createItem(int item, const std::string &revision, int size);
497 std::string createItem(int item, int revision, int size) {
499 sprintf(buffer, "%d", revision);
500 return createItem(item, std::string(buffer), size);
503 /* for more information on the different tests see their implementation */
505 virtual void testOpen();
506 virtual void testIterateTwice();
507 virtual void testSimpleInsert();
508 virtual void testLocalDeleteAll();
509 virtual void testComplexInsert();
510 virtual void testLocalUpdate();
511 virtual void testChanges();
512 virtual void testImport();
513 virtual void testImportDelete();
514 virtual void testManyChanges();
515 virtual void testLinkedItemsParent();
516 virtual void testLinkedItemsChild();
517 virtual void testLinkedItemsParentChild();
518 virtual void testLinkedItemsChildParent();
519 virtual void testLinkedItemsChildChangesParent();
520 virtual void testLinkedItemsRemoveParentFirst();
521 virtual void testLinkedItemsRemoveNormal();
522 virtual void testLinkedItemsInsertParentTwice();
523 virtual void testLinkedItemsInsertChildTwice();
524 virtual void testLinkedItemsParentUpdate();
525 virtual void testLinkedItemsUpdateChild();
526 virtual void testLinkedItemsInsertBothUpdateChild();
527 virtual void testLinkedItemsInsertBothUpdateParent();
531 int countItemsOfType(TestingSyncSource *source, int state);
532 std::list<std::string> listItemsOfType(TestingSyncSource *source, int state);
535 * Tests synchronization with one or more sync sources enabled.
536 * When testing multiple sources at once only the first config
537 * is checked to see which tests can be executed.
539 class SyncTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
541 /** the client we are testing */
544 SyncTests(const std::string &name, ClientTest &cl, std::vector<int> sourceIndices, bool isClientA = true);
547 /** adds the supported tests to the instance itself */
548 virtual void addTests();
551 /** list with all local test classes for manipulating the sources and their index in the client */
552 typedef std::vector< std::pair<int, LocalTests *> > source_array_t;
553 source_array_t sources;
554 typedef source_array_t::iterator source_it;
557 * Stack of log file prefixes which are to be appended to the base name,
558 * which already contains the current test name. Add a new prefix by
559 * instantiating SyncPrefix. Its destructor takes care of popping
562 std::list<std::string> logPrefixes;
567 SyncPrefix(const std::string &prefix, SyncTests &tests) :
569 tests.logPrefixes.push_back(prefix);
572 m_tests.logPrefixes.pop_back();
575 friend class SyncPrefix;
577 /** the indices from sources, terminated by -1 (for sync()) */
580 /** utility functions for second client */
581 SyncTests *accessClientB;
584 DELETE_ALL_SYNC, /**< make sure client and server are in sync,
587 DELETE_ALL_REFRESH /**< delete locally, refresh server */
591 * Compare databases second client with either reference file(s)
592 * or first client. The reference file(s) must follow the naming
593 * scheme <reFileBase><source name>.dat
595 virtual bool compareDatabases(const char *refFileBase = NULL,
596 bool raiseAssert = true);
598 /** deletes all items locally and on server */
599 virtual void deleteAll(DeleteAllMode mode = DELETE_ALL_SYNC);
601 /** get both clients in sync with empty server, then copy one item from client A to B */
602 virtual void doCopy();
605 * replicate server database locally: same as SYNC_REFRESH_FROM_SERVER,
606 * but done with explicit local delete and then a SYNC_SLOW because some
607 * servers do no support SYNC_REFRESH_FROM_SERVER
609 virtual void refreshClient(SyncOptions options = SyncOptions());
611 /* for more information on the different tests see their implementation */
613 // do a two-way sync without additional checks,
614 // may or may not actually be done in two-way mode
615 virtual void testTwoWaySync() {
616 doSync(SyncOptions(SYNC_TWO_WAY));
619 // do a slow sync without additional checks
620 virtual void testSlowSync() {
621 doSync(SyncOptions(SYNC_SLOW,
622 CheckSyncReport(-1,-1,-1, -1,-1,-1, true, SYNC_SLOW)));
624 // do a refresh from server sync without additional checks
625 virtual void testRefreshFromServerSync() {
626 doSync(SyncOptions(SYNC_REFRESH_FROM_SERVER,
627 CheckSyncReport(-1,-1,-1, -1,-1,-1, true, SYNC_REFRESH_FROM_SERVER)));
630 // do a refresh from client sync without additional checks
631 virtual void testRefreshFromClientSync() {
632 doSync(SyncOptions(SYNC_REFRESH_FROM_CLIENT,
633 CheckSyncReport(-1,-1,-1, -1,-1,-1, true, SYNC_REFRESH_FROM_CLIENT)));
636 // delete all items, locally and on server using two-way sync
637 virtual void testDeleteAllSync() {
638 deleteAll(DELETE_ALL_SYNC);
641 virtual void testDeleteAllRefresh();
642 virtual void testRefreshFromClientSemantic();
643 virtual void testRefreshFromServerSemantic();
644 virtual void testRefreshStatus();
646 // test that a two-way sync copies an item from one address book into the other
652 virtual void testUpdate();
653 virtual void testComplexUpdate();
654 virtual void testDelete();
655 virtual void testMerge();
656 virtual void testTwinning();
657 virtual void testOneWayFromServer();
658 virtual void testOneWayFromClient();
659 bool doConversionCallback(bool *success,
661 SyncOptions &options);
662 virtual void testConversion();
663 virtual void testItems();
664 virtual void testItemsXML();
665 virtual void testAddUpdate();
667 // test copying with maxMsg and no large object support
669 doVarSizes(true, false);
671 // test copying with maxMsg and large object support
672 void testLargeObject() {
673 doVarSizes(true, true);
676 virtual void testManyItems();
677 virtual void testManyDeletes();
678 virtual void testSlowSyncSemantic();
679 virtual void testComplexRefreshFromServerSemantic();
681 virtual void doInterruptResume(int changes,
682 boost::shared_ptr<TransportWrapper> wrapper);
685 CLIENT_REMOVE = (1<<1),
686 CLIENT_UPDATE = (1<<2),
688 SERVER_REMOVE = (1<<4),
689 SERVER_UPDATE = (1<<5)
691 virtual void testInterruptResumeClientAdd();
692 virtual void testInterruptResumeClientRemove();
693 virtual void testInterruptResumeClientUpdate();
694 virtual void testInterruptResumeServerAdd();
695 virtual void testInterruptResumeServerRemove();
696 virtual void testInterruptResumeServerUpdate();
697 virtual void testInterruptResumeFull();
699 virtual void testUserSuspendClientAdd();
700 virtual void testUserSuspendClientRemove();
701 virtual void testUserSuspendClientUpdate();
702 virtual void testUserSuspendServerAdd();
703 virtual void testUserSuspendServerRemove();
704 virtual void testUserSuspendServerUpdate();
705 virtual void testUserSuspendFull();
707 virtual void testResendClientAdd();
708 virtual void testResendClientRemove();
709 virtual void testResendClientUpdate();
710 virtual void testResendServerAdd();
711 virtual void testResendServerRemove();
712 virtual void testResendServerUpdate();
713 virtual void testResendFull();
716 * implements testMaxMsg(), testLargeObject(), testLargeObjectEncoded()
717 * using a sequence of items with varying sizes
719 virtual void doVarSizes(bool withMaxMsgSize,
720 bool withLargeObject);
723 * executes a sync with the given options,
724 * checks the result and (optionally) the sync report
726 virtual void doSync(const SyncOptions &options);
727 virtual void doSync(const char *logPrefix,
728 const SyncOptions &options) {
729 SyncPrefix prefix(logPrefix, *this);
735 * A transport wraper wraps a real transport impl and gives user
736 * possibility to do additional work before/after transport operation.
737 * We use TransportFaultInjector to emulate a network failure;
738 * We use UserSuspendInjector to emulate a user suspend after receving
741 class TransportWrapper : public TransportAgent {
743 int m_interruptAtMessage, m_messageCount;
744 boost::shared_ptr<TransportAgent> m_wrappedAgent;
746 SyncOptions *m_options;
750 m_interruptAtMessage = -1;
751 m_wrappedAgent = boost::shared_ptr<TransportAgent>();
755 ~TransportWrapper() {
758 virtual int getMessageCount() { return m_messageCount; }
760 virtual void setURL(const std::string &url) { m_wrappedAgent->setURL(url); }
761 virtual void setContentType(const std::string &type) { m_wrappedAgent->setContentType(type); }
762 virtual void setAgent(boost::shared_ptr<TransportAgent> agent) {m_wrappedAgent = agent;}
763 virtual void setSyncOptions(SyncOptions *options) {m_options = options;}
764 virtual void setInterruptAtMessage (int interrupt) {m_interruptAtMessage = interrupt;}
765 virtual void cancel() { m_wrappedAgent->cancel(); }
766 virtual void shutdown() { m_wrappedAgent->shutdown(); }
768 virtual void rewind() {
770 m_interruptAtMessage = -1;
773 m_wrappedAgent.reset();
775 virtual Status wait(bool noReply = false) { return m_status; }
776 virtual void setCallback (TransportCallback cb, void *udata, int interval)
777 { return m_wrappedAgent->setCallback(cb, udata, interval);}
780 /** assert equality, include string in message if unequal */
781 #define CLIENT_TEST_EQUAL( _prefix, \
784 CPPUNIT_ASSERT_EQUAL_MESSAGE( std::string(_prefix) + ": " + #_expected + " == " + #_actual, \
788 /** execute _x and then check the status of the _source pointer */
789 #define SOURCE_ASSERT_NO_FAILURE(_source, _x) \
791 CPPUNIT_ASSERT_NO_THROW(_x); \
792 CPPUNIT_ASSERT((_source)); \
795 /** check _x for true and then the status of the _source pointer */
796 #define SOURCE_ASSERT(_source, _x) \
798 CPPUNIT_ASSERT(_x); \
799 CPPUNIT_ASSERT((_source)); \
802 /** check that _x evaluates to a specific value and then the status of the _source pointer */
803 #define SOURCE_ASSERT_EQUAL(_source, _value, _x) \
805 CPPUNIT_ASSERT_EQUAL(_value, _x); \
806 CPPUNIT_ASSERT((_source)); \
809 /** same as SOURCE_ASSERT() with a specific failure message */
810 #define SOURCE_ASSERT_MESSAGE(_message, _source, _x) \
812 CPPUNIT_ASSERT_MESSAGE((_message), (_x)); \
813 CPPUNIT_ASSERT((_source)); \
817 * convenience macro for adding a test name like a function,
818 * to be used inside addTests() of an instance of that class
820 * @param _class class which contains the function
821 * @param _function a function without parameters in that class
823 #define ADD_TEST(_class, _function) \
824 ADD_TEST_TO_SUITE(this, _class, _function)
826 #define ADD_TEST_TO_SUITE(_suite, _class, _function) \
827 _suite->addTest(FilterTest(new CppUnit::TestCaller<_class>(_suite->getName() + "::" #_function, &_class::_function, *this)))
831 #endif // ENABLE_INTEGRATION_TESTS
832 #endif // INCL_TESTSYNCCLIENT