test/ClientTest.h

00001 /*
00002  * Funambol is a mobile platform developed by Funambol, Inc.
00003  * Copyright (C) 2003 - 2007 Funambol, Inc.
00004  *
00005  * This program is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Affero General Public License version 3 as published by
00007  * the Free Software Foundation with the addition of the following permission
00008  * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
00009  * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
00010  * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
00011  *
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00015  * details.
00016  *
00017  * You should have received a copy of the GNU Affero General Public License
00018  * along with this program; if not, see http://www.gnu.org/licenses or write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00020  * MA 02110-1301 USA.
00021  *
00022  * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
00023  * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
00024  *
00025  * The interactive user interfaces in modified source and object code versions
00026  * of this program must display Appropriate Legal Notices, as required under
00027  * Section 5 of the GNU Affero General Public License version 3.
00028  *
00029  * In accordance with Section 7(b) of the GNU Affero General Public License
00030  * version 3, these Appropriate Legal Notices must retain the display of the
00031  * "Powered by Funambol" logo. If the display of the logo is not reasonably
00032  * feasible for technical reasons, the Appropriate Legal Notices must display
00033  * the words "Powered by Funambol".
00034  */
00035 
00036 #ifndef INCL_TESTSYNCCLIENT
00037 #define INCL_TESTSYNCCLIENT
00038 
00042 #include <string>
00043 #include <vector>
00044 #include <list>
00045 #include "spds/SyncSource.h"
00046 #include "spds/SyncReport.h"
00047 
00048 #ifdef ENABLE_INTEGRATION_TESTS
00049 
00050 #include <cppunit/TestSuite.h>
00051 #include <cppunit/TestAssert.h>
00052 #include <cppunit/TestFixture.h>
00053 #include "base/globalsdef.h"
00054 #include "MappingsTest.h"
00055 USE_NAMESPACE
00056 
00066 class CheckSyncReport {
00067   public:
00068     CheckSyncReport(int clAdded = -1, int clUpdated = -1, int clDeleted = -1,
00069                     int srAdded = -1, int srUpdated = -1, int srDeleted = -1) :
00070         clientAdded(clAdded),
00071         clientUpdated(clUpdated),
00072         clientDeleted(clDeleted),
00073         serverAdded(srAdded),
00074         serverUpdated(srUpdated),
00075         serverDeleted(srDeleted)
00076         {}
00077 
00078     virtual ~CheckSyncReport() {}
00079 
00080     const int clientAdded, clientUpdated, clientDeleted,
00081         serverAdded, serverUpdated, serverDeleted;
00082 
00090     virtual void check(int res, SyncReport &report) const;
00091 };
00092 
00093 class LocalTests;
00094 class SyncTests;
00095 
00139 class ClientTest {
00140   public:
00141     ClientTest(int serverSleepSec = 0, const std::string &serverLog= "");
00142     virtual ~ClientTest();
00143 
00152     virtual void registerTests();
00153 
00154     struct Config;
00155 
00166     virtual LocalTests *createLocalTests(const std::string &name, int sourceParam, ClientTest::Config &co);
00167 
00176     virtual SyncTests *createSyncTests(const std::string &name, std::vector<int> sourceIndices, bool isClientA = true);
00177 
00181     static int dump(ClientTest &client, SyncSource &source, const char *file);
00182 
00186     static int import(ClientTest &client, SyncSource &source, const char *file);
00187 
00192     static bool compare(ClientTest &client, const char *fileA, const char *fileB);
00193 
00208     static void getTestData(const char *type, Config &config);
00209 
00217     struct Config {
00221         const char *sourceName;
00222 
00226         const char *uri;
00227 
00251         typedef SyncSource *(*createsource_t)(ClientTest &client, int source, bool isSourceA);
00252 
00258         createsource_t createSourceA;
00259 
00276         createsource_t createSourceB;
00277 
00285         const char *templateItem;
00286 
00291         const char *uniqueProperties;
00292 
00296         int numItems;
00297 
00302         const char *sizeProperty;
00303 
00308         const char *insertItem;
00309 
00315         const char *updateItem;
00316 
00322         const char *complexUpdateItem;
00323 
00328         const char *mergeItem1;
00329 
00336         const char *mergeItem2;
00337 
00354         const char *parentItem, *childItem;
00355 
00361 #ifndef LINKED_ITEMS_RELAXED_SEMANTIC
00362 # define LINKED_ITEMS_RELAXED_SEMANTIC 1
00363 #endif
00364 
00376         int (*dump)(ClientTest &client, SyncSource &source, const char *file);
00377 
00390         int (*import)(ClientTest &client, SyncSource &source, const char *file);
00391 
00399         bool (*compare)(ClientTest &client, const char *fileA, const char *fileB);
00400 
00404         const char *testcases;
00405 
00410         const char *type;
00411     };
00412 
00417     virtual int getNumSources() = 0;
00418 
00425     virtual void getSourceConfig(int source, Config &config) = 0;
00426 
00436     virtual ClientTest *getClientB() = 0;
00437 
00443     virtual bool isB64Enabled() = 0;
00444 
00464     virtual int sync(
00465         const int *activeSources,
00466         SyncMode syncMode,
00467         const CheckSyncReport &checkReport,
00468         long maxMsgSize = 0,
00469         long maxObjSize = 0,
00470         bool loSupport = false,
00471         const char *encoding = "") = 0;
00472 
00482     virtual void postSync(int res, const std::string &logname);
00483 
00484   protected:
00488     int serverSleepSeconds;
00489 
00495     std::string serverLogFileName;
00496 
00497   private:
00503     void *factory;
00504 };
00505 
00510 class CreateSource {
00511 public:
00512     CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
00513         createSource(createSourceParam),
00514         client(clientParam),
00515         source(sourceParam),
00516         isSourceA(isSourceAParam) {}
00517 
00518     SyncSource *operator() () {
00519         CPPUNIT_ASSERT(createSource);
00520         return createSource(client, source, isSourceA);
00521     }
00522 
00523     const ClientTest::Config::createsource_t createSource;
00524     ClientTest &client;
00525     const int source;
00526     const bool isSourceA;
00527 };
00528 
00529 
00534 class LocalTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00535 public:
00537     ClientTest &client;
00538 
00540     const int source;
00541 
00543     const ClientTest::Config config;
00544 
00546     CreateSource createSourceA, createSourceB;
00547 
00548     LocalTests(const std::string &name, ClientTest &cl, int sourceParam, ClientTest::Config &co) :
00549         CppUnit::TestSuite(name),
00550         client(cl),
00551         source(sourceParam),
00552         config(co),
00553         createSourceA(co.createSourceA, cl, sourceParam, true),
00554         createSourceB(co.createSourceB, cl, sourceParam, false)
00555         {}
00556 
00562     virtual void addTests();
00563 
00574     virtual std::string insert(CreateSource createSource, const char *data, bool relaxed = false);
00575 
00583     virtual void update(CreateSource createSource, const char *data, bool check = true);
00584 
00586     virtual void deleteAll(CreateSource createSource);
00587 
00596     virtual void compareDatabases(const char *refFile, SyncSource &copy, bool raiseAssert = true);
00597 
00608     virtual int insertManyItems(CreateSource createSource, int startIndex = 1, int numItems = 0, int size = -1);
00609 
00610 
00611     /* for more information on the different tests see their implementation */
00612 
00613     virtual void testOpen();
00614     virtual void testIterateTwice();
00615     virtual void testSimpleInsert();
00616     virtual void testLocalDeleteAll();
00617     virtual void testComplexInsert();
00618     virtual void testLocalUpdate();
00619     virtual void testChanges();
00620     virtual void testImport();
00621     virtual void testImportDelete();
00622     virtual void testManyChanges();
00623     virtual void testLinkedItemsParent();
00624     virtual void testLinkedItemsChild();
00625     virtual void testLinkedItemsParentChild();
00626     virtual void testLinkedItemsChildParent();
00627     virtual void testLinkedItemsChildChangesParent();
00628     virtual void testLinkedItemsRemoveParentFirst();
00629     virtual void testLinkedItemsRemoveNormal();
00630     virtual void testLinkedItemsInsertParentTwice();
00631     virtual void testLinkedItemsInsertChildTwice();
00632     virtual void testLinkedItemsParentUpdate();
00633     virtual void testLinkedItemsUpdateChild();
00634     virtual void testLinkedItemsInsertBothUpdateChild();
00635     virtual void testLinkedItemsInsertBothUpdateParent();
00636 
00637 };
00638 
00639 enum itemType {
00640     NEW_ITEMS,
00641     UPDATED_ITEMS,
00642     DELETED_ITEMS,
00643     TOTAL_ITEMS
00644 };
00645 
00652 int countItemsOfType(SyncSource *source, itemType type);
00653 
00654 typedef std::list<std::string> UIDList;
00658 UIDList listItemsOfType(SyncSource *source, itemType type);
00659 
00665 class SyncTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00666 public:
00668     ClientTest &client;
00669 
00670     SyncTests(const std::string &name, ClientTest &cl, std::vector<int> sourceIndices, bool isClientA = true);
00671     ~SyncTests();
00672 
00674     virtual void addTests();
00675 
00676 protected:
00678     std::vector< std::pair<int, LocalTests *> > sources;
00679     typedef std::vector< std::pair<int, LocalTests *> >::iterator source_it;
00680 
00682     int *sourceArray;
00683 
00685     SyncTests *accessClientB;
00686 
00687     enum DeleteAllMode {
00688         DELETE_ALL_SYNC,   
00691         DELETE_ALL_REFRESH 
00692     };
00693 
00695     virtual void compareDatabases();
00696 
00698     virtual void deleteAll(DeleteAllMode mode = DELETE_ALL_SYNC);
00699 
00701     virtual void doCopy();
00702 
00708     virtual void refreshClient();
00709 
00710     /* for more information on the different tests see their implementation */
00711 
00712     // do a two-way sync without additional checks
00713     virtual void testTwoWaySync() {
00714         sync(SYNC_TWO_WAY);
00715     }
00716 
00717     // do a slow sync without additional checks
00718     virtual void testSlowSync() {
00719         sync(SYNC_SLOW);
00720     }
00721     // do a refresh from server sync without additional checks
00722     virtual void testRefreshFromServerSync() {
00723         sync(SYNC_REFRESH_FROM_SERVER);
00724     }
00725 
00726     // do a refresh from client sync without additional checks
00727     virtual void testRefreshFromClientSync() {
00728         sync(SYNC_REFRESH_FROM_CLIENT);
00729     }
00730 
00731     // delete all items, locally and on server using two-way sync
00732     virtual void testDeleteAllSync() {
00733         deleteAll(DELETE_ALL_SYNC);
00734     }
00735 
00736     virtual void testDeleteAllRefresh();
00737     virtual void testRefreshSemantic();
00738     virtual void testRefreshStatus();
00739 
00740     // test that a two-way sync copies an item from one address book into the other
00741     void testCopy() {
00742         doCopy();
00743         compareDatabases();
00744     }
00745 
00746     virtual void testUpdate();
00747     virtual void testComplexUpdate();
00748     virtual void testDelete();
00749     virtual void testMerge();
00750     virtual void testTwinning();
00751     virtual void testOneWayFromServer();
00752     virtual void testOneWayFromClient();
00753     virtual void testItems();
00754     virtual void testAddUpdate();
00755 
00756     // test copying with maxMsg and no large object support
00757     void testMaxMsg() {
00758         doVarSizes(true, false, NULL);
00759     }
00760     // test copying with maxMsg and large object support
00761     void testLargeObject() {
00762         doVarSizes(true, true, NULL);
00763     }
00764     // test copying with maxMsg and large object support using explicit "bin" encoding
00765     void testLargeObjectBin() {
00766         doVarSizes(true, true, "bin");
00767     }
00768     // test copying with maxMsg and large object support using B64 encoding
00769     void testLargeObjectEncoded() {
00770         doVarSizes(true, true, "b64");
00771     }
00772 
00773     virtual void testManyItems();
00774 
00775     // Check the tests
00776     virtual void testMappings() {
00777         MappingsTest mapping;
00778         mapping.runTests();        
00779     }
00780 
00785     virtual void doVarSizes(bool withMaxMsgSize,
00786                             bool withLargeObject,
00787                             const char *encoding);
00788 
00793     virtual void sync(SyncMode syncMode,
00794                       const std::string &logprefix = "",
00795                       CheckSyncReport checkReport = CheckSyncReport(),
00796                       long maxMsgSize = 0,
00797                       long maxObjSize = 0,
00798                       bool loSupport = false,
00799                       const char *encoding = "");
00800 };
00801 
00802 
00804 #define CLIENT_TEST_EQUAL( _prefix, \
00805                            _expected, \
00806                            _actual ) \
00807     CPPUNIT_ASSERT_EQUAL_MESSAGE( std::string(_prefix) + ": " + #_expected + " == " + #_actual, \
00808                                   _expected, \
00809                                   _actual )
00810 
00812 #define SOURCE_ASSERT_NO_FAILURE(_source, _x) \
00813 { \
00814     CPPUNIT_ASSERT_NO_THROW(_x); \
00815     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00816 }
00817 
00819 #define SOURCE_ASSERT(_source, _x) \
00820 { \
00821     CPPUNIT_ASSERT(_x); \
00822     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00823 }
00824 
00826 #define SOURCE_ASSERT_EQUAL(_source, _value, _x) \
00827 { \
00828     CPPUNIT_ASSERT_EQUAL(_value, _x); \
00829     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00830 }
00831 
00833 #define SOURCE_ASSERT_MESSAGE(_message, _source, _x)     \
00834 { \
00835     CPPUNIT_ASSERT_MESSAGE((_message), (_x)); \
00836     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00837 }
00838 
00839 
00847 #define ADD_TEST(_class, _function) \
00848     addTest(new CppUnit::TestCaller<_class>(getName() + "::" #_function, &_class::_function, *this))
00849 
00850 
00851 #endif // ENABLE_INTEGRATION_TESTS
00852 
00853 
00856 #endif // INCL_TESTSYNCCLIENT

Generated on Wed Jan 14 17:15:37 2009 for Funambol C++ Client Library by  doxygen 1.5.2