00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INCL_TESTSYNCCLIENT
00020 #define INCL_TESTSYNCCLIENT
00021
00025 #include <string>
00026 #include <vector>
00027 #include "spds/SyncSource.h"
00028 #include "spds/SyncReport.h"
00029
00030 #ifdef ENABLE_INTEGRATION_TESTS
00031
00032 #include <cppunit/TestSuite.h>
00033 #include <cppunit/TestAssert.h>
00034 #include <cppunit/TestFixture.h>
00035
00045 class CheckSyncReport {
00046 public:
00047 CheckSyncReport(int clAdded = -1, int clUpdated = -1, int clDeleted = -1,
00048 int srAdded = -1, int srUpdated = -1, int srDeleted = -1) :
00049 clientAdded(clAdded),
00050 clientUpdated(clUpdated),
00051 clientDeleted(clDeleted),
00052 serverAdded(srAdded),
00053 serverUpdated(srUpdated),
00054 serverDeleted(srDeleted)
00055 {}
00056
00057 const int clientAdded, clientUpdated, clientDeleted,
00058 serverAdded, serverUpdated, serverDeleted;
00059
00067 virtual void check(int res, SyncReport &report) const;
00068 };
00069
00070 class LocalTests;
00071 class SyncTests;
00072
00116 class ClientTest {
00117 public:
00118 ClientTest(int serverSleepSec = 0, const std::string &serverLog= "");
00119 virtual ~ClientTest();
00120
00129 virtual void registerTests();
00130
00131 class Config;
00132
00143 virtual LocalTests *createLocalTests(const std::string &name, int sourceParam, ClientTest::Config &co);
00144
00153 virtual SyncTests *createSyncTests(const std::string &name, std::vector<int> sourceIndices, bool isClientA = true);
00154
00158 static int dump(ClientTest &client, SyncSource &source, const char *file);
00159
00163 static int import(ClientTest &client, SyncSource &source, const char *file);
00164
00169 static bool compare(ClientTest &client, const char *fileA, const char *fileB);
00170
00171 struct Config;
00172
00187 static void getTestData(const char *type, Config &config);
00188
00196 struct Config {
00200 const char *sourceName;
00201
00205 const char *uri;
00206
00230 typedef SyncSource *(*createsource_t)(ClientTest &client, int source, bool isSourceA);
00231
00237 createsource_t createSourceA;
00238
00255 createsource_t createSourceB;
00256
00264 const char *templateItem;
00265
00270 const char *uniqueProperties;
00271
00275 int numItems;
00276
00281 const char *sizeProperty;
00282
00287 const char *insertItem;
00288
00294 const char *updateItem;
00295
00301 const char *complexUpdateItem;
00302
00307 const char *mergeItem1;
00308
00315 const char *mergeItem2;
00316
00328 int (*dump)(ClientTest &client, SyncSource &source, const char *file);
00329
00342 int (*import)(ClientTest &client, SyncSource &source, const char *file);
00343
00351 bool (*compare)(ClientTest &client, const char *fileA, const char *fileB);
00352
00356 const char *testcases;
00357
00362 const char *type;
00363 };
00364
00369 virtual int getNumSources() = 0;
00370
00377 virtual void getSourceConfig(int source, Config &config) = 0;
00378
00388 virtual ClientTest *getClientB() = 0;
00389
00395 virtual bool isB64Enabled() = 0;
00396
00416 virtual int sync(
00417 const int *activeSources,
00418 SyncMode syncMode,
00419 const CheckSyncReport &checkReport,
00420 long maxMsgSize = 0,
00421 long maxObjSize = 0,
00422 bool loSupport = false,
00423 const char *encoding = "") = 0;
00424
00434 virtual void postSync(int res, const std::string &logname);
00435
00436 protected:
00440 int serverSleepSeconds;
00441
00447 std::string serverLogFileName;
00448
00449 private:
00455 void *factory;
00456 };
00457
00462 class CreateSource {
00463 public:
00464 CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
00465 createSource(createSourceParam),
00466 client(clientParam),
00467 source(sourceParam),
00468 isSourceA(isSourceAParam) {}
00469
00470 SyncSource *operator() () {
00471 CPPUNIT_ASSERT(createSource);
00472 return createSource(client, source, isSourceA);
00473 }
00474
00475 const ClientTest::Config::createsource_t createSource;
00476 ClientTest &client;
00477 const int source;
00478 const bool isSourceA;
00479 };
00480
00481
00486 class LocalTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00487 public:
00489 ClientTest &client;
00490
00492 const int source;
00493
00495 const ClientTest::Config config;
00496
00498 CreateSource createSourceA, createSourceB;
00499
00500 LocalTests(const std::string &name, ClientTest &cl, int sourceParam, ClientTest::Config &co) :
00501 CppUnit::TestSuite(name),
00502 client(cl),
00503 source(sourceParam),
00504 config(co),
00505 createSourceA(co.createSourceA, cl, sourceParam, true),
00506 createSourceB(co.createSourceB, cl, sourceParam, false)
00507 {}
00508
00514 virtual void addTests();
00515
00523 virtual void insert(CreateSource createSource, const char *data);
00524
00532 virtual void update(CreateSource createSource, const char *data, bool check = true);
00533
00535 virtual void deleteAll(CreateSource createSource);
00536
00545 virtual void compareDatabases(const char *refFile, SyncSource ©, bool raiseAssert = true);
00546
00557 virtual int insertManyItems(CreateSource createSource, int startIndex = 1, int numItems = 0, int size = -1);
00558
00559
00560
00561
00562 virtual void testOpen();
00563 virtual void testIterateTwice();
00564 virtual void testSimpleInsert();
00565 virtual void testLocalDeleteAll();
00566 virtual void testComplexInsert();
00567 virtual void testLocalUpdate();
00568 virtual void testChanges();
00569 virtual void testImport();
00570 virtual void testImportDelete();
00571 virtual void testManyChanges();
00572 };
00573
00574 enum itemType {
00575 NEW_ITEMS,
00576 UPDATED_ITEMS,
00577 DELETED_ITEMS,
00578 TOTAL_ITEMS
00579 };
00580
00587 int countItemsOfType(SyncSource *source, itemType type);
00588
00594 class SyncTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00595 public:
00597 ClientTest &client;
00598
00599 SyncTests(const std::string &name, ClientTest &cl, std::vector<int> sourceIndices, bool isClientA = true);
00600 ~SyncTests();
00601
00603 virtual void addTests();
00604
00605 protected:
00607 std::vector< std::pair<int, LocalTests *> > sources;
00608 typedef std::vector< std::pair<int, LocalTests *> >::iterator source_it;
00609
00611 int *sourceArray;
00612
00614 SyncTests *accessClientB;
00615
00616 enum DeleteAllMode {
00617 DELETE_ALL_SYNC,
00620 DELETE_ALL_REFRESH
00621 };
00622
00624 virtual void compareDatabases();
00625
00627 virtual void deleteAll(DeleteAllMode mode = DELETE_ALL_SYNC);
00628
00630 virtual void doCopy();
00631
00637 virtual void refreshClient();
00638
00639
00640
00641
00642 virtual void testTwoWaySync() {
00643 sync(SYNC_TWO_WAY);
00644 }
00645
00646
00647 virtual void testSlowSync() {
00648 sync(SYNC_SLOW);
00649 }
00650
00651 virtual void testRefreshFromServerSync() {
00652 sync(SYNC_REFRESH_FROM_SERVER);
00653 }
00654
00655
00656 virtual void testRefreshFromClientSync() {
00657 sync(SYNC_REFRESH_FROM_CLIENT);
00658 }
00659
00660
00661 virtual void testDeleteAllSync() {
00662 deleteAll(DELETE_ALL_SYNC);
00663 }
00664
00665 virtual void testDeleteAllRefresh();
00666 virtual void testRefreshSemantic();
00667 virtual void testRefreshStatus();
00668
00669
00670 void testCopy() {
00671 doCopy();
00672 compareDatabases();
00673 }
00674
00675 virtual void testUpdate();
00676 virtual void testComplexUpdate();
00677 virtual void testDelete();
00678 virtual void testMerge();
00679 virtual void testTwinning();
00680 virtual void testOneWayFromServer();
00681 virtual void testOneWayFromClient();
00682 virtual void testItems();
00683 virtual void testAddUpdate();
00684
00685
00686 void testMaxMsg() {
00687 doVarSizes(true, false, NULL);
00688 }
00689
00690 void testLargeObject() {
00691 doVarSizes(true, true, NULL);
00692 }
00693
00694 void testLargeObjectBin() {
00695 doVarSizes(true, true, "bin");
00696 }
00697
00698 void testLargeObjectEncoded() {
00699 doVarSizes(true, true, "b64");
00700 }
00701
00702 virtual void testManyItems();
00703
00704
00709 virtual void doVarSizes(bool withMaxMsgSize,
00710 bool withLargeObject,
00711 const char *encoding);
00712
00717 virtual void sync(SyncMode syncMode,
00718 const std::string &logprefix = "",
00719 CheckSyncReport checkReport = CheckSyncReport(),
00720 long maxMsgSize = 0,
00721 long maxObjSize = 0,
00722 bool loSupport = false,
00723 const char *encoding = "");
00724 };
00725
00726
00728 #define CLIENT_TEST_EQUAL( _prefix, \
00729 _expected, \
00730 _actual ) \
00731 CPPUNIT_ASSERT_EQUAL_MESSAGE( std::string(_prefix) + ": " + #_expected + " == " + #_actual, \
00732 _expected, \
00733 _actual )
00734
00736 #define SOURCE_ASSERT_NO_FAILURE(_source, _x) \
00737 { \
00738 CPPUNIT_ASSERT_NO_THROW(_x); \
00739 CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00740 }
00741
00743 #define SOURCE_ASSERT(_source, _x) \
00744 { \
00745 CPPUNIT_ASSERT(_x); \
00746 CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00747 }
00748
00750 #define SOURCE_ASSERT_EQUAL(_source, _value, _x) \
00751 { \
00752 CPPUNIT_ASSERT_EQUAL(_value, _x); \
00753 CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00754 }
00755
00757 #define SOURCE_ASSERT_MESSAGE(_message, _source, _x) \
00758 { \
00759 CPPUNIT_ASSERT_MESSAGE((_message), (_x)); \
00760 CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00761 }
00762
00763
00771 #define ADD_TEST(_class, _function) \
00772 addTest(new CppUnit::TestCaller<_class>(getName() + "::" #_function, &_class::_function, *this))
00773
00774
00775 #endif // ENABLE_INTEGRATION_TESTS
00776
00779 #endif // INCL_TESTSYNCCLIENT