use the new C++ client library testing framework

git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@291 15ad00c4-1369-45f4-8270-35d70d36bdcd
This commit is contained in:
Patrick Ohly 2006-12-01 22:50:17 +00:00
parent 9b64d15b58
commit f7404e6f54
3 changed files with 336 additions and 4 deletions

View File

@ -4,6 +4,9 @@ AC_INIT(src/syncevolution.cpp)
AM_INIT_AUTOMAKE(syncevolution, 0.5)
AM_CONFIG_HEADER(config.h)
# command used to configure client library, including options
CLIENT_CONFIGURE=$PWD/src/client-api/build/autotools/configure
AC_ARG_WITH(sync4j,
AS_HELP_STRING([--with-sync4j=<base directory>],
[specifies location of Sync4j client library]),
@ -14,6 +17,35 @@ AC_ARG_WITH(sync4j-src,
[specifies location of the Sync4j '3x/client-api/native' source code]),
[SYNC4JSRC="$withval"])
AC_ARG_ENABLE(unit-tests,
AS_HELP_STRING([--enable-unit-tests],
[enables tests embedded in the source code of the library (changes content of executable)]),
enable_unit_tests="$enableval", enable_unit_tests="no")
AC_ARG_ENABLE(integration-tests,
AS_HELP_STRING([--enable-integration-tests],
[enables tests outside of the library (can be used together with normal builds of the library)]),
enable_integration_tests="$enableval", enable_integration_tests="no")
# cppunit needed?
if test $enable_unit_tests == "yes" || test $enable_integration_tests == yes; then
CPPUNIT_CXXFLAGS=`cppunit-config --cflags` || AC_MSG_ERROR("cppunit-config --cflags failed - is it installed?")
CPPUNIT_LDFLAGS=`cppunit-config --libs` || AC_MSG_ERROR("cppunit-config --libs failed - is it installed?")
CPPUNIT_TESTS=client-test
AC_CHECK_HEADERS(signal.h)
fi
AC_SUBST(CPPUNIT_CXXFLAGS)
AC_SUBST(CPPUNIT_LDFLAGS)
AC_SUBST(CPPUNIT_TESTS)
if test $enable_unit_tests == "yes"; then
CLIENT_CONFIGURE="$CLIENT_CONFIGURE --enable-unit-tests"
AC_DEFINE(ENABLE_UNIT_TESTS, 1, [enable unit tests inside the library's source code])
fi
if test $enable_integration_tests == "yes"; then
CLIENT_CONFIGURE="$CLIENT_CONFIGURE --enable-integration-tests"
AC_DEFINE(ENABLE_INTEGRATION_TESTS, 1, [enable unit tests outside of the library's source code])
fi
if test ! "$SYNC4J"; then
if test "$SYNC4JSRC"; then
# make a copy of the sources
@ -44,12 +76,11 @@ if test ! "$SYNC4J"; then
# use local copy of the sources
SYNC4J_SUBDIR=$PWD/src/client-api.build
SYNC4J_CFLAGS="-I$SYNC4J_SUBDIR/include/common -I$SYNC4J_SUBDIR/include"
SYNC4J_CFLAGS="-I$SYNC4J_SUBDIR/include/common -I$SYNC4J_SUBDIR/include -I$SYNC4J_SUBDIR/test"
SYNC4J_LIBS="-L$SYNC4J_SUBDIR/src -lsync4j"
AC_MSG_NOTICE( [configuring the client library] )
CLIENT_CONFIGURE=$PWD/src/client-api/build/autotools/configure
if (mkdir -p $SYNC4J_SUBDIR && cd $SYNC4J_SUBDIR && $CLIENT_CONFIGURE --disable-shared); then true; else
if (set -x; mkdir -p $SYNC4J_SUBDIR && cd $SYNC4J_SUBDIR && $CLIENT_CONFIGURE --disable-shared); then true; else
AC_MSG_ERROR( [configuring client library failed] )
fi
else

View File

@ -6,6 +6,9 @@ AM_CFLAGS = -Wall -Werror -Wno-return-type
bin_PROGRAMS = syncevolution
bin_SCRIPTS = synccompare
EXTRA_DIST = normalize_vcard.pl testVCard.vcf testCalendar.ics testTask.ics vocl/README
EXTRA_PROGRAMS = client-test
check_PROGRAMS = @CPPUNIT_TESTS@
TESTS = @CPPUNIT_TESTS@
DISTCLEANFILES = synccompare
MAINTAINERCLEANFILES = Makefile.in
@ -51,7 +54,7 @@ syncevolution_LDADD = $(CORE_LDADD)
# prevent a successful "distcheck"
# TESTS = test
# check_PROGRAMS = test
EXTRA_PROGRAMS = TestEvolution
EXTRA_PROGRAMS += TestEvolution
TestEvolution_SOURCES = \
Test.h \
TestMain.cpp \
@ -81,6 +84,16 @@ BUILT_SOURCES = $(SYNC4J_SUBDIR)/all
clean distclean mostlyclean distdir maintainer-clean : % : $(SYNC4J_SUBDIR)/%
clean : testclean
# With --disable-shared autotools links against libsync4j.a which does not
# pull any of the test suites into the test binary, so they would not be
# executed. The workaround is to explicitly set them as undefined on the
# link line.
client_test_SOURCES = client-test-app.cpp ClientTest.cpp client-test-main.cpp $(CORE_SOURCES)
client_test_LDFLAGS = `nm $(SYNC4J_SUBDIR)/src/.libs/libsync4j.a | grep funambolAutoRegisterRegistry | sed -e 's/.* /-u /'`
client_test_LDADD = $(SYNC4J_SUBDIR)/src/libsync4j.la $(CORE_LDADD)
vpath %.cpp : $(SYNC4J_SUBDIR)/test/test
TestEvolution syncevolution vcardconverter : \
$(SYNC4J_SUBDIR)/src/libsync4j.la
test : TestEvolution addressbook.tests calendar.tests todo.tests synccompare vcardconverter

288
src/client-test-app.cpp Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright (C) 2005 Patrick Ohly
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#include <base/test.h>
#include <test/ClientTest.h>
#include <cppunit/extensions/HelperMacros.h>
#include <exception>
#include "EvolutionSyncClient.h"
#include "EvolutionCalendarSource.h"
#include "EvolutionContactSource.h"
/** a wrapper class which automatically does an open() in the constructor and a close() in the destructor */
template<class T> class TestEvolutionSyncSource : public T {
public:
TestEvolutionSyncSource(ECalSourceType type, string changeID, string database) :
T(type, "dummy", NULL, changeID, database) {}
TestEvolutionSyncSource(string changeID, string database) :
T("dummy", NULL, changeID, database) {}
virtual int beginSync() {
CPPUNIT_ASSERT_NO_THROW(open());
CPPUNIT_ASSERT(!hasFailed());
return T::beginSync();
}
virtual int endSync() {
CPPUNIT_ASSERT_NO_THROW(close());
CPPUNIT_ASSERT(!hasFailed());
return T::endSync();
}
};
class TestEvolution : public ClientTest {
public:
enum sourceType {
TEST_CONTACT_SOURCE,
TEST_CALENDAR_SOURCE,
#if 0
TEST_TASK_SOURCE,
#endif
TEST_MAX_SOURCE
};
virtual int getNumSources() {
return TEST_MAX_SOURCE;
}
virtual void getSourceConfig(int source, Config &config) {
const char *delaystr = getenv("TEST_EVOLUTION_DELAY");
int delayseconds = delaystr ? atoi(delaystr) : 0;
memset(&config, 0, sizeof(config));
switch (source) {
case TEST_CONTACT_SOURCE:
config.sourceName = "Contact";
config.createSourceA = createContactSourceA;
config.createSourceB = createContactSourceB;
config.serverDelaySeconds = delayseconds;
config.insertItem =
"BEGIN:VCARD\n"
"VERSION:3.0\n"
"TITLE:tester\n"
"FN:John Doe\n"
"N:Doe;John;;;\n"
"TEL;TYPE=WORK;TYPE=VOICE:business 1\n"
"X-EVOLUTION-FILE-AS:Doe\\, John\n"
"X-MOZILLA-HTML:FALSE\n"
"NOTE:\n"
"END:VCARD\n";
config.updateItem =
"BEGIN:VCARD\n"
"VERSION:3.0\n"
"TITLE:tester\n"
"FN:Joan Doe\n"
"N:Doe;Joan;;;\n"
"X-EVOLUTION-FILE-AS:Doe\\, Joan\n"
"TEL;TYPE=WORK;TYPE=VOICE:business 2\n"
"BDAY:2006-01-08\n"
"X-MOZILLA-HTML:TRUE\n"
"END:VCARD\n";
/* adds a second phone number: */
config.complexUpdateItem =
"BEGIN:VCARD\n"
"VERSION:3.0\n"
"TITLE:tester\n"
"FN:Joan Doe\n"
"N:Doe;Joan;;;\n"
"X-EVOLUTION-FILE-AS:Doe\\, Joan\n"
"TEL;TYPE=WORK;TYPE=VOICE:business 1\n"
"TEL;TYPE=HOME;TYPE=VOICE:home 2\n"
"BDAY:2006-01-08\n"
"X-MOZILLA-HTML:TRUE\n"
"END:VCARD\n";
/* add a telephone number, email and X-AIM to initial item */
config.mergeItem1 =
"BEGIN:VCARD\n"
"VERSION:3.0\n"
"TITLE:tester\n"
"FN:John Doe\n"
"N:Doe;John;;;\n"
"X-EVOLUTION-FILE-AS:Doe\\, John\n"
"X-MOZILLA-HTML:FALSE\n"
"TEL;TYPE=WORK;TYPE=VOICE:business 1\n"
"EMAIL:john.doe@work.com\n"
"X-AIM:AIM JOHN\n"
"END:VCARD\n";
config.mergeItem2 =
"BEGIN:VCARD\n"
"VERSION:3.0\n"
"TITLE:developer\n"
"FN:John Doe\n"
"N:Doe;John;;;\n"
"X-EVOLUTION-FILE-AS:Doe\\, John\n"
"X-MOZILLA-HTML:TRUE\n"
"BDAY:2006-01-08\n"
"END:VCARD\n";
config.templateItem = config.insertItem;
config.uniqueProperties = "FN:N:X-EVOLUTION-FILE-AS";
config.sizeProperty = "NOTE";
break;
case TEST_CALENDAR_SOURCE:
config.sourceName = "Calendar";
config.createSourceA = createCalendarSourceA;
config.createSourceB = createCalendarSourceB;
config.serverDelaySeconds = delayseconds;
break;
}
}
virtual ClientTest *getClientB() {
return NULL;
}
virtual int sync(
const int *sources,
SyncMode syncMode,
long maxMsgSize = 0,
long maxObjSize = 0,
bool loSupport = false,
const char *encoding = NULL) {
set<string> activeSources;
for(int i = 0; sources[i] >= 0; i++) {
string database;
switch (sources[i]) {
case TEST_CONTACT_SOURCE:
database = "addressbook";
break;
case TEST_CALENDAR_SOURCE:
database = "calendar";
break;
#if 0
case TEST_TASK_SOURCE:
database = "task";
break;
#endif
default:
CPPUNIT_ASSERT(sources[i] < TEST_MAX_SOURCE);
break;
}
/* TODO */
activeSources.insert(database + "_1");
}
/* TODO */
string server = "funambol_1";
class ClientTest : public EvolutionSyncClient {
public:
ClientTest(const string &server,
const set<string> &activeSources,
SyncMode syncMode,
long maxMsgSize,
long maxObjSize,
bool loSupport,
const char *encoding) :
EvolutionSyncClient(server, false, activeSources),
m_syncMode(syncMode),
m_maxMsgSize(maxMsgSize),
m_maxObjSize(maxObjSize),
m_loSupport(loSupport),
m_encoding(encoding)
{}
protected:
virtual void prepare(SyncManagerConfig &config,
SyncSource **sources) {
for (SyncSource **source = sources;
*source;
source++) {
if (m_encoding) {
(*source)->getConfig().setEncoding(m_encoding);
}
(*source)->setPreferredSyncMode(m_syncMode);
}
DeviceConfig &dc(config.getDeviceConfig());
dc.setLoSupport(m_loSupport);
dc.setMaxObjSize(m_maxObjSize);
AccessConfig &ac(config.getAccessConfig());
ac.setMaxMsgSize(m_maxMsgSize);
EvolutionSyncClient::prepare(config, sources);
}
private:
const SyncMode m_syncMode;
const long m_maxMsgSize;
const long m_maxObjSize;
const bool m_loSupport;
const char *m_encoding;
} client(server, activeSources, syncMode, maxMsgSize, maxObjSize, loSupport, encoding);
return client.sync();
}
private:
SyncSource *createSyncSource(sourceType type, string changeID, string database) {
switch (type) {
case TEST_CONTACT_SOURCE:
return new TestEvolutionSyncSource<EvolutionContactSource>(changeID, database);
break;
case TEST_CALENDAR_SOURCE:
return new TestEvolutionSyncSource<EvolutionCalendarSource>(E_CAL_SOURCE_TYPE_EVENT, changeID, database);
break;
#if 0
case TEST_TASK_SOURCE:
return new TestEvolutionSyncSource<EvolutionCalendarSource>(E_CAL_SOURCE_TYPE_TASK, changeID, database);
#endif
default:
return NULL;
}
}
static SyncSource *createContactSourceA(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_CONTACT_SOURCE, "SyncEvolution Change ID #1", "SyncEvolution test #1");
}
static SyncSource *createContactSourceB(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_CONTACT_SOURCE, "SyncEvolution Change ID #2", "SyncEvolution test #1");
}
static SyncSource *createCalendarSourceA(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_CALENDAR_SOURCE, "SyncEvolution Change ID #1", "SyncEvolution test #1");
}
static SyncSource *createCalendarSourceB(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_CALENDAR_SOURCE, "SyncEvolution Change ID #2", "SyncEvolution test #1");
}
#if 0
static SyncSource *createTaskSourceA(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_TASK_SOURCE, "SyncEvolution Change ID #1", "SyncEvolution test #1");
}
static SyncSource *createTaskSourceB(ClientTest &client) {
return ((TestEvolution *)&client)->createSyncSource(TEST_TASK_SOURCE, "SyncEvolution Change ID #2", "SyncEvolution test #1");
}
#endif
};
static class RegisterTestEvolution {
public:
RegisterTestEvolution() {
testClient.registerTests();
}
private:
TestEvolution testClient;
} testEvolution;