synccompare and test suite are now taken from C++ client library
git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@343 15ad00c4-1369-45f4-8270-35d70d36bdcd
This commit is contained in:
parent
1bbbec4440
commit
d0a9067be2
9 changed files with 332 additions and 2346 deletions
|
@ -1,131 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The scripts and library files supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package. If such scripts or library files are aggregated with this
|
||||
Package via the so-called "undump" or "unexec" methods of producing a
|
||||
binary executable image, then distribution of such an image shall
|
||||
neither be construed as a distribution of this Package nor shall it
|
||||
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||
not represent such an executable image as a Standard Version of this
|
||||
Package.
|
||||
|
||||
7. C subroutines (or comparably compiled subroutines in other
|
||||
languages) supplied by you and linked into this Package in order to
|
||||
emulate subroutines and variables of the language defined by this
|
||||
Package shall not be considered part of this Package, but are the
|
||||
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||
not change the language in any way that would cause it to fail the
|
||||
regression tests for the language.
|
||||
|
||||
8. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
File diff suppressed because it is too large
Load diff
|
@ -1,81 +0,0 @@
|
|||
This is a module for computing the difference between two files, two
|
||||
strings, or any other two lists of things. It uses an intelligent
|
||||
algorithm similar to (or identical to) the one used by the Unix "diff"
|
||||
program. It is guaranteed to find the *smallest possible* set of
|
||||
differences.
|
||||
|
||||
This package contains a few parts.
|
||||
|
||||
Algorithm::Diff is the module that contains several interfaces for which
|
||||
computing the differences betwen two lists.
|
||||
|
||||
The several "diff" programs also included in this package use
|
||||
Algorithm::Diff to find the differences and then they format the output.
|
||||
|
||||
Algorithm::Diff also includes some other useful functions such as "LCS",
|
||||
which computes the longest common subsequence of two lists.
|
||||
|
||||
A::D is suitable for many uses. You can use it for finding the smallest
|
||||
set of differences between two strings, or for computing the most
|
||||
efficient way to update the screen if you were replacing "curses".
|
||||
|
||||
Algorithm::DiffOld is a previous version of the module which is included
|
||||
primarilly for those wanting to use a custom comparison function rather
|
||||
than a key generating function (and who don't mind the significant
|
||||
performance penalty of perhaps 20-fold).
|
||||
|
||||
diff.pl implements a "diff" in Perl that is as simple as (was
|
||||
previously) possible so that you can see how it works. The output
|
||||
format is not compatible with regular "diff". It needs to be
|
||||
reimplemented using the OO interface to greatly simplify the code.
|
||||
|
||||
diffnew.pl implements a "diff" in Perl with full bells and whistles. By
|
||||
Mark-Jason, with code from cdiff.pl included.
|
||||
|
||||
cdiff.pl implements "diff" that generates real context diffs in either
|
||||
traditional format or GNU unified format. Original contextless
|
||||
"context" diff supplied by Christian Murphy. Modifications to make it
|
||||
into a real full-featured diff with -c and -u options supplied by Amir
|
||||
D. Karger.
|
||||
|
||||
Yes, you can use this program to generate patches.
|
||||
|
||||
OTHER RESOURCES
|
||||
|
||||
"Longest Common Subsequences", at
|
||||
http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
|
||||
This code was adapted from the Smalltalk code of Mario Wolczko
|
||||
<mario@wolczko.com>, which is available at
|
||||
ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
|
||||
|
||||
THANKS SECTION
|
||||
|
||||
Thanks to Ned Konz's for rewriting the module to greatly improve
|
||||
performance, for maintaining it over the years, and for readilly handing
|
||||
it over to me so I could plod along with my improvements.
|
||||
|
||||
(From Ned Konz's earlier versions):
|
||||
|
||||
Thanks to Mark-Jason Dominus for doing the original Perl version and
|
||||
maintaining it over the last couple of years. Mark-Jason has been a huge
|
||||
contributor to the Perl community and CPAN; it's because of people like
|
||||
him that Perl has become a success.
|
||||
|
||||
Thanks to Mario Wolczko <mario@wolczko.com> for writing and making
|
||||
publicly available his Smalltalk version of diff, which this Perl
|
||||
version is heavily based on.
|
||||
|
||||
Thanks to Mike Schilli <m@perlmeister.com> for writing sdiff and
|
||||
traverse_balanced and making them available for the Algorithm::Diff
|
||||
distribution.
|
||||
|
||||
(From Mark-Jason Dominus' earlier versions):
|
||||
|
||||
Huge thanks to Amir Karger for adding full context diff supprt to
|
||||
"cdiff.pl", and then for waiting patiently for five months while I let
|
||||
it sit in a closet and didn't release it. Thank you thank you thank
|
||||
you, Amir!
|
||||
|
||||
Thanks to Christian Murphy for adding the first context diff format
|
||||
support to "cdiff.pl".
|
|
@ -1,18 +0,0 @@
|
|||
This is a subset of the original Algorithm::Diff distribution, added
|
||||
here to avoid the external dependency. No other changes were made.
|
||||
|
||||
The original sources should always be available from the Comprehensive
|
||||
Perl Archive Network (CPAN). Visit <URL:http://www.perl.com/CPAN/> to
|
||||
find a CPAN site near you.
|
||||
|
||||
The Algorithm::Diff copyright is as follows:
|
||||
|
||||
| Parts Copyright (c) 2000-2004 Ned Konz. All rights reserved.
|
||||
| Parts by Tye McQueen.
|
||||
|
|
||||
| This program is free software; you can redistribute it and/or modify it
|
||||
| under the same terms as Perl.
|
||||
|
||||
The content of this directory is distributed under the original license:
|
||||
dual-licensed under GPL-2 (../../COPYING) and Larry Wall's "Artistic
|
||||
License" (./Artistic).
|
119
src/EvolutionClientConfig.h
Normal file
119
src/EvolutionClientConfig.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2006 Patrick Ohly
|
||||
* Copyright (C) 2007 Funambol
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef INCL_EVOLUTIONCLIENTCONFIG
|
||||
#define INCL_EVOLUTIONCLIENTCONFIG
|
||||
|
||||
#include <client/DMTClientConfig.h>
|
||||
#include <EvolutionSmartPtr.h>
|
||||
|
||||
/**
|
||||
* config class which ensures backwards compatibility
|
||||
* and (optionally) prevents writing of properties that the
|
||||
* code is not supposed to set
|
||||
*/
|
||||
class EvolutionClientConfig : public DMTClientConfig {
|
||||
public:
|
||||
EvolutionClientConfig(const char *root, bool saveAll = false) :
|
||||
DMTClientConfig(root),
|
||||
m_saveAll(saveAll)
|
||||
{}
|
||||
|
||||
protected:
|
||||
/*
|
||||
* tweak the base class in two ways:
|
||||
* - continue to use the "syncml" node for all non-source properties, as in previous versions
|
||||
* - do not save properties which cannot be configured
|
||||
*/
|
||||
virtual int readAuthConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& authNode) {
|
||||
return DMTClientConfig::readAuthConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveAuthConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& authNode) {
|
||||
DMTClientConfig::saveAuthConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readConnConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& connNode) {
|
||||
return DMTClientConfig::readConnConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveConnConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& connNode) {
|
||||
DMTClientConfig::saveConnConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readExtAccessConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
return DMTClientConfig::readExtAccessConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveExtAccessConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
DMTClientConfig::saveExtAccessConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readDevInfoConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devInfoNode) {
|
||||
int res = DMTClientConfig::readDevInfoConfig(syncMLNode, syncMLNode);
|
||||
|
||||
// always read device ID from the traditional property "deviceId"
|
||||
arrayptr<char> tmp(syncMLNode.readPropertyValue("deviceId"));
|
||||
if (tmp && tmp[0]) {
|
||||
deviceConfig.setDevID(tmp);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
virtual void saveDevInfoConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devInfoNode) {
|
||||
if (m_saveAll) {
|
||||
DMTClientConfig::saveDevInfoConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
}
|
||||
virtual int readDevDetailConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devDetailNode) {
|
||||
return DMTClientConfig::readDevDetailConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveDevDetailConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devDetailNode) {
|
||||
if (m_saveAll) {
|
||||
DMTClientConfig::saveDevDetailConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
}
|
||||
virtual int readExtDevConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
return DMTClientConfig::readExtDevConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveExtDevConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
if (m_saveAll) {
|
||||
DMTClientConfig::saveExtDevConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void saveSourceConfig(int i,
|
||||
ManagementNode& sourcesNode,
|
||||
ManagementNode& sourceNode) {
|
||||
if (m_saveAll) {
|
||||
DMTClientConfig::saveSourceConfig(i, sourcesNode, sourceNode);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_saveAll;
|
||||
};
|
||||
|
||||
#endif // INCL_EVOLUTIONCLIENTCONFIG
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "EvolutionSyncClient.h"
|
||||
#include "EvolutionSyncSource.h"
|
||||
#include <EvolutionClientConfig.h>
|
||||
|
||||
#include <client/DMTClientConfig.h>
|
||||
#include <posix/base/posixlog.h>
|
||||
|
||||
#include <list>
|
||||
|
@ -40,11 +40,12 @@ using namespace std;
|
|||
#include <errno.h>
|
||||
|
||||
EvolutionSyncClient::EvolutionSyncClient(const string &server,
|
||||
bool doLogging, const set<string> &sources) :
|
||||
bool doLogging, const set<string> &sources,
|
||||
const string &configRoot ) :
|
||||
m_server(server),
|
||||
m_sources(sources),
|
||||
m_doLogging(doLogging),
|
||||
m_configPath(string("evolution/") + server)
|
||||
m_configPath(configRoot + server)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,11 +97,11 @@ class LogDir {
|
|||
string m_logfile; /**< path to log file there */
|
||||
const string &m_server; /**< name of the server for this synchronization */
|
||||
LogLevel m_oldLogLevel; /**< logging level to restore */
|
||||
|
||||
bool m_restoreLog; /**< false if nothing needs to be restored because setLogdir() was never called */
|
||||
|
||||
public:
|
||||
LogDir(const string &server) : m_server(server),
|
||||
m_oldLogLevel(LOG.getLevel())
|
||||
m_restoreLog(false)
|
||||
{}
|
||||
|
||||
// setup log directory and redirect logging into it
|
||||
|
@ -177,7 +178,9 @@ public:
|
|||
out.open(m_logfile.c_str());
|
||||
out.close();
|
||||
setLogFile(m_logfile.c_str(), true);
|
||||
m_oldLogLevel = LOG.getLevel();
|
||||
LOG.setLevel(LOG_LEVEL_DEBUG);
|
||||
m_restoreLog = true;
|
||||
}
|
||||
|
||||
// return log directory, empty if not enabled
|
||||
|
@ -223,6 +226,10 @@ public:
|
|||
|
||||
// remove redirection of stderr and (optionally) also of logging
|
||||
void restore(bool all) {
|
||||
if (!m_restoreLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
setLogFile("-", false);
|
||||
LOG.setLevel(m_oldLogLevel);
|
||||
|
@ -406,79 +413,8 @@ void unref(SourceList *sourceList)
|
|||
|
||||
int EvolutionSyncClient::sync()
|
||||
{
|
||||
class EvolutionClientConfig : public DMTClientConfig {
|
||||
public:
|
||||
EvolutionClientConfig(const char *root) :
|
||||
DMTClientConfig(root) {}
|
||||
|
||||
protected:
|
||||
/*
|
||||
* tweak the base class in two ways:
|
||||
* - continue to use the "syncml" node for all non-source properties, as in previous versions
|
||||
* - do not save properties which cannot be configured
|
||||
*/
|
||||
virtual int readAuthConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& authNode) {
|
||||
return DMTClientConfig::readAuthConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveAuthConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& authNode) {
|
||||
DMTClientConfig::saveAuthConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readConnConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& connNode) {
|
||||
return DMTClientConfig::readConnConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveConnConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& connNode) {
|
||||
DMTClientConfig::saveConnConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readExtAccessConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
return DMTClientConfig::readExtAccessConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveExtAccessConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
DMTClientConfig::saveExtAccessConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual int readDevInfoConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devInfoNode) {
|
||||
int res = DMTClientConfig::readDevInfoConfig(syncMLNode, syncMLNode);
|
||||
|
||||
// always read device ID from the traditional property "deviceId"
|
||||
arrayptr<char> tmp(syncMLNode.readPropertyValue("deviceId"));
|
||||
deviceConfig.setDevID(tmp);
|
||||
|
||||
return res;
|
||||
}
|
||||
virtual void saveDevInfoConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devInfoNode) {
|
||||
// these properties are always set by the code, don't save them
|
||||
}
|
||||
virtual int readDevDetailConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devDetailNode) {
|
||||
return DMTClientConfig::readDevDetailConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveDevDetailConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& devDetailNode) {
|
||||
// these properties are always set by the code, don't save them
|
||||
}
|
||||
virtual int readExtDevConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
return DMTClientConfig::readExtDevConfig(syncMLNode, syncMLNode);
|
||||
}
|
||||
virtual void saveExtDevConfig(ManagementNode& syncMLNode,
|
||||
ManagementNode& extNode) {
|
||||
// these properties are always set by the code, don't save them
|
||||
}
|
||||
|
||||
virtual void saveSourceConfig(int i,
|
||||
ManagementNode& sourcesNode,
|
||||
ManagementNode& sourceNode) {
|
||||
// no, don't overwrite config, in particular not the "type"
|
||||
}
|
||||
|
||||
} config(m_configPath.c_str());
|
||||
int res = 1;
|
||||
EvolutionClientConfig config(m_configPath.c_str());
|
||||
|
||||
if (!config.read() || !config.open()) {
|
||||
throw runtime_error("reading configuration failed");
|
||||
|
@ -578,7 +514,7 @@ int EvolutionSyncClient::sync()
|
|||
sourceList.syncPrepare();
|
||||
|
||||
// do it
|
||||
int res = SyncClient::sync(config, sourceList.getSourceArray());
|
||||
res = SyncClient::sync(config, sourceList.getSourceArray());
|
||||
|
||||
if (res) {
|
||||
if (lastErrorCode && lastErrorMsg[0]) {
|
||||
|
@ -593,6 +529,8 @@ int EvolutionSyncClient::sync()
|
|||
|
||||
// all went well: print final report before cleaning up
|
||||
sourceList.syncDone(true);
|
||||
|
||||
res = 0;
|
||||
} catch (const std::exception &ex) {
|
||||
LOG.error( "%s", ex.what() );
|
||||
|
||||
|
@ -603,5 +541,5 @@ int EvolutionSyncClient::sync()
|
|||
sourceList.syncDone(false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -46,10 +46,12 @@ class EvolutionSyncClient : public SyncClient {
|
|||
* @param server identifies the server config to be used
|
||||
* @param syncMode setting this overrides the sync mode from the config
|
||||
* @param doLogging write additional log and datatbase files about the sync
|
||||
* @param configRoot DM config root (= ".sync4j/<configRoot>")
|
||||
*/
|
||||
EvolutionSyncClient(const string &server,
|
||||
bool doLogging = false,
|
||||
const set<string> &sources = set<string>());
|
||||
const set<string> &sources = set<string>(),
|
||||
const string &configRoot = "evolution/");
|
||||
~EvolutionSyncClient();
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,7 +19,7 @@ CLEANFILES = libstdc++.a
|
|||
|
||||
# synccompare is created by replacing its 'import Algorithm::Diff;'
|
||||
# with a simplified copy of Diff.pm.
|
||||
synccompare : Algorithm/Diff.pm normalize_vcard.pl
|
||||
synccompare : $(SYNC4J_SUBDIR)/test/test/Algorithm/Diff.pm $(SYNC4J_SUBDIR)/test/test/synccompare.pl
|
||||
perl -e '$$diff = shift; open(DIFF, "<$$diff"); ($$_) = split(/__END__/, join("", <DIFF>)); s/\*import.*//m; s/require +Exporter;//; s/^#.*\n//mg; s/ +#.*\n//mg; $$diff = $$_;' -e 'while(<>) {' @MODIFY_SYNCCOMPARE@ -e 's/use +Algorithm::Diff;/"# embedded version of Algorithm::Diff follows, copyright by the original authors\n" . $$diff . "# end of embedded Algorithm::Diff\n"/e; print;}' $+ >$@
|
||||
chmod u+x $@
|
||||
|
||||
|
@ -83,17 +83,17 @@ syncebook_la_LDFLAGS = -module -rpath '$(pkglibdir)'
|
|||
# prevent a successful "distcheck"
|
||||
# TESTS = test
|
||||
# check_PROGRAMS = test
|
||||
EXTRA_PROGRAMS += TestEvolution
|
||||
TestEvolution_SOURCES = \
|
||||
Test.h \
|
||||
TestMain.cpp \
|
||||
TestEvolution.cpp \
|
||||
$(CORE_SOURCES)
|
||||
#EXTRA_PROGRAMS += TestEvolution
|
||||
#TestEvolution_SOURCES = \
|
||||
# Test.h \
|
||||
# TestMain.cpp \
|
||||
# TestEvolution.cpp \
|
||||
# $(CORE_SOURCES)
|
||||
|
||||
TestEvolution_CXXFLAGS = `cppunit-config --cflags`
|
||||
TestEvolution_LDFLAGS = `cppunit-config --libs`
|
||||
TestEvolution_LDADD = @SYNCEVOLUTION_MODULES@ @LIBDBUS@ $(CORE_LDADD)
|
||||
TestEvolution_DEPENDENCIES = @SYNCEVOLUTION_MODULES@
|
||||
#TestEvolution_CXXFLAGS = `cppunit-config --cflags`
|
||||
#TestEvolution_LDFLAGS = `cppunit-config --libs`
|
||||
#TestEvolution_LDADD = @SYNCEVOLUTION_MODULES@ @LIBDBUS@ $(CORE_LDADD)
|
||||
#TestEvolution_DEPENDENCIES = @SYNCEVOLUTION_MODULES@
|
||||
|
||||
EXTRA_PROGRAMS += vcardconverter
|
||||
vcardconverter_SOURCES = \
|
||||
|
@ -120,28 +120,40 @@ clean : testclean
|
|||
# executed. The workaround is to explicitly set them as undefined on the
|
||||
# link line.
|
||||
client_test_SOURCES = client-test-app.cpp $(CORE_SOURCES)
|
||||
nodist_client_test_SOURCES = ClientTest.cpp client-test-main.cpp
|
||||
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)
|
||||
nodist_client_test_SOURCES = ClientTest.cpp client-test-main.cpp ClientTest.h
|
||||
client_test_CPPFLAGS = -DHAVE_CONFIG_H -DENABLE_INTEGRATION_TESTS
|
||||
client_test_CXXFLAGS = `cppunit-config --cflags`
|
||||
client_test_LDFLAGS = `cppunit-config --libs` `nm $(SYNC4J_SUBDIR)/src/.libs/libsync4j.a | grep funambolAutoRegisterRegistry | sed -e 's/.* /-u /'`
|
||||
client_test_LDADD = @SYNCEVOLUTION_MODULES@ @LIBDBUS@ $(SYNC4J_SUBDIR)/src/libsync4j.la $(CORE_LDADD)
|
||||
|
||||
vpath %.cpp : $(SYNC4J_SUBDIR)/test/test
|
||||
# automake build rules expect these to be available locally,
|
||||
# and we need to get rid of WCHAR
|
||||
ClientTest.h ClientTest.cpp client-test-main.cpp : % : $(SYNC4J_SUBDIR)/test/test/%
|
||||
sed -e 's/WCHAR_T/char/g' -e 's/TEXT(/(/g' -e 's/wcslen/strlen/g' -e 's/wcscmp/strcmp/g' $< >$@
|
||||
ClientTest.cpp : ClientTest.h
|
||||
|
||||
TestEvolution syncevolution vcardconverter : \
|
||||
@CORE_LDADD_DEP@ \
|
||||
$(SYNC4J_SUBDIR)/src/libsync4j.la
|
||||
test : TestEvolution addressbook.tests calendar.tests todo.tests memo.tests synccompare vcardconverter
|
||||
testcases: $(SYNC4J_SUBDIR)/test/test/testcases
|
||||
ln -s $< $@
|
||||
|
||||
test : client-test testcases synccompare
|
||||
|
||||
|
||||
# TestEvolution syncevolution vcardconverter : \
|
||||
# @CORE_LDADD_DEP@ \
|
||||
# $(SYNC4J_SUBDIR)/src/libsync4j.la
|
||||
#test : TestEvolution addressbook.tests calendar.tests todo.tests memo.tests synccompare vcardconverter
|
||||
|
||||
# test files are in CVS under a different name so that they
|
||||
# can be copied to the work directory under the name expected
|
||||
# by the "test" program
|
||||
addressbook.tests : testVCard.vcf
|
||||
cp $< $@
|
||||
calendar.tests : testCalendar.ics
|
||||
cp $< $@
|
||||
todo.tests : testTask.ics
|
||||
cp $< $@
|
||||
memo.tests : testMemo.ics
|
||||
cp $< $@
|
||||
#addressbook.tests : testVCard.vcf
|
||||
# cp $< $@
|
||||
#calendar.tests : testCalendar.ics
|
||||
# cp $< $@
|
||||
#todo.tests : testTask.ics
|
||||
# cp $< $@
|
||||
#memo.tests : testMemo.ics
|
||||
# cp $< $@
|
||||
|
||||
testclean :
|
||||
rm -f *.test.vcf *.log *.tests *.diff
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <base/test.h>
|
||||
#include <test/ClientTest.h>
|
||||
#include <EvolutionClientConfig.h>
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <exception>
|
||||
|
@ -52,302 +53,136 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static bool compare(ClientTest &client, const char *fileA, const char *fileB)
|
||||
{
|
||||
stringstream cmd;
|
||||
|
||||
string diff = getCurrentTest() + ".diff";
|
||||
simplifyFilename(diff);
|
||||
cmd << "perl synccompare " << fileA << " " << fileB << ">" << diff;
|
||||
cmd << " || (echo; echo '*** " << diff << " non-empty ***'; cat " << diff << "; exit 1 )";
|
||||
|
||||
string cmdstr = cmd.str();
|
||||
return system(cmdstr.c_str()) == 0;
|
||||
}
|
||||
|
||||
class TestEvolution : public ClientTest {
|
||||
public:
|
||||
/**
|
||||
* can be instantiated as client A with id == "1" and client B with id == "2"
|
||||
*/
|
||||
TestEvolution(const string &id) :
|
||||
ClientTest(getenv("TEST_EVOLUTION_DELAY") ? atoi(getenv("TEST_EVOLUTION_DELAY")) : 0,
|
||||
getenv("TEST_EVOLUTION_LOG") ? getenv("TEST_EVOLUTION_LOG") : ""),
|
||||
ClientTest(getenv("CLIENT_TEST_DELAY") ? atoi(getenv("CLIENT_TEST_DELAY")) : 0,
|
||||
getenv("CLIENT_TEST_LOG") ? getenv("CLIENT_TEST_LOG") : ""),
|
||||
clientID(id) {
|
||||
const char *server = getenv("CLIENT_TEST_SERVER");
|
||||
|
||||
if (id == "1") {
|
||||
clientB.reset(new TestEvolution("2"));
|
||||
}
|
||||
|
||||
/* check server */
|
||||
if (!server) {
|
||||
server = "funambol";
|
||||
setenv("CLIENT_TEST_SERVER", "funambol", 1);
|
||||
}
|
||||
|
||||
/* check sources */
|
||||
const char *sourcelist = getenv("CLIENT_TEST_SOURCES");
|
||||
if (!sourcelist) {
|
||||
sourcelist = "vcard21,vcard30,ical20,imemo20,itodo20";
|
||||
}
|
||||
numSources = 0;
|
||||
for (SourceType sourceType = (SourceType)0; sourceType < TEST_MAX_SOURCE; sourceType = (SourceType)((int)sourceType + 1) ) {
|
||||
string name = getSourceName(sourceType);
|
||||
|
||||
#ifndef ENABLE_EBOOK
|
||||
if (sourceType == TEST_CONTACT21_SOURCE || sourceType == TEST_CONTACT30_SOURCE) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifndef ENABLE_ECAL
|
||||
if (sourceType == TEST_CALENDAR_SOURCE || sourceType == TEST_TASK_SOURCE) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (strstr(sourcelist, name.c_str())) {
|
||||
enabledSources[numSources++] = sourceType;
|
||||
}
|
||||
}
|
||||
|
||||
// get configuration and set obligatory fields
|
||||
LOG.setLevel(LOG_LEVEL_DEBUG);
|
||||
std::string root = std::string("evolution/") + server + "_" + id;
|
||||
std::auto_ptr<DMTClientConfig> config(new EvolutionClientConfig(root.c_str(), true));
|
||||
config->read();
|
||||
DeviceConfig &dc(config->getDeviceConfig());
|
||||
if (!strlen(dc.getDevID())) {
|
||||
// no configuration yet
|
||||
config->setClientDefaults();
|
||||
dc.setDevID(id == "1" ? "sc-api-nat" : "sc-pim-ppc");
|
||||
}
|
||||
for (SourceType sourceType = (SourceType)0; sourceType < TEST_MAX_SOURCE; sourceType = (SourceType)((int)sourceType + 1) ) {
|
||||
ClientTest::Config testconfig;
|
||||
getSourceConfig(sourceType, testconfig);
|
||||
CPPUNIT_ASSERT(testconfig.type);
|
||||
|
||||
SyncSourceConfig* sc = config->getSyncSourceConfig(testconfig.sourceName);
|
||||
if (!sc) {
|
||||
// no configuration yet
|
||||
config->setSourceDefaults(testconfig.sourceName);
|
||||
sc = config->getSyncSourceConfig(testconfig.sourceName);
|
||||
CPPUNIT_ASSERT(sc);
|
||||
sc->setURI(testconfig.uri);
|
||||
config->save();
|
||||
config->open();
|
||||
ManagementNode *node = config->getSyncSourceNode(testconfig.sourceName);
|
||||
CPPUNIT_ASSERT(node);
|
||||
string database = getDatabaseName(sourceType);
|
||||
node->setPropertyValue("evolutionsource", database.c_str());
|
||||
|
||||
// flush config to disk
|
||||
config.reset(new EvolutionClientConfig(root.c_str(), true));
|
||||
config->read();
|
||||
sc = config->getSyncSourceConfig(testconfig.sourceName);
|
||||
CPPUNIT_ASSERT(sc);
|
||||
}
|
||||
|
||||
sc->setType(testconfig.type);
|
||||
}
|
||||
config->save();
|
||||
}
|
||||
|
||||
enum sourceType {
|
||||
#ifdef ENABLE_EBOOK
|
||||
TEST_CONTACT_SOURCE,
|
||||
#endif
|
||||
#ifdef ENABLE_ECAL
|
||||
enum SourceType {
|
||||
TEST_CONTACT21_SOURCE,
|
||||
TEST_CONTACT30_SOURCE,
|
||||
TEST_CALENDAR_SOURCE,
|
||||
TEST_TASK_SOURCE,
|
||||
#endif
|
||||
// TEST_MEMO_SOURCE,
|
||||
TEST_MAX_SOURCE
|
||||
};
|
||||
|
||||
virtual int getNumSources() {
|
||||
return TEST_MAX_SOURCE;
|
||||
return numSources;
|
||||
}
|
||||
|
||||
virtual void getSourceConfig(SourceType sourceType, Config &config) {
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
switch (sourceType) {
|
||||
case TEST_CONTACT21_SOURCE:
|
||||
getTestData("vcard30", config);
|
||||
config.sourceName = "vcard21";
|
||||
config.uri = "card"; // Funambol
|
||||
config.type = "text/x-vcard";
|
||||
break;
|
||||
case TEST_CONTACT30_SOURCE:
|
||||
getTestData("vcard30", config);
|
||||
break;
|
||||
case TEST_CALENDAR_SOURCE:
|
||||
getTestData("ical20", config);
|
||||
break;
|
||||
case TEST_TASK_SOURCE:
|
||||
getTestData("itodo20", config);
|
||||
break;
|
||||
default:
|
||||
CPPUNIT_ASSERT(sourceType < TEST_MAX_SOURCE);
|
||||
break;
|
||||
}
|
||||
config.createSourceA = createSource;
|
||||
config.createSourceB = createSource;
|
||||
config.compare = compare;
|
||||
}
|
||||
|
||||
virtual void getSourceConfig(int source, Config &config) {
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
switch (source) {
|
||||
#ifdef ENABLE_EBOOK
|
||||
case TEST_CONTACT_SOURCE:
|
||||
config.sourceName = "Contact";
|
||||
config.createSourceA = createSource;
|
||||
config.createSourceB = createSource;
|
||||
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";
|
||||
config.import = ClientTest::import;
|
||||
config.dump = ClientTest::dump;
|
||||
config.compare = compare;
|
||||
config.testcases = "addressbook.tests";
|
||||
break;
|
||||
#endif /* ENABLE_EBOOK */
|
||||
#ifdef ENABLE_ECAL
|
||||
case TEST_CALENDAR_SOURCE:
|
||||
config.sourceName = "Calendar";
|
||||
config.createSourceA = createSource;
|
||||
config.createSourceB = createSource;
|
||||
config.insertItem =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VEVENT\n"
|
||||
"SUMMARY:phone meeting\n"
|
||||
"DTEND;20060406T163000Z\n"
|
||||
"DTSTART;20060406T160000Z\n"
|
||||
"UID:1234567890!@#$%^&*()<>@dummy\n"
|
||||
"DTSTAMP:20060406T211449Z\n"
|
||||
"LAST-MODIFIED:20060409T213201\n"
|
||||
"CREATED:20060409T213201\n"
|
||||
"LOCATION:my office\n"
|
||||
"DESCRIPTION:let's talk\n"
|
||||
"CLASS:PUBLIC\n"
|
||||
"TRANSP:OPAQUE\n"
|
||||
"SEQUENCE:1\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.updateItem =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VEVENT\n"
|
||||
"SUMMARY:meeting on site\n"
|
||||
"DTEND;20060406T163000Z\n"
|
||||
"DTSTART;20060406T160000Z\n"
|
||||
"UID:1234567890!@#$%^&*()<>@dummy\n"
|
||||
"DTSTAMP:20060406T211449Z\n"
|
||||
"LAST-MODIFIED:20060409T213201\n"
|
||||
"CREATED:20060409T213201\n"
|
||||
"LOCATION:big meeting room\n"
|
||||
"DESCRIPTION:nice to see you\n"
|
||||
"CLASS:PUBLIC\n"
|
||||
"TRANSP:OPAQUE\n"
|
||||
"SEQUENCE:1\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.complexUpdateItem = NULL;
|
||||
/* change location in insertItem in testMerge() */
|
||||
config.mergeItem1 =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VEVENT\n"
|
||||
"SUMMARY:phone meeting\n"
|
||||
"DTEND;20060406T163000Z\n"
|
||||
"DTSTART;20060406T160000Z\n"
|
||||
"UID:1234567890!@#$%^&*()<>@dummy\n"
|
||||
"DTSTAMP:20060406T211449Z\n"
|
||||
"LAST-MODIFIED:20060409T213201\n"
|
||||
"CREATED:20060409T213201\n"
|
||||
"LOCATION:calling from home\n"
|
||||
"DESCRIPTION:let's talk\n"
|
||||
"CLASS:PUBLIC\n"
|
||||
"TRANSP:OPAQUE\n"
|
||||
"SEQUENCE:1\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.mergeItem2 =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VEVENT\n"
|
||||
"SUMMARY:phone meeting\n"
|
||||
"DTEND;20060406T163000Z\n"
|
||||
"DTSTART;20060406T160000Z\n"
|
||||
"UID:1234567890!@#$%^&*()<>@dummy\n"
|
||||
"DTSTAMP:20060406T211449Z\n"
|
||||
"LAST-MODIFIED:20060409T213201\n"
|
||||
"CREATED:20060409T213201\n"
|
||||
"LOCATION:my office\n"
|
||||
"DESCRIPTION:what the heck\\, let's even shout a bit\n"
|
||||
"CLASS:PUBLIC\n"
|
||||
"TRANSP:OPAQUE\n"
|
||||
"SEQUENCE:1\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.templateItem = config.insertItem;
|
||||
config.uniqueProperties = "SUMMARY:UID";
|
||||
config.sizeProperty = "DESCRIPTION";
|
||||
config.import = ClientTest::import;
|
||||
config.dump = ClientTest::dump;
|
||||
config.compare = compare;
|
||||
config.testcases = "calendar.tests";
|
||||
break;
|
||||
case TEST_TASK_SOURCE:
|
||||
config.sourceName = "Todo";
|
||||
config.createSourceA = createSource;
|
||||
config.createSourceB = createSource;
|
||||
config.insertItem =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VTODO\n"
|
||||
"UID:20060417T173712Z-4360-727-1-2730@gollum\n"
|
||||
"DTSTAMP:20060417T173712Z\n"
|
||||
"SUMMARY:do me\n"
|
||||
"DESCRIPTION:to be done\n"
|
||||
"PRIORITY:0\n"
|
||||
"STATUS:IN-PROCESS\n"
|
||||
"CREATED:20060417T173712\n"
|
||||
"LAST-MODIFIED:20060417T173712\n"
|
||||
"END:VTODO\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.updateItem =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VTODO\n"
|
||||
"UID:20060417T173712Z-4360-727-1-2730@gollum\n"
|
||||
"DTSTAMP:20060417T173712Z\n"
|
||||
"SUMMARY:do me ASAP\n"
|
||||
"DESCRIPTION:to be done\n"
|
||||
"PRIORITY:1\n"
|
||||
"STATUS:IN-PROCESS\n"
|
||||
"CREATED:20060417T173712\n"
|
||||
"LAST-MODIFIED:20060417T173712\n"
|
||||
"END:VTODO\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.complexUpdateItem = NULL;
|
||||
/* change summary in insertItem in testMerge() */
|
||||
config.mergeItem1 =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VTODO\n"
|
||||
"UID:20060417T173712Z-4360-727-1-2730@gollum\n"
|
||||
"DTSTAMP:20060417T173712Z\n"
|
||||
"SUMMARY:do me please\\, please\n"
|
||||
"DESCRIPTION:to be done\n"
|
||||
"PRIORITY:0\n"
|
||||
"STATUS:IN-PROCESS\n"
|
||||
"CREATED:20060417T173712\n"
|
||||
"LAST-MODIFIED:20060417T173712\n"
|
||||
"END:VTODO\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.mergeItem2 =
|
||||
"BEGIN:VCALENDAR\n"
|
||||
"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
|
||||
"VERSION:2.0\n"
|
||||
"METHOD:PUBLISH\n"
|
||||
"BEGIN:VTODO\n"
|
||||
"UID:20060417T173712Z-4360-727-1-2730@gollum\n"
|
||||
"DTSTAMP:20060417T173712Z\n"
|
||||
"SUMMARY:do me\n"
|
||||
"DESCRIPTION:to be done\n"
|
||||
"PRIORITY:7\n"
|
||||
"STATUS:IN-PROCESS\n"
|
||||
"CREATED:20060417T173712\n"
|
||||
"LAST-MODIFIED:20060417T173712\n"
|
||||
"END:VTODO\n"
|
||||
"END:VCALENDAR\n";
|
||||
config.templateItem = config.insertItem;
|
||||
config.uniqueProperties = "SUMMARY:UID";
|
||||
config.sizeProperty = "DESCRIPTION";
|
||||
config.import = ClientTest::import;
|
||||
config.dump = ClientTest::dump;
|
||||
config.compare = compare;
|
||||
config.testcases = "todo.tests";
|
||||
break;
|
||||
#endif /* ENABLE_ECAL */
|
||||
default:
|
||||
CPPUNIT_ASSERT(source < TEST_MAX_SOURCE);
|
||||
break;
|
||||
}
|
||||
getSourceConfig(enabledSources[source], config);
|
||||
}
|
||||
|
||||
virtual ClientTest *getClientB() {
|
||||
|
@ -361,37 +196,17 @@ public:
|
|||
virtual int sync(
|
||||
const int *sources,
|
||||
SyncMode syncMode,
|
||||
const CheckSyncReport &checkReport,
|
||||
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]) {
|
||||
#ifdef ENABLE_EBOOK
|
||||
case TEST_CONTACT_SOURCE:
|
||||
database = "addressbook";
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_ECAL
|
||||
case TEST_CALENDAR_SOURCE:
|
||||
database = "calendar";
|
||||
break;
|
||||
case TEST_TASK_SOURCE:
|
||||
database = "task";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CPPUNIT_ASSERT(sources[i] >= 0 && sources[i] < TEST_MAX_SOURCE);
|
||||
break;
|
||||
}
|
||||
|
||||
activeSources.insert(database + "_" + clientID);
|
||||
activeSources.insert(getSourceName(enabledSources[sources[i]]));
|
||||
}
|
||||
|
||||
string server = getenv("TEST_EVOLUTION_SERVER") ? getenv("TEST_EVOLUTION_SERVER") : "funambol";
|
||||
string server = getenv("CLIENT_TEST_SERVER") ? getenv("CLIENT_TEST_SERVER") : "funambol";
|
||||
server += "_";
|
||||
server += clientID;
|
||||
|
||||
|
@ -404,7 +219,7 @@ public:
|
|||
long maxObjSize,
|
||||
bool loSupport,
|
||||
const char *encoding) :
|
||||
EvolutionSyncClient(server, false, activeSources),
|
||||
EvolutionSyncClient(server, false, activeSources, "evolution/"),
|
||||
m_syncMode(syncMode),
|
||||
m_maxMsgSize(maxMsgSize),
|
||||
m_maxObjSize(maxObjSize),
|
||||
|
@ -439,22 +254,65 @@ public:
|
|||
const char *m_encoding;
|
||||
} client(server, activeSources, syncMode, maxMsgSize, maxObjSize, loSupport, encoding);
|
||||
|
||||
return client.sync();
|
||||
int res = client.sync();
|
||||
CPPUNIT_ASSERT(client.getSyncReport());
|
||||
checkReport.check(res, *client.getSyncReport());
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool compare(ClientTest &client, const char *fileA, const char *fileB) {
|
||||
std::string cmdstr = std::string("./synccompare ") + fileA + " " + fileB;
|
||||
return system(cmdstr.c_str()) == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
string clientID;
|
||||
std::auto_ptr<TestEvolution> clientB;
|
||||
|
||||
/** all sources that are active in the current test run */
|
||||
SourceType enabledSources[TEST_MAX_SOURCE];
|
||||
/** number of active sources */
|
||||
int numSources;
|
||||
|
||||
/** returns the name corresponding to the type, using the same strings as the C++ client testing system */
|
||||
string getSourceName(SourceType type) {
|
||||
switch (type) {
|
||||
#ifdef ENABLE_EBOOK
|
||||
case TEST_CONTACT21_SOURCE:
|
||||
return "vcard21";
|
||||
break;
|
||||
case TEST_CONTACT30_SOURCE:
|
||||
return "vcard30";
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_ECAL
|
||||
case TEST_CALENDAR_SOURCE:
|
||||
return "ical20";
|
||||
break;
|
||||
case TEST_TASK_SOURCE:
|
||||
return "itodo20";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CPPUNIT_ASSERT(type >= 0 && type < TEST_MAX_SOURCE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** returns the name of the Evolution database */
|
||||
string getDatabaseName(SourceType type) {
|
||||
return string("SyncEvolution test ") + getSourceName(type) + " #" + clientID;
|
||||
}
|
||||
|
||||
static SyncSource *createSource(ClientTest &client, int type, bool isSourceA) {
|
||||
string changeID = "SyncEvolution Change ID #";
|
||||
changeID += isSourceA ? "1" : "2";
|
||||
string database = "SyncEvolution test #";
|
||||
database += ((TestEvolution &)client).clientID;
|
||||
string database = ((TestEvolution &)client).getDatabaseName((SourceType)type);
|
||||
|
||||
switch (type) {
|
||||
#ifdef ENABLE_EBOOK
|
||||
case TEST_CONTACT_SOURCE:
|
||||
case TEST_CONTACT21_SOURCE:
|
||||
case TEST_CONTACT30_SOURCE:
|
||||
return new TestEvolutionSyncSource<EvolutionContactSource>(changeID, database);
|
||||
break;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue