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 "spds/SyncSource.h"
00045 #include "spds/SyncReport.h"
00046 
00047 #ifdef ENABLE_INTEGRATION_TESTS
00048 
00049 #include <cppunit/TestSuite.h>
00050 #include <cppunit/TestAssert.h>
00051 #include <cppunit/TestFixture.h>
00052 
00062 class CheckSyncReport {
00063   public:
00064     CheckSyncReport(int clAdded = -1, int clUpdated = -1, int clDeleted = -1,
00065                     int srAdded = -1, int srUpdated = -1, int srDeleted = -1) :
00066         clientAdded(clAdded),
00067         clientUpdated(clUpdated),
00068         clientDeleted(clDeleted),
00069         serverAdded(srAdded),
00070         serverUpdated(srUpdated),
00071         serverDeleted(srDeleted)
00072         {}
00073 
00074     const int clientAdded, clientUpdated, clientDeleted,
00075         serverAdded, serverUpdated, serverDeleted;
00076 
00084     virtual void check(int res, SyncReport &report) const;
00085 };
00086 
00087 class LocalTests;
00088 class SyncTests;
00089 
00133 class ClientTest {
00134   public:
00135     ClientTest(int serverSleepSec = 0, const std::string &serverLog= "");
00136     virtual ~ClientTest();
00137 
00146     virtual void registerTests();
00147 
00148     class Config;
00149 
00160     virtual LocalTests *createLocalTests(const std::string &name, int sourceParam, ClientTest::Config &co);
00161 
00170     virtual SyncTests *createSyncTests(const std::string &name, std::vector<int> sourceIndices, bool isClientA = true);
00171 
00175     static int dump(ClientTest &client, SyncSource &source, const char *file);
00176 
00180     static int import(ClientTest &client, SyncSource &source, const char *file);
00181 
00186     static bool compare(ClientTest &client, const char *fileA, const char *fileB);
00187 
00188     struct Config;
00189 
00204     static void getTestData(const char *type, Config &config);
00205 
00213     struct Config {
00217         const char *sourceName;
00218 
00222         const char *uri;
00223 
00247         typedef SyncSource *(*createsource_t)(ClientTest &client, int source, bool isSourceA);
00248 
00254         createsource_t createSourceA;
00255 
00272         createsource_t createSourceB;
00273 
00281         const char *templateItem;
00282 
00287         const char *uniqueProperties;
00288 
00292         int numItems;
00293 
00298         const char *sizeProperty;
00299 
00304         const char *insertItem;
00305 
00311         const char *updateItem;
00312 
00318         const char *complexUpdateItem;
00319 
00324         const char *mergeItem1;
00325 
00332         const char *mergeItem2;
00333 
00345         int (*dump)(ClientTest &client, SyncSource &source, const char *file);
00346 
00359         int (*import)(ClientTest &client, SyncSource &source, const char *file);
00360 
00368         bool (*compare)(ClientTest &client, const char *fileA, const char *fileB);
00369 
00373         const char *testcases;
00374 
00379         const char *type;
00380     };
00381 
00386     virtual int getNumSources() = 0;
00387 
00394     virtual void getSourceConfig(int source, Config &config) = 0;
00395 
00405     virtual ClientTest *getClientB() = 0;
00406 
00412     virtual bool isB64Enabled() = 0;
00413 
00433     virtual int sync(
00434         const int *activeSources,
00435         SyncMode syncMode,
00436         const CheckSyncReport &checkReport,
00437         long maxMsgSize = 0,
00438         long maxObjSize = 0,
00439         bool loSupport = false,
00440         const char *encoding = "") = 0;
00441 
00451     virtual void postSync(int res, const std::string &logname);
00452 
00453   protected:
00457     int serverSleepSeconds;
00458 
00464     std::string serverLogFileName;
00465 
00466   private:
00472     void *factory;
00473 };
00474 
00479 class CreateSource {
00480 public:
00481     CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
00482         createSource(createSourceParam),
00483         client(clientParam),
00484         source(sourceParam),
00485         isSourceA(isSourceAParam) {}
00486 
00487     SyncSource *operator() () {
00488         CPPUNIT_ASSERT(createSource);
00489         return createSource(client, source, isSourceA);
00490     }
00491 
00492     const ClientTest::Config::createsource_t createSource;
00493     ClientTest &client;
00494     const int source;
00495     const bool isSourceA;
00496 };
00497 
00498 
00503 class LocalTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00504 public:
00506     ClientTest &client;
00507 
00509     const int source;
00510 
00512     const ClientTest::Config config;
00513 
00515     CreateSource createSourceA, createSourceB;
00516 
00517     LocalTests(const std::string &name, ClientTest &cl, int sourceParam, ClientTest::Config &co) :
00518         CppUnit::TestSuite(name),
00519         client(cl),
00520         source(sourceParam),
00521         config(co),
00522         createSourceA(co.createSourceA, cl, sourceParam, true),
00523         createSourceB(co.createSourceB, cl, sourceParam, false)
00524         {}
00525 
00531     virtual void addTests();
00532 
00540     virtual void insert(CreateSource createSource, const char *data);
00541 
00549     virtual void update(CreateSource createSource, const char *data, bool check = true);
00550 
00552     virtual void deleteAll(CreateSource createSource);
00553 
00562     virtual void compareDatabases(const char *refFile, SyncSource &copy, bool raiseAssert = true);
00563 
00574     virtual int insertManyItems(CreateSource createSource, int startIndex = 1, int numItems = 0, int size = -1);
00575 
00576 
00577     /* for more information on the different tests see their implementation */
00578 
00579     virtual void testOpen();
00580     virtual void testIterateTwice();
00581     virtual void testSimpleInsert();
00582     virtual void testLocalDeleteAll();
00583     virtual void testComplexInsert();
00584     virtual void testLocalUpdate();
00585     virtual void testChanges();
00586     virtual void testImport();
00587     virtual void testImportDelete();
00588     virtual void testManyChanges();
00589 };
00590 
00591 enum itemType {
00592     NEW_ITEMS,
00593     UPDATED_ITEMS,
00594     DELETED_ITEMS,
00595     TOTAL_ITEMS
00596 };
00597 
00604 int countItemsOfType(SyncSource *source, itemType type);
00605 
00611 class SyncTests : public CppUnit::TestSuite, public CppUnit::TestFixture {
00612 public:
00614     ClientTest &client;
00615 
00616     SyncTests(const std::string &name, ClientTest &cl, std::vector<int> sourceIndices, bool isClientA = true);
00617     ~SyncTests();
00618 
00620     virtual void addTests();
00621 
00622 protected:
00624     std::vector< std::pair<int, LocalTests *> > sources;
00625     typedef std::vector< std::pair<int, LocalTests *> >::iterator source_it;
00626 
00628     int *sourceArray;
00629 
00631     SyncTests *accessClientB;
00632 
00633     enum DeleteAllMode {
00634         DELETE_ALL_SYNC,   
00637         DELETE_ALL_REFRESH 
00638     };
00639 
00641     virtual void compareDatabases();
00642 
00644     virtual void deleteAll(DeleteAllMode mode = DELETE_ALL_SYNC);
00645 
00647     virtual void doCopy();
00648 
00654     virtual void refreshClient();
00655 
00656     /* for more information on the different tests see their implementation */
00657 
00658     // do a two-way sync without additional checks
00659     virtual void testTwoWaySync() {
00660         sync(SYNC_TWO_WAY);
00661     }
00662 
00663     // do a slow sync without additional checks
00664     virtual void testSlowSync() {
00665         sync(SYNC_SLOW);
00666     }
00667     // do a refresh from server sync without additional checks
00668     virtual void testRefreshFromServerSync() {
00669         sync(SYNC_REFRESH_FROM_SERVER);
00670     }
00671 
00672     // do a refresh from client sync without additional checks
00673     virtual void testRefreshFromClientSync() {
00674         sync(SYNC_REFRESH_FROM_CLIENT);
00675     }
00676 
00677     // delete all items, locally and on server using two-way sync
00678     virtual void testDeleteAllSync() {
00679         deleteAll(DELETE_ALL_SYNC);
00680     }
00681 
00682     virtual void testDeleteAllRefresh();
00683     virtual void testRefreshSemantic();
00684     virtual void testRefreshStatus();
00685 
00686     // test that a two-way sync copies an item from one address book into the other
00687     void testCopy() {
00688         doCopy();
00689         compareDatabases();
00690     }
00691 
00692     virtual void testUpdate();
00693     virtual void testComplexUpdate();
00694     virtual void testDelete();
00695     virtual void testMerge();
00696     virtual void testTwinning();
00697     virtual void testOneWayFromServer();
00698     virtual void testOneWayFromClient();
00699     virtual void testItems();
00700     virtual void testAddUpdate();
00701 
00702     // test copying with maxMsg and no large object support
00703     void testMaxMsg() {
00704         doVarSizes(true, false, NULL);
00705     }
00706     // test copying with maxMsg and large object support
00707     void testLargeObject() {
00708         doVarSizes(true, true, NULL);
00709     }
00710     // test copying with maxMsg and large object support using explicit "bin" encoding
00711     void testLargeObjectBin() {
00712         doVarSizes(true, true, "bin");
00713     }
00714     // test copying with maxMsg and large object support using B64 encoding
00715     void testLargeObjectEncoded() {
00716         doVarSizes(true, true, "b64");
00717     }
00718 
00719     virtual void testManyItems();
00720 
00721 
00726     virtual void doVarSizes(bool withMaxMsgSize,
00727                             bool withLargeObject,
00728                             const char *encoding);
00729 
00734     virtual void sync(SyncMode syncMode,
00735                       const std::string &logprefix = "",
00736                       CheckSyncReport checkReport = CheckSyncReport(),
00737                       long maxMsgSize = 0,
00738                       long maxObjSize = 0,
00739                       bool loSupport = false,
00740                       const char *encoding = "");
00741 };
00742 
00743 
00745 #define CLIENT_TEST_EQUAL( _prefix, \
00746                            _expected, \
00747                            _actual ) \
00748     CPPUNIT_ASSERT_EQUAL_MESSAGE( std::string(_prefix) + ": " + #_expected + " == " + #_actual, \
00749                                   _expected, \
00750                                   _actual )
00751 
00753 #define SOURCE_ASSERT_NO_FAILURE(_source, _x) \
00754 { \
00755     CPPUNIT_ASSERT_NO_THROW(_x); \
00756     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00757 }
00758 
00760 #define SOURCE_ASSERT(_source, _x) \
00761 { \
00762     CPPUNIT_ASSERT(_x); \
00763     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00764 }
00765 
00767 #define SOURCE_ASSERT_EQUAL(_source, _value, _x) \
00768 { \
00769     CPPUNIT_ASSERT_EQUAL(_value, _x); \
00770     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00771 }
00772 
00774 #define SOURCE_ASSERT_MESSAGE(_message, _source, _x)     \
00775 { \
00776     CPPUNIT_ASSERT_MESSAGE((_message), (_x)); \
00777     CPPUNIT_ASSERT((_source) && (!(_source)->getReport() || (_source)->getReport()->getState() != SOURCE_ERROR)); \
00778 }
00779 
00780 
00788 #define ADD_TEST(_class, _function) \
00789     addTest(new CppUnit::TestCaller<_class>(getName() + "::" #_function, &_class::_function, *this))
00790 
00791 
00792 #endif // ENABLE_INTEGRATION_TESTS
00793 
00796 #endif // INCL_TESTSYNCCLIENT

Generated on Thu Mar 6 14:25:06 2008 for Funambol C++ Client Library by  doxygen 1.5.2