ActiveSync: allow testing against Google
Google doesn't seem to support the Fetch operation, which is used during testing to retrieve unchanged items. During syncing it will only be needed when merging incoming data with an existing item, which should not be necessary... except that testing shows that it is necessary. The case where it is needed is: - incremental sync (cache empty) - calendar event series needs to be modified - items from that series need to be fetched in preparation for updating it To allow testing, several workarounds are necessary: - request *all* data before doing a data dump in testImport (and friends), to ensure that the cache in the backend is fully populated - use the cache in ActiveSyncCalendarSource instead of accessing the base class directly, because that would trigger a Fetch Accessing the base class is still useful for Exchange+calendar, because testing then avoids the cache (and thus can expose bugs in it). While at it, adapted the README. "database" needs to be set explicitly, "client-test" only does it when creating configs.
This commit is contained in:
parent
c464394eda
commit
14889ede24
4 changed files with 79 additions and 23 deletions
|
@ -142,7 +142,8 @@ namespace {
|
|||
* operation. Using the cached information implies that we won't find bugs in
|
||||
* the handling of that information.
|
||||
*/
|
||||
static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::string &file)
|
||||
static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::string &file,
|
||||
bool forceBaseReadItem)
|
||||
{
|
||||
ActiveSyncSource &eassource = static_cast<ActiveSyncSource &>(source);
|
||||
ofstream out(file.c_str());
|
||||
|
@ -161,7 +162,20 @@ static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::s
|
|||
|
||||
BOOST_FOREACH(const std::string &easid, easids) {
|
||||
std::string item;
|
||||
eassource.ActiveSyncSource::readItem(easid, item);
|
||||
if (forceBaseReadItem) {
|
||||
// This bypasses the more specialized
|
||||
// ActiveSyncCalendarSource::readItem(), which helps
|
||||
// reveal potential bugs in it. However, it depends on a
|
||||
// working Fetch operation in the ActiveSync server, which
|
||||
// Google doesn't seem to provide (404 error).
|
||||
eassource.ActiveSyncSource::readItem(easid, item);
|
||||
} else {
|
||||
// Normal readItem() works with Google by using the cached
|
||||
// item. However, the source must have done a beginSync()
|
||||
// with empty sync key, because otherwise the cache is
|
||||
// not guaranteed to be complete.
|
||||
eassource.readItem(easid, item);
|
||||
}
|
||||
out << item << '\n';
|
||||
if (!boost::ends_with(item, "\n")) {
|
||||
out << '\n';
|
||||
|
@ -201,7 +215,8 @@ static TestingSyncSource *createEASSource(const ClientTestConfig::createsource_t
|
|||
|
||||
// common settings for all kinds of data
|
||||
static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
|
||||
ClientTestConfig &config)
|
||||
ClientTestConfig &config,
|
||||
EasItemType type)
|
||||
{
|
||||
// cannot run tests involving a second database:
|
||||
// wrap orginal source creation, set default database for
|
||||
|
@ -211,7 +226,12 @@ static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
|
|||
config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB,
|
||||
_1, _2, _3, _4);
|
||||
|
||||
config.m_dump = DumpItems;
|
||||
config.m_dump = boost::bind(DumpItems, _1, _2, _3,
|
||||
type == EAS_ITEM_CONTACT ||
|
||||
// need to read from our cache for Google Calendar,
|
||||
// because it does not support Fetch
|
||||
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
|
||||
);
|
||||
config.m_sourceLUIDsAreVolatile = true;
|
||||
// TODO: find out how ActiveSync/Exchange handle children without parent;
|
||||
// at the moment, the child is stored as if it was a stand-alone event
|
||||
|
@ -233,7 +253,7 @@ public:
|
|||
// TODO: provide comprehensive set of vCard 3.0 contacts as they are understood by the ActiveSync library
|
||||
// config.testcases = "testcases/eas_contact.vcf";
|
||||
|
||||
updateConfigEAS(this, config);
|
||||
updateConfigEAS(this, config, EAS_ITEM_CONTACT);
|
||||
}
|
||||
} ActiveSyncContactTest;
|
||||
|
||||
|
@ -246,7 +266,7 @@ public:
|
|||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.m_type = "eas-events";
|
||||
updateConfigEAS(this, config);
|
||||
updateConfigEAS(this, config, EAS_ITEM_CALENDAR);
|
||||
}
|
||||
} ActiveSyncEventTest;
|
||||
|
||||
|
@ -259,7 +279,7 @@ public:
|
|||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.m_type = "eas-todos";
|
||||
updateConfigEAS(this, config);
|
||||
updateConfigEAS(this, config, EAS_ITEM_TODO);
|
||||
}
|
||||
} ActiveSyncTodoTest;
|
||||
|
||||
|
@ -272,7 +292,7 @@ public:
|
|||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.m_type = "eas-memos";
|
||||
updateConfigEAS(this, config);
|
||||
updateConfigEAS(this, config, EAS_ITEM_JOURNAL);
|
||||
}
|
||||
} ActiveSyncMemoTest;
|
||||
|
||||
|
|
|
@ -74,6 +74,10 @@ which must simulate two independent ActiveSync clients.
|
|||
|
||||
Configure "local" testing (backend is covered, no syncing involved):
|
||||
./syncevolution --configure username=<EAS account ID> \
|
||||
eas_event/backend=eas-events \
|
||||
eas_event/database= \
|
||||
eas_contact/backend=eas-contacts \
|
||||
eas_contact/database= \
|
||||
--template SyncEvolution target-config@client-test-exchange
|
||||
|
||||
On MeeGo:
|
||||
|
@ -114,19 +118,22 @@ Sync Testing
|
|||
syncevolution --configure \
|
||||
syncURL=local://@exchange \
|
||||
username=<EAS account ID> \
|
||||
backend=evolution-calendar \
|
||||
eds_event/backend=evolution-calendar \
|
||||
eds_event/uri=calendar \
|
||||
eds_event/uri=eas_event \
|
||||
eds_event/database=SyncEvolution_Test_eds_event_1 \
|
||||
eds_contact/backend=evolution-contacts \
|
||||
eds_contact/uri=addressbook \
|
||||
eds_contact/uri=eas_contact \
|
||||
eds_contact/database=SyncEvolution_Test_eds_contact_1 \
|
||||
--template SyncEvolution_Client exchange_1@client-test-1 eds_event eds_contact
|
||||
syncevolution --configure \
|
||||
syncURL=local://@exchange \
|
||||
username=<EAS account ID>_B \
|
||||
eds_event/backend=evolution-calendar \
|
||||
eds_event/uri=calendar \
|
||||
eds_event/uri=eas_event \
|
||||
eds_event/database=SyncEvolution_Test_eds_event_2 \
|
||||
eds_contact/backend=evolution-contacts \
|
||||
eds_contact/uri=addressbook \
|
||||
eds_contact/uri=eas_contact \
|
||||
eds_contact/database=SyncEvolution_Test_eds_contact_2 \
|
||||
--template SyncEvolution_Client exchange_2@client-test-2 eds_event eds_contact
|
||||
- Create calendars named as follows in Evolution:
|
||||
SyncEvolution_Test_eds_event_1
|
||||
|
@ -140,3 +147,11 @@ target-config@exchange with different usernames in each sync
|
|||
config. This is necessary because change tracking depends on that
|
||||
username.
|
||||
|
||||
|
||||
Google via ActiveSync
|
||||
=====================
|
||||
|
||||
- Use "googleeas" instead of "exchange", because ActiveSyncSourceRegister.cpp
|
||||
needs to know that it is talking to Google, to work around the lack of
|
||||
Fetch command support.
|
||||
|
||||
|
|
|
@ -280,7 +280,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void reset(TestingSyncSource *source = NULL)
|
||||
enum Flags {
|
||||
SLOW, /**< erase anchor, start accessing database from scratch */
|
||||
INCREMENTAL /**< allow source to do incremental data read */
|
||||
};
|
||||
|
||||
void reset(TestingSyncSource *source = NULL, Flags flags = INCREMENTAL)
|
||||
{
|
||||
if (get() && m_active) {
|
||||
stopAccess();
|
||||
|
@ -291,7 +296,7 @@ public:
|
|||
base_t::reset(source);
|
||||
}
|
||||
if (source) {
|
||||
startAccess();
|
||||
startAccess(flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +304,7 @@ public:
|
|||
* done automatically as part of reset(), only to be called
|
||||
* after an explicit stopAccess()
|
||||
*/
|
||||
void startAccess()
|
||||
void startAccess(Flags flags = INCREMENTAL)
|
||||
{
|
||||
CT_ASSERT(get());
|
||||
CT_ASSERT(!m_active);
|
||||
|
@ -311,6 +316,9 @@ public:
|
|||
CT_ASSERT_NO_THROW(get()->open());
|
||||
string node = get()->getTrackingNode()->getName();
|
||||
string anchor = m_anchors[node];
|
||||
if (flags == SLOW) {
|
||||
anchor = "";
|
||||
}
|
||||
get()->beginSync(anchor, "");
|
||||
if (isServerMode()) {
|
||||
CT_ASSERT_NO_THROW(get()->enableServerMode());
|
||||
|
@ -1282,9 +1290,13 @@ void LocalTests::testImport() {
|
|||
backupStorage(config, client);
|
||||
CT_ASSERT_NO_THROW(source.reset());
|
||||
|
||||
// export again and compare against original file
|
||||
// export again and compare against original file,
|
||||
// without relying on change tracking (because
|
||||
// Google ActiveSync has problems with Fetch,
|
||||
// which would be needed for a data dump when
|
||||
// using the incremental approach)
|
||||
TestingSyncSourcePtr copy;
|
||||
SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceA()));
|
||||
SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceA(), TestingSyncSourcePtr::SLOW));
|
||||
bool equal = compareDatabases(testcases.c_str(), *copy.get(), false);
|
||||
CT_ASSERT_NO_THROW(source.reset());
|
||||
|
||||
|
@ -1371,7 +1383,7 @@ void LocalTests::testRemoveProperties() {
|
|||
|
||||
// compare
|
||||
TestingSyncSourcePtr copy;
|
||||
SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceA()));
|
||||
SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceA(), TestingSyncSourcePtr::SLOW));
|
||||
bool equal = compareDatabases(updated.c_str(), *copy.get(), false);
|
||||
CT_ASSERT_NO_THROW(source.reset());
|
||||
|
||||
|
|
|
@ -84,7 +84,9 @@ my $full_timezones = $ENV{CLIENT_TEST_FULL_TIMEZONES}; # do not simplify VTIMEZO
|
|||
my $exchange = $server =~ /exchange/; # Exchange via ActiveSync
|
||||
my $egroupware = $server =~ /egroupware/;
|
||||
my $funambol = $server =~ /funambol/;
|
||||
my $google = $server =~ /google/;
|
||||
my $googlesyncml = $server eq "google";
|
||||
my $googlecaldav = $server eq "googlecalendar";
|
||||
my $googleeas = $server eq "googleeas";
|
||||
my $google_valarm = $ENV{CLIENT_TEST_GOOGLE_VALARM};
|
||||
my $yahoo = $server =~ /yahoo/;
|
||||
my $davical = $server =~ /davical/;
|
||||
|
@ -363,7 +365,7 @@ sub NormalizeItem {
|
|||
# > LY
|
||||
s/^(\w+)([^:\n]*);X-EVOLUTION-ENDDATE=[0-9TZ]*/$1$2/mg;
|
||||
|
||||
if ($scheduleworld || $egroupware || $synthesis || $addressbook || $funambol ||$google || $mobical || $memotoo) {
|
||||
if ($scheduleworld || $egroupware || $synthesis || $addressbook || $funambol ||$googlesyncml || $googleeas || $mobical || $memotoo) {
|
||||
# does not preserve X-EVOLUTION-UI-SLOT=
|
||||
s/^(\w+)([^:\n]*);X-EVOLUTION-UI-SLOT=\d+/$1$2/mg;
|
||||
}
|
||||
|
@ -389,7 +391,7 @@ sub NormalizeItem {
|
|||
s/^(TEL.*);TYPE=PREF/$1/mg;
|
||||
}
|
||||
|
||||
if($google) {
|
||||
if($googlesyncml) {
|
||||
# ignore the PHOTO encoding data
|
||||
s/^PHOTO(.*?): .*\n/^PHOTO$1: [...]\n/mg;
|
||||
# FN propertiey is not correct
|
||||
|
@ -398,7 +400,9 @@ sub NormalizeItem {
|
|||
s!^TEL\;TYPE=CAR(.*)\n!TEL$1\n!mg;
|
||||
# some properties are lost
|
||||
s/^(X-EVOLUTION-FILE-AS|NICKNAME|BDAY|CATEGORIES|CALURI|FBURL|ROLE|URL|X-AIM|X-EVOLUTION-UI-SLOT|X-ANNIVERSARY|X-ASSISTANT|X-EVOLUTION-BLOG-URL|X-EVOLUTION-VIDEO-URL|X-GROUPWISE|X-ICQ|X-GADUGADU|X-JABBER|X-MSN|X-SIP|X-SKYPE|X-MANAGER|X-SPOUSE|X-MOZILLA-HTML|X-YAHOO)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
}
|
||||
|
||||
if ($googlecaldav) {
|
||||
#several properties are not preserved by Google in icalendar2.0 format
|
||||
s/^(SEQUENCE|X-EVOLUTION-ALARM-UID)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
|
||||
|
@ -429,7 +433,7 @@ sub NormalizeItem {
|
|||
s/^(X-RADICALE-NAME)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
}
|
||||
|
||||
if ($google || $yahoo) {
|
||||
if ($googlecaldav || $yahoo) {
|
||||
# default status is CONFIRMED
|
||||
s/^STATUS:CONFIRMED\r?\n?//gm;
|
||||
}
|
||||
|
@ -650,6 +654,11 @@ sub NormalizeItem {
|
|||
s/^DESCRIPTION:Reminder\n//m;
|
||||
}
|
||||
|
||||
if ($googleeas) {
|
||||
# unsupported properties
|
||||
s/^(FN)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
}
|
||||
|
||||
# treat X-MOZILLA-HTML=FALSE as if the property didn't exist
|
||||
s/^X-MOZILLA-HTML:FALSE\r?\n?//gm;
|
||||
|
||||
|
|
Loading…
Reference in a new issue