clienttest.h

来自「funambol window mobile客户端源代码」· C头文件 代码 · 共 854 行 · 第 1/3 页

H
854
字号
/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#ifndef INCL_TESTSYNCCLIENT
#define INCL_TESTSYNCCLIENT
/** @cond API */
/** @addtogroup Client */
/** @{ */

#include <string>
#include <vector>
#include <list>
#include "spds/SyncSource.h"
#include "spds/SyncReport.h"

#ifdef ENABLE_INTEGRATION_TESTS

#include <cppunit/TestSuite.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include "base/globalsdef.h"

BEGIN_NAMESPACE

/**
 * This class encapsulates logging and checking of a SyncReport.
 * When constructed with default parameters, no checking will be done.
 * Otherwise the sync report has to contain exactly the expected result.
 * When multiple sync sources are active, @b all of them have to behave
 * alike (which is how the tests are constructed).
 *
 * No item is ever supposed to fail.
 */
class CheckSyncReport {
  public:
    CheckSyncReport(int clAdded = -1, int clUpdated = -1, int clDeleted = -1,
                    int srAdded = -1, int srUpdated = -1, int srDeleted = -1) :
        clientAdded(clAdded),
        clientUpdated(clUpdated),
        clientDeleted(clDeleted),
        serverAdded(srAdded),
        serverUpdated(srUpdated),
        serverDeleted(srDeleted)
        {}

    virtual ~CheckSyncReport() {}

    const int clientAdded, clientUpdated, clientDeleted,
        serverAdded, serverUpdated, serverDeleted;

    /**
     * checks that the sync completed as expected and throws
     * CPPUnit exceptions if something is wrong
     *
     * @param res     return code from SyncClient::sync()
     * @param report  the sync report stored in the SyncClient
     */
    virtual void check(int res, SyncReport &report) const;
};

class LocalTests;
class SyncTests;

/**
 * This is the interface expected by the testing framework for sync
 * clients.  It defines several methods that a derived class must
 * implement if it wants to use that framework. Note that this class
 * itself is not derived from SyncClient. This gives a user of this
 * framework the freedom to implement it in two different ways:
 * - implement a class derived from both SyncClient and ClientTest
 * - add testing of an existing subclass of SyncClient by implementing
 *   a ClientTest which uses that subclass
 *
 * The client is expected to support change tracking for multiple
 * servers. Although the framework always always tests against the
 * same server, for most tests it is necessary to access the database
 * without affecting the next synchronization with the server. This is
 * done by asking the client for two different sync sources via
 * Config::createSourceA and Config::createSourceB which have to
 * create them in a suitable way - pretty much as if the client was
 * synchronized against different server. A third, different change
 * tracking is needed for real synchronizations of the data.
 *
 * Furthermore the client is expected to support multiple data sources
 * of the same kind, f.i. two different address books. This is used to
 * test full client A <-> server <-> client B synchronizations in some
 * tests or to check server modifications done by client A with a
 * synchronization against client B. In those tests client A is mapped
 * to the first data source and client B to the second one.
 *
 * Finally the SyncSource API is used in slightly different ways which
 * go beyond what is normally expected from a SyncSource implementation:
 * - beginSync() may be called without setting a sync mode:
 *   when SyncSource::getSyncMode() returns SYNC_NONE the source is
 *   expected to make itself ready to iterate over all, new, updated and
 *   deleted items
 * - items may be added via SyncSource::addItem() with a type of "raw":
 *   this implies that the type is the one used for items in the
 *   ClientTest::Config below
 *
 * Handling configuration and creating classes is entirely done by the
 * subclass of ClientTest, the frameworks makes no assumptions
 * about how this is done. Instead it queries the ClientTest for
 * properties (like available sync sources) and then creates several
 * tests.
 */
class ClientTest {
  public:
    ClientTest(int serverSleepSec = 0, const std::string &serverLog= "");
    virtual ~ClientTest();

    /**
     * This function registers tests using this instance of ClientTest for
     * later use during a test run.
     *
     * The instance must remain valid until after the tests were
     * run. To run them use a separate test runner, like the one from
     * client-test-main.cpp.
     */
    virtual void registerTests();

    struct Config;

    /**
     * Creates an instance of LocalTests (default implementation) or a
     * class derived from it.  LocalTests provides tests which cover
     * the SyncSource interface and can be executed without a SyncML
     * server. It also contains utility functions for working with
     * SyncSources.
     *
     * A ClientTest implementation can, but doesn't have to extend
     * these tests by instantiating a derived class here.
     */
    virtual LocalTests *createLocalTests(const std::string &name, int sourceParam, ClientTest::Config &co);

    /**
     * Creates an instance of SyncTests (default) or a class derived
     * from it.  SyncTests provides tests which cover the actual
     * interaction with a SyncML server.
     *
     * A ClientTest implementation can, but doesn't have to extend
     * these tests by instantiating a derived class here.
     */
    virtual SyncTests *createSyncTests(const std::string &name, std::vector<int> sourceIndices, bool isClientA = true);

    /**
     * utility function for dumping items which are C strings with blank lines as separator
     */
    static int dump(ClientTest &client, SyncSource &source, const char *file);

    /**
     * utility function for importing items with blank lines as separator
     */
    static int import(ClientTest &client, SyncSource &source, const char *file);

    /**
     * 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);

    /**
     * A derived class can use this call to get default test
     * cases, but still has to add callbacks which create sources
     * and execute a sync session.
     *
     * Some of the test cases are compiled into the library, other
     * depend on the auxiliary files from the "test" directory.
     * Currently supported types:
     * - vcard30 = vCard 3.0 contacts
     * - vcard21 = vCard 2.1 contacts
     * - ical20 = iCal 2.0 events
     * - vcal10 = vCal 1.0 events
     * - itodo20 = iCal 2.0 tasks
     */
    static void getTestData(const char *type, Config &config);

    /**
     * Information about a data source. For the sake of simplicity all
     * items pointed to are owned by the ClientTest and must
     * remain valid throughout a test session. Not setting a pointer
     * is okay, but it will disable all tests that need the
     * information.
     */
    struct Config {
        /**
         * The name is used in test names and has to be set.
         */
        const char *sourceName;

        /**
         * A default URI to be used when creating a client config.
         */
        const char *uri;

        /**
         * A member function of a subclass which is called to create a
         * sync source referencing the data. This is used in tests of
         * the SyncSource API itself as well as in tests which need to
         * modify or check the data sources used during synchronization.
         *
         * The test framework will call beginSync() and then some of
         * the functions it wants to test. After a successful test it
         * will call endSync() which is then expected to store all
         * changes persistently. Creating a sync source again
         * with the same call should not report any
         * new/updated/deleted items until such changes are made via
         * another sync source.
         *
         * The instance will be deleted by the caller. Because this
         * may be in the error case or in an exception handler,
         * the sync source's desctructor should not thow exceptions.
         *
         * @param client    the same instance to which this config belongs
         * @param source    index of the data source (from 0 to ClientTest::getNumSources() - 1)
         * @param isSourceA true if the requested SyncSource is the first one accessing that
         *                  data, otherwise the second
         */
        typedef SyncSource *(*createsource_t)(ClientTest &client, int source, bool isSourceA);

        /**
         * Creates a sync source which references the primary database;
         * it may report the same changes as the sync source used during
         * sync tests.
         */
        createsource_t createSourceA;

        /**
         * A second sync source also referencing the primary data
         * source, but configured so that it tracks changes
         * independently from the the primary sync source.
         *
         * In local tests the usage is like this:
         * - add item via first SyncSource
         * - iterate over new items in second SyncSource
         * - check that it lists the added item
         *
         * In tests with a server the usage is:
         * - do a synchronization with the server
         * - iterate over items in second SyncSource
         * - check that the total number and number of
         *   added/updated/deleted items is as expected
         */
        createsource_t createSourceB;

        /**
         * The framework can generate vCard and vCalendar/iCalendar items
         * automatically by copying a template item and modifying certain
         * properties.
         *
         * This is the template for these automatically generated items.
         */
        const char *templateItem;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?