Merge branch 'FREMANTLE-1-2-0' into HARMATTAN-1-2-0
Conflicts: debian/changelog debian/control debian/rules
This commit is contained in:
commit
b2d6d21491
301
NEWS
301
NEWS
|
@ -1,3 +1,304 @@
|
|||
SyncEvolution 1.1.1 -> 1.2, 13.10.2011
|
||||
======================================
|
||||
|
||||
The major new feature of the 1.2 release is support for non-SyncML
|
||||
protocols in general and CalDAV/CardDAV in particular. ActiveSync
|
||||
support is in development and will be in 1.3. These protocols are
|
||||
implemented as backends which are combined with other backends by
|
||||
SyncEvolution in a so called "local sync". The GTK sync-ui does not
|
||||
yet support configuring non-SyncML protocols. See the README.rst and
|
||||
man page for more information on how to use the new feature via the
|
||||
command line.
|
||||
|
||||
Properties not supported by SyncML servers can now be preserved
|
||||
locally in two-way synchronization (BMC #15030). This depends on
|
||||
information about what properties a SyncML server supports ("CtCap"),
|
||||
which is typically not provided by servers. SyncEvolution contains a
|
||||
copy of that information for Google Contacts (BMC #15029).
|
||||
|
||||
Akonadi backend and KWallet support were merged. They are not included
|
||||
yet in syncevolution.org binaries. To use them compile from source.
|
||||
|
||||
The configuration format was updated to solve a conceptual problem
|
||||
inherited with the legacy property names: the "type" property had
|
||||
multiple, sometimes conflicting roles. For example, setting the
|
||||
preferred data format for sync with one peer might have changed the
|
||||
backend selection for some other peer (BMC #1023). Now
|
||||
"backend/databaseFormat/syncFormat/forceSyncFormat" replace
|
||||
"type". "type" is still accepted by the command line as alias.
|
||||
|
||||
Upgrading from releases before 1.2:
|
||||
|
||||
Old configurations can still be read. But writing, as it happens
|
||||
during a sync, must migrate the configuration first. Release 1.2
|
||||
automatically migrates configurations. The old configurations
|
||||
will still be available (see "syncevolution --print-configs") but must
|
||||
be renamed manually to use them again under their original names with
|
||||
older SyncEvolution releases.
|
||||
|
||||
|
||||
Other changes:
|
||||
|
||||
* Using the --sync-property and --source-property command line options is
|
||||
optional, just specifying the property assignment is enough.
|
||||
|
||||
* syncevo-http-server was enhanced considerably. See http://syncevolution.org/wiki/http-server-howto
|
||||
|
||||
* support NetworkManager API >= 0.9 (BMC #19470)
|
||||
|
||||
* syncevolution.org binaries: now compatible with Debian Testing/libnotify.so.4 (BMC #22668)
|
||||
|
||||
libnotify is not linked directly into syncevo-dbus-server in the
|
||||
syncevolution.org binaries. Instead libnotify.so.1 till .so.4
|
||||
(current Debian Testing) are opened opened dynamically and the
|
||||
necessary functions are looked up via dlsym(). Not finding the
|
||||
libraries or the functions silently disables this notification
|
||||
mechanism.
|
||||
|
||||
* Sync mode is recorded when running in SyncML server mode (BMC #2786).
|
||||
|
||||
* syncevo-dbus-server automatically stops when some of its libraries
|
||||
are updated and restarts if auto-syncing is on (BMC #14955).
|
||||
|
||||
* Added code for Buteo, mKCal and QtContacts in MeeGo.
|
||||
|
||||
Buteo and mKCal were removed again from MeeGo, so the code
|
||||
is obsolete. The QtContacts backend may be still be useful
|
||||
to access items via that API, but for syncing on MeeGo
|
||||
the normal EDS backend is used since MeeGo reverted back
|
||||
to EDS as PIM storage.
|
||||
|
||||
* "databasePassword" source property: lookup failure in keyring (BMC #22937)
|
||||
|
||||
The databasePassword also wasn't looked up at all when doing item operations
|
||||
via the command line.
|
||||
|
||||
When configuring sources for an HTTP server, the config name typically
|
||||
is just the context (@foo). When using the config in the HTTP server,
|
||||
the config name is the peer inside that context (client@foo). Because
|
||||
the GNOME keyring lookup keys for the "databasePassword" (more
|
||||
specifically, the object name) contained the full config name which
|
||||
was different in both cases, looking up the saved password failed.
|
||||
|
||||
The solution is to normalize the config name (to accomodate for
|
||||
different ways of spelling it) and use only the context, with @ as
|
||||
before. This will break existing setups where the object name in the
|
||||
keyring (incorrectly) includes the full config name. In that case just
|
||||
configure the source again to set the password anew.
|
||||
|
||||
* Evolution Calendar: fixed detached recurrence support (BMC #22940)
|
||||
|
||||
When manipulating a meeting series with more than one detached
|
||||
recurrence certain sequences of operations could incorrectly fail
|
||||
with "UID already exists".
|
||||
|
||||
* iCalendar 2.0: must set VALUE in EXDATE (part of BMC #22940)
|
||||
|
||||
EXDATE has a VALUE parameter, which wasn't defined in the XML
|
||||
profile. Didn't seem to matter at all in practice, but wasn't
|
||||
standard-compliant.
|
||||
|
||||
* GTK sync-ui: wrap sync service descriptions (BMC #7199)
|
||||
|
||||
Descriptions of different sync services are not fully visible unless
|
||||
word-wrapping gets enabled.
|
||||
|
||||
* CalDAV/CardDAV + local storage: avoid empty properties
|
||||
|
||||
The main motivation for this change is that a recent Apple Calendar
|
||||
server rejects vCards with empty BDAY property. Another reason is that
|
||||
keeping the data as small as possible is desirable by itself.
|
||||
|
||||
Sending an empty property serves as a hint for the peer that the
|
||||
property is supported. This is not necessary when storing an item in a
|
||||
backend. Therefore this commit disables empty properties for all
|
||||
backends which do not themselves set the m_backendRule Synthesis info
|
||||
value.
|
||||
|
||||
* Google Contacts: ensure that first/middle/name are set when storing in EDS (BMC #20864)
|
||||
|
||||
Evolution and the MeeGo UX assume that first/middle/last name are set.
|
||||
That is not the case when a contact is created in the Google Contacts
|
||||
web interface. Such contacts are sent by Google without the N
|
||||
property.
|
||||
|
||||
SyncEvolution now tries to recreate the name components from the FN
|
||||
string, by splitting at word boundaries and assuming "<first>
|
||||
<middle> <last>" or "<last>, <first>" format. Obviously this
|
||||
heuristic fails for some locales.
|
||||
|
||||
* Evolution Calendar: fixed error handling for broken TZIDs
|
||||
|
||||
* Sony Ericsson: use ISO-8859-1 for all devices (BMC #14414)
|
||||
|
||||
Passing invalid UTF-8 strings into libecal caused glib to
|
||||
abort syncevo-dbus-server.
|
||||
|
||||
* auto sync: show all failed syncs except for temporary network errors (BMC #21888)
|
||||
|
||||
Notifications were meant to be shown for all errors except temporary
|
||||
ones. This has never been implemented correctly since the feature was
|
||||
introduced: instead of hiding known temporary errors, all errors except
|
||||
500 (fatal error) were suppressed.
|
||||
|
||||
* vCard: inline local photo data (BMC #19661)
|
||||
|
||||
Some platforms (Maemo, MeeGo) store photos in separate files. Now SyncEvolution
|
||||
efficiently includes that photo data in the generated vCard right before sending
|
||||
it to a peer; previously it sent a useless local file:// URI. The Maemo port
|
||||
has a less efficient workaround for that which now should be obsolete.
|
||||
|
||||
* syncevo-dbus-server: online status wrong without Network Manager or ConnMan (BMC #21543)
|
||||
|
||||
When neither Network Manager nor ConnMan are running, network presence was "not
|
||||
online". This prevented running automatic syncs.
|
||||
|
||||
|
||||
For developers:
|
||||
|
||||
* modified backend API
|
||||
- ClientTestConfig modernized
|
||||
- InsertItemResult::m_merged turned from boolean to enum
|
||||
|
||||
* testing and compilation changes; for example, the minimum version of
|
||||
libsynthesis is now checked at configure time instead of failing at
|
||||
runtime due to missing features in the Synthesis engine
|
||||
|
||||
|
||||
SyncEvolution 1.1.99.7 -> 1.2, 13.10.2011
|
||||
=========================================
|
||||
|
||||
Some more bug fixes and testing improvements.
|
||||
|
||||
* fixed potential invalid memory access in add<->add conflict handling
|
||||
* fixed memory leak in workaround for EDS bug
|
||||
* CalDAV/CardDAV: handle ETags without quotation marks (eGroupware)
|
||||
* updated README: warning about sync direction moved to --sync option
|
||||
|
||||
|
||||
SyncEvolution 1.1.99.6 -> 1.1.99.7, 15.09.2011
|
||||
==============================================
|
||||
|
||||
Mostly bug fixes again. Some are a bit more intrusive, thus another
|
||||
pre-release.
|
||||
|
||||
* syncevolution.org binaries: now compatible with Debian Testing/libnotify.so.4 (BMC #22668)
|
||||
|
||||
libnotify is not linked directly into syncevo-dbus-server in the
|
||||
syncevolution.org binaries. Instead libnotify.so.1 till .so.4
|
||||
(current Debian Testing) are opened opened dynamically and the
|
||||
necessary functions are looked up via dlsym(). Not finding the
|
||||
libraries or the functions silently disables this notification
|
||||
mechanism.
|
||||
|
||||
* calendar sync: better handling for add<->add conflicts (partly fixes BMC #22783)
|
||||
|
||||
When both sides of a sync have added the same event, the sync must
|
||||
determine which one is more recent instead of blindly overwriting
|
||||
always the same side. Such conflicts are typically rare except for
|
||||
enterprise scenarios where meeting invitiations are processed
|
||||
automatically by a groupware (Exchange, Google Calendar/Mail, ...)
|
||||
and then the attendee status is updated on one side.
|
||||
|
||||
SyncEvolution now does the necessary age comparison and preserves the more
|
||||
recent data for most properties. In some properties the data from both
|
||||
sides is preserved by concatenating the text (description, location, ...).
|
||||
It remains to be seen whether that is really desirable. Also, sync statistics
|
||||
are slightly off: the incoming item is counted as "added" even though it
|
||||
gets turned into an update.
|
||||
|
||||
* item operations: authentication problem for WebDAV when using keyring (BMC #21311)
|
||||
|
||||
The password still wasn't looked up in the keyring when using
|
||||
--import/export/delete-items.
|
||||
|
||||
* "databasePassword" source property: lookup failure in keyring (BMC #22937)
|
||||
|
||||
The databasePassword also wasn't looked up at all when doing item operations
|
||||
via the command line.
|
||||
|
||||
When configuring sources for an HTTP server, the config name typically
|
||||
is just the context (@foo). When using the config in the HTTP server,
|
||||
the config name is the peer inside that context (client@foo). Because
|
||||
the GNOME keyring lookup keys for the "databasePassword" (more
|
||||
specifically, the object name) contained the full config name which
|
||||
was different in both cases, looking up the saved password failed.
|
||||
|
||||
The solution is to normalize the config name (to accomodate for
|
||||
different ways of spelling it) and use only the context, with @ as
|
||||
before. This will break existing setups where the object name in the
|
||||
keyring (incorrectly) includes the full config name. In that case just
|
||||
configure the source again to set the password anew.
|
||||
|
||||
* Evolution Calendar: fixed detached recurrence support (BMC #22940)
|
||||
|
||||
When manipulating a meeting series with more than one detached
|
||||
recurrence certain sequences of operations could incorrectly fail
|
||||
with "UID already exists".
|
||||
|
||||
* iCalendar 2.0: must set VALUE in EXDATE (part of BMC #22940)
|
||||
|
||||
EXDATE has a VALUE parameter, which wasn't defined in the XML
|
||||
profile. Didn't seem to matter at all in practice, but wasn't
|
||||
standard-compliant.
|
||||
|
||||
* GTK sync-ui: wrap sync service descriptions (BMC #7199)
|
||||
|
||||
Descriptions of different sync services are not fully visible unless
|
||||
word-wrapping gets enabled.
|
||||
|
||||
* source configs: don't check "backend" unless it is needed
|
||||
|
||||
When using a config which has sources with a backend type set which is
|
||||
not currently available, an error was thrown even if those sources
|
||||
weren't even part of the current operation (for example, syncing
|
||||
another source which is currently supported).
|
||||
|
||||
* config migration: avoid name conflicts and auto syncing of old configs (BMC #22691)
|
||||
|
||||
When (auto-)migrating a config, it was possible that a name for the
|
||||
peer, say foo.old, was chosen for the renamed config although there
|
||||
was already such a config, for example foo.old in ~/.sync4j. Besides
|
||||
being confusing for users, this also led to a bug in the code where it
|
||||
copied from the older config with the foo.old name.
|
||||
|
||||
The main problem fixed is the disabling of auto syncing
|
||||
in the old config. Otherwise it was still used by syncevo-dbus-server
|
||||
for syncing, which triggered another auto-migration, ad infinitum...
|
||||
|
||||
* auto syncing: must check whether enabled when looking at unknown URLs (part of BMC #22691)
|
||||
|
||||
"syncURL = insert your URL here" with "autoSync = 0" did lead to auto
|
||||
sync attempts although it wasn't enabled. A check for "auto syncing
|
||||
enabled" was missing for the "unknown transport" case.
|
||||
|
||||
* CalDAV/CardDAV + local storage: avoid empty properties
|
||||
|
||||
The main motivation for this change is that a recent Apple Calendar
|
||||
server rejects vCards with empty BDAY property. Another reason is that
|
||||
keeping the data as small as possible is desirable by itself.
|
||||
|
||||
Sending an empty property serves as a hint for the peer that the
|
||||
property is supported. This is not necessary when storing an item in a
|
||||
backend. Therefore this commit disables empty properties for all
|
||||
backends which do not themselves set the m_backendRule Synthesis info
|
||||
value.
|
||||
|
||||
* Apple CardDAV: apply PHOTO import/export scripts by default
|
||||
|
||||
A recent Apple Calendar server (correctly) rejects the invalid
|
||||
PHOTO;TYPE=unknown: property in a vCard. This internal representation
|
||||
must be cleared before serializing the field list.
|
||||
|
||||
* for developers: modified backend API
|
||||
- ClientTestConfig modernized
|
||||
- InsertItemResult::m_merged turned from boolean to enum
|
||||
|
||||
* testing and compilation changes; for example, the minimum version of
|
||||
libsynthesis is now checked at configure time instead of failing at
|
||||
runtime due to missing features in the Synthesis engine
|
||||
|
||||
|
||||
SyncEvolution 1.1.99.5 -> 1.1.99.6, 17.08.2011
|
||||
==============================================
|
||||
|
||||
|
|
16
README.rst
16
README.rst
|
@ -274,6 +274,15 @@ a list of valid values.
|
|||
for a `refresh-from-server` or `refresh-from-client` sync which
|
||||
clears all data at one end and copies all items from the other.
|
||||
|
||||
**Warning:** in local sync (CalDAV/CardDAV/ActiveSync, ...) and
|
||||
direct sync with a phone, the sync is started by the side which acts
|
||||
as server. Therefore the ``from-server`` variants
|
||||
(``one-way-from-server``, ``refresh-from-server``) transfer data
|
||||
from the sync config into the target config (see "Synchronization
|
||||
beyond SyncML" below) resp. to a phone. The ``from-client`` variants
|
||||
transfer in the other direction, even if the target config happens
|
||||
to access data on a remote server.
|
||||
|
||||
--print-servers|--print-configs|--print-peers
|
||||
Prints the names of all configured peers to stdout. There is no
|
||||
difference between these options, the are just aliases.
|
||||
|
@ -661,13 +670,6 @@ source in the target config. The ``sync`` property in the sync config
|
|||
defines the direction of the data flow. It can be set temporarily when
|
||||
starting a synchronzation with the sync config.
|
||||
|
||||
**Warning:** in local sync, the sync config side acts as
|
||||
server. Therefore the ``from-server`` variants
|
||||
(``one-way-from-server``, ``refresh-from-server``) transfer data
|
||||
from the sync config into the target config. The ``from-client``
|
||||
variants transfer in the other direction, even if the target config
|
||||
happens to access data on a remote server.
|
||||
|
||||
**Warning:** because the client in the local sync starts the sync,
|
||||
``preventSlowSync=0`` must be set in the target config to have an effect.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ dnl Invoke autogen.sh to produce a configure script.
|
|||
#
|
||||
# Starting with the 1.1 release cycle, the rpm-style
|
||||
# .99 pseudo-version number is used to mark a pre-release.
|
||||
AC_INIT([syncevolution], [1.1.99.6])
|
||||
AC_INIT([syncevolution], [1.2])
|
||||
# STABLE_VERSION=1.0.1+
|
||||
AC_SUBST(STABLE_VERSION)
|
||||
|
||||
|
@ -20,6 +20,10 @@ AC_SUBST(STABLE_VERSION)
|
|||
# SyncEvolution >= 1.1.99.5: release mode by default
|
||||
define([STABLE_RELEASE], [yes])
|
||||
|
||||
# Minimum version of libsynthesis as defined in its
|
||||
# configure script and thus .pc files:
|
||||
define([SYNTHESIS_MIN_VERSION], [3.4.0.16.4])
|
||||
|
||||
# Line above is patched by gen-autotools.sh. Handle
|
||||
# both "yes" and "no".
|
||||
define([STABLE_RELEASE_HELP], ifelse(STABLE_RELEASE,yes,--disable-release-mode,--enable-release-mode))
|
||||
|
@ -509,6 +513,17 @@ if test $enable_dbus_service = "yes"; then
|
|||
AC_DEFINE(HAS_NOTIFY, 1, [define if libnotify could be used in dbus service])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(notify-compatibility,
|
||||
AS_HELP_STRING([--enable-notify-compatibility],
|
||||
[increase compatibility with binary libnotify installations by loading libnotify.so.1..4 dynamically instead of linking against it]),
|
||||
[enable_notify_compat="$enableval"],
|
||||
[enable_notify_compat="no"]
|
||||
)
|
||||
if test "$enable_notify_compat" = "yes"; then
|
||||
AC_DEFINE(NOTIFY_COMPATIBILITY, 1, [dynamically open libnotify])
|
||||
LIBNOTIFY_LIBS="`echo $LIBNOTIFY_LIBS | sed -e 's/\(-lnotify\|[^ ]*libnotify.la\)/-ldl/'`"
|
||||
fi
|
||||
|
||||
# Here we're using QtGui too because mlite fails to depend on it,
|
||||
# despite using QAction.
|
||||
PKG_CHECK_MODULES(MLITE, [mlite QtGui], HAVE_MLITE=yes, HAVE_MLITE=no)
|
||||
|
@ -527,6 +542,8 @@ if test $enable_dbus_service = "yes"; then
|
|||
fi
|
||||
AC_DEFINE(DBUS_SERVICE, 1, [define if dbus service is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL([NOTIFY_COMPATIBILITY], [test "$enable_notify_compat" = "yes"])
|
||||
|
||||
AC_SUBST(DBUS_CFLAGS)
|
||||
AC_SUBST(DBUS_LIBS)
|
||||
AC_SUBST(DBUS_GLIB_CFLAGS)
|
||||
|
@ -721,7 +738,7 @@ else
|
|||
#SYNTHESIS_ENGINE="`echo $SYNTHESIS_LIBS | sed -e 's/-lsynthesisstubs/-lsynthesis/'`"
|
||||
|
||||
# can't use the SDK alone because of sysync::SySyncDebugPuts()
|
||||
PKG_CHECK_MODULES([SYNTHESIS], [synthesis >= 3.4.0.16.1])
|
||||
PKG_CHECK_MODULES([SYNTHESIS], [synthesis >= SYNTHESIS_MIN_VERSION])
|
||||
SYNTHESIS_ENGINE="$SYNTHESIS_LIBS"
|
||||
fi
|
||||
|
||||
|
@ -762,6 +779,13 @@ if test $SYNTHESIS_SRC != "no-synthesis-source"; then
|
|||
if (set -x; mkdir -p $SYNTHESIS_SUBDIR && cd $SYNTHESIS_SUBDIR && eval "\$SHELL \"\$SYNTHESIS_CONFIGURE\" $ac_configure_args \"--srcdir=\$SYNTHESIS_SRC\" " ); then true; else
|
||||
AC_MSG_ERROR( [configuring Synthesis library failed] )
|
||||
fi
|
||||
|
||||
# do the version check with the .pc files prepared by the configure step above
|
||||
export PKG_CONFIG_PATH=$SYNTHESIS_SUBDIR:$PKG_CONFIG_PATH
|
||||
PKG_CHECK_MODULES([WITH_SYNTHESIS_SRC], [synthesis >= SYNTHESIS_MIN_VERSION],
|
||||
[],
|
||||
[AC_MSG_ERROR([need at least libsynthesis >= SYNTHESIS_MIN_VERSION; the latest libsynthesis for SyncEvolution is the one from http://meego.gitorious.org/meego-middleware/libsynthesis])])
|
||||
|
||||
fi
|
||||
|
||||
AC_SUBST(SYNTHESIS_CFLAGS)
|
||||
|
|
8
debian/changelog
vendored
8
debian/changelog
vendored
|
@ -1,3 +1,11 @@
|
|||
syncevolution (1:1.2.0-4) unstable; urgency=low
|
||||
|
||||
* SyncEvolution 1.2 for Harmattan.
|
||||
* Packaging updates for Fremantle merged into Harmattan tree
|
||||
(that's the reason for the version number jump on Harmattan).
|
||||
|
||||
-- Ove Kaaven <ovek@arcticnet.no> Sun, 20 Nov 2011 19:19:24 +0100
|
||||
|
||||
syncevolution (1:1.1.99.6-2) unstable; urgency=low
|
||||
|
||||
* Removed static libraries.
|
||||
|
|
|
@ -24,13 +24,46 @@
|
|||
#if HAS_NOTIFY
|
||||
|
||||
#include "NotificationBackendLibnotify.h"
|
||||
#include "syncevo/util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#ifdef NOTIFY_COMPATIBILITY
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
SE_BEGIN_CXX
|
||||
|
||||
#ifdef NOTIFY_COMPATIBILITY
|
||||
/**
|
||||
* set to real old C notify_notification_new() (with widget pointer) or new one (without);
|
||||
* because of the x86/AMD64 calling conventions, calling the newer function with
|
||||
* one extra parameter is okay
|
||||
*/
|
||||
gboolean (*notify_init)(const char *app_name);
|
||||
GList *(*notify_get_server_caps)(void);
|
||||
NotifyNotification *(*notify_notification_new)(const char *summary, const char *body, const char *icon, void *widget);
|
||||
void (*notify_notification_add_action)(NotifyNotification *notification,
|
||||
const char *action,
|
||||
const char *label,
|
||||
NotifyActionCallback callback,
|
||||
gpointer user_data,
|
||||
GFreeFunc free_func);
|
||||
void (*notify_notification_clear_actions)(NotifyNotification *notification);
|
||||
gboolean (*notify_notification_close)(NotifyNotification *notification,
|
||||
GError **error);
|
||||
gboolean (*notify_notification_show)(NotifyNotification *notification,
|
||||
GError **error);
|
||||
|
||||
static bool NotFound(const char *func)
|
||||
{
|
||||
SE_LOG_DEBUG(NULL, NULL, "%s: not found", func);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NotificationBackendLibnotify::NotificationBackendLibnotify()
|
||||
: m_initialized(false),
|
||||
m_acceptsActions(false),
|
||||
|
@ -64,6 +97,36 @@ bool NotificationBackendLibnotify::init()
|
|||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
#ifdef NOTIFY_COMPATIBILITY
|
||||
void *dlhandle = NULL;
|
||||
int i;
|
||||
for (i = 1; i <= 4; i++) {
|
||||
dlhandle = dlopen(StringPrintf("libnotify.so.%d", i).c_str(), RTLD_LAZY|RTLD_GLOBAL);
|
||||
if (!dlhandle) {
|
||||
SE_LOG_DEBUG(NULL, NULL, "failed to load libnotify.so.%d: %s", i, dlerror());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dlhandle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define LOOKUP(_x) ((_x = reinterpret_cast<typeof(_x)>(dlsym(dlhandle, #_x))) || \
|
||||
NotFound(#_x))
|
||||
|
||||
if (!LOOKUP(notify_init) ||
|
||||
!LOOKUP(notify_get_server_caps) ||
|
||||
!LOOKUP(notify_notification_new) ||
|
||||
!LOOKUP(notify_notification_add_action) ||
|
||||
!LOOKUP(notify_notification_clear_actions) ||
|
||||
!LOOKUP(notify_notification_close) ||
|
||||
!LOOKUP(notify_notification_show)) {
|
||||
return false;
|
||||
}
|
||||
SE_LOG_DEBUG(NULL, NULL, "using libnotify.so.%d", i);
|
||||
#endif
|
||||
|
||||
m_initialized = notify_init("SyncEvolution");
|
||||
if(m_initialized) {
|
||||
GList *list = notify_get_server_caps();
|
||||
|
@ -94,7 +157,7 @@ void NotificationBackendLibnotify::publish(
|
|||
#ifndef NOTIFY_CHECK_VERSION
|
||||
# define NOTIFY_CHECK_VERSION(_x,_y,_z) 0
|
||||
#endif
|
||||
#if !NOTIFY_CHECK_VERSION(0,7,0)
|
||||
#if !NOTIFY_CHECK_VERSION(0,7,0) || defined(NOTIFY_COMPATIBILITY)
|
||||
m_notification = notify_notification_new(summary.c_str(), body.c_str(), NULL, NULL);
|
||||
#else
|
||||
m_notification = notify_notification_new(summary.c_str(), body.c_str(), NULL);
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "apple-contacts:text/x-vcard";
|
||||
config.m_type = "apple-contacts:text/x-vcard";
|
||||
}
|
||||
} vCard21Test;
|
||||
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "apple-contacts:text/vcard";
|
||||
config.m_type = "apple-contacts:text/vcard";
|
||||
}
|
||||
} vCard30Test;
|
||||
|
||||
|
|
|
@ -348,7 +348,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "kde-calendar";
|
||||
config.m_type = "kde-calendar";
|
||||
}
|
||||
} iCal20Test;
|
||||
|
||||
|
@ -358,7 +358,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "kde-tasks";
|
||||
config.m_type = "kde-tasks";
|
||||
}
|
||||
} iTodo20Test;
|
||||
|
||||
|
@ -368,7 +368,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "KDE Memos"; // use an alias here to test that
|
||||
config.m_type = "KDE Memos"; // use an alias here to test that
|
||||
}
|
||||
} memoTest;
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
ItemCreateJob *createJob = new ItemCreateJob(item, m_collection);
|
||||
if (!createJob->exec()) {
|
||||
throwError(string("storing new item ") + luid);
|
||||
return InsertItemResult("", "", false);
|
||||
return InsertItemResult("", "", ITEM_OKAY);
|
||||
}
|
||||
item = createJob->item();
|
||||
} else {
|
||||
|
@ -215,7 +215,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
// TODO: check that the item has not been updated in the meantime
|
||||
if (!modifyJob->exec()) {
|
||||
throwError(string("updating item ") + luid);
|
||||
return InsertItemResult("", "", false);
|
||||
return InsertItemResult("", "", ITEM_OKAY);
|
||||
}
|
||||
item = modifyJob->item();
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
// above will take care of this
|
||||
return InsertItemResult(QByteArray::number(item.id()).constData(),
|
||||
QByteArray::number(item.revision()).constData(),
|
||||
false);
|
||||
ITEM_OKAY);
|
||||
}
|
||||
|
||||
void AkonadiSyncSource::removeItem(const string &luid)
|
||||
|
|
|
@ -14,7 +14,7 @@ if ! test "$KDEPIM_CFLAGS"; then
|
|||
fi
|
||||
fi
|
||||
if ! test "$KDEPIM_LIBS"; then
|
||||
KDEPIM_LIBS="-L`kde4-config --prefix`/lib`kde4-config --libsuffix` -lakonadi-kde"
|
||||
KDEPIM_LIBS="-L`kde4-config --prefix`/lib`kde4-config --libsuffix` -lakonadi-kde -lQtDBus -lQtCore -lkdeui -lkdecore"
|
||||
fi
|
||||
AC_LANG_PUSH(C++)
|
||||
old_CPPFLAGS="$CPPFLAGS"
|
||||
|
|
|
@ -56,6 +56,32 @@ class unrefECalObjectList {
|
|||
}
|
||||
};
|
||||
|
||||
bool EvolutionCalendarSource::LUIDs::containsLUID(const ItemID &id) const
|
||||
{
|
||||
const_iterator it = findUID(id.m_uid);
|
||||
return it != end() &&
|
||||
it->second.find(id.m_rid) != it->second.end();
|
||||
}
|
||||
|
||||
void EvolutionCalendarSource::LUIDs::insertLUID(const ItemID &id)
|
||||
{
|
||||
(*this)[id.m_uid].insert(id.m_rid);
|
||||
}
|
||||
|
||||
void EvolutionCalendarSource::LUIDs::eraseLUID(const ItemID &id)
|
||||
{
|
||||
iterator it = find(id.m_uid);
|
||||
if (it != end()) {
|
||||
set<string>::iterator it2 = it->second.find(id.m_rid);
|
||||
if (it2 != it->second.end()) {
|
||||
it->second.erase(it2);
|
||||
if (it->second.empty()) {
|
||||
erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int granularity()
|
||||
{
|
||||
// This long delay is necessary in combination
|
||||
|
@ -254,7 +280,7 @@ void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
|||
string luid = id.getLUID();
|
||||
string modTime = getItemModTime(ecomp);
|
||||
|
||||
m_allLUIDs.insert(luid);
|
||||
m_allLUIDs.insertLUID(id);
|
||||
revisions[luid] = modTime;
|
||||
nextItem = nextItem->next;
|
||||
}
|
||||
|
@ -274,7 +300,7 @@ void EvolutionCalendarSource::readItem(const string &luid, std::string &item, bo
|
|||
EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(const string &luid, const std::string &item, bool raw)
|
||||
{
|
||||
bool update = !luid.empty();
|
||||
bool merged = false;
|
||||
InsertItemResultState state = ITEM_OKAY;
|
||||
bool detached = false;
|
||||
string newluid = luid;
|
||||
string data = item;
|
||||
|
@ -389,14 +415,14 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// gets used twice during a sync (examples: add + add, delete + add),
|
||||
// which should never happen.
|
||||
newluid = id.getLUID();
|
||||
if (m_allLUIDs.find(newluid) != m_allLUIDs.end()) {
|
||||
merged = true;
|
||||
if (m_allLUIDs.containsLUID(id)) {
|
||||
state = ITEM_NEEDS_MERGE;
|
||||
} else {
|
||||
// if this is a detached recurrence, then we
|
||||
// must use e_cal_modify_object() below if
|
||||
// the parent already exists
|
||||
// the parent or any other child already exists
|
||||
if (!id.m_rid.empty() &&
|
||||
m_allLUIDs.find(ItemID::getLUID(id.m_uid, "")) != m_allLUIDs.end()) {
|
||||
m_allLUIDs.containsUID(id.m_uid)) {
|
||||
detached = true;
|
||||
} else {
|
||||
// Creating the parent while children are already in
|
||||
|
@ -420,7 +446,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
ItemID newid(!id.m_uid.empty() ? id.m_uid : uid, id.m_rid);
|
||||
newluid = newid.getLUID();
|
||||
modTime = getItemModTime(newid);
|
||||
m_allLUIDs.insert(newluid);
|
||||
m_allLUIDs.insertLUID(newid);
|
||||
} else {
|
||||
throwError("storing new item", gerror);
|
||||
}
|
||||
|
@ -438,7 +464,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
}
|
||||
}
|
||||
|
||||
if (update || merged || detached) {
|
||||
if (update || state != ITEM_NEEDS_MERGE || detached) {
|
||||
ItemID id(newluid);
|
||||
bool isParent = id.m_rid.empty();
|
||||
|
||||
|
@ -475,11 +501,13 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// Therefore we have to use CALOBJ_MOD_ALL, but that removes
|
||||
// children.
|
||||
bool hasChildren = false;
|
||||
BOOST_FOREACH(ItemID existingId, m_allLUIDs) {
|
||||
if (existingId.m_uid == id.m_uid &&
|
||||
existingId.m_rid.size()) {
|
||||
hasChildren = true;
|
||||
break;
|
||||
LUIDs::const_iterator it = m_allLUIDs.find(id.m_uid);
|
||||
if (it != m_allLUIDs.end()) {
|
||||
BOOST_FOREACH(const string &rid, it->second) {
|
||||
if (!rid.empty()) {
|
||||
hasChildren = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,17 +554,17 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
modTime = getItemModTime(newid);
|
||||
}
|
||||
|
||||
return InsertItemResult(newluid, modTime, merged);
|
||||
return InsertItemResult(newluid, modTime, state);
|
||||
}
|
||||
|
||||
EvolutionCalendarSource::ICalComps_t EvolutionCalendarSource::removeEvents(const string &uid, bool returnOnlyChildren)
|
||||
{
|
||||
ICalComps_t events;
|
||||
|
||||
BOOST_FOREACH(const string &luid, m_allLUIDs) {
|
||||
ItemID id(luid);
|
||||
|
||||
if (id.m_uid == uid) {
|
||||
LUIDs::const_iterator it = m_allLUIDs.find(uid);
|
||||
if (it != m_allLUIDs.end()) {
|
||||
BOOST_FOREACH(const string &rid, it->second) {
|
||||
ItemID id(uid, rid);
|
||||
icalcomponent *icomp = retrieveItem(id);
|
||||
if (icomp) {
|
||||
if (id.m_rid.empty() && returnOnlyChildren) {
|
||||
|
@ -582,11 +610,21 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
ICalComps_t children = removeEvents(id.m_uid, true);
|
||||
|
||||
// recreate children
|
||||
bool first = true;
|
||||
BOOST_FOREACH(boost::shared_ptr< eptr<icalcomponent> > &icalcomp, children) {
|
||||
char *uid;
|
||||
if (first) {
|
||||
char *uid;
|
||||
|
||||
if (!e_cal_create_object(m_calendar, *icalcomp, &uid, &gerror)) {
|
||||
throwError(string("recreating item ") + luid, gerror);
|
||||
if (!e_cal_create_object(m_calendar, *icalcomp, &uid, &gerror)) {
|
||||
throwError(string("recreating first item ") + luid, gerror);
|
||||
}
|
||||
first = false;
|
||||
} else {
|
||||
if (!e_cal_modify_object(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS,
|
||||
&gerror)) {
|
||||
throwError(string("recreating following item ") + luid, gerror);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(!e_cal_remove_object_with_mod(m_calendar,
|
||||
|
@ -603,7 +641,7 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
throwError(string("deleting item " ) + luid, gerror);
|
||||
}
|
||||
}
|
||||
m_allLUIDs.erase(luid);
|
||||
m_allLUIDs.eraseLUID(id);
|
||||
|
||||
if (!id.m_rid.empty()) {
|
||||
// Removing the child may have modified the parent.
|
||||
|
@ -642,8 +680,21 @@ icalcomponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
|||
if (!comp) {
|
||||
throwError(string("retrieving item: ") + id.getLUID());
|
||||
}
|
||||
eptr<icalcomponent> ptr(comp);
|
||||
|
||||
return comp;
|
||||
/*
|
||||
* EDS bug: if a parent doesn't exist while a child does, and we ask
|
||||
* for the parent, we are sent the (first?) child. Detect this and
|
||||
* turn it into a "not found" error.
|
||||
*/
|
||||
if (id.m_rid.empty()) {
|
||||
struct icaltimetype rid = icalcomponent_get_recurrenceid(comp);
|
||||
if (!icaltime_is_null_time(rid)) {
|
||||
throwError(string("retrieving item: got child instead of parent: ") + id.m_uid);
|
||||
}
|
||||
}
|
||||
|
||||
return ptr.release();
|
||||
}
|
||||
|
||||
string EvolutionCalendarSource::retrieveItemAsString(const ItemID &id)
|
||||
|
|
|
@ -179,7 +179,15 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
* implemented without the troublesome querying of the EDS
|
||||
* backend.
|
||||
*/
|
||||
set<string> m_allLUIDs;
|
||||
class LUIDs : public map< string, set<string> > {
|
||||
public:
|
||||
bool containsUID(const std::string &uid) const { return findUID(uid) != end(); }
|
||||
const_iterator findUID(const std::string &uid) const { return find(uid); }
|
||||
|
||||
bool containsLUID(const ItemID &id) const;
|
||||
void insertLUID(const ItemID &id);
|
||||
void eraseLUID(const ItemID &id);
|
||||
} m_allLUIDs;
|
||||
|
||||
/**
|
||||
* A list of ref-counted smart pointers to icalcomponents.
|
||||
|
|
|
@ -317,7 +317,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "evolution-calendar";
|
||||
config.m_type = "evolution-calendar";
|
||||
}
|
||||
} iCal20Test;
|
||||
|
||||
|
@ -327,7 +327,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "evolution-tasks";
|
||||
config.m_type = "evolution-tasks";
|
||||
}
|
||||
} iTodo20Test;
|
||||
|
||||
|
@ -337,8 +337,8 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "virtual:text/x-vcalendar";
|
||||
config.subConfigs = "eds_event,eds_task";
|
||||
config.m_type = "virtual:text/x-vcalendar";
|
||||
config.m_subConfigs = "eds_event,eds_task";
|
||||
}
|
||||
|
||||
} superTest;
|
||||
|
@ -349,7 +349,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "Evolution Memos"; // use an alias here to test that
|
||||
config.m_type = "Evolution Memos"; // use an alias here to test that
|
||||
}
|
||||
} memoTest;
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
throwError("no UID for contact");
|
||||
}
|
||||
string newrev = getRevision(newuid);
|
||||
return InsertItemResult(newuid, newrev, false);
|
||||
return InsertItemResult(newuid, newrev, ITEM_OKAY);
|
||||
} else {
|
||||
throwError(uid.empty() ?
|
||||
"storing new contact" :
|
||||
|
@ -341,7 +341,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
throwError(string("failure parsing vcard " ) + item);
|
||||
}
|
||||
// not reached!
|
||||
return InsertItemResult("", "", false);
|
||||
return InsertItemResult("", "", ITEM_OKAY);
|
||||
}
|
||||
|
||||
void EvolutionContactSource::removeItem(const string &uid)
|
||||
|
|
|
@ -152,8 +152,8 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "evolution-contacts:text/vcard";
|
||||
config.update = config.genericUpdate;
|
||||
config.m_type = "evolution-contacts:text/vcard";
|
||||
config.m_update = config.m_genericUpdate;
|
||||
}
|
||||
} vCard30Test;
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionMemoSource::insertItem(const
|
|||
}
|
||||
|
||||
bool update = !luid.empty();
|
||||
bool merged = false;
|
||||
InsertItemResultState state = ITEM_OKAY;
|
||||
string newluid = luid;
|
||||
string modTime;
|
||||
|
||||
|
@ -170,28 +170,31 @@ EvolutionCalendarSource::InsertItemResult EvolutionMemoSource::insertItem(const
|
|||
}
|
||||
|
||||
GError *gerror = NULL;
|
||||
char *uid = NULL;
|
||||
|
||||
if (!update) {
|
||||
if(!e_cal_create_object(m_calendar, subcomp, &uid, &gerror)) {
|
||||
const char *uid = NULL;
|
||||
|
||||
if(!e_cal_create_object(m_calendar, subcomp, (char **)&uid, &gerror)) {
|
||||
if (gerror->domain == E_CALENDAR_ERROR &&
|
||||
gerror->code == E_CALENDAR_STATUS_OBJECT_ID_ALREADY_EXISTS) {
|
||||
// Deal with error due to adding already existing item.
|
||||
// Should never happen for plain text journal entries because
|
||||
// they have no embedded ID, but who knows...
|
||||
merged = true;
|
||||
state = ITEM_NEEDS_MERGE;
|
||||
uid = icalcomponent_get_uid(subcomp);
|
||||
if (!uid) {
|
||||
throwError("storing new memo item, no UID set", gerror);
|
||||
}
|
||||
g_clear_error(&gerror);
|
||||
} else {
|
||||
throwError( "storing new memo item", gerror );
|
||||
}
|
||||
} else {
|
||||
ItemID id(uid, "");
|
||||
newluid = id.getLUID();
|
||||
}
|
||||
ItemID id(uid, "");
|
||||
newluid = id.getLUID();
|
||||
if (state != ITEM_NEEDS_MERGE) {
|
||||
modTime = getItemModTime(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (update || merged) {
|
||||
} else {
|
||||
ItemID id(newluid);
|
||||
|
||||
// ensure that the component has the right UID
|
||||
|
@ -207,7 +210,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionMemoSource::insertItem(const
|
|||
modTime = getItemModTime(newid);
|
||||
}
|
||||
|
||||
return InsertItemResult(newluid, modTime, merged);
|
||||
return InsertItemResult(newluid, modTime, state);
|
||||
}
|
||||
|
||||
bool EvolutionMemoSource::isNativeType(const char *type)
|
||||
|
|
|
@ -233,7 +233,7 @@ TrackingSyncSource::InsertItemResult FileSyncSource::insertItem(const string &ui
|
|||
|
||||
return InsertItemResult(newuid,
|
||||
getATimeString(filename),
|
||||
false /* true if adding item was turned into update */);
|
||||
ITEM_OKAY);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "file:text/vcard:3.0";
|
||||
config.m_type = "file:text/vcard:3.0";
|
||||
}
|
||||
} VCard30Test;
|
||||
|
||||
|
@ -131,7 +131,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "file:text/calendar:2.0";
|
||||
config.m_type = "file:text/calendar:2.0";
|
||||
|
||||
// A sync source which supports linked items (= recurring
|
||||
// event with detached exception) is expected to handle
|
||||
|
@ -143,7 +143,7 @@ public:
|
|||
// Client::Source::file_event::testLinkedItemsInsertChildTwice
|
||||
//
|
||||
// Disable linked item testing to avoid this.
|
||||
config.sourceKnowsItemSemantic = false;
|
||||
config.m_sourceKnowsItemSemantic = false;
|
||||
}
|
||||
} ICal20Test;
|
||||
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "file:text/calendar:2.0";
|
||||
config.m_type = "file:text/calendar:2.0";
|
||||
}
|
||||
} ITodo20Test;
|
||||
|
||||
|
@ -163,8 +163,8 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "virtual:text/x-vcalendar";
|
||||
config.subConfigs = "file_event,file_task";
|
||||
config.m_type = "virtual:text/x-vcalendar";
|
||||
config.m_subConfigs = "file_event,file_task";
|
||||
}
|
||||
|
||||
} superTest;
|
||||
|
|
|
@ -93,10 +93,10 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "KCalExtended:text/calendar";
|
||||
config.m_type = "KCalExtended:text/calendar";
|
||||
// after fixing BMC #6061, mKCal is able to delete individual
|
||||
// VEVENTs, without enforcing the "each child must have parent" rule
|
||||
config.linkedItemsRelaxedSemantic = true;
|
||||
config.m_linkedItemsRelaxedSemantic = true;
|
||||
}
|
||||
} iCal20Test;
|
||||
|
||||
|
|
|
@ -73,6 +73,14 @@ std::string MaemoCalendarSource::getMimeVersion() const
|
|||
}
|
||||
}
|
||||
|
||||
void MaemoCalendarSource::getSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments)
|
||||
{
|
||||
TrackingSyncSource::getSynthesisInfo(info, fragments);
|
||||
info.m_backendRule = "MAEMO-CALENDAR";
|
||||
info.m_afterReadScript += "$FIX_EXDATE_SCRIPT;\n";
|
||||
}
|
||||
|
||||
void MaemoCalendarSource::open()
|
||||
{
|
||||
string id = getDatabaseID();
|
||||
|
@ -211,7 +219,8 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
|||
{
|
||||
int err;
|
||||
CComponent *c;
|
||||
bool r, u = false;
|
||||
bool r;
|
||||
InsertItemResultState u = ITEM_OKAY;
|
||||
TrackingSyncSource::InsertItemResult result;
|
||||
|
||||
if (cal->getCalendarType() == BIRTHDAY_CALENDAR) {
|
||||
|
@ -270,7 +279,7 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
|||
throwError(string("creating item "));
|
||||
}
|
||||
if (err == CALENDAR_ENTRY_DUPLICATED) {
|
||||
u = true;
|
||||
u = ITEM_MERGED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ class MaemoCalendarSource : public TrackingSyncSource, private boost::noncopyabl
|
|||
virtual Databases getDatabases();
|
||||
virtual std::string getMimeType() const;
|
||||
virtual std::string getMimeVersion() const;
|
||||
virtual void getSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments);
|
||||
|
||||
/* implementation of TrackingSyncSource interface */
|
||||
virtual void listAllItems(RevisionMap_t &revisions);
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "maemo-events";
|
||||
config.m_type = "maemo-events";
|
||||
}
|
||||
} iCal20Test;
|
||||
|
||||
|
@ -147,7 +147,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "maemo-tasks";
|
||||
config.m_type = "maemo-tasks";
|
||||
}
|
||||
} iTodo20Test;
|
||||
|
||||
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "maemo-notes";
|
||||
config.m_type = "maemo-notes";
|
||||
}
|
||||
} memoTest;
|
||||
|
||||
|
|
|
@ -202,8 +202,8 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "qt-contacts:text/vcard";
|
||||
config.testcases = "testcases/qt_contact.vcf";
|
||||
config.m_type = "qt-contacts:text/vcard";
|
||||
config.m_testcases = "testcases/qt_contact.vcf";
|
||||
}
|
||||
} vCard30Test;
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = "sqlite-contacts:text/x-vcard";
|
||||
config.testcases = "testcases/sqlite_vcard21.vcf";
|
||||
config.m_type = "sqlite-contacts:text/x-vcard";
|
||||
config.m_testcases = "testcases/sqlite_vcard21.vcf";
|
||||
}
|
||||
} VCard21Test;
|
||||
|
||||
|
|
|
@ -25,6 +25,22 @@ static std::string SubIDName(const std::string &subid)
|
|||
return subid.empty() ? "<master>" : subid;
|
||||
}
|
||||
|
||||
/** remove X-SYNCEVOLUTION-EXDATE-DETACHED from VEVENT */
|
||||
static void removeSyncEvolutionExdateDetached(icalcomponent *parent)
|
||||
{
|
||||
icalproperty *prop = icalcomponent_get_first_property(parent, ICAL_ANY_PROPERTY);
|
||||
while (prop) {
|
||||
icalproperty *next = icalcomponent_get_next_property(parent, ICAL_ANY_PROPERTY);
|
||||
const char *xname = icalproperty_get_x_name(prop);
|
||||
if (xname &&
|
||||
!strcmp(xname, "X-SYNCEVOLUTION-EXDATE-DETACHED")) {
|
||||
icalcomponent_remove_property(parent, prop);
|
||||
icalproperty_free(prop);
|
||||
}
|
||||
prop = next;
|
||||
}
|
||||
}
|
||||
|
||||
CalDAVSource::CalDAVSource(const SyncSourceParams ¶ms,
|
||||
const boost::shared_ptr<Neon::Settings> &settings) :
|
||||
WebDAVSource(params, settings)
|
||||
|
@ -328,6 +344,10 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
comp = icalcomponent_get_next_component(newEvent->m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
std::string subid = Event::getSubID(comp);
|
||||
EventCache::iterator it;
|
||||
// remove X-SYNCEVOLUTION-EXDATE-DETACHED, could be added by
|
||||
// the engine's read/modify/write cycle when resolving a
|
||||
// conflict
|
||||
removeSyncEvolutionExdateDetached(comp);
|
||||
if (!luid.empty() &&
|
||||
(it = m_cache.find(luid)) != m_cache.end()) {
|
||||
// Additional sanity check: ensure that the expected UID is set.
|
||||
|
@ -433,8 +453,9 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
Event &event = loadItem(*it->second);
|
||||
event.m_etag = res.m_revision;
|
||||
if (event.m_subids.find(subid) != event.m_subids.end()) {
|
||||
// was already in that item but caller didn't seem to know
|
||||
subres.m_merged = true;
|
||||
// was already in that item but caller didn't seem to know,
|
||||
// and now we replaced the data on the CalDAV server
|
||||
subres.m_state = ITEM_REPLACED;
|
||||
} else {
|
||||
// add to merged item
|
||||
event.m_subids.insert(subid);
|
||||
|
@ -466,6 +487,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
icalproperty *lastmod = icalcomponent_get_first_property(firstcomp, ICAL_LASTMODIFIED_PROPERTY);
|
||||
if (lastmod) {
|
||||
lastmodtime = icaltime_from_timet(newEvent->m_lastmodtime, false);
|
||||
lastmodtime.is_utc = 1;
|
||||
icalproperty_set_lastmodified(lastmod, lastmodtime);
|
||||
}
|
||||
icalproperty *dtstamp = icalcomponent_get_first_property(firstcomp, ICAL_DTSTAMP_PROPERTY);
|
||||
|
@ -496,10 +518,55 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (subid != knownSubID) {
|
||||
SE_THROW("new CalDAV item does not have right RECURRENCE-ID");
|
||||
if (!subid.empty() && subid != knownSubID) {
|
||||
SE_THROW(StringPrintf("new CalDAV item does not have right RECURRENCE-ID: item %s != expected %s",
|
||||
subid.c_str(), knownSubID.c_str()));
|
||||
}
|
||||
Event &event = loadItem(davLUID);
|
||||
|
||||
if (subid.empty() && subid != knownSubID) {
|
||||
// fix incomplete iCalendar 2.0 item: should have had a RECURRENCE-ID
|
||||
icalcomponent *newcomp =
|
||||
icalcomponent_get_first_component(newEvent->m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
icalproperty *prop = icalcomponent_get_first_property(newcomp, ICAL_RECURRENCEID_PROPERTY);
|
||||
if (prop) {
|
||||
icalcomponent_remove_property(newcomp, prop);
|
||||
icalproperty_free(prop);
|
||||
}
|
||||
|
||||
// reconstruct RECURRENCE-ID with known value and TZID from start time of
|
||||
// the parent event or (if not found) the current event
|
||||
eptr<icalproperty> rid(icalproperty_new_recurrenceid(icaltime_from_string(knownSubID.c_str())),
|
||||
"new rid");
|
||||
icalproperty *dtstart = NULL;
|
||||
icalcomponent *comp;
|
||||
// look for parent first
|
||||
for (comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp && !dtstart;
|
||||
comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
if (!icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY)) {
|
||||
dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY);
|
||||
}
|
||||
}
|
||||
// fall back to current event
|
||||
if (!dtstart) {
|
||||
dtstart = icalcomponent_get_first_property(newcomp, ICAL_DTSTART_PROPERTY);
|
||||
}
|
||||
// ignore missing TZID
|
||||
if (dtstart) {
|
||||
icalparameter *tzid = icalproperty_get_first_parameter(dtstart, ICAL_TZID_PARAMETER);
|
||||
if (tzid) {
|
||||
icalproperty_set_parameter(rid, icalparameter_new_clone(tzid));
|
||||
}
|
||||
}
|
||||
|
||||
// finally add RECURRENCE-ID and fix newEvent's meta information
|
||||
icalcomponent_add_property(newcomp, rid.release());
|
||||
subid = knownSubID;
|
||||
newEvent->m_subids.erase("");
|
||||
newEvent->m_subids.insert(subid);
|
||||
}
|
||||
|
||||
// no changes expected yet, copy previous attributes
|
||||
subres.m_mainid = davLUID;
|
||||
subres.m_uid = event.m_UID;
|
||||
|
@ -547,13 +614,11 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
}
|
||||
}
|
||||
if (davLUID != luid) {
|
||||
// caller didn't know final UID: if found, the tell him that
|
||||
// we merged the item for him, if not, then don't complain about
|
||||
// it not being found (like we do when the item should exist
|
||||
// but doesn't)
|
||||
// caller didn't know final UID: if found, then tell him to
|
||||
// merge the data and try again
|
||||
if (removeme) {
|
||||
subres.m_merged = true;
|
||||
icalcomponent_remove_component(event.m_calendar, removeme);
|
||||
subres.m_state = ITEM_NEEDS_MERGE;
|
||||
goto done;
|
||||
} else {
|
||||
event.m_subids.insert(subid);
|
||||
}
|
||||
|
@ -561,6 +626,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
if (removeme) {
|
||||
// this is what we expect when the caller mentions the DAV LUID
|
||||
icalcomponent_remove_component(event.m_calendar, removeme);
|
||||
icalcomponent_free(removeme);
|
||||
} else {
|
||||
// caller confused?!
|
||||
SE_THROW("event not found");
|
||||
|
@ -583,7 +649,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
try {
|
||||
SE_LOG_DEBUG(this, NULL, "updating VEVENT");
|
||||
InsertItemResult res = insertItem(event.m_DAVluid, data, true);
|
||||
if (res.m_merged ||
|
||||
if (res.m_state != ITEM_OKAY ||
|
||||
res.m_luid != event.m_DAVluid) {
|
||||
// should not merge with anything, if so, our cache was invalid
|
||||
SE_THROW("CalDAV item not updated as expected");
|
||||
|
@ -615,12 +681,56 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
|||
subres.m_merged = true;
|
||||
subres.m_revision = event.m_etag;
|
||||
#endif
|
||||
} else if (ex.syncMLStatus() == 409 &&
|
||||
strstr(ex.what(), "Can only store an event with a newer DTSTAMP")) {
|
||||
SE_LOG_DEBUG(NULL, NULL, "resending VEVENT with updated SEQUENCE/LAST-MODIFIED/DTSTAMP to work around 409");
|
||||
|
||||
// Sometimes a PUT of two linked events updates one of them on the server
|
||||
// (visible in modified SEQUENCE and LAST-MODIFIED values) and then
|
||||
// fails with 409 because, presumably, the other item now has
|
||||
// too low SEQUENCE/LAST-MODIFIED/DTSTAMP values.
|
||||
//
|
||||
// An attempt with splitting the PUT in advance worked for some cases,
|
||||
// but then it still happened for others. So let's use brute force and
|
||||
// try again once more after reading the updated event anew.
|
||||
eptr<icalcomponent> fullcal = event.m_calendar;
|
||||
loadItem(event);
|
||||
event.m_sequence++;
|
||||
lastmodtime = icaltime_from_timet(event.m_lastmodtime, false);
|
||||
lastmodtime.is_utc = 1;
|
||||
event.m_calendar = fullcal;
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
if (!icaltime_is_null_time(lastmodtime)) {
|
||||
icalproperty *dtstamp = icalcomponent_get_first_property(comp, ICAL_DTSTAMP_PROPERTY);
|
||||
if (dtstamp) {
|
||||
icalproperty_set_dtstamp(dtstamp, lastmodtime);
|
||||
}
|
||||
icalproperty *lastmod = icalcomponent_get_first_property(comp, ICAL_LASTMODIFIED_PROPERTY);
|
||||
if (lastmod) {
|
||||
icalproperty_set_lastmodified(lastmod, lastmodtime);
|
||||
}
|
||||
}
|
||||
Event::setSequence(comp, event.m_sequence);
|
||||
}
|
||||
eptr<char> icalstr(ical_strdup(icalcomponent_as_ical_string(event.m_calendar)));
|
||||
std::string data = icalstr.get();
|
||||
InsertItemResult res = insertItem(event.m_DAVluid, data, true);
|
||||
if (res.m_state != ITEM_OKAY ||
|
||||
res.m_luid != event.m_DAVluid) {
|
||||
// should not merge with anything, if so, our cache was invalid
|
||||
SE_THROW("CalDAV item not updated as expected");
|
||||
}
|
||||
event.m_etag = res.m_revision;
|
||||
subres.m_revision = event.m_etag;
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return subres;
|
||||
}
|
||||
|
||||
|
@ -646,19 +756,57 @@ void CalDAVSource::readSubItem(const std::string &davLUID, const std::string &su
|
|||
icalcomponent_add_component(calendar, clone.release());
|
||||
}
|
||||
bool found = false;
|
||||
icalcomponent *parent = NULL;
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
if (Event::getSubID(comp) == subid) {
|
||||
eptr<icalcomponent> clone(icalcomponent_new_clone(comp), "VEVENT");
|
||||
if (subid.empty()) {
|
||||
parent = clone.get();
|
||||
}
|
||||
icalcomponent_add_component(calendar, clone.release());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
SE_THROW("event not found");
|
||||
}
|
||||
|
||||
// tell engine and peers about EXDATEs implied by
|
||||
// RECURRENCE-IDs in detached recurrences by creating
|
||||
// X-SYNCEVOLUTION-EXDATE-DETACHED in the parent
|
||||
if (parent && event.m_subids.size() > 1) {
|
||||
// remove all old X-SYNCEVOLUTION-EXDATE-DETACHED (just in case)
|
||||
removeSyncEvolutionExdateDetached(parent);
|
||||
|
||||
// now populate with RECURRENCE-IDs of detached recurrences
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
icalproperty *prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY);
|
||||
if (prop) {
|
||||
eptr<char> rid(ical_strdup(icalproperty_get_value_as_string(prop)));
|
||||
icalproperty *exdate = icalproperty_new_from_string(StringPrintf("X-SYNCEVOLUTION-EXDATE-DETACHED:%s", rid.get()).c_str());
|
||||
if (exdate) {
|
||||
icalparameter *tzid = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
|
||||
if (tzid) {
|
||||
icalproperty_add_parameter(exdate, icalparameter_new_clone(tzid));
|
||||
}
|
||||
#if 0
|
||||
// not needed
|
||||
if (icalproperty_get_recurrenceid(exdate).is_date) {
|
||||
icalproperty_add_parameter(exdate, icalparameter_new_value(ICAL_VALUE_DATE));
|
||||
}
|
||||
#endif
|
||||
icalcomponent_add_property(parent, exdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eptr<char> icalstr(ical_strdup(icalcomponent_as_ical_string(calendar)));
|
||||
item = icalstr.get();
|
||||
}
|
||||
|
@ -720,10 +868,12 @@ std::string CalDAVSource::removeSubItem(const string &davLUID, const std::string
|
|||
icalproperty *prop;
|
||||
while ((prop = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY)) != NULL) {
|
||||
icalcomponent_remove_property(comp, prop);
|
||||
icalproperty_free(prop);
|
||||
updated = true;
|
||||
}
|
||||
while ((prop = icalcomponent_get_first_property(comp, ICAL_EXDATE_PROPERTY)) != NULL) {
|
||||
icalcomponent_remove_property(comp, prop);
|
||||
icalproperty_free(prop);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
@ -802,7 +952,7 @@ std::string CalDAVSource::removeSubItem(const string &davLUID, const std::string
|
|||
} else {
|
||||
res = insertItem(davLUID, icalstr.get(), true);
|
||||
}
|
||||
if (res.m_merged ||
|
||||
if (res.m_state != ITEM_OKAY ||
|
||||
res.m_luid != davLUID) {
|
||||
SE_THROW("unexpected result of removing sub event");
|
||||
}
|
||||
|
@ -1012,6 +1162,7 @@ void CalDAVSource::Event::fixIncomingCalendar(icalcomponent *calendar)
|
|||
// time.
|
||||
bool ridInUTC = false;
|
||||
const icaltimezone *zone = NULL;
|
||||
icalcomponent *parent = NULL;
|
||||
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
|
@ -1025,6 +1176,7 @@ void CalDAVSource::Event::fixIncomingCalendar(icalcomponent *calendar)
|
|||
// is parent event? -> remember time zone unless it is UTC
|
||||
static const struct icaltimetype null = { 0 };
|
||||
if (!memcmp(&rid, &null, sizeof(null))) {
|
||||
parent = comp;
|
||||
struct icaltimetype dtstart = icalcomponent_get_dtstart(comp);
|
||||
if (!icaltime_is_utc(dtstart)) {
|
||||
zone = icaltime_get_timezone(dtstart);
|
||||
|
|
|
@ -44,6 +44,10 @@ class CalDAVSource : public WebDAVSource,
|
|||
virtual std::string removeSubItem(const string &uid, const std::string &subid);
|
||||
virtual void flushItem(const string &uid);
|
||||
virtual std::string getSubDescription(const string &uid, const string &subid);
|
||||
virtual void updateSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments) {
|
||||
info.m_backendRule = "HAVE-SYNCEVOLUTION-EXDATE-DETACHED";
|
||||
}
|
||||
|
||||
// implementation of SyncSourceLogging callback
|
||||
virtual std::string getDescription(const string &luid);
|
||||
|
|
|
@ -1020,7 +1020,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
|||
{
|
||||
std::string new_uid;
|
||||
std::string rev;
|
||||
bool update = false; /* true if adding item was turned into update */
|
||||
InsertItemResultState state = ITEM_OKAY;
|
||||
|
||||
Timespec deadline = createDeadline(); // no resending if left empty
|
||||
m_session->startOperation("PUT", deadline);
|
||||
|
@ -1087,7 +1087,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
|||
SE_LOG_DEBUG(NULL, NULL, "new item mapped to %s", real_luid.c_str());
|
||||
new_uid = real_luid;
|
||||
// TODO: find a better way of detecting unexpected updates.
|
||||
// update = true;
|
||||
// state = ...
|
||||
} else if (!rev.empty()) {
|
||||
// Yahoo Contacts returns an etag, but no href. For items
|
||||
// that were really created as requested, that's okay. But
|
||||
|
@ -1114,7 +1114,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
|||
new_uid.c_str(),
|
||||
revisions.begin()->first.c_str());
|
||||
new_uid = revisions.begin()->first;
|
||||
update = true;
|
||||
state = ITEM_REPLACED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1182,7 +1182,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
|
|||
}
|
||||
}
|
||||
|
||||
return InsertItemResult(new_uid, rev, update);
|
||||
return InsertItemResult(new_uid, rev, state);
|
||||
}
|
||||
|
||||
std::string WebDAVSource::ETag2Rev(const std::string &etag)
|
||||
|
@ -1191,7 +1191,9 @@ std::string WebDAVSource::ETag2Rev(const std::string &etag)
|
|||
if (boost::starts_with(res, "W/")) {
|
||||
res.erase(0, 2);
|
||||
}
|
||||
if (res.size() >= 2) {
|
||||
if (res.size() >= 2 &&
|
||||
res[0] == '"' &&
|
||||
res[res.size() - 1] == '"') {
|
||||
res = res.substr(1, res.size() - 2);
|
||||
}
|
||||
return res;
|
||||
|
|
|
@ -229,13 +229,16 @@ public:
|
|||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
config.type = m_type.c_str();
|
||||
config.createSourceA = boost::bind(&WebDAVTest::createSource, this, _3);
|
||||
config.createSourceB = boost::bind(&WebDAVTest::createSource, this, _3);
|
||||
config.m_type = m_type.c_str();
|
||||
if (m_type == "caldav") {
|
||||
config.m_supportsReccurenceEXDates = true;
|
||||
}
|
||||
config.m_createSourceA = boost::bind(&WebDAVTest::createSource, this, _3);
|
||||
config.m_createSourceB = boost::bind(&WebDAVTest::createSource, this, _3);
|
||||
ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
|
||||
if (it != m_props.end() ||
|
||||
(it = m_props.find("testcases")) != m_props.end()) {
|
||||
config.testcases = it->second.c_str();
|
||||
config.m_testcases = it->second.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ TrackingSyncSource::InsertItemResult XMLRPCSyncSource::insertItem(const string &
|
|||
|
||||
return InsertItemResult((*it).first,
|
||||
xmlrpc_c::value_string((*it).second),
|
||||
false);
|
||||
ITEM_OKAY);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,46 +65,6 @@ public:
|
|||
|
||||
virtual void addTests() {
|
||||
LocalTests::addTests();
|
||||
|
||||
#ifdef ENABLE_MAEMO
|
||||
if (config.createSourceA &&
|
||||
config.createSourceB &&
|
||||
config.templateItem &&
|
||||
strstr(config.templateItem, "BEGIN:VCARD") &&
|
||||
config.uniqueProperties) {
|
||||
ADD_TEST(EvolutionLocalTests, testOssoDelete);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// insert am item,
|
||||
// overwrite it with an additional X-OSSO-CONTACT-STATE:DELETED as Maemoe address book does,
|
||||
// iterate again and check that our own code deleted the item
|
||||
void testOssoDelete() {
|
||||
// get into clean state with one template item added
|
||||
deleteAll(createSourceA);
|
||||
insert(createSourceA, config.templateItem, config.itemType);
|
||||
|
||||
// add X-OSSO-CONTACT-STATE:DELETED
|
||||
string item = config.templateItem;
|
||||
const char *comma = strchr(config.uniqueProperties, ':');
|
||||
size_t offset = item.find(config.uniqueProperties, 0,
|
||||
comma ? comma - config.uniqueProperties : strlen(config.uniqueProperties));
|
||||
CPPUNIT_ASSERT(offset != item.npos);
|
||||
item.insert(offset, "X-OSSO-CONTACT-STATE:DELETED\n");
|
||||
update(createSourceA, item.c_str(), false);
|
||||
|
||||
// opening and preparing the source should delete the item
|
||||
std::auto_ptr<TestingSyncSource> source;
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceA()));
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source->open());
|
||||
SOURCE_ASSERT_NO_FAILURE(source.get(), source->beginSync("", "") );
|
||||
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::ANY));
|
||||
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::NEW));
|
||||
CPPUNIT_ASSERT_EQUAL(0, countItemsOfType(source.get(), SyncSourceChanges::UPDATED));
|
||||
CPPUNIT_ASSERT_EQUAL(1, countItemsOfType(source.get(), SyncSourceChanges::DELETED));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -233,9 +193,9 @@ public:
|
|||
ClientTest::Config conf;
|
||||
BOOST_FOREACH (string source, sources) {
|
||||
getSourceConfig (source, conf);
|
||||
if (conf.subConfigs) {
|
||||
if (!conf.m_subConfigs.empty()) {
|
||||
vector<string> subs;
|
||||
boost::split (subs, conf.subConfigs, boost::is_any_of(","));
|
||||
boost::split (subs, conf.m_subConfigs, boost::is_any_of(","));
|
||||
BOOST_FOREACH (string sub, subs) {
|
||||
pushLocalSource2Config(sub);
|
||||
}
|
||||
|
@ -264,17 +224,17 @@ public:
|
|||
BOOST_FOREACH(const RegisterSyncSourceTest *test, m_configs) {
|
||||
ClientTest::Config testconfig;
|
||||
getSourceConfig(test, testconfig);
|
||||
CPPUNIT_ASSERT(testconfig.type);
|
||||
CPPUNIT_ASSERT(!testconfig.m_type.empty());
|
||||
|
||||
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.sourceName);
|
||||
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName);
|
||||
if (!sc || !sc->exists()) {
|
||||
// no configuration yet
|
||||
config->setSourceDefaults(testconfig.sourceName);
|
||||
sc = config->getSyncSourceConfig(testconfig.sourceName);
|
||||
config->setSourceDefaults(testconfig.m_sourceName);
|
||||
sc = config->getSyncSourceConfig(testconfig.m_sourceName);
|
||||
CPPUNIT_ASSERT(sc);
|
||||
sc->setURI(testconfig.uri);
|
||||
if(from && testconfig.sourceNameServerTemplate){
|
||||
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.sourceNameServerTemplate);
|
||||
sc->setURI(testconfig.m_uri);
|
||||
if(from && !testconfig.m_sourceNameServerTemplate.empty()) {
|
||||
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate);
|
||||
sc->setURI(scServerTemplate->getURI());
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +244,7 @@ public:
|
|||
sc->setDatabaseID(database);
|
||||
sc->setUser(m_evoUser);
|
||||
sc->setPassword(m_evoPassword);
|
||||
sc->setBackend(SourceType(testconfig.type).m_backend);
|
||||
sc->setBackend(SourceType(testconfig.m_type).m_backend);
|
||||
}
|
||||
config->flush();
|
||||
}
|
||||
|
@ -330,11 +290,10 @@ public:
|
|||
}
|
||||
|
||||
static void getSourceConfig(const RegisterSyncSourceTest *test, Config &config) {
|
||||
memset(&config, 0, sizeof(config));
|
||||
ClientTest::getTestData(test->m_testCaseName.c_str(), config);
|
||||
config.createSourceA = createSource;
|
||||
config.createSourceB = createSource;
|
||||
config.sourceName = test->m_configName.c_str();
|
||||
config.m_createSourceA = createSource;
|
||||
config.m_createSourceB = createSource;
|
||||
config.m_sourceName = test->m_configName.c_str();
|
||||
|
||||
test->updateConfig(config);
|
||||
}
|
||||
|
@ -539,7 +498,7 @@ private:
|
|||
getSourceConfig(test, testConfig);
|
||||
|
||||
PersistentSyncSourceConfig sourceConfig(params.m_name, params.m_nodes);
|
||||
sourceConfig.setSourceType(SourceType(testConfig.type));
|
||||
sourceConfig.setSourceType(SourceType(testConfig.m_type));
|
||||
|
||||
// downcasting here: anyone who registers his sources for testing
|
||||
// must ensure that they are indeed TestingSyncSource instances
|
||||
|
|
|
@ -1969,6 +1969,7 @@ sync_config_widget_init (SyncConfigWidget *self)
|
|||
self->description_label = gtk_label_new ("");
|
||||
gtk_misc_set_alignment (GTK_MISC (self->description_label), 0.0, 0.5);
|
||||
gtk_widget_set_size_request (self->description_label, 700, -1);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (self->description_label), TRUE);
|
||||
gtk_box_pack_start (GTK_BOX (tmp_box), self->description_label, FALSE, FALSE, 0);
|
||||
|
||||
tmp_box = gtk_hbox_new (FALSE, 0);
|
||||
|
|
|
@ -6519,13 +6519,16 @@ void AutoSyncManager::initConfig(const string &configName)
|
|||
|
||||
//enable http and bt?
|
||||
bool http = false, bt = false;
|
||||
bool any = false;
|
||||
if(autoSync.empty() || boost::iequals(autoSync, "0")
|
||||
|| boost::iequals(autoSync, "f")) {
|
||||
http = false;
|
||||
bt = false;
|
||||
any = false;
|
||||
} else if(boost::iequals(autoSync, "1") || boost::iequals(autoSync, "t")) {
|
||||
http = true;
|
||||
bt = true;
|
||||
any = true;
|
||||
} else {
|
||||
vector<string> options;
|
||||
boost::split(options, autoSync, boost::is_any_of(","));
|
||||
|
@ -6561,7 +6564,7 @@ void AutoSyncManager::initConfig(const string &configName)
|
|||
}
|
||||
if((transport == AutoSyncTask::NEEDS_HTTP && http) ||
|
||||
(transport == AutoSyncTask::NEEDS_BT && bt) ||
|
||||
(transport == AutoSyncTask::NEEDS_OTHER)) {
|
||||
(transport == AutoSyncTask::NEEDS_OTHER && any)) {
|
||||
AutoSyncTask syncTask(configName, duration, transport, url);
|
||||
PeerMap::iterator it = m_peerMap.find(interval);
|
||||
if(it != m_peerMap.end()) {
|
||||
|
|
|
@ -424,8 +424,7 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
|||
{
|
||||
string oldname = from->getRootPath();
|
||||
string newname, suffix;
|
||||
int counter = 0;
|
||||
while (true) {
|
||||
for (int counter = 0; true; counter++) {
|
||||
ostringstream newsuffix;
|
||||
newsuffix << ".old";
|
||||
if (counter) {
|
||||
|
@ -433,6 +432,16 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
|||
}
|
||||
suffix = newsuffix.str();
|
||||
newname = oldname + suffix;
|
||||
if (from->hasPeerProperties()) {
|
||||
boost::shared_ptr<SyncConfig> renamed(new SyncConfig(from->getPeerName() + suffix));
|
||||
if (renamed->exists()) {
|
||||
// don't pick a config name which has the same peer name
|
||||
// as some other, existing config
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// now renaming should succeed, but let's check anyway
|
||||
if (!rename(oldname.c_str(),
|
||||
newname.c_str())) {
|
||||
break;
|
||||
|
@ -442,7 +451,6 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
|
|||
newname.c_str(),
|
||||
strerror(errno)));
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
string newConfigName;
|
||||
|
@ -518,12 +526,28 @@ void Cmdline::finishCopy(const boost::shared_ptr<SyncConfig> &from,
|
|||
// config to hide that old config from normal UI users. Must
|
||||
// do this without going through SyncConfig, because that
|
||||
// would bump the version.
|
||||
FileConfigNode node(from->getRootPath(), "config.ini", false);
|
||||
BoolConfigProperty ready("ConsumerReady", "", "0");
|
||||
if (ready.getPropertyValue(node)) {
|
||||
ready.setProperty(node, false);
|
||||
// Also disable auto-syncing in the migrated config.
|
||||
StringConfigProperty autosync("autoSync", "", "");
|
||||
{
|
||||
FileConfigNode node(from->getRootPath(), "config.ini", false);
|
||||
if (ready.getPropertyValue(node)) {
|
||||
ready.setProperty(node, false);
|
||||
}
|
||||
if (!autosync.getProperty(node).empty()) {
|
||||
autosync.setProperty(node, "0");
|
||||
}
|
||||
node.flush();
|
||||
}
|
||||
|
||||
// same for very old configs
|
||||
{
|
||||
FileConfigNode node(from->getRootPath() + "/spds/syncml", "config.txt", false);
|
||||
if (!autosync.getProperty(node).empty()) {
|
||||
autosync.setProperty(node, "0");
|
||||
}
|
||||
node.flush();
|
||||
}
|
||||
node.flush();
|
||||
|
||||
// Set ConsumerReady for migrated SyncEvolution < 1.2
|
||||
// configs, because in older releases all existing
|
||||
|
@ -1141,6 +1165,22 @@ bool Cmdline::run() {
|
|||
sysync::TSyError err;
|
||||
#define CHECK_ERROR(_op) if (err) { SE_THROW_EXCEPTION_STATUS(StatusException, string(source->getName()) + ": " + (_op), SyncMLStatus(err)); }
|
||||
|
||||
// acquire passwords before doing anything (interactive password
|
||||
// access not supported for the command line)
|
||||
{
|
||||
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*context, m_server, *context->getProperties());
|
||||
}
|
||||
}
|
||||
{
|
||||
ConfigPropertyRegistry ®istry = SyncSourceConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*context, m_server, *context->getProperties(),
|
||||
source->getName(), sourceNodes.getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
source->open();
|
||||
const SyncSource::Operations &ops = source->getOperations();
|
||||
if (m_printItems) {
|
||||
|
@ -1150,11 +1190,6 @@ bool Cmdline::run() {
|
|||
source->throwError("reading items not supported");
|
||||
}
|
||||
|
||||
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*context, m_server, *context->getProperties());
|
||||
}
|
||||
|
||||
err = ops.m_startDataRead("", "");
|
||||
CHECK_ERROR("reading items");
|
||||
list<string> luids;
|
||||
|
@ -2242,6 +2277,7 @@ class CmdlineTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testListSources);
|
||||
CPPUNIT_TEST(testMigrate);
|
||||
CPPUNIT_TEST(testMigrateContext);
|
||||
CPPUNIT_TEST(testMigrateAutoSync);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
|
@ -3897,8 +3933,9 @@ protected:
|
|||
boost::replace_all(expected, "# forceSyncFormat = 0", "forceSyncFormat = 0");
|
||||
boost::replace_first(expected, "# databaseFormat = ", "databaseFormat = text/vcard");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
string renamedConfig = scanFiles(newRoot, "scheduleworld.old");
|
||||
boost::replace_all(createdConfig, "/scheduleworld/", "/scheduleworld.old/");
|
||||
string renamedConfig = scanFiles(newRoot, "scheduleworld.old.1");
|
||||
boost::replace_first(createdConfig, "ConsumerReady = 1", "ConsumerReady = 0");
|
||||
boost::replace_all(createdConfig, "/scheduleworld/", "/scheduleworld.old.1/");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(createdConfig, renamedConfig);
|
||||
}
|
||||
|
||||
|
@ -3939,6 +3976,7 @@ protected:
|
|||
"peers/scheduleworld/config.ini");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
string renamedConfig = scanFiles(oldRoot + ".old.1");
|
||||
boost::replace_first(createdConfig, "ConsumerReady = 1", "ConsumerReady = 0");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(createdConfig, renamedConfig);
|
||||
}
|
||||
|
||||
|
@ -3996,8 +4034,8 @@ protected:
|
|||
boost::replace_all(expected, "# forceSyncFormat = 0", "forceSyncFormat = 0");
|
||||
boost::replace_first(expected, "# databaseFormat = ", "databaseFormat = text/vcard");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old/");
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old.3");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old.3/");
|
||||
boost::replace_all(expected, "ConsumerReady = 1", "ConsumerReady = 0");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, renamedConfig);
|
||||
|
||||
|
@ -4012,11 +4050,11 @@ protected:
|
|||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
}
|
||||
migratedConfig = scanFiles(otherRoot, "scheduleworld");
|
||||
boost::replace_all(expected, "/scheduleworld.old/", "/scheduleworld/");
|
||||
boost::replace_all(expected, "/scheduleworld.old.3/", "/scheduleworld/");
|
||||
boost::replace_all(expected, "ConsumerReady = 0", "ConsumerReady = 1");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old.1");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old.1/");
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old.4");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old.4/");
|
||||
boost::replace_all(expected, "ConsumerReady = 1", "ConsumerReady = 0");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, renamedConfig);
|
||||
|
||||
|
@ -4042,10 +4080,10 @@ protected:
|
|||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
}
|
||||
migratedConfig = scanFiles(otherRoot, "scheduleworld");
|
||||
boost::replace_all(expected, "/scheduleworld.old.1/", "/scheduleworld/");
|
||||
boost::replace_all(expected, "/scheduleworld.old.4/", "/scheduleworld/");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old.2");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old.2/");
|
||||
renamedConfig = scanFiles(otherRoot, "scheduleworld.old.5");
|
||||
boost::replace_all(expected, "/scheduleworld/", "/scheduleworld.old.5/");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, renamedConfig);
|
||||
}
|
||||
}
|
||||
|
@ -4126,6 +4164,82 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void testMigrateAutoSync() {
|
||||
ScopedEnvChange templates("SYNCEVOLUTION_TEMPLATE_DIR", "templates");
|
||||
ScopedEnvChange xdg("XDG_CONFIG_HOME", m_testDir);
|
||||
ScopedEnvChange home("HOME", m_testDir);
|
||||
|
||||
string oldRoot = m_testDir + "/.sync4j/evolution/scheduleworld";
|
||||
string newRoot = m_testDir + "/syncevolution/default";
|
||||
|
||||
string oldConfig = "spds/syncml/config.txt:autoSync = 1\n";
|
||||
oldConfig += OldScheduleWorldConfig();
|
||||
|
||||
{
|
||||
// migrate old config
|
||||
createFiles(oldRoot, oldConfig);
|
||||
string createdConfig = scanFiles(oldRoot);
|
||||
TestCmdline cmdline("--migrate",
|
||||
"scheduleworld",
|
||||
NULL);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
|
||||
string migratedConfig = scanFiles(newRoot);
|
||||
string expected = ScheduleWorldConfig();
|
||||
boost::replace_first(expected, "# autoSync = 0", "autoSync = 1");
|
||||
sortConfig(expected);
|
||||
// migrating SyncEvolution < 1.2 configs sets
|
||||
// ConsumerReady, to keep config visible in the updated
|
||||
// sync-ui
|
||||
boost::replace_all(expected, "# ConsumerReady = 0", "ConsumerReady = 1");
|
||||
boost::replace_first(expected, "# database = ", "database = xyz");
|
||||
boost::replace_first(expected, "# databaseUser = ", "databaseUser = foo");
|
||||
boost::replace_first(expected, "# databasePassword = ", "databasePassword = bar");
|
||||
// migrating "type" sets forceSyncFormat (always)
|
||||
// and databaseFormat (if format was part of type, as for addressbook)
|
||||
boost::replace_all(expected, "# forceSyncFormat = 0", "forceSyncFormat = 0");
|
||||
boost::replace_first(expected, "# databaseFormat = ", "databaseFormat = text/vcard");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
string renamedConfig = scanFiles(oldRoot + ".old");
|
||||
// autoSync must have been unset
|
||||
boost::replace_first(createdConfig, ":autoSync = 1", ":autoSync = 0");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(createdConfig, renamedConfig);
|
||||
}
|
||||
|
||||
{
|
||||
// rewrite existing config with autoSync set
|
||||
string createdConfig = scanFiles(newRoot, "scheduleworld");
|
||||
|
||||
TestCmdline cmdline("--migrate",
|
||||
"scheduleworld",
|
||||
NULL);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_out.str());
|
||||
|
||||
string migratedConfig = scanFiles(newRoot, "scheduleworld");
|
||||
string expected = ScheduleWorldConfig();
|
||||
boost::replace_first(expected, "# autoSync = 0", "autoSync = 1");
|
||||
sortConfig(expected);
|
||||
boost::replace_all(expected, "# ConsumerReady = 0", "ConsumerReady = 1");
|
||||
boost::replace_first(expected, "# database = ", "database = xyz");
|
||||
boost::replace_first(expected, "# databaseUser = ", "databaseUser = foo");
|
||||
boost::replace_first(expected, "# databasePassword = ", "databasePassword = bar");
|
||||
boost::replace_all(expected, "# forceSyncFormat = 0", "forceSyncFormat = 0");
|
||||
boost::replace_first(expected, "# databaseFormat = ", "databaseFormat = text/vcard");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(expected, migratedConfig);
|
||||
string renamedConfig = scanFiles(newRoot, "scheduleworld.old.1");
|
||||
// autoSync must have been unset
|
||||
boost::replace_first(createdConfig, ":autoSync = 1", ":autoSync = 0");
|
||||
// the scheduleworld config was consumer ready, the migrated one isn't
|
||||
boost::replace_all(createdConfig, "ConsumerReady = 1", "ConsumerReady = 0");
|
||||
boost::replace_all(createdConfig, "/scheduleworld/", "/scheduleworld.old.1/");
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(createdConfig, renamedConfig);
|
||||
}
|
||||
}
|
||||
|
||||
const string m_testDir;
|
||||
|
||||
private:
|
||||
|
@ -4518,7 +4632,7 @@ private:
|
|||
size_t fileoff = fullpath.rfind('/');
|
||||
mkdir_p(fullpath.substr(0, fileoff));
|
||||
out.open(fullpath.c_str(),
|
||||
append ? ios_base::out : (ios_base::out|ios_base::trunc));
|
||||
append ? (ios_base::out|ios_base::ate|ios_base::app) : (ios_base::out|ios_base::trunc));
|
||||
outname = newname;
|
||||
}
|
||||
out << line << endl;
|
||||
|
|
|
@ -107,21 +107,6 @@ public:
|
|||
/** the run() call modified configurations (added, updated, removed) */
|
||||
bool configWasModified() const { return m_configModified; }
|
||||
|
||||
/**
|
||||
* Acts like a boolean, but in addition, can also tell whether the
|
||||
* value was explicitly set.
|
||||
*/
|
||||
class Bool {
|
||||
public:
|
||||
Bool(bool val = false) : m_value(val), m_wasSet(false) {}
|
||||
operator bool () const { return m_value; }
|
||||
Bool & operator = (bool val) { m_value = val; m_wasSet = true; return *this; }
|
||||
bool wasSet() const { return m_wasSet; }
|
||||
private:
|
||||
bool m_value;
|
||||
bool m_wasSet;
|
||||
};
|
||||
|
||||
Bool useDaemon() { return m_useDaemon; }
|
||||
|
||||
/** whether '--monitor' is set */
|
||||
|
|
|
@ -288,12 +288,15 @@ SyncSourceRaw::InsertItemResult MapSyncSource::insertItem(const std::string &lui
|
|||
{
|
||||
StringPair ids = splitLUID(luid);
|
||||
SubSyncSource::SubItemResult res = m_sub->insertSubItem(ids.first, ids.second, item);
|
||||
SubRevisionEntry &entry = m_revisions[res.m_mainid];
|
||||
entry.m_uid = res.m_uid;
|
||||
entry.m_revision = res.m_revision;
|
||||
entry.m_subids.insert(res.m_subid);
|
||||
// anything changed?
|
||||
if (res.m_state != ITEM_NEEDS_MERGE) {
|
||||
SubRevisionEntry &entry = m_revisions[res.m_mainid];
|
||||
entry.m_uid = res.m_uid;
|
||||
entry.m_revision = res.m_revision;
|
||||
entry.m_subids.insert(res.m_subid);
|
||||
}
|
||||
return SyncSourceRaw::InsertItemResult(createLUID(res.m_mainid, res.m_subid),
|
||||
res.m_revision, res.m_merged);
|
||||
res.m_revision, res.m_state);
|
||||
}
|
||||
|
||||
void MapSyncSource::readItem(const std::string &luid, std::string &item)
|
||||
|
|
|
@ -67,7 +67,7 @@ class SubSyncSource : virtual public SyncSourceBase
|
|||
class SubItemResult {
|
||||
public:
|
||||
SubItemResult() :
|
||||
m_merged(false)
|
||||
m_state(ITEM_OKAY)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -79,25 +79,25 @@ class SubSyncSource : virtual public SyncSourceBase
|
|||
* @param uid an arbitrary string, stored, but not used by MapSyncSource;
|
||||
* used in the CalDAV backend to associate mainid (= resource path)
|
||||
* with UID (= part of the item content, but with special semantic)
|
||||
* @param merged set this to true if an existing sub item was updated instead of adding it
|
||||
* @param state report about what was done with the data
|
||||
*/
|
||||
SubItemResult(const string &mainid,
|
||||
const string &subid,
|
||||
const string &revision,
|
||||
const string &uid,
|
||||
bool merged) :
|
||||
InsertItemResultState state) :
|
||||
m_mainid(mainid),
|
||||
m_subid(subid),
|
||||
m_revision(revision),
|
||||
m_uid(uid),
|
||||
m_merged(merged)
|
||||
m_state(state)
|
||||
{}
|
||||
|
||||
string m_mainid;
|
||||
string m_subid;
|
||||
string m_revision;
|
||||
string m_uid;
|
||||
bool m_merged;
|
||||
InsertItemResultState m_state;
|
||||
};
|
||||
|
||||
SubSyncSource() : m_parent(NULL) {}
|
||||
|
@ -180,6 +180,12 @@ class SubSyncSource : virtual public SyncSourceBase
|
|||
*/
|
||||
virtual std::string getSubDescription(const string &mainid, const string &subid) = 0;
|
||||
|
||||
/**
|
||||
* Called after MapSyncSource already populated the info structure.
|
||||
*/
|
||||
virtual void updateSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments) {}
|
||||
|
||||
private:
|
||||
MapSyncSource *m_parent;
|
||||
};
|
||||
|
@ -266,6 +272,13 @@ class MapSyncSource :
|
|||
virtual std::string getDescription(sysync::KeyH aItemKey) { return dynamic_cast<SyncSourceLogging &>(*m_sub).getDescription(aItemKey); }
|
||||
virtual std::string getDescription(const string &luid);
|
||||
|
||||
protected:
|
||||
virtual void getSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments) {
|
||||
TestingSyncSource::getSynthesisInfo(info, fragments);
|
||||
m_sub->updateSynthesisInfo(info, fragments);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<SubSyncSource> m_sub;
|
||||
/** escape / in uid with %2F, so that splitMainIDValue() and splitLUID() can use / as separator */
|
||||
|
|
|
@ -74,6 +74,8 @@ class Unref {
|
|||
#endif // HAVE_GLIB
|
||||
#ifdef ENABLE_ICAL
|
||||
static void unref(icalcomponent *pointer) { icalcomponent_free(pointer); }
|
||||
static void unref(icalproperty *pointer) { icalproperty_free(pointer); }
|
||||
static void unref(icalparameter *pointer) { icalparameter_free(pointer); }
|
||||
static void unref(icaltimezone *pointer) { icaltimezone_free(pointer, 1); }
|
||||
#endif // ENABLE_ICAL
|
||||
};
|
||||
|
|
|
@ -2558,7 +2558,11 @@ ConfigPasswordKey DatabasePasswordConfigProperty::getPasswordKey(const string &d
|
|||
{
|
||||
ConfigPasswordKey key;
|
||||
key.user = sourcePropUser.getProperty(*sourceConfigNode);
|
||||
key.object = serverName;
|
||||
std::string configName = SyncConfig::normalizeConfigString(serverName, SyncConfig::NORMALIZE_LONG_FORMAT);
|
||||
std::string peer, context;
|
||||
SyncConfig::splitConfigString(configName, peer, context);
|
||||
key.object = "@";
|
||||
key.object += context;
|
||||
key.object += " ";
|
||||
key.object += sourceName;
|
||||
key.object += " backend";
|
||||
|
|
|
@ -1915,16 +1915,16 @@ void SyncContext::startLoopThread()
|
|||
#endif
|
||||
}
|
||||
|
||||
SyncSource *SyncContext::findSource(const char *name)
|
||||
SyncSource *SyncContext::findSource(const std::string &name)
|
||||
{
|
||||
if (!m_activeContext || !m_activeContext->m_sourceListPtr) {
|
||||
return NULL;
|
||||
}
|
||||
const char *realname = strrchr(name, m_findSourceSeparator);
|
||||
const char *realname = strrchr(name.c_str(), m_findSourceSeparator);
|
||||
if (realname) {
|
||||
realname++;
|
||||
} else {
|
||||
realname = name;
|
||||
realname = name.c_str();
|
||||
}
|
||||
return (*m_activeContext->m_sourceListPtr)[realname];
|
||||
}
|
||||
|
@ -1950,11 +1950,11 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
BOOST_FOREACH(const string &name, configuredSources) {
|
||||
boost::shared_ptr<PersistentSyncSourceConfig> sc(getSyncSourceConfig(name));
|
||||
SyncSourceNodes source = getSyncSourceNodes (name);
|
||||
SourceType sourceType = SyncSource::getSourceType(source);
|
||||
// is the source enabled?
|
||||
string sync = sc->getSync();
|
||||
bool enabled = sync != "disabled";
|
||||
if (enabled) {
|
||||
SourceType sourceType = SyncSource::getSourceType(source);
|
||||
if (sourceType.m_backend == "virtual") {
|
||||
//This is a virtual sync source, check and enable the referenced
|
||||
//sub syncsources here
|
||||
|
@ -1995,12 +1995,12 @@ void SyncContext::initSources(SourceList &sourceList)
|
|||
boost::shared_ptr<PersistentSyncSourceConfig> sc(getSyncSourceConfig(name));
|
||||
|
||||
SyncSourceNodes source = getSyncSourceNodes (name);
|
||||
SourceType sourceType = SyncSource::getSourceType(source);
|
||||
|
||||
// is the source enabled?
|
||||
string sync = sc->getSync();
|
||||
bool enabled = sync != "disabled";
|
||||
if (enabled) {
|
||||
SourceType sourceType = SyncSource::getSourceType(source);
|
||||
if (sourceType.m_backend != "virtual") {
|
||||
SyncSourceParams params(name,
|
||||
source,
|
||||
|
@ -3269,7 +3269,7 @@ SyncMLStatus SyncContext::doSync()
|
|||
target;
|
||||
target = m_engine.OpenSubkey(targets, sysync::KEYVAL_ID_NEXT, true)) {
|
||||
s = m_engine.GetStrValue(target, "dbname");
|
||||
SyncSource *source = findSource(s.c_str());
|
||||
SyncSource *source = findSource(s);
|
||||
if (source) {
|
||||
m_engine.SetInt32Value(target, "enabled", 1);
|
||||
int slow = 0;
|
||||
|
|
|
@ -452,7 +452,7 @@ class SyncContext : public SyncConfig, public ConfigUserInterface {
|
|||
* @TODO: roll SourceList into SyncContext and
|
||||
* make this non-static
|
||||
*/
|
||||
static SyncSource *findSource(const char *name);
|
||||
static SyncSource *findSource(const std::string &name);
|
||||
static const char m_findSourceSeparator = '@';
|
||||
|
||||
/**
|
||||
|
|
|
@ -541,6 +541,9 @@ void SyncSourceSerialize::getSynthesisInfo(SynthesisInfo &info,
|
|||
{
|
||||
string type = getMimeType();
|
||||
|
||||
// default remote rule (local-storage.xml): suppresses empty properties
|
||||
info.m_backendRule = "LOCALSTORAGE";
|
||||
|
||||
if (type == "text/x-vcard") {
|
||||
info.m_native = "vCard21";
|
||||
info.m_fieldlist = "contacts";
|
||||
|
@ -555,6 +558,14 @@ void SyncSourceSerialize::getSynthesisInfo(SynthesisInfo &info,
|
|||
info.m_datatypes =
|
||||
" <use datatype='vCard21' mode='rw'/>\n"
|
||||
" <use datatype='vCard30' mode='rw' preferred='yes'/>\n";
|
||||
// If a backend overwrites the m_beforeWriteScript, then it must
|
||||
// include $VCARD_OUTGOING_PHOTO_VALUE_SCRIPT in its own script,
|
||||
// otherwise it will be sent invalid, empty PHOTO;TYPE=unknown;VALUE=binary:
|
||||
// properties.
|
||||
info.m_beforeWriteScript = "$VCARD_OUTGOING_PHOTO_VALUE_SCRIPT;\n";
|
||||
// Likewise for reading. This is needed to ensure proper merging
|
||||
// of contact data.
|
||||
info.m_afterReadScript = "$VCARD_INCOMING_PHOTO_VALUE_SCRIPT;\n";
|
||||
} else if (type == "text/x-calendar" || type == "text/x-vcalendar") {
|
||||
info.m_native = "vCalendar10";
|
||||
info.m_fieldlist = "calendar";
|
||||
|
@ -657,6 +668,19 @@ sysync::TSyError SyncSourceSerialize::insertItemAsKey(sysync::KeyH aItemKey, sys
|
|||
InsertItemResult inserted =
|
||||
insertItem(!aID ? "" : aID->item, data.get());
|
||||
newID->item = StrAlloc(inserted.m_luid.c_str());
|
||||
switch (inserted.m_state) {
|
||||
case ITEM_OKAY:
|
||||
break;
|
||||
case ITEM_REPLACED:
|
||||
res = sysync::DB_DataReplaced;
|
||||
break;
|
||||
case ITEM_MERGED:
|
||||
res = sysync::DB_DataMerged;
|
||||
break;
|
||||
case ITEM_NEEDS_MERGE:
|
||||
res = sysync::DB_Conflict;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -162,23 +162,23 @@ class TestingSyncSource;
|
|||
* is okay, but it will disable all tests that need the
|
||||
* information.
|
||||
*/
|
||||
struct ClientTestConfig{
|
||||
struct ClientTestConfig {
|
||||
/**
|
||||
* The name is used in test names and has to be set.
|
||||
*/
|
||||
const char *sourceName;
|
||||
std::string m_sourceName;
|
||||
|
||||
/**
|
||||
* A default URI to be used when creating a client config.
|
||||
*/
|
||||
const char *uri;
|
||||
std::string m_uri;
|
||||
|
||||
/**
|
||||
* A corresponding source name in the default server template,
|
||||
* this is used to copy corresponding uri set in the server template
|
||||
* instead of the uri field above (which is the same for all servers).
|
||||
*/
|
||||
const char *sourceNameServerTemplate;
|
||||
std::string m_sourceNameServerTemplate;
|
||||
|
||||
/**
|
||||
* A member function of a subclass which is called to create a
|
||||
|
@ -210,7 +210,7 @@ struct ClientTestConfig{
|
|||
* it may report the same changes as the sync source used during
|
||||
* sync tests.
|
||||
*/
|
||||
createsource_t createSourceA;
|
||||
createsource_t m_createSourceA;
|
||||
|
||||
/**
|
||||
* A second sync source also referencing the primary data
|
||||
|
@ -228,7 +228,7 @@ struct ClientTestConfig{
|
|||
* - check that the total number and number of
|
||||
* added/updated/deleted items is as expected
|
||||
*/
|
||||
createsource_t createSourceB;
|
||||
createsource_t m_createSourceB;
|
||||
|
||||
/**
|
||||
* The framework can generate vCard and vCalendar/iCalendar items
|
||||
|
@ -239,24 +239,19 @@ struct ClientTestConfig{
|
|||
* It must contain the string <<REVISION>> which will be replaced
|
||||
* with the revision parameter of the createItem() method.
|
||||
*/
|
||||
const char *templateItem;
|
||||
std::string m_templateItem;
|
||||
|
||||
/**
|
||||
* This is a colon (:) separated list of properties which need
|
||||
* to be modified in templateItem.
|
||||
*/
|
||||
const char *uniqueProperties;
|
||||
|
||||
/**
|
||||
* the number of items to create during stress tests
|
||||
*/
|
||||
int numItems;
|
||||
std::string m_uniqueProperties;
|
||||
|
||||
/**
|
||||
* This is a single property in templateItem which can be extended
|
||||
* to increase the size of generated items.
|
||||
*/
|
||||
const char *sizeProperty;
|
||||
std::string m_sizeProperty;
|
||||
|
||||
/**
|
||||
* Type to be set when importing any of the items into the
|
||||
|
@ -266,7 +261,7 @@ struct ClientTestConfig{
|
|||
* Not currently used! All items are assumed to be in the raw,
|
||||
* internal format (see SyncSourceRaw and SyncSourceSerialize).
|
||||
*/
|
||||
const char *itemType;
|
||||
std::string m_itemType;
|
||||
|
||||
/**
|
||||
* callback which is invoked with a specific item as paramter
|
||||
|
@ -276,33 +271,33 @@ struct ClientTestConfig{
|
|||
* @param update modify item content so that it can be
|
||||
* used as an update of the old data
|
||||
*/
|
||||
string (*mangleItem)(const char *data, bool update);
|
||||
boost::function<std::string (const std::string &, bool)> m_mangleItem;
|
||||
|
||||
/**
|
||||
* A very simple item that is inserted during basic tests. Ideally
|
||||
* it only contains properties supported by all servers.
|
||||
*/
|
||||
const char *insertItem;
|
||||
std::string m_insertItem;
|
||||
|
||||
/**
|
||||
* A slightly modified version of insertItem. If the source has UIDs
|
||||
* embedded into the item data, then both must have the same UID.
|
||||
* Again all servers should better support these modified properties.
|
||||
*/
|
||||
const char *updateItem;
|
||||
std::string m_updateItem;
|
||||
|
||||
/**
|
||||
* A more heavily modified version of insertItem. Same UID if necessary,
|
||||
* but can test changes to items only supported by more advanced
|
||||
* servers.
|
||||
*/
|
||||
const char *complexUpdateItem;
|
||||
std::string m_complexUpdateItem;
|
||||
|
||||
/**
|
||||
* To test merge conflicts two different updates of insertItem are
|
||||
* needed. This is the first such update.
|
||||
*/
|
||||
const char *mergeItem1;
|
||||
std::string m_mergeItem1;
|
||||
|
||||
/**
|
||||
* The second merge update item. To avoid true conflicts it should
|
||||
|
@ -310,13 +305,14 @@ struct ClientTestConfig{
|
|||
* usually have problems perfectly merging items. Therefore the
|
||||
* test is run without expecting a certain merge result.
|
||||
*/
|
||||
const char *mergeItem2;
|
||||
std::string m_mergeItem2;
|
||||
|
||||
/**
|
||||
* These two items are related: one is main one, the other is
|
||||
* a subordinate one. The semantic is that the main item is
|
||||
* complete on it its own, while the other normally should only
|
||||
* be used in combination with the main one.
|
||||
* The items in the inner vector are related: the first one the is
|
||||
* main one, the other(s) is/are a subordinate ones. The semantic
|
||||
* is that the main item is complete on it its own, while the
|
||||
* other normally should only be used in combination with the main
|
||||
* one.
|
||||
*
|
||||
* Because SyncML cannot express such dependencies between items,
|
||||
* a SyncSource has to be able to insert, updated and remove
|
||||
|
@ -328,26 +324,49 @@ struct ClientTestConfig{
|
|||
* One example for main and subordinate items are a recurring
|
||||
* iCalendar 2.0 event and a detached recurrence.
|
||||
*/
|
||||
const char *parentItem, *childItem;
|
||||
typedef std::vector<std::string> LinkedItems_t;
|
||||
|
||||
/**
|
||||
* The linked items may exist in different variations (outer vector).
|
||||
*/
|
||||
typedef std::vector<LinkedItems_t> MultipleLinkedItems_t;
|
||||
|
||||
MultipleLinkedItems_t m_linkedItems;
|
||||
|
||||
/**
|
||||
* Backends atomic modification tests
|
||||
*/
|
||||
bool atomicModification;
|
||||
Bool m_atomicModification;
|
||||
|
||||
/**
|
||||
* set to false to disable tests which slightly violate the
|
||||
* semantic of linked items by inserting children
|
||||
* before/without their parent
|
||||
*/
|
||||
bool linkedItemsRelaxedSemantic;
|
||||
Bool m_linkedItemsRelaxedSemantic;
|
||||
|
||||
/**
|
||||
* setting this to false disables tests which depend
|
||||
* on the source's support for linked item semantic
|
||||
* (testLinkedItemsInsertParentTwice, testLinkedItemsInsertChildTwice)
|
||||
*/
|
||||
bool sourceKnowsItemSemantic;
|
||||
Bool m_sourceKnowsItemSemantic;
|
||||
|
||||
/**
|
||||
* Set this to true if the backend does not have IDs which are the
|
||||
* same for all clients and across slow syncs. For example, when
|
||||
* testing the ActiveSync backend this field needs to be true,
|
||||
* because items are renumbered as 1:x with x = 1, 2, ... for each
|
||||
* clients when a sync anchor is assigned to it.
|
||||
*/
|
||||
Bool m_sourceLUIDsAreVolatile;
|
||||
|
||||
/**
|
||||
* Set this to true if the backend supports
|
||||
* X-SYNCEVOLUTION-EXDATE-DETACHED, see CalDAVSource.cpp
|
||||
* CalDAVSource::readSubItem().
|
||||
*/
|
||||
Bool m_supportsReccurenceEXDates;
|
||||
|
||||
/**
|
||||
* called to dump all items into a file, required by tests which need
|
||||
|
@ -360,7 +379,7 @@ struct ClientTestConfig{
|
|||
* @param file a file name
|
||||
* @return error code, 0 for success
|
||||
*/
|
||||
int (*dump)(ClientTest &client, TestingSyncSource &source, const char *file);
|
||||
boost::function<int (ClientTest &, TestingSyncSource &, const std::string &)> m_dump;
|
||||
|
||||
/**
|
||||
* import test items: which these are is determined entirely by
|
||||
|
@ -376,8 +395,8 @@ struct ClientTestConfig{
|
|||
* this may depend on the current server that is being tested
|
||||
* @return error string, empty for success
|
||||
*/
|
||||
std::string (*import)(ClientTest &client, TestingSyncSource &source, const ClientTestConfig &config,
|
||||
const char *file, std::string &realfile);
|
||||
boost::function<std::string (ClientTest &, TestingSyncSource &, const ClientTestConfig &,
|
||||
const std::string &, std::string &)> m_import;
|
||||
|
||||
/**
|
||||
* a function which compares two files with items in the format used by "dump"
|
||||
|
@ -386,7 +405,7 @@ struct ClientTestConfig{
|
|||
* @param fileB second file name
|
||||
* @return true if the content of the files is considered equal
|
||||
*/
|
||||
bool (*compare)(ClientTest &client, const char *fileA, const char *fileB);
|
||||
boost::function<bool (ClientTest &, const std::string &, const std::string &)> m_compare;
|
||||
|
||||
/**
|
||||
* A file with test cases in the format expected by import and compare.
|
||||
|
@ -405,27 +424,27 @@ struct ClientTestConfig{
|
|||
* That file then will be used in testItems instead of the base
|
||||
* version. See the src/Makefile.am for rules that maintain such files.
|
||||
*/
|
||||
const char *testcases;
|
||||
std::string m_testcases;
|
||||
|
||||
/**
|
||||
* the item type normally used by the source (not used by the tests
|
||||
* themselves; client-test.cpp uses it to initialize source configs)
|
||||
*/
|
||||
const char *type;
|
||||
std::string m_type;
|
||||
|
||||
/**
|
||||
* a list of sub configs separated via , if this is a super datastore
|
||||
*/
|
||||
const char *subConfigs;
|
||||
std::string m_subConfigs;
|
||||
|
||||
/**
|
||||
* TRUE if the source supports recovery from an interrupted
|
||||
* synchronization. Enables the Client::Sync::*::Retry group
|
||||
* of tests.
|
||||
*/
|
||||
bool retrySync;
|
||||
bool suspendSync;
|
||||
bool resendSync;
|
||||
Bool m_retrySync;
|
||||
Bool m_suspendSync;
|
||||
Bool m_resendSync;
|
||||
|
||||
/**
|
||||
* Set this to test if the source supports preserving local data extensions.
|
||||
|
@ -438,8 +457,8 @@ struct ClientTestConfig{
|
|||
* genericUpdate works for vCard and iCalendar by updating FN, N, resp. SUMMARY
|
||||
* and can be used as implementation of update.
|
||||
*/
|
||||
void (*update)(std::string &item);
|
||||
void (*genericUpdate)(std::string &item);
|
||||
boost::function<void (std::string &)> m_update;
|
||||
boost::function<void (std::string &)> m_genericUpdate;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1408,6 +1427,53 @@ class SyncSourceDelete : virtual public SyncSourceBase {
|
|||
sysync::TSyError deleteItemSynthesis(sysync::cItemID aID);
|
||||
};
|
||||
|
||||
enum InsertItemResultState {
|
||||
/**
|
||||
* item added or updated as requested
|
||||
*/
|
||||
ITEM_OKAY,
|
||||
|
||||
/**
|
||||
* When a backend is asked to add an item and recognizes
|
||||
* that the item matches an already existing item, it may
|
||||
* replace that item instead of creating a duplicate. In this
|
||||
* case it must return ITEM_REPLACED and set the luid/revision
|
||||
* of that updated item.
|
||||
*
|
||||
* This can happen when such an item was added concurrently to
|
||||
* the running sync or, more likely, was reported as new by
|
||||
* the backend and the engine failed to find the match because
|
||||
* it doesn't know about some special semantic, like iCalendar
|
||||
* 2.0 UID).
|
||||
*
|
||||
* Note that depending on the age of the items, the older data
|
||||
* will replace the more recent one when always using item
|
||||
* replacement.
|
||||
*/
|
||||
ITEM_REPLACED,
|
||||
|
||||
/**
|
||||
* Same as ITEM_REPLACED, except that the backend did some
|
||||
* modifications to the data that was sent to it before
|
||||
* storing it, like merging it with the existing item. The
|
||||
* engine will treat the updated item as modified and send
|
||||
* back the update to the peer as soon as possible. In server
|
||||
* mode that will be in the same sync session, in a client in
|
||||
* the next session (client cannot send changes after having
|
||||
* received data from the server).
|
||||
*/
|
||||
ITEM_MERGED,
|
||||
|
||||
/**
|
||||
* As before, a match against an existing item was detected.
|
||||
* By returning this state and the luid of the matched item
|
||||
* (revision not needed) the engine is instructed to do the
|
||||
* necessary data comparison and merging itself. Useful when a
|
||||
* backend can't do the necessary merging itself.
|
||||
*/
|
||||
ITEM_NEEDS_MERGE
|
||||
};
|
||||
|
||||
/**
|
||||
* an interface for reading and writing items in the internal
|
||||
* format; see SyncSourceSerialize for an explanation
|
||||
|
@ -1417,26 +1483,26 @@ class SyncSourceRaw : virtual public SyncSourceBase {
|
|||
class InsertItemResult {
|
||||
public:
|
||||
InsertItemResult() :
|
||||
m_merged(false)
|
||||
m_state(ITEM_OKAY)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @param luid the LUID after the operation; during an update the LUID must
|
||||
* not be changed, so return the original one here
|
||||
* @param revision the revision string after the operation; leave empty if not used
|
||||
* @param merged set this to true if an existing item was updated instead of adding it
|
||||
* @param state report about what was done with the data
|
||||
*/
|
||||
InsertItemResult(const string &luid,
|
||||
const string &revision,
|
||||
bool merged) :
|
||||
InsertItemResultState state) :
|
||||
m_luid(luid),
|
||||
m_revision(revision),
|
||||
m_merged(merged)
|
||||
m_state(state)
|
||||
{}
|
||||
|
||||
string m_luid;
|
||||
string m_revision;
|
||||
bool m_merged;
|
||||
InsertItemResultState m_state;
|
||||
};
|
||||
|
||||
/** same as SyncSourceSerialize::insertItem(), but with internal format */
|
||||
|
|
|
@ -140,14 +140,18 @@ std::string TrackingSyncSource::endSync(bool success)
|
|||
TrackingSyncSource::InsertItemResult TrackingSyncSource::insertItem(const std::string &luid, const std::string &item)
|
||||
{
|
||||
InsertItemResult res = insertItem(luid, item, false);
|
||||
updateRevision(*m_trackingNode, luid, res.m_luid, res.m_revision);
|
||||
if (res.m_state != ITEM_NEEDS_MERGE) {
|
||||
updateRevision(*m_trackingNode, luid, res.m_luid, res.m_revision);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TrackingSyncSource::InsertItemResult TrackingSyncSource::insertItemRaw(const std::string &luid, const std::string &item)
|
||||
{
|
||||
InsertItemResult res = insertItem(luid, item, true);
|
||||
updateRevision(*m_trackingNode, luid, res.m_luid, res.m_revision);
|
||||
if (res.m_state != ITEM_NEEDS_MERGE) {
|
||||
updateRevision(*m_trackingNode, luid, res.m_luid, res.m_revision);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,20 @@
|
|||
<!-- for events -->
|
||||
<field name="EXDATES" array="yes" type="timestamp" compare="never"/>
|
||||
|
||||
<!-- EXDATEs for detached recurrences: meant to be used for the
|
||||
RECURRENCE-IDs of all detached recurrences.
|
||||
|
||||
Can be ignored when dealing with only iCalendar 2.0 aware
|
||||
peers, because these EXDATEs are implied for detached
|
||||
recurrences and don't have to be specified explicitly. Can
|
||||
be used to create additional EXDATEs for non-iCalendar 2.0
|
||||
peers. For that, EXDATES_DETACHED must be populated by the
|
||||
backend creating the parent event, because the engine
|
||||
itself doesn't have the necessary
|
||||
information. X-SYNCEVOLUTION-EXDATE-DETACHED can be used
|
||||
for that in serialized calendar events. -->
|
||||
<field name="EXDATES_DETACHED" array="yes" type="timestamp" compare="never"/>
|
||||
|
||||
<field name="ORIGSTART" array="no" type="timestamp" compare="never"/>
|
||||
<field name="SEQNO" array="no" type="integer" compare="never"/>
|
||||
|
||||
|
|
|
@ -378,12 +378,21 @@
|
|||
with the EXDATE:value1,value2 format (correct in iCalendar 2.0):
|
||||
as a workaround, accept all valid formats plus ; but
|
||||
generate separate properties with one value each. -->
|
||||
<property name="EXDATE" values="expandedlist" suppressempty="yes" onlyformode="standard" delayedparsing="1" valueseparator="," altvalueseparator=";">
|
||||
<!-- The simplified version of EXDATE is needed by the Maemo Calendar backend
|
||||
because the calendar storage doesn't parse EXDATE;TZID=...: -->
|
||||
<property name="EXDATE" values="expandedlist" suppressempty="yes" onlyformode="standard" delayedparsing="1" valueseparator="," altvalueseparator=";" rule="SIMPLE-EXDATE">
|
||||
<value field="EXDATES"/>
|
||||
<position field="EXDATES" repeat="array" increment="1" minshow="0"/>
|
||||
</property>
|
||||
<property name="EXDATE" values="expandedlist" suppressempty="yes" onlyformode="standard" delayedparsing="1" valueseparator="," altvalueseparator=";" rule="other">
|
||||
<value field="EXDATES"/>
|
||||
<position field="EXDATES" repeat="array" increment="1" minshow="0"/>
|
||||
<parameter name="TZID" default="no" show="yes">
|
||||
<value field="EXDATES" conversion="TZID"/>
|
||||
</parameter>
|
||||
<parameter name="VALUE" default="no" show="yes">
|
||||
<value field="EXDATES" conversion="VALUETYPE"/>
|
||||
</parameter>
|
||||
</property>
|
||||
|
||||
<property name="EXDATE" values="list" suppressempty="yes" onlyformode="old" delayedparsing="1" valueseparator=";" altvalueseparator=",">
|
||||
|
@ -391,6 +400,28 @@
|
|||
<position field="EXDATES" repeat="array" increment="1" minshow="0"/>
|
||||
</property>
|
||||
|
||||
<!-- parse X-SYNCEVOLUTION-EXDATE-DETACHED, but never encode it like this except internally -->
|
||||
<property name="X-SYNCEVOLUTION-EXDATE-DETACHED" delayedparsing="1" mandatory="no"
|
||||
show="no" rule="HAVE-SYNCEVOLUTION-EXDATE-DETACHED">
|
||||
<value field="EXDATES_DETACHED"/>
|
||||
<parameter name="TZID" default="no" show="yes">
|
||||
<value field="EXDATES_DETACHED" conversion="TZID"/>
|
||||
</parameter>
|
||||
<position field="EXDATES_DETACHED" repeat="array" increment="1" minshow="0"/>
|
||||
</property>
|
||||
<!-- encode as normal EXDATE when backend asks for it -->
|
||||
<property name="EXDATE" show="no" rule="HAVE-EXDATE-DETACHED" mandatory="no">
|
||||
<value field="EXDATES_DETACHED"/>
|
||||
<parameter name="TZID" default="no" show="yes">
|
||||
<value field="EXDATES_DETACHED" conversion="TZID"/>
|
||||
</parameter>
|
||||
<position field="EXDATES_DETACHED" repeat="array" increment="1" minshow="0"/>
|
||||
</property>
|
||||
<!-- encode as EXDATE without TZID when backend asks for it -->
|
||||
<property name="EXDATE" show="no" rule="HAVE-EXDATE-DETACHED-NO-TZID" mandatory="no">
|
||||
<value field="EXDATES_DETACHED"/>
|
||||
<position field="EXDATES_DETACHED" repeat="array" increment="1" minshow="0"/>
|
||||
</property>
|
||||
|
||||
<property name="DTEND" suppressempty="yes" delayedparsing="1">
|
||||
<value field="DTEND" conversion="autoenddate"/>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<subrule name="HAVE-EXDATE-DETACHED"/>
|
||||
<subrule name="HAVE-EXDATE-DETACHED-NO-TZID"/>
|
|
@ -0,0 +1 @@
|
|||
<subrule name="HAVE-SYNCEVOLUTION-EXDATE-DETACHED"/>
|
1
src/syncevo/configs/remoterules/00_simple_exdate.xml
Normal file
1
src/syncevo/configs/remoterules/00_simple_exdate.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<subrule name="SIMPLE-EXDATE"></subrule>
|
|
@ -2,6 +2,8 @@
|
|||
<manufacturer>Patrick Ohly</manufacturer>
|
||||
<model>SyncEvolution</model>
|
||||
|
||||
<include rule="HAVE-SYNCEVOLUTION-EXDATE-DETACHED"/>
|
||||
|
||||
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
|
||||
<!-- Merging between SyncEvolution instances is expected to work
|
||||
well, so allow the engine to update items on both
|
||||
|
|
5
src/syncevo/configs/remoterules/10_maemo_calendar.xml
Normal file
5
src/syncevo/configs/remoterules/10_maemo_calendar.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<remoterule name="MAEMO-CALENDAR">
|
||||
<deviceid>none - this rule is activated via its name in MAKE/PARSETEXTWITHPROFILE() macro calls</deviceid>
|
||||
<include rule="HAVE-EXDATE-DETACHED-NO-TZID"/>
|
||||
<include rule="SIMPLE-EXDATE"/>
|
||||
</remoterule>
|
5
src/syncevo/configs/remoterules/local-storage.xml
Normal file
5
src/syncevo/configs/remoterules/local-storage.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<remoterule name="LOCALSTORAGE">
|
||||
<deviceid>none - this rule is activated by default via its name in MAKE/PARSETEXTWITHPROFILE() macro calls</deviceid>
|
||||
<!-- storing empty properties only wastes space and causes overhead, suppress them -->
|
||||
<noemptyproperties>yes</noemptyproperties>
|
||||
</remoterule>
|
|
@ -188,6 +188,26 @@
|
|||
}
|
||||
]]></macro>
|
||||
|
||||
<macro name="FIX_EXDATE_SCRIPT"><![CDATA[
|
||||
// Add time zone information to EXDATEs: necessary for
|
||||
// the Maemo calendar storages because it uses EXDATE
|
||||
// without TZID.
|
||||
if (!ISFLOATING(DTSTART)) {
|
||||
STRING tz;
|
||||
tz = TIMEZONE(DTSTART);
|
||||
if (tz != "UTC") {
|
||||
INTEGER i;
|
||||
i = 0;
|
||||
while (i<SIZE(EXDATES)) {
|
||||
if (ISFLOATING(EXDATES[i])) {
|
||||
SETTIMEZONE(EXDATES[i], tz);
|
||||
}
|
||||
i=i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></macro>
|
||||
|
||||
<!-- Uses the UID/RECURRENCE-ID fields as the only criteria for
|
||||
comparing calendar data if the VCALENDAR_COMPARE_UID session
|
||||
variable is true, else does a normal comparison of the
|
||||
|
|
|
@ -231,8 +231,10 @@ extern "C" void EDSAbiWrapperInit()
|
|||
# endif // ENABLE_EBOOK
|
||||
|
||||
# ifdef ENABLE_ECAL
|
||||
static const int libecalMinVersion = 3,
|
||||
libecalMaxVersion = 8;
|
||||
ecalhandle =
|
||||
findSymbols("libecal-1.2.so", 3, 8,
|
||||
findSymbols("libecal-1.2.so", libecalMinVersion, libecalMaxVersion,
|
||||
FIND_SYMBOLS_NEED_ALL|FIND_SYMBOLS_LENIENT_MAX_VERSION, NULL,
|
||||
&EDSAbiWrapperSingleton.e_cal_add_timezone, "e_cal_add_timezone",
|
||||
&EDSAbiWrapperSingleton.e_cal_component_get_icalcomponent, "e_cal_component_get_icalcomponent",
|
||||
|
@ -282,6 +284,7 @@ extern "C" void EDSAbiWrapperInit()
|
|||
&EDSAbiWrapperSingleton.icalparameter_get_tzid, "icalparameter_get_tzid",
|
||||
&EDSAbiWrapperSingleton.icalparameter_set_tzid, "icalparameter_set_tzid",
|
||||
&EDSAbiWrapperSingleton.icalparameter_new_from_value_string, "icalparameter_new_from_value_string",
|
||||
&EDSAbiWrapperSingleton.icalparameter_new_clone, "icalparameter_new_clone",
|
||||
&EDSAbiWrapperSingleton.icalproperty_new_clone, "icalproperty_new_clone",
|
||||
&EDSAbiWrapperSingleton.icalproperty_free, "icalproperty_free",
|
||||
&EDSAbiWrapperSingleton.icalproperty_get_description, "icalproperty_get_description",
|
||||
|
@ -299,12 +302,17 @@ extern "C" void EDSAbiWrapperInit()
|
|||
&EDSAbiWrapperSingleton.icalproperty_new_summary, "icalproperty_new_summary",
|
||||
&EDSAbiWrapperSingleton.icalproperty_new_uid, "icalproperty_new_uid",
|
||||
&EDSAbiWrapperSingleton.icalproperty_new_sequence, "icalproperty_new_sequence",
|
||||
&EDSAbiWrapperSingleton.icalproperty_new_recurrenceid, "icalproperty_new_recurrenceid",
|
||||
&EDSAbiWrapperSingleton.icalproperty_set_value_from_string, "icalproperty_set_value_from_string",
|
||||
&EDSAbiWrapperSingleton.icalproperty_set_dtstamp, "icalproperty_set_dtstamp",
|
||||
&EDSAbiWrapperSingleton.icalproperty_set_lastmodified, "icalproperty_set_lastmodified",
|
||||
&EDSAbiWrapperSingleton.icalproperty_set_sequence, "icalproperty_set_sequence",
|
||||
&EDSAbiWrapperSingleton.icalproperty_set_uid, "icalproperty_set_uid",
|
||||
&EDSAbiWrapperSingleton.icalproperty_remove_parameter_by_kind, "icalproperty_remove_parameter_by_kind",
|
||||
&EDSAbiWrapperSingleton.icalproperty_add_parameter, "icalproperty_add_parameter",
|
||||
&EDSAbiWrapperSingleton.icalproperty_get_value_as_string, "icalproperty_get_value_as_string",
|
||||
&EDSAbiWrapperSingleton.icalproperty_get_x_name, "icalproperty_get_x_name",
|
||||
&EDSAbiWrapperSingleton.icalproperty_new_from_string, "icalproperty_new_from_string",
|
||||
&EDSAbiWrapperSingleton.icaltime_is_null_time, "icaltime_is_null_time",
|
||||
&EDSAbiWrapperSingleton.icaltime_is_utc, "icaltime_is_utc",
|
||||
&EDSAbiWrapperSingleton.icaltime_as_ical_string, "icaltime_as_ical_string",
|
||||
|
@ -325,10 +333,11 @@ extern "C" void EDSAbiWrapperInit()
|
|||
(void *)0);
|
||||
EDSAbiHaveEcal = EDSAbiWrapperSingleton.e_cal_new != 0;
|
||||
ecalhandle =
|
||||
findSymbols("libecal-1.2.so", 3, 7,
|
||||
findSymbols("libecal-1.2.so", libecalMinVersion, libecalMaxVersion,
|
||||
FIND_SYMBOLS_LENIENT_MAX_VERSION, NULL,
|
||||
&EDSAbiWrapperSingleton.icalcomponent_as_ical_string_r, "icalcomponent_as_ical_string_r",
|
||||
&EDSAbiWrapperSingleton.icaltime_as_ical_string_r, "icaltime_as_ical_string_r",
|
||||
&EDSAbiWrapperSingleton.icalproperty_get_value_as_string_r, "icalproperty_get_value_as_string_r",
|
||||
(void *)0);
|
||||
# endif // ENABLE_ECAL
|
||||
|
||||
|
|
|
@ -180,6 +180,7 @@ struct EDSAbiWrapper {
|
|||
const char* (*icalparameter_get_tzid) (const icalparameter* value);
|
||||
void (*icalparameter_set_tzid) (icalparameter* value, const char* v);
|
||||
icalparameter *(*icalparameter_new_from_value_string)(icalparameter_kind kind, const char *value);
|
||||
icalparameter *(*icalparameter_new_clone)(icalparameter *param);
|
||||
icalproperty *(*icalproperty_new_clone)(icalproperty *prop);
|
||||
void (*icalproperty_free)(icalproperty *prop);
|
||||
const char* (*icalproperty_get_description) (const icalproperty* prop);
|
||||
|
@ -197,6 +198,7 @@ struct EDSAbiWrapper {
|
|||
icalproperty* (*icalproperty_new_summary) (const char* v);
|
||||
icalproperty* (*icalproperty_new_sequence) (int v);
|
||||
icalproperty* (*icalproperty_new_uid) (const char* v);
|
||||
icalproperty* (*icalproperty_new_recurrenceid) (icaltimetype v);
|
||||
void (*icalproperty_set_value_from_string) (icalproperty* prop,const char* value, const char* kind);
|
||||
void (*icalproperty_set_dtstamp) (icalproperty* prop, struct icaltimetype v);
|
||||
void (*icalproperty_set_lastmodified) (icalproperty* prop, struct icaltimetype v);
|
||||
|
@ -204,6 +206,11 @@ struct EDSAbiWrapper {
|
|||
void (*icalproperty_set_uid) (icalproperty* prop, const char *v);
|
||||
void (*icalproperty_remove_parameter_by_kind)(icalproperty* prop,
|
||||
icalparameter_kind kind);
|
||||
void (*icalproperty_add_parameter)(icalproperty* prop,icalparameter* parameter);
|
||||
const char* (*icalproperty_get_value_as_string)(const icalproperty* prop);
|
||||
const char* (*icalproperty_get_x_name)(icalproperty* prop);
|
||||
icalproperty* (*icalproperty_new_from_string)(const char* str);
|
||||
|
||||
int (*icaltime_is_null_time)(const struct icaltimetype t);
|
||||
int (*icaltime_is_utc)(const struct icaltimetype t);
|
||||
const char* (*icaltime_as_ical_string) (const struct icaltimetype tt);
|
||||
|
@ -226,6 +233,7 @@ struct EDSAbiWrapper {
|
|||
// optional variants which allocate the returned string for us
|
||||
const char* (*icaltime_as_ical_string_r) (const struct icaltimetype tt);
|
||||
char* (*icalcomponent_as_ical_string_r) (icalcomponent* component);
|
||||
char* (*icalproperty_get_value_as_string_r) (const icalproperty* prop);
|
||||
# endif /* ENABLE_ICAL */
|
||||
|
||||
# ifdef ENABLE_BLUETOOTH
|
||||
|
@ -347,6 +355,7 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton;
|
|||
# define icalparameter_get_tzid EDSAbiWrapperSingleton.icalparameter_get_tzid
|
||||
# define icalparameter_set_tzid EDSAbiWrapperSingleton.icalparameter_set_tzid
|
||||
# define icalparameter_new_from_value_string EDSAbiWrapperSingleton.icalparameter_new_from_value_string
|
||||
# define icalparameter_new_clone EDSAbiWrapperSingleton.icalparameter_new_clone
|
||||
# define icalproperty_new_clone EDSAbiWrapperSingleton.icalproperty_new_clone
|
||||
# define icalproperty_free EDSAbiWrapperSingleton.icalproperty_free
|
||||
# define icalproperty_get_description EDSAbiWrapperSingleton.icalproperty_get_description
|
||||
|
@ -364,12 +373,17 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton;
|
|||
# define icalproperty_new_summary EDSAbiWrapperSingleton.icalproperty_new_summary
|
||||
# define icalproperty_new_uid EDSAbiWrapperSingleton.icalproperty_new_uid
|
||||
# define icalproperty_new_sequence EDSAbiWrapperSingleton.icalproperty_new_sequence
|
||||
# define icalproperty_new_recurrenceid EDSAbiWrapperSingleton.icalproperty_new_recurrenceid
|
||||
# define icalproperty_set_value_from_string EDSAbiWrapperSingleton.icalproperty_set_value_from_string
|
||||
# define icalproperty_set_dtstamp EDSAbiWrapperSingleton.icalproperty_set_dtstamp
|
||||
# define icalproperty_set_lastmodified EDSAbiWrapperSingleton.icalproperty_set_lastmodified
|
||||
# define icalproperty_set_sequence EDSAbiWrapperSingleton.icalproperty_set_sequence
|
||||
# define icalproperty_set_uid EDSAbiWrapperSingleton.icalproperty_set_uid
|
||||
# define icalproperty_remove_parameter_by_kind EDSAbiWrapperSingleton.icalproperty_remove_parameter_by_kind
|
||||
# define icalproperty_add_parameter EDSAbiWrapperSingleton.icalproperty_add_parameter
|
||||
# define icalproperty_get_value_as_string (EDSAbiWrapperSingleton.icalproperty_get_value_as_string_r ? EDSAbiWrapperSingleton.icalproperty_get_value_as_string_r : (char *(*)(const icalproperty*))EDSAbiWrapperSingleton.icalproperty_get_value_as_string)
|
||||
# define icalproperty_get_x_name EDSAbiWrapperSingleton.icalproperty_get_x_name
|
||||
# define icalproperty_new_from_string EDSAbiWrapperSingleton.icalproperty_new_from_string
|
||||
# define icaltime_is_null_time EDSAbiWrapperSingleton.icaltime_is_null_time
|
||||
# define icaltime_is_utc EDSAbiWrapperSingleton.icaltime_is_utc
|
||||
# define icaltime_as_ical_string (EDSAbiWrapperSingleton.icaltime_as_ical_string_r ? EDSAbiWrapperSingleton.icaltime_as_ical_string_r : EDSAbiWrapperSingleton.icaltime_as_ical_string)
|
||||
|
@ -418,6 +432,7 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton;
|
|||
# define LIBICAL_MEMFIXES 1
|
||||
# define icaltime_as_ical_string icaltime_as_ical_string_r
|
||||
# define icalcomponent_as_ical_string icalcomponent_as_ical_string_r
|
||||
# define icalproperty_get_value_as_string icalproperty_get_value_as_string_r
|
||||
# endif /* LIBICAL_MEMFIXES */
|
||||
# endif /* ENABLE_ICAL */
|
||||
# endif /* EDS_ABI_WRAPPER_NO_REDEFINE */
|
||||
|
|
|
@ -381,7 +381,21 @@ class Timespec : public timespec
|
|||
static Timespec monotonic() { Timespec res; clock_gettime(CLOCK_MONOTONIC, &res); return res; }
|
||||
static Timespec system() { Timespec res; clock_gettime(CLOCK_REALTIME, &res); return res; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Acts like a boolean, but in addition, can also tell whether the
|
||||
* value was explicitly set. Defaults to false.
|
||||
*/
|
||||
class Bool {
|
||||
public:
|
||||
Bool(bool val = false) : m_value(val), m_wasSet(false) {}
|
||||
operator bool () const { return m_value; }
|
||||
Bool & operator = (bool val) { m_value = val; m_wasSet = true; return *this; }
|
||||
bool wasSet() const { return m_wasSet; }
|
||||
private:
|
||||
bool m_value;
|
||||
bool m_wasSet;
|
||||
};
|
||||
|
||||
/**
|
||||
* an exception which records the source file and line
|
||||
|
|
|
@ -508,7 +508,7 @@ int main( int argc, char **argv )
|
|||
return 0;
|
||||
}
|
||||
|
||||
Cmdline::Bool useDaemon = cmdline.useDaemon();
|
||||
Bool useDaemon = cmdline.useDaemon();
|
||||
|
||||
if(cmdline.monitor()) {
|
||||
|
||||
|
|
1494
test/ClientTest.cpp
1494
test/ClientTest.cpp
File diff suppressed because it is too large
Load diff
|
@ -286,7 +286,7 @@ class ClientTest {
|
|||
/**
|
||||
* utility function for dumping items which are C strings with blank lines as separator
|
||||
*/
|
||||
static int dump(ClientTest &client, TestingSyncSource &source, const char *file);
|
||||
static int dump(ClientTest &client, TestingSyncSource &source, const std::string &file);
|
||||
|
||||
/**
|
||||
* utility function for splitting file into items with blank lines as separator
|
||||
|
@ -295,20 +295,20 @@ class ClientTest {
|
|||
* of the generic version. The caller gets the name of the
|
||||
* file that was opened here.
|
||||
*/
|
||||
static void getItems(const char *file, std::list<std::string> &items, std::string &realfile);
|
||||
static void getItems(const std::string &file, std::list<std::string> &items, std::string &realfile);
|
||||
|
||||
/**
|
||||
* utility function for importing items with blank lines as separator
|
||||
*/
|
||||
static std::string import(ClientTest &client, TestingSyncSource &source,
|
||||
const ClientTestConfig &config,
|
||||
const char *file, std::string &realfile);
|
||||
const std::string &file, std::string &realfile);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
static bool compare(ClientTest &client, const std::string &fileA, const std::string &fileB);
|
||||
|
||||
/**
|
||||
* utility function: update a vCard or iCalendar item by inserting "MOD-" into
|
||||
|
@ -429,7 +429,7 @@ class ClientTest {
|
|||
*/
|
||||
class CreateSource {
|
||||
public:
|
||||
CreateSource(ClientTest::Config::createsource_t createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
|
||||
CreateSource(const ClientTest::Config::createsource_t &createSourceParam, ClientTest &clientParam, int sourceParam, bool isSourceAParam) :
|
||||
createSource(createSourceParam),
|
||||
client(clientParam),
|
||||
source(sourceParam),
|
||||
|
@ -473,8 +473,8 @@ public:
|
|||
client(cl),
|
||||
source(sourceParam),
|
||||
config(co),
|
||||
createSourceA(co.createSourceA, cl, sourceParam, true),
|
||||
createSourceB(co.createSourceB, cl, sourceParam, false)
|
||||
createSourceA(co.m_createSourceA, cl, sourceParam, true),
|
||||
createSourceB(co.m_createSourceB, cl, sourceParam, false)
|
||||
{}
|
||||
|
||||
/** set up before running a test */
|
||||
|
@ -495,21 +495,21 @@ public:
|
|||
* @retval inserted actual data that was inserted, optional
|
||||
* @return the LUID of the inserted item
|
||||
*/
|
||||
virtual std::string insert(CreateSource createSource, const char *data, bool relaxed = false, std::string *inserted = NULL);
|
||||
virtual std::string insert(CreateSource createSource, const std::string &data, bool relaxed = false, std::string *inserted = NULL);
|
||||
|
||||
/**
|
||||
* assumes that exactly one element is currently inserted and updates it with the given item
|
||||
*
|
||||
* @param check if true, then reopen the source and verify that the reported items are as expected
|
||||
*/
|
||||
virtual void update(CreateSource createSource, const char *data, bool check = true);
|
||||
virtual void update(CreateSource createSource, const std::string &data, bool check = true);
|
||||
|
||||
/**
|
||||
* updates one item identified by its LUID with the given item
|
||||
*
|
||||
* The type of the item is cleared, as in insert() above.
|
||||
*/
|
||||
virtual void update(CreateSource createSource, const char *data, const std::string &luid);
|
||||
virtual void update(CreateSource createSource, const std::string &data, const std::string &luid);
|
||||
|
||||
/** deletes all items locally via sync source */
|
||||
virtual void deleteAll(CreateSource createSource);
|
||||
|
@ -590,6 +590,8 @@ public:
|
|||
virtual void testLinkedItemsInsertBothUpdateChild();
|
||||
virtual void testLinkedItemsInsertBothUpdateParent();
|
||||
|
||||
/** retrieve right set of items for running test */
|
||||
ClientTestConfig::LinkedItems_t getParentChildData();
|
||||
};
|
||||
|
||||
int countItemsOfType(TestingSyncSource *source, int state);
|
||||
|
@ -751,6 +753,8 @@ protected:
|
|||
virtual void testSlowSyncSemantic();
|
||||
virtual void testComplexRefreshFromServerSemantic();
|
||||
virtual void testDeleteBothSides();
|
||||
virtual void testAddBothSides();
|
||||
virtual void testAddBothSidesRefresh();
|
||||
virtual void testLinkedItemsParentChild();
|
||||
virtual void testLinkedItemsChild();
|
||||
virtual void testLinkedItemsChildParent();
|
||||
|
|
|
@ -113,6 +113,11 @@ itodo20
|
|||
UID, DTSTART,PERCENT-COMPLETE,SEQUENCE, URL, CLASS
|
||||
text
|
||||
-- N/A
|
||||
-- All-day events are not supported. The server is sent such events as DTSTART/END 00:00:00/23:59:59
|
||||
floating time and returns them with shifted times (DTSTART 22:00:00 UTC on a different day).
|
||||
This cannot be recognized as an all-day event anymore by the client.
|
||||
-- For the same reason, exceptions to a recurring meeting may shift during synchronization
|
||||
(EXDATE:20001231 -> EXDATE:20001230T220000Z).
|
||||
|
||||
* Known test failures:
|
||||
Client::Sync::vcard21
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
# start D-Bus session
|
||||
eval `dbus-launch`
|
||||
export DBUS_SESSION_BUS_ADDRESS
|
||||
trap "kill $DBUS_SESSION_BUS_PID" EXIT
|
||||
|
||||
# Work-around for GNOME keyring daemon not started
|
||||
# when accessed via org.freedesktop.secrets: start it
|
||||
|
@ -15,20 +14,27 @@ trap "kill $DBUS_SESSION_BUS_PID" EXIT
|
|||
# https://bugzilla.redhat.com/show_bug.cgi?id=572137
|
||||
/usr/bin/gnome-keyring-daemon --start --foreground --components=secrets &
|
||||
KEYRING_PID=$!
|
||||
trap "kill $KEYRING_PID" EXIT
|
||||
|
||||
# kill all programs started by us
|
||||
trap "kill $KEYRING_PID; kill $DBUS_SESSION_BUS_PID" EXIT
|
||||
|
||||
# If DBUS_SESSION_SH_EDS_BASE is set and our main program runs
|
||||
# under valgrind, then also check EDS. DBUS_SESSION_SH_EDS_BASE
|
||||
# must be the directory which contains e-addressbook/calendar-factory.
|
||||
# under valgrind, then also check EDS. Otherwise start EDS only
|
||||
# for certain known operations which need EDS (syncevolution, client-test)
|
||||
# but not others (make, configure).
|
||||
#
|
||||
# DBUS_SESSION_SH_EDS_BASE must be the directory which contains
|
||||
# e-addressbook/calendar-factory.
|
||||
E_CAL_PID=
|
||||
E_BOOK_PID=
|
||||
case "$@" in *valgrind*) prefix=`echo $@ | perl -p -e 's;.*?(\S*/?valgrind\S*).*;$1;'`;;
|
||||
*) prefix=;;
|
||||
*syncevolution\ *|*client-test\ *|*test-dbus.py\ *) prefix=env;;
|
||||
*) prefix=;; # don't start EDS
|
||||
esac
|
||||
if [ "$DBUS_SESSION_SH_EDS_BASE" ] && [ "$prefix" ]; then
|
||||
$prefix $DBUS_SESSION_SH_EDS_BASE/e-calendar-factory &
|
||||
$prefix $DBUS_SESSION_SH_EDS_BASE/e-calendar-factory --keep-running &
|
||||
E_CAL_PID=$!
|
||||
$prefix $DBUS_SESSION_SH_EDS_BASE/e-addressbook-factory &
|
||||
$prefix $DBUS_SESSION_SH_EDS_BASE/e-addressbook-factory --keep-running &
|
||||
E_BOOK_PID=$!
|
||||
|
||||
# give daemons some time to start and register with D-Bus
|
||||
|
@ -59,7 +65,7 @@ shutdown () {
|
|||
fi
|
||||
wait "$pid"
|
||||
subres=$?
|
||||
case $subres in 0|130|143) true;; # 130 and 143 indicate that it was killed, probably by us
|
||||
case $subres in 0|130|137|143) true;; # 130 and 143 indicate that it was killed, probably by us
|
||||
*) echo $program failed with return code $subres >&2
|
||||
if [ $res -eq 0 ]; then
|
||||
res=$subres
|
||||
|
|
361
test/evo.supp
361
test/evo.supp
|
@ -3959,52 +3959,6 @@
|
|||
obj:*
|
||||
}
|
||||
|
||||
# ==30565==
|
||||
# ==30565== Thread 1:
|
||||
# ==30565==
|
||||
# ==30565== 6,564 bytes in 144 blocks are definitely lost in loss record 48 of 72
|
||||
# ==30565== at 0x4C2391E: malloc (vg_replace_malloc.c:207)
|
||||
# ==30565== by 0x5B1FA21: strdup (in /lib/libc-2.9.so)
|
||||
# ==30565== by 0xD9E080C: icalparameter_new_from_value_string (in /usr/lib/libical.so.0.43.0)
|
||||
# ==30565== by 0xD9F6AF0: icalparser_add_line (in /usr/lib/libical.so.0.43.0)
|
||||
# ==30565== by 0xD9F7088: icalparser_parse (in /usr/lib/libical.so.0.43.0)
|
||||
# ==30565== by 0xD9F7230: icalparser_parse_string (in /usr/lib/libical.so.0.43.0)
|
||||
# ==30565== by 0xA2CB224: SyncEvo::EvolutionCalendarSource::insertItem(std::string const&, std::string const&, bool) (EvolutionCalendarSource.cpp:287)
|
||||
# ==30565== by 0x511AF67: SyncEvo::TrackingSyncSource::insertItem(std::string const&, std::string const&) (TrackingSyncSource.cpp:69)
|
||||
# ==30565== by 0x50D9B8C: SyncEvo::SyncSourceSerialize::insertItemAsKey(sysync::KeyType*, sysync::ItemIDType const*, sysync::ItemIDType*) (SyncSource.cpp:531)
|
||||
# ==30565== by 0x50D6165: SyncEvo::SyncSourceLogging::insertItemAsKey(sysync::KeyType*, sysync::ItemIDType*, boost::function<unsigned short ()(sysync::KeyType*, sysync::ItemIDType*), std::allocator<void> > const&) (function_template.hpp:825)
|
||||
# ==30565== by 0x50E3064: SyncEvolution_InsertItemAsKey (function_template.hpp:825)
|
||||
# ==30565== by 0x5EE86C2: sysync::TDB_Api::InsertItemAsKey(sysync::KeyType*, char const*, sysync::TDB_Api_ItemID&) (dbapi.cpp:1874)
|
||||
# ==30565== by 0x5EE54B5: sysync::TPluginApiDS::apiAddItem(sysync::TMultiFieldItem&, std::string&) (pluginapids.cpp:1354)
|
||||
# ==30565== by 0x5E358D1: sysync::TCustomImplDS::createItem(sysync::TSyncItem*, std::string&, bool&) (customimplds.cpp:3219)
|
||||
# ==30565== by 0x5E6F8C0: sysync::TBinfileImplDS::implProcessItem(sysync::TSyncItem*, sysync::TStatusCommand&) (binfileimplds.cpp:1779)
|
||||
# ==30565== by 0x5EB0EC9: sysync::TStdLogicDS::logicProcessRemoteItem(sysync::TSyncItem*, sysync::TStatusCommand&, bool&, std::string*) (stdlogicds.cpp:1222)
|
||||
# ==30565== by 0x5E7FB6D: sysync::TLocalEngineDS::engProcessRemoteItemAsClient(sysync::TSyncItem*, sysync::TStatusCommand&) (localengineds.cpp:5932)
|
||||
# ==30565== by 0x5E7FFC8: sysync::TLocalEngineDS::engProcessSyncOpItem(sysync::TSyncOperation, sml_item_s*, sml_metinf_metinf_s*, sysync::TStatusCommand&) (localengineds.cpp:4790)
|
||||
# ==30565== by 0x5E856D9: sysync::TSyncSession::processSyncOpItem(sysync::TSyncOperation, sml_item_s*, sml_metinf_metinf_s*, sysync::TLocalEngineDS*, sysync::TStatusCommand&, bool&) (syncsession.cpp:3643)
|
||||
# ==30565== by 0x5E6B501: sysync::TSyncOpCommand::execute() (synccommand.cpp:2561)
|
||||
# ==30565== by 0x5E8AC64: sysync::TSyncSession::process(sysync::TSmlCommand*) (syncsession.cpp:2352)
|
||||
# ==30565== by 0x5E29548: sysync::TSyncAppBase::AddCmd(void*, sml_generic_s*) (syncappbase.cpp:2071)
|
||||
# ==30565== by 0x7818D0E: smlProcessData (mgrcmddispatcher.c:484)
|
||||
# ==30565== by 0x5E3796A: sysync::TSyncClient::processingStep(unsigned short&, sysync::TEngineProgressType*) (syncclient.cpp:541)
|
||||
# ==30565== by 0x5E5CB9D: sysync::TClientEngineInterface::SessionStep(sysync::SessionType*, unsigned short&, sysync::TEngineProgressType*) (syncclientbase.cpp:274)
|
||||
# ==30565== by 0x50C0AA7: SyncEvo::SharedEngine::SessionStep(boost::shared_ptr<sysync::SessionType> const&, unsigned short&, sysync::TEngineProgressType*) (SynthesisEngine.cpp:95)
|
||||
# ==30565== by 0x50E8BC5: SyncEvo::SyncContext::doSync() (SyncContext.cpp:1777)
|
||||
# ==30565== by 0x50EC228: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:1572)
|
||||
# ==30565== by 0x43AC59: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (in /work/runtests/head-evolution-testing/build/src/.libs/lt-client-test)
|
||||
# ==30565== by 0x44F871: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (in /work/runtests/head-evolution-testing/build/src/.libs/lt-client-test)
|
||||
{
|
||||
icalparameter new from value string
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:strdup
|
||||
fun:icalparameter_new_from_value_string
|
||||
fun:icalparser_add_line
|
||||
fun:icalparser_parse
|
||||
fun:icalparser_parse_string
|
||||
fun:*EvolutionCalendarSource*insertItem*
|
||||
}
|
||||
|
||||
# ==17808==
|
||||
# ==17808==
|
||||
# ==17808== 32,519 (2,104 direct, 30,415 indirect) bytes in 67 blocks are definitely lost in loss==17813==
|
||||
|
@ -4523,321 +4477,6 @@
|
|||
fun:clone
|
||||
}
|
||||
|
||||
# ==10204== Invalid read of size 8
|
||||
# ==10204== at 0x73FA92D: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x73FBD14: (within /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x73FBD64: icaltimezone_get_component (in /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x6BE01C: sysync::loadSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:158)
|
||||
# ==10204== by 0x6A81B8: sysync::GZones::initialize() (timezones.cpp:95)
|
||||
# ==10204== by 0x6D095E: sysync::TSyncAppBase::TSyncAppBase() (syncappbase.cpp:1227)
|
||||
# ==10204== by 0x6EC128: sysync::TSyncClientBase::TSyncClientBase() (syncclientbase.cpp:352)
|
||||
# ==10204== by 0x77B3F8: sysync::TEngineClientBase::TEngineClientBase() (engineclientbase.cpp:102)
|
||||
# ==10204== by 0x6BE88A: sysync::TCustomClientEngineBase::TCustomClientEngineBase() (clientengine_custom_Base.cpp:49)
|
||||
# ==10204== by 0x6BE912: sysync::TCustomClientEngineInterface::newSyncAppBase() (clientengine_custom_Base.cpp:39)
|
||||
# ==10204== by 0x6A420C: sysync::TEngineInterface::Init() (engineinterface.cpp:1056)
|
||||
# ==10204== by 0x6BBB65: sysync::TEngineModuleBase::Connect(std::string, unsigned long, unsigned short) (enginemodulebase.cpp:85)
|
||||
# ==10204== by 0x6A673D: sysync::internal_ConnectEngine(bool, sysync::SDK_InterfaceType**, unsigned short, unsigned long*, unsigned long, unsigned short) (engineinterface.cpp:1869)
|
||||
# ==10204== by 0x6A145A: sysync::UI_Connect(sysync::SDK_InterfaceType*&, void*&, bool&, char const*, unsigned long, unsigned short) (UI_util.cpp:181)
|
||||
# ==10204== by 0x6BBB65: sysync::TEngineModuleBase::Connect(std::string, unsigned long, unsigned short) (enginemodulebase.cpp:85)
|
||||
# ==10204== by 0x695D36: SyncEvo::SharedEngine::Connect(std::string const&, unsigned long, unsigned short) (SynthesisEngine.cpp:32)
|
||||
# ==10204== by 0x62F070: SyncEvo::SyncContext::createEngine() (SyncContext.cpp:2537)
|
||||
# ==10204== by 0x63DDEB: SyncEvo::SyncContext::SwapEngine::SwapEngine(SyncEvo::SyncContext&) (SyncContext.h:452)
|
||||
# ==10204== by 0x636DE5: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2708)
|
||||
# ==10204== by 0x4C07CF: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==10204== by 0x4DE479: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==10204== by 0x587412: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==10204== by 0x4E8AB6: SyncEvo::SyncTests::testDeleteAllRefresh() (ClientTest.cpp:1695)
|
||||
# ==10204== by 0x5B6F406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B617D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6B278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6AFBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B76D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6F09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6F9FB: CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== Address 0xec7b9b0 is 0 bytes after a block of size 0 alloc'd
|
||||
# ==10204== at 0x4C216F4: calloc (vg_replace_malloc.c:397)
|
||||
# ==10204== by 0x73FA492: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x73FBD14: (within /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x73FBD64: icaltimezone_get_component (in /usr/lib/libical.so.0.43.0)
|
||||
# ==10204== by 0x6BE01C: sysync::loadSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:158)
|
||||
# ==10204== by 0x6A81B8: sysync::GZones::initialize() (timezones.cpp:95)
|
||||
# ==10204== by 0x6D095E: sysync::TSyncAppBase::TSyncAppBase() (syncappbase.cpp:1227)
|
||||
# ==10204== by 0x6EC128: sysync::TSyncClientBase::TSyncClientBase() (syncclientbase.cpp:352)
|
||||
# ==10204== by 0x77B3F8: sysync::TEngineClientBase::TEngineClientBase() (engineclientbase.cpp:102)
|
||||
# ==10204== by 0x6BE88A: sysync::TCustomClientEngineBase::TCustomClientEngineBase() (clientengine_custom_Base.cpp:49)
|
||||
# ==10204== by 0x6BE912: sysync::TCustomClientEngineInterface::newSyncAppBase() (clientengine_custom_Base.cpp:39)
|
||||
# ==10204== by 0x6A420C: sysync::TEngineInterface::Init() (engineinterface.cpp:1056)
|
||||
# ==10204== by 0x6BBB65: sysync::TEngineModuleBase::Connect(std::string, unsigned long, unsigned short) (enginemodulebase.cpp:85)
|
||||
# ==10204== by 0x6A673D: sysync::internal_ConnectEngine(bool, sysync::SDK_InterfaceType**, unsigned short, unsigned long*, unsigned long, unsigned short) (engineinterface.cpp:1869)
|
||||
# ==10204== by 0x6A145A: sysync::UI_Connect(sysync::SDK_InterfaceType*&, void*&, bool&, char const*, unsigned long, unsigned short) (UI_util.cpp:181)
|
||||
# ==10204== by 0x6BBB65: sysync::TEngineModuleBase::Connect(std::string, unsigned long, unsigned short) (enginemodulebase.cpp:85)
|
||||
# ==10204== by 0x695D36: SyncEvo::SharedEngine::Connect(std::string const&, unsigned long, unsigned short) (SynthesisEngine.cpp:32)
|
||||
# ==10204== by 0x62F070: SyncEvo::SyncContext::createEngine() (SyncContext.cpp:2537)
|
||||
# ==10204== by 0x63DDEB: SyncEvo::SyncContext::SwapEngine::SwapEngine(SyncEvo::SyncContext&) (SyncContext.h:452)
|
||||
# ==10204== by 0x636DE5: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2708)
|
||||
# ==10204== by 0x4C07CF: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==10204== by 0x4DE479: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==10204== by 0x587412: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==10204== by 0x4E8AB6: SyncEvo::SyncTests::testDeleteAllRefresh() (ClientTest.cpp:1695)
|
||||
# ==10204== by 0x5B6F406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B617D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6B278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6AFBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B76D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==10204== by 0x5B6F09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
{
|
||||
icaltimezone_get_component
|
||||
Memcheck:Addr8
|
||||
fun:icaltzutil_fetch_timezone
|
||||
obj:*libical.so.*
|
||||
fun:icaltimezone_get_component
|
||||
}
|
||||
|
||||
# ==23938== Conditional jump or move depends on uninitialised value(s)
|
||||
# ==23938== at 0x7423FBE: icaltime_adjust (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74294D3: icaltimezone_convert_time (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742587B: icaltime_from_timet_with_zone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742597A: icaltime_from_timet (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74263CB: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74276F4: (within /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7427744: icaltimezone_get_component (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x6CA11A: sysync::finalizeSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:186)
|
||||
# ==23938== by 0x6B4544: sysync::GZones::loggingStarted() (timezones.cpp:114)
|
||||
# ==23938== by 0x6DA507: sysync::TSyncAppBase::finishConfig() (syncappbase.cpp:1441)
|
||||
# ==23938== by 0x6DA67F: sysync::TSyncAppBase::readXMLConfigStream(int (*)(char*, unsigned long, unsigned long*, void*), void*) (syncappbase.cpp:1753)
|
||||
# ==23938== by 0x6DA787: sysync::TSyncAppBase::readXMLConfigConstant(char const*) (syncappbase.cpp:1786)
|
||||
# ==23938== by 0x6B27E9: sysync::TEngineInterface::InitEngineXML(char const*) (engineinterface.cpp:1194)
|
||||
# ==23938== by 0x69F47C: SyncEvo::SharedEngine::InitEngineXML(std::string const&) (SynthesisEngine.cpp:48)
|
||||
# ==23938== by 0x624EB6: SyncEvo::SyncContext::initEngine(bool) (SyncContext.cpp:2622)
|
||||
# ==23938== by 0x6364FE: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2709)
|
||||
# ==23938== by 0x4BF856: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==23938== by 0x56B6C0: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==23938== by 0x57D9A1: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==23938== by 0x4D4EE0: SyncEvo::SyncTests::deleteAll(SyncEvo::SyncTests::DeleteAllMode) (ClientTest.cpp:1620)
|
||||
# ==23938== by 0x4CDB1E: SyncEvo::SyncTests::testItems() (ClientTest.cpp:2333)
|
||||
# ==23938== by 0x5B7A406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B6C7D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B76278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B75FBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B7A09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81B29: CppUnit::TestResult::runTest(CppUnit::Test*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B84121: CppUnit::TestRunner::run(CppUnit::TestResult&, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B8713A: CppUnit::TextTestRunner::run(std::string, bool, bool, bool) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
{
|
||||
icaltimezone_get_component II
|
||||
Memcheck:Cond
|
||||
fun:icaltime_adjust
|
||||
fun:icaltimezone_convert_time
|
||||
fun:icaltime_from_timet_with_zone
|
||||
fun:icaltime_from_timet
|
||||
fun:icaltzutil_fetch_timezone
|
||||
obj:*libical.so*
|
||||
fun:icaltimezone_get_component
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
|
||||
# ==23938== Use of uninitialised value of size 8
|
||||
# ==23938== at 0x7423DFB: icaltime_days_in_month (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742400B: icaltime_adjust (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74294FB: icaltimezone_convert_time (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742587B: icaltime_from_timet_with_zone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742597A: icaltime_from_timet (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74263CB: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74276F4: (within /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7427744: icaltimezone_get_component (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x6CA11A: sysync::finalizeSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:186)
|
||||
# ==23938== by 0x6B4544: sysync::GZones::loggingStarted() (timezones.cpp:114)
|
||||
# ==23938== by 0x6DA507: sysync::TSyncAppBase::finishConfig() (syncappbase.cpp:1441)
|
||||
# ==23938== by 0x6DA67F: sysync::TSyncAppBase::readXMLConfigStream(int (*)(char*, unsigned long, unsigned long*, void*), void*) (syncappbase.cpp:1753)
|
||||
# ==23938== by 0x6DA787: sysync::TSyncAppBase::readXMLConfigConstant(char const*) (syncappbase.cpp:1786)
|
||||
# ==23938== by 0x6B27E9: sysync::TEngineInterface::InitEngineXML(char const*) (engineinterface.cpp:1194)
|
||||
# ==23938== by 0x69F47C: SyncEvo::SharedEngine::InitEngineXML(std::string const&) (SynthesisEngine.cpp:48)
|
||||
# ==23938== by 0x624EB6: SyncEvo::SyncContext::initEngine(bool) (SyncContext.cpp:2622)
|
||||
# ==23938== by 0x6364FE: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2709)
|
||||
# ==23938== by 0x4BF856: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==23938== by 0x56B6C0: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==23938== by 0x57D9A1: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==23938== by 0x4D4EE0: SyncEvo::SyncTests::deleteAll(SyncEvo::SyncTests::DeleteAllMode) (ClientTest.cpp:1620)
|
||||
# ==23938== by 0x4CDB1E: SyncEvo::SyncTests::testItems() (ClientTest.cpp:2333)
|
||||
# ==23938== by 0x5B7A406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B6C7D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B76278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B75FBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B7A09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81B29: CppUnit::TestResult::runTest(CppUnit::Test*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B84121: CppUnit::TestRunner::run(CppUnit::TestResult&, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
{
|
||||
icaltimezone_get_component III
|
||||
Memcheck:Value8
|
||||
fun:icaltime_days_in_month
|
||||
fun:icaltime_adjust
|
||||
fun:icaltimezone_convert_time
|
||||
fun:icaltime_from_timet_with_zone
|
||||
fun:icaltime_from_timet
|
||||
fun:icaltzutil_fetch_timezone
|
||||
obj:*libical.so*
|
||||
fun:icaltimezone_get_component
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
{
|
||||
icaltimezone_get_component III, version 2
|
||||
Memcheck:Cond
|
||||
fun:icaltime_days_in_month
|
||||
fun:icaltime_adjust
|
||||
fun:icaltimezone_convert_time
|
||||
fun:icaltime_from_timet_with_zone
|
||||
fun:icaltime_from_timet
|
||||
fun:icaltzutil_fetch_timezone
|
||||
obj:*libical.so*
|
||||
fun:icaltimezone_get_component
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
{
|
||||
icaltimezone_get_component IV
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:icalcomponent_as_ical_string*
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
{
|
||||
icaltimezone_get_component V
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:icalcomponent_as_ical_string*
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
|
||||
# ==23938== Conditional jump or move depends on uninitialised value(s)
|
||||
# ==23938== at 0x742B5CC: icalvalue_reset_kind (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7415284: icalvalue_new_datetime (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7412488: icalproperty_set_dtstart (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7412554: icalproperty_new_dtstart (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7426476: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x74276F4: (within /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x7427744: icaltimezone_get_component (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x6CA11A: sysync::finalizeSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:186)
|
||||
# ==23938== by 0x6B4544: sysync::GZones::loggingStarted() (timezones.cpp:114)
|
||||
# ==23938== by 0x6DA507: sysync::TSyncAppBase::finishConfig() (syncappbase.cpp:1441)
|
||||
# ==23938== by 0x6DA67F: sysync::TSyncAppBase::readXMLConfigStream(int (*)(char*, unsigned long, unsigned long*, void*), void*) (syncappbase.cpp:1753)
|
||||
# ==23938== by 0x6DA787: sysync::TSyncAppBase::readXMLConfigConstant(char const*) (syncappbase.cpp:1786)
|
||||
# ==23938== by 0x6B27E9: sysync::TEngineInterface::InitEngineXML(char const*) (engineinterface.cpp:1194)
|
||||
# ==23938== by 0x69F47C: SyncEvo::SharedEngine::InitEngineXML(std::string const&) (SynthesisEngine.cpp:48)
|
||||
# ==23938== by 0x624EB6: SyncEvo::SyncContext::initEngine(bool) (SyncContext.cpp:2622)
|
||||
# ==23938== by 0x6364FE: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2709)
|
||||
# ==23938== by 0x4BF856: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==23938== by 0x56B6C0: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==23938== by 0x57D9A1: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==23938== by 0x4D4EE0: SyncEvo::SyncTests::deleteAll(SyncEvo::SyncTests::DeleteAllMode) (ClientTest.cpp:1620)
|
||||
# ==23938== by 0x4CDB1E: SyncEvo::SyncTests::testItems() (ClientTest.cpp:2333)
|
||||
# ==23938== by 0x5B7A406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B6C7D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B76278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B75FBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B7A09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81B29: CppUnit::TestResult::runTest(CppUnit::Test*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B84121: CppUnit::TestRunner::run(CppUnit::TestResult&, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B8713A: CppUnit::TextTestRunner::run(std::string, bool, bool, bool) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
{
|
||||
icaltimezone_get_component IV
|
||||
Memcheck:Cond
|
||||
fun:icalvalue_reset_kind
|
||||
fun:icalvalue_new_datetime
|
||||
fun:icalproperty_set_dtstart
|
||||
fun:icalproperty_new_dtstart
|
||||
fun:icaltzutil_fetch_timezone
|
||||
obj:*libical.so*
|
||||
fun:icaltimezone_get_component
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
# ==23938== Conditional jump or move depends on uninitialised value(s)
|
||||
# ==23938== at 0x8053794: vfprintf (in /lib/libc-2.9.so)
|
||||
# ==23938== by 0x8076759: vsnprintf (in /lib/libc-2.9.so)
|
||||
# ==23938== by 0x805BBA2: snprintf (in /lib/libc-2.9.so)
|
||||
# ==23938== by 0x742B728: print_date_to_string (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742B865: print_datetime_to_string (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x742BFF8: icalvalue_as_ical_string_r (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x741F1C4: icalproperty_as_ical_string_r (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x741AD58: icalcomponent_as_ical_string_r (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x741ADAF: icalcomponent_as_ical_string_r (in /usr/lib/libical.so.0.44.0)
|
||||
# ==23938== by 0x6CA12D: sysync::finalizeSystemZoneDefinitions(sysync::GZones*) (platform_timezones.cpp:189)
|
||||
# ==23938== by 0x6B4544: sysync::GZones::loggingStarted() (timezones.cpp:114)
|
||||
# ==23938== by 0x6DA507: sysync::TSyncAppBase::finishConfig() (syncappbase.cpp:1441)
|
||||
# ==23938== by 0x6DA67F: sysync::TSyncAppBase::readXMLConfigStream(int (*)(char*, unsigned long, unsigned long*, void*), void*) (syncappbase.cpp:1753)
|
||||
# ==23938== by 0x6DA787: sysync::TSyncAppBase::readXMLConfigConstant(char const*) (syncappbase.cpp:1786)
|
||||
# ==23938== by 0x6B27E9: sysync::TEngineInterface::InitEngineXML(char const*) (engineinterface.cpp:1194)
|
||||
# ==23938== by 0x69F47C: SyncEvo::SharedEngine::InitEngineXML(std::string const&) (SynthesisEngine.cpp:48)
|
||||
# ==23938== by 0x624EB6: SyncEvo::SyncContext::initEngine(bool) (SyncContext.cpp:2622)
|
||||
# ==23938== by 0x6364FE: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2709)
|
||||
# ==23938== by 0x4BF856: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:379)
|
||||
# ==23938== by 0x56B6C0: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3248)
|
||||
# ==23938== by 0x57D9A1: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (ClientTest.h:765)
|
||||
# ==23938== by 0x4D4EE0: SyncEvo::SyncTests::deleteAll(SyncEvo::SyncTests::DeleteAllMode) (ClientTest.cpp:1620)
|
||||
# ==23938== by 0x4CDB1E: SyncEvo::SyncTests::testItems() (ClientTest.cpp:2333)
|
||||
# ==23938== by 0x5B7A406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B6C7D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B76278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B75FBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B7A09C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==23938== by 0x5B81B29: CppUnit::TestResult::runTest(CppUnit::Test*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
{
|
||||
icalcomponent_as_ical_string_r
|
||||
Memcheck:Cond
|
||||
fun:vfprintf
|
||||
fun:vsnprintf
|
||||
fun:snprintf
|
||||
fun:print_date_to_string
|
||||
fun:print_datetime_to_string
|
||||
fun:icalvalue_as_ical_string_r
|
||||
fun:icalproperty_as_ical_string_r
|
||||
fun:icalcomponent_as_ical_string_r
|
||||
fun:icalcomponent_as_ical_string_r
|
||||
fun:_ZN6sysync29finalizeSystemZoneDefinitionsEPNS_6GZonesE
|
||||
}
|
||||
|
||||
# ==12472== 13,800 bytes in 5 blocks are possibly lost in loss record 890 of 925
|
||||
# ==12472== at 0x4C244E8: malloc (vg_replace_malloc.c:236)
|
||||
# ==12472== by 0x74A36E8: icalvalue_set_recur (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x74A375F: icalvalue_new_recur (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x749DC17: icalproperty_set_rrule (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x749DC7F: icalproperty_new_rrule (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x74B3900: icaltzutil_fetch_timezone (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x74B46F4: ??? (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0x74B4744: icaltimezone_get_component (in /usr/lib/libical.so.0.44.0)
|
||||
# ==12472== by 0xAA9C3C: sysync::finalizeSystemZoneDefinitions(sysync::GZones*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0xA78EA8: sysync::GZones::loggingStarted() (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0xA37ECD: sysync::TSyncAppBase::finishConfig() (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0xA386E0: sysync::TSyncAppBase::readXMLConfigStream(int (*)(char*, unsigned long, unsigned long*, void*), void*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0xA38A25: sysync::TSyncAppBase::readXMLConfigConstant(char const*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9DEB2E: sysync::TEngineInterface::InitEngineXML(char const*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9DA630: sysync::InitEngineXML(void*, char const*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9CF250: sysync::TEngineModuleBridge::InitEngineXML(char const*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9C1264: SyncEvo::SharedEngine::InitEngineXML(std::string const&) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9046AD: SyncEvo::SyncContext::initEngine(bool) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x9051F1: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x65E8D8: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x75F090: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x76BCD1: SyncEvo::SyncTests::doSync(char const*, SyncEvo::SyncOptions const&) (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x75D7AB: SyncEvo::SyncTests::testTimeout() (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x7737F9: CppUnit::TestCaller<SyncEvo::SyncTests>::runTest() (in /home/pohly/work/syncevolution/src/client-test)
|
||||
# ==12472== by 0x5C22406: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472== by 0x5C147D3: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472== by 0x5C1E278: CppUnit::ProtectorChain::ProtectFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472== by 0x5C1DFBB: CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472== by 0x5C29D9F: CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::string const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472== by 0x5C2209C: CppUnit::TestCase::run(CppUnit::TestResult*) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==12472==
|
||||
{
|
||||
potential leaks in time zone allocation
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:icaltimezone_get_component
|
||||
fun:*finalizeSystemZoneDefinitions*
|
||||
}
|
||||
|
||||
# ==16317== 1 bytes in 1 blocks are possibly lost in loss record 1 of 1,445
|
||||
# ==16317== at 0x4C244E8: malloc (vg_replace_malloc.c:236)
|
||||
# ==16317== by 0x6901534: g_malloc (in /lib/libglib-2.0.so.0.2400.2)
|
||||
|
|
50
test/notification-daemon.py
Executable file
50
test/notification-daemon.py
Executable file
|
@ -0,0 +1,50 @@
|
|||
#! /usr/bin/python -u
|
||||
#
|
||||
# Copyright (C) 2009 Intel Corporation
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) version 3.
|
||||
#
|
||||
# This library 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
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301 USA
|
||||
|
||||
import dbus
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
import dbus.service
|
||||
import gobject
|
||||
import random
|
||||
|
||||
class Notifications (dbus.service.Object):
|
||||
'''fake org.freedesktop.Notifications implementation,'''
|
||||
'''used when there is none already registered on the session bus'''
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='', out_signature='ssss')
|
||||
def GetServerInformation(self):
|
||||
return ('test-dbus', 'SyncEvolution', '0.1', '1.1')
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='', out_signature='as')
|
||||
def GetCapabilities(self):
|
||||
return ['actions', 'body', 'body-hyperlinks', 'body-markup', 'icon-static', 'sound']
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='susssasa{sv}i', out_signature='u')
|
||||
def Notify(self, app, replaces, icon, summary, body, actions, hints, expire):
|
||||
return random.randint(1,100)
|
||||
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
bus = dbus.SessionBus()
|
||||
loop = gobject.MainLoop()
|
||||
name = dbus.service.BusName("org.freedesktop.Notifications", bus)
|
||||
# start dummy notification daemon, if possible;
|
||||
# if it fails, ignore (probably already one running)
|
||||
notifications = Notifications(bus, "/org/freedesktop/Notifications")
|
||||
|
||||
loop.run()
|
|
@ -341,14 +341,23 @@ def step2(resultdir, result, servers, indents, srcdir, shellprefix, backenddir):
|
|||
# <path>/Client_Sync_eds_contact_testItems.log
|
||||
# <path>/SyncEvo_CmdlineTest_testConfigure.log
|
||||
# <path>/N7SyncEvo11CmdlineTestE_testConfigure.log - C++ name mangling?
|
||||
m = re.match(r'.*/(Client_Source_|Client_Sync_|N7SyncEvo\d+|[^_]*_)(.*)_([^_]*)', log)
|
||||
m = re.match(r'.*/(Client_Source_|Client_Sync_|N7SyncEvo\d+|[^_]*_)(.*)_([^_]*)\.log', log)
|
||||
# Client_Sync_, Client_Source_, SyncEvo_, ...
|
||||
prefix = m.group(1)
|
||||
# eds_contact, CmdlineTest, ...
|
||||
format = m.group(2)
|
||||
# testImport
|
||||
casename = m.group(3)
|
||||
# special case grouping of some tests: include group inside casename instead of
|
||||
# format, example:
|
||||
# <path>/Client_Source_apple_caldav_LinkedItems_1_testLinkedItemsParent
|
||||
m = re.match(r'(.*)_(LinkedItems_\d+)', format)
|
||||
if m:
|
||||
format = m.group(1)
|
||||
casename = m.group(2) + '::' + casename
|
||||
if(format not in logdic):
|
||||
logdic[format]=[]
|
||||
logdic[format].append(log)
|
||||
logdic[format].append((casename, log))
|
||||
logprefix[format]=prefix
|
||||
for format in logdic.keys():
|
||||
indent +=space
|
||||
|
@ -360,23 +369,27 @@ def step2(resultdir, result, servers, indents, srcdir, shellprefix, backenddir):
|
|||
qformat = qformat.replace("_", "__");
|
||||
qformat = qformat.replace("+", "_-");
|
||||
result.write(indent+'<'+qformat+' prefix="'+prefix+'">\n')
|
||||
for case in logdic[format]:
|
||||
for casename, log in logdic[format]:
|
||||
indent +=space
|
||||
indents.append(indent)
|
||||
casename = case.rpartition('_')[2].partition('.')[0]
|
||||
result.write(indent+'<'+casename+'>')
|
||||
# must avoid :: in XML
|
||||
tag = casename.replace('::', '__')
|
||||
# special case LinkedItems_1::testLinkedItems...: shorten it
|
||||
# if tag.startswith('LinkedItems_'):
|
||||
# tag = tag.split('_', 1)[1]
|
||||
result.write(indent+'<'+tag+'>')
|
||||
match=format+'::'+casename
|
||||
matchOk=match+": okay \*\*\*"
|
||||
matchKnownFailure=match+": \*\*\* failure ignored \*\*\*"
|
||||
if not os.system("grep -q '" + matchKnownFailure + "' "+case):
|
||||
if not os.system("grep -q '" + matchKnownFailure + "' "+log):
|
||||
result.write('knownfailure')
|
||||
elif not os.system("tail -10 %s | grep -q 'external transport failure (local, status 20043)'" % case):
|
||||
elif not os.system("tail -10 %s | grep -q 'external transport failure (local, status 20043)'" % log):
|
||||
result.write('network')
|
||||
elif os.system("grep -q '" + matchOk + "' "+case):
|
||||
elif os.system("grep -q '" + matchOk + "' "+log):
|
||||
result.write('failed')
|
||||
else:
|
||||
result.write('okay')
|
||||
result.write('</'+casename+'>\n')
|
||||
result.write('</'+tag+'>\n')
|
||||
indents.pop()
|
||||
indent = indents[-1]
|
||||
result.write(indent+'</'+qformat+'>\n')
|
||||
|
|
|
@ -772,7 +772,7 @@ class SyncEvolutionDist(AutotoolsBuild):
|
|||
cd(self.builddir)
|
||||
if self.packagesuffix:
|
||||
context.runCommand("%s %s BINSUFFIX=%s deb rpm" % (self.runner, context.make, self.packagesuffix))
|
||||
put, get = os.popen4("%s %s dpkg-architecture -qDEB_HOST_ARCH" % (self.runner, context.make))
|
||||
put, get = os.popen4("%s dpkg-architecture -qDEB_HOST_ARCH" % (self.runner))
|
||||
for arch in get.readlines():
|
||||
if "i386" in arch:
|
||||
context.runCommand("%s %s BINSUFFIX=%s PKGARCH=lpia deb" % (self.runner, context.make, self.packagesuffix))
|
||||
|
@ -838,7 +838,7 @@ context.add(test)
|
|||
|
||||
test = SyncEvolutionTest("davical", compile,
|
||||
"", options.shell,
|
||||
"Client::Sync::eds_contact::testItems Client::Sync::eds_event::testItems Client::Source::davical_caldav Client::Source::davical_carddav",
|
||||
"Client::Sync::eds_contact Client::Sync::eds_event Client::Source::davical_caldav Client::Source::davical_carddav",
|
||||
[ "davical_caldav", "davical_carddav", "eds_event", "eds_contact" ],
|
||||
"CLIENT_TEST_WEBDAV='davical caldav carddav' "
|
||||
"CLIENT_TEST_NUM_ITEMS=10 " # don't stress server
|
||||
|
@ -855,7 +855,6 @@ test = SyncEvolutionTest("apple", compile,
|
|||
"CLIENT_TEST_WEBDAV='apple caldav carddav' "
|
||||
"CLIENT_TEST_NUM_ITEMS=250 " # test is local, so we can afford a higher number
|
||||
"CLIENT_TEST_ALARM=2400 " # but even with a local server does the test run a long time
|
||||
"CLIENT_TEST_SIMPLE_UID=1 " # server gets confused by UID with special characters
|
||||
"CLIENT_TEST_MODE=server " # for Client::Sync
|
||||
,
|
||||
testPrefix=options.testprefix)
|
||||
|
@ -1001,6 +1000,15 @@ class FunambolTest(SyncEvolutionTest):
|
|||
"eds_task",
|
||||
"eds_memo" ],
|
||||
"CLIENT_TEST_SKIP="
|
||||
# server duplicates items in add<->add conflict because it
|
||||
# does not check UID
|
||||
"Client::Sync::eds_event::testAddBothSides,"
|
||||
"Client::Sync::eds_event::testAddBothSidesRefresh,"
|
||||
"Client::Sync::eds_task::testAddBothSides,"
|
||||
"Client::Sync::eds_task::testAddBothSidesRefresh,"
|
||||
# test cannot pass because we don't have CtCap info about
|
||||
# the Funambol server
|
||||
"Client::Sync::eds_contact::testExtensions,"
|
||||
"Client::Sync::eds_event::Retry,"
|
||||
"Client::Sync::eds_event::Suspend,"
|
||||
"Client::Sync::eds_event::Resend,"
|
||||
|
@ -1097,6 +1105,12 @@ mobicaltest = SyncEvolutionTest("mobical", compile,
|
|||
"CLIENT_TEST_NOCHECK_SYNCMODE=1 "
|
||||
"CLIENT_TEST_MAX_ITEMSIZE=2048 "
|
||||
"CLIENT_TEST_SKIP="
|
||||
# server duplicates items in add<->add conflict because it
|
||||
# does not check UID
|
||||
"Client::Sync::eds_event::testAddBothSides,"
|
||||
"Client::Sync::eds_event::testAddBothSidesRefresh,"
|
||||
"Client::Sync::eds_task::testAddBothSides,"
|
||||
"Client::Sync::eds_task::testAddBothSidesRefresh,"
|
||||
"Client::Sync::eds_contact::Retry,"
|
||||
"Client::Sync::eds_contact::Suspend,"
|
||||
"Client::Sync::eds_contact::Resend,"
|
||||
|
@ -1174,12 +1188,18 @@ memotootest = SyncEvolutionTest("memotoo", compile,
|
|||
"CLIENT_TEST_NOCHECK_SYNCMODE=1 "
|
||||
"CLIENT_TEST_NUM_ITEMS=10 "
|
||||
"CLIENT_TEST_SKIP="
|
||||
# server duplicates items in add<->add conflict because it
|
||||
# does not check UID
|
||||
"Client::Sync::eds_event::testAddBothSides,"
|
||||
"Client::Sync::eds_event::testAddBothSidesRefresh,"
|
||||
"Client::Sync::eds_task::testAddBothSides,"
|
||||
"Client::Sync::eds_task::testAddBothSidesRefresh,"
|
||||
"Client::Sync::eds_contact::Retry,"
|
||||
"Client::Sync::eds_contact::Suspend,"
|
||||
"Client::Sync::eds_contact::testRefreshFromClientSync,"
|
||||
"Client::Sync::eds_contact::testRefreshFromClientSemantic,"
|
||||
"Client::Sync::eds_contact::testDeleteAllRefresh,"
|
||||
"Client::Sync::eds_contact::testOneWayFromServer,"
|
||||
# "Client::Sync::eds_contact::testRefreshFromClientSync,"
|
||||
# "Client::Sync::eds_contact::testRefreshFromClientSemantic,"
|
||||
# "Client::Sync::eds_contact::testDeleteAllRefresh,"
|
||||
# "Client::Sync::eds_contact::testOneWayFromServer,"
|
||||
"Client::Sync::eds_event::testRefreshFromClientSync,"
|
||||
"Client::Sync::eds_event::testRefreshFromClientSemantic,"
|
||||
"Client::Sync::eds_event::testOneWayFromServer,"
|
||||
|
|
|
@ -421,15 +421,11 @@ sub NormalizeItem {
|
|||
|
||||
if ($synthesis) {
|
||||
# does not preserve certain properties
|
||||
s/^(FN|BDAY|X-MOZILLA-HTML|X-EVOLUTION-FILE-AS|X-AIM|NICKNAME|UID|PHOTO|CALURI|SEQUENCE|TRANSP|ORGANIZER)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
s/^(FN|BDAY|X-MOZILLA-HTML|X-EVOLUTION-FILE-AS|X-AIM|NICKNAME|UID|PHOTO|CALURI|SEQUENCE|TRANSP|ORGANIZER|ROLE|FBURL|X-ANNIVERSARY|X-ASSISTANT|X-EVOLUTION-BLOG-URL|X-EVOLUTION-VIDEO-URL|X-GADUGADU|X-GROUPWISE|X-ICQ|X-JABBER|X-MANAGER|X-MSN|X-SIP|X-SKYPE|X-SPOUSE|X-YAHOO)(;[^:;\n]*)*:.*\r?\n?//gm;
|
||||
# default ADR is HOME
|
||||
s/^ADR;TYPE=HOME/ADR/gm;
|
||||
# only some parts of N are preserved
|
||||
s/^N((?:;[^;:]*)*)\:(.*)/@_ = split(\/(?<!\\);\/, $2); "N$1:$_[0];" . ($_[1] || "") . ";;" . ($_[3] || "")/gme;
|
||||
# this vcard contains too many ADR and PHONE entries - ignore it
|
||||
if (/This is a test case which uses almost all Evolution fields/) {
|
||||
next;
|
||||
}
|
||||
# breaks lines at semicolons, which adds white space
|
||||
while( s/^ADR:(.*); +/ADR:$1;/gm ) {}
|
||||
# no attributes stored for ATTENDEEs
|
||||
|
|
|
@ -542,3 +542,87 @@
|
|||
fun:smlProcessData
|
||||
}
|
||||
|
||||
# ==19808== Invalid read of size 4
|
||||
# ==19808== at 0x106E4E9A: asn1_der_coding (in /usr/lib/x86_64-linux-gnu/libtasn1.so.3.1.11)
|
||||
# ==19808== by 0xD37A2F8: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD35D754: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD35D995: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD360442: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3537EC: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3505DF: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3506D4: gnutls_handshake (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0x1473F1A8: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x14740D22: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x5B9C6F0: soup_socket_write (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x5B8BEDA: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x5B8C81D: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x6762E7D: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x67748D6: ??? (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x677DD04: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x677DED2: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x5B9A1AD: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x1473EC0F: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x6DF64A2: g_main_context_dispatch (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x6DF6C7F: ??? (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x6DF72F1: g_main_loop_run (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x7240A8: SyncEvo::SoupTransportAgent::wait(bool) (SoupTransportAgent.cpp:177)
|
||||
# ==19808== by 0x6B6E51: SyncEvo::SyncContext::doSync() (SyncContext.cpp:3597)
|
||||
# ==19808== by 0x6BD0B4: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2904)
|
||||
# ==19808== by 0x4F6521: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:472)
|
||||
# ==19808== by 0x511D6B: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3959)
|
||||
# ==19808== by 0x5C0BDF: SyncEvo::SyncTests::testTwoWaySync() (ClientTest.h:688)
|
||||
# ==19808== by 0x610F749: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==19808== by 0x6102C83: CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==19808== Address 0x10fbcaf4 is 20 bytes inside a block of size 22 alloc'd
|
||||
# ==19808== at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
# ==19808== by 0x106E4E7B: asn1_der_coding (in /usr/lib/x86_64-linux-gnu/libtasn1.so.3.1.11)
|
||||
# ==19808== by 0xD37A2F8: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD35D754: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD35D995: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD360442: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3537EC: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3505DF: ??? (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0xD3506D4: gnutls_handshake (in /usr/lib/libgnutls.so.26.16.14)
|
||||
# ==19808== by 0x1473F1A8: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x14740D22: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x5B9C6F0: soup_socket_write (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x5B8BEDA: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x5B8C81D: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x6762E7D: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x67748D6: ??? (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x677DD04: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x677DED2: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x5B9A1AD: ??? (in /usr/lib/libsoup-2.4.so.1.4.0)
|
||||
# ==19808== by 0x1473EC0F: ??? (in /usr/lib/gio/modules/libgiognutls.so)
|
||||
# ==19808== by 0x6DF64A2: g_main_context_dispatch (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x6DF6C7F: ??? (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x6DF72F1: g_main_loop_run (in /lib/libglib-2.0.so.0.2800.6)
|
||||
# ==19808== by 0x7240A8: SyncEvo::SoupTransportAgent::wait(bool) (SoupTransportAgent.cpp:177)
|
||||
# ==19808== by 0x6B6E51: SyncEvo::SyncContext::doSync() (SyncContext.cpp:3597)
|
||||
# ==19808== by 0x6BD0B4: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) (SyncContext.cpp:2904)
|
||||
# ==19808== by 0x4F6521: SyncEvo::TestEvolution::doSync(int const*, std::string const&, SyncEvo::SyncOptions const&) (client-test-app.cpp:472)
|
||||
# ==19808== by 0x511D6B: SyncEvo::SyncTests::doSync(SyncEvo::SyncOptions const&) (ClientTest.cpp:3959)
|
||||
# ==19808== by 0x5C0BDF: SyncEvo::SyncTests::testTwoWaySync() (ClientTest.h:688)
|
||||
# ==19808== by 0x610F749: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
|
||||
# ==19808==
|
||||
{
|
||||
glib-networking 2.28.7 + gnutls 2.10.5-3 + Google: ASN buffer
|
||||
Memcheck:Addr4
|
||||
fun:asn1_der_coding
|
||||
...
|
||||
obj:*libgiognutls.so
|
||||
}
|
||||
{
|
||||
gnutls + libneon: ASN buffer
|
||||
Memcheck:Addr4
|
||||
fun:asn1_der_coding
|
||||
...
|
||||
obj:*libneon*
|
||||
}
|
||||
{
|
||||
gnutls certificate: ASN buffer
|
||||
Memcheck:Addr4
|
||||
fun:asn1_der_coding
|
||||
...
|
||||
fun:gnutls_certificate_set_x509_trust_file
|
||||
}
|
|
@ -33,6 +33,7 @@ import dbus.service
|
|||
import gobject
|
||||
import sys
|
||||
import re
|
||||
import atexit
|
||||
|
||||
# introduced in python-gobject 2.16, not available
|
||||
# on all Linux distros => make it optional
|
||||
|
@ -44,9 +45,6 @@ except ImportError:
|
|||
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
bus = dbus.SessionBus()
|
||||
loop = gobject.MainLoop()
|
||||
|
||||
debugger = "" # "gdb"
|
||||
server = ["syncevo-dbus-server"]
|
||||
monitor = ["dbus-monitor"]
|
||||
|
@ -54,6 +52,50 @@ monitor = ["dbus-monitor"]
|
|||
xdg_root = "temp-test-dbus"
|
||||
configName = "dbus_unittest"
|
||||
|
||||
def GrepNotifications(dbuslog):
|
||||
'''finds all Notify calls and returns their parameters as list of line lists'''
|
||||
return re.findall(r'^method call .* dest=.* .*interface=org.freedesktop.Notifications; member=Notify\n((?:^ .*\n)*)',
|
||||
dbuslog,
|
||||
re.MULTILINE)
|
||||
|
||||
# See notification-daemon.py for a stand-alone version.
|
||||
#
|
||||
# Embedded here to avoid issues with setting up the environment
|
||||
# in such a way that the stand-alone version can be run
|
||||
# properly.
|
||||
class Notifications (dbus.service.Object):
|
||||
'''fake org.freedesktop.Notifications implementation,'''
|
||||
'''used when there is none already registered on the session bus'''
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='', out_signature='ssss')
|
||||
def GetServerInformation(self):
|
||||
return ('test-dbus', 'SyncEvolution', '0.1', '1.1')
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='', out_signature='as')
|
||||
def GetCapabilities(self):
|
||||
return ['actions', 'body', 'body-hyperlinks', 'body-markup', 'icon-static', 'sound']
|
||||
|
||||
@dbus.service.method(dbus_interface='org.freedesktop.Notifications', in_signature='susssasa{sv}i', out_signature='u')
|
||||
def Notify(self, app, replaces, icon, summary, body, actions, hints, expire):
|
||||
return random.randint(1,100)
|
||||
|
||||
# fork before connecting to the D-Bus daemon
|
||||
child = os.fork()
|
||||
if child == 0:
|
||||
bus = dbus.SessionBus()
|
||||
loop = gobject.MainLoop()
|
||||
name = dbus.service.BusName("org.freedesktop.Notifications", bus)
|
||||
# start dummy notification daemon, if possible;
|
||||
# if it fails, ignore (probably already one running)
|
||||
notifications = Notifications(bus, "/org/freedesktop/Notifications")
|
||||
loop.run()
|
||||
sys.exit(0)
|
||||
|
||||
# testing continues in parent process
|
||||
atexit.register(os.kill, child, 9)
|
||||
bus = dbus.SessionBus()
|
||||
loop = gobject.MainLoop()
|
||||
|
||||
def property(key, value):
|
||||
"""Function decorator which sets an arbitrary property of a test.
|
||||
Use like this:
|
||||
|
@ -313,6 +355,10 @@ class DBusUtil(Timeout):
|
|||
# and increase log level
|
||||
env["SYNCEVOLUTION_DEBUG"] = "1"
|
||||
|
||||
# can be set by a test to run additional tests on the content
|
||||
# of the D-Bus log
|
||||
self.runTestDBusCheck = None
|
||||
|
||||
# testAutoSyncFailure (__main__.TestSessionAPIsDummy) => testAutoSyncFailure_TestSessionAPIsDummy
|
||||
testname = str(self).replace(" ", "_").replace("__main__.", "").replace("(", "").replace(")", "")
|
||||
dbuslog = testname + ".dbus.log"
|
||||
|
@ -407,6 +453,13 @@ class DBusUtil(Timeout):
|
|||
monitorout = open(dbuslog).read()
|
||||
report = "\n\nD-Bus traffic:\n%s\n\nserver output:\n%s\n" % \
|
||||
(monitorout, serverout)
|
||||
if self.runTestDBusCheck:
|
||||
try:
|
||||
self.runTestDBusCheck(self, monitorout)
|
||||
except:
|
||||
# only append report if not part of some other error below
|
||||
result.errors.append((self,
|
||||
"D-Bus log failed check: %s\n%s" % (sys.exc_info()[1], (not hasfailed and report) or "")))
|
||||
if DBusUtil.pserver.returncode and DBusUtil.pserver.returncode != -15:
|
||||
# create a new failure specifically for the server
|
||||
result.errors.append((self,
|
||||
|
@ -1912,11 +1965,11 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
|
|||
self.failUnlessEqual(self.lastState, "done")
|
||||
|
||||
@timeout(60)
|
||||
def testAutoSyncFailure(self):
|
||||
"""TestSessionAPIsDummy.testAutoSyncFailure - test that auto-sync is triggered, fails here"""
|
||||
def testAutoSyncNetworkFailure(self):
|
||||
"""TestSessionAPIsDummy.testAutoSyncNetworkFailure - test that auto-sync is triggered, fails due to (temporary?!) network error here"""
|
||||
self.setupConfig()
|
||||
# enable auto-sync
|
||||
config = self.config
|
||||
config = copy.deepcopy(self.config)
|
||||
# Note that writing this config will modify the host's keyring!
|
||||
# Use a syncURL that is unlikely to conflict with the host
|
||||
# or any other D-Bus test.
|
||||
|
@ -1980,12 +2033,23 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
|
|||
self.failUnless(delta < 13)
|
||||
self.failUnless(delta > 7)
|
||||
|
||||
# check that org.freedesktop.Notifications.Notify was not called
|
||||
# (network errors are considered temporary, can't tell in this case
|
||||
# that the name lookup error is permanent)
|
||||
def checkDBusLog(self, content):
|
||||
notifications = GrepNotifications(content)
|
||||
self.failUnlessEqual(notifications,
|
||||
[])
|
||||
|
||||
# done as part of post-processing in runTest()
|
||||
self.runTestDBusCheck = checkDBusLog
|
||||
|
||||
@timeout(60)
|
||||
def testAutoSyncLocal(self):
|
||||
"""TestSessionAPIsDummy.testAutoSyncLocal - test that auto-sync is triggered for local sync"""
|
||||
def testAutoSyncLocalConfigError(self):
|
||||
"""TestSessionAPIsDummy.testAutoSyncLocalConfigError - test that auto-sync is triggered for local sync, fails due to permanent config error here"""
|
||||
self.setupConfig()
|
||||
# enable auto-sync
|
||||
config = self.config
|
||||
config = copy.deepcopy(self.config)
|
||||
config[""]["syncURL"] = "local://@foobar" # will fail
|
||||
config[""]["autoSync"] = "1"
|
||||
config[""]["autoSyncDelay"] = "0"
|
||||
|
@ -2028,6 +2092,128 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
|
|||
flags = session.GetFlags()
|
||||
self.failUnlessEqual(flags, [])
|
||||
|
||||
# check that org.freedesktop.Notifications.Notify was called
|
||||
# once to report the failed attempt to start the sync
|
||||
def checkDBusLog(self, content):
|
||||
notifications = GrepNotifications(content)
|
||||
self.failUnlessEqual(notifications,
|
||||
[' string "SyncEvolution"\n'
|
||||
' uint32 0\n'
|
||||
' string ""\n'
|
||||
' string "Sync problem."\n'
|
||||
' string "Sorry, there\'s a problem with your sync that you need to attend to."\n'
|
||||
' array [\n'
|
||||
' string "view"\n'
|
||||
' string "View"\n'
|
||||
' string "default"\n'
|
||||
' string "Dismiss"\n'
|
||||
' ]\n'
|
||||
' array [\n'
|
||||
' ]\n'
|
||||
' int32 -1\n'])
|
||||
|
||||
# done as part of post-processing in runTest()
|
||||
self.runTestDBusCheck = checkDBusLog
|
||||
|
||||
@timeout(60)
|
||||
def testAutoSyncLocalSuccess(self):
|
||||
"""TestSessionAPIsDummy.testAutoSyncLocalSuccess - test that auto-sync is done successfully for local sync between file backends"""
|
||||
# create @foobar config
|
||||
self.session.Detach()
|
||||
self.setUpSession("target-config@foobar")
|
||||
config = copy.deepcopy(self.config)
|
||||
config[""]["remoteDeviceId"] = "foo"
|
||||
config[""]["deviceId"] = "bar"
|
||||
for i in ("addressbook", "calendar", "todo", "memo"):
|
||||
source = config["source/" + i]
|
||||
source["database"] = source["database"] + ".server"
|
||||
self.session.SetConfig(False, False, config, utf8_strings=True)
|
||||
self.session.Detach()
|
||||
|
||||
# create dummy-test@default auto-sync config
|
||||
self.setUpSession("dummy-test")
|
||||
config = copy.deepcopy(self.config)
|
||||
config[""]["syncURL"] = "local://@foobar"
|
||||
config[""]["PeerIsClient"] = "1"
|
||||
config[""]["autoSync"] = "1"
|
||||
config[""]["autoSyncDelay"] = "0"
|
||||
config[""]["autoSyncInterval"] = "10s"
|
||||
config["source/addressbook"]["uri"] = "addressbook"
|
||||
self.session.SetConfig(False, False, config, utf8_strings=True)
|
||||
|
||||
def session_ready(object, ready):
|
||||
if self.running and object != self.sessionpath and \
|
||||
(self.auto_sync_session_path == None and ready or \
|
||||
self.auto_sync_session_path == object):
|
||||
self.auto_sync_session_path = object
|
||||
DBusUtil.quit_events.append("session " + object + (ready and " ready" or " done"))
|
||||
loop.quit()
|
||||
|
||||
signal = bus.add_signal_receiver(session_ready,
|
||||
'SessionChanged',
|
||||
'org.syncevolution.Server',
|
||||
self.server.bus_name,
|
||||
None,
|
||||
byte_arrays=True,
|
||||
utf8_strings=True)
|
||||
|
||||
# shut down current session, will allow auto-sync
|
||||
self.session.Detach()
|
||||
|
||||
# wait for start and end of auto-sync session
|
||||
loop.run()
|
||||
loop.run()
|
||||
self.failUnlessEqual(DBusUtil.quit_events, ["session " + self.auto_sync_session_path + " ready",
|
||||
"session " + self.auto_sync_session_path + " done"])
|
||||
session = dbus.Interface(bus.get_object(self.server.bus_name,
|
||||
self.auto_sync_session_path),
|
||||
'org.syncevolution.Session')
|
||||
reports = session.GetReports(0, 100, utf8_strings=True)
|
||||
self.failUnlessEqual(len(reports), 1)
|
||||
self.failUnlessEqual(reports[0]["status"], "200")
|
||||
name = session.GetConfigName()
|
||||
self.failUnlessEqual(name, "dummy-test")
|
||||
flags = session.GetFlags()
|
||||
self.failUnlessEqual(flags, [])
|
||||
|
||||
# check that org.freedesktop.Notifications.Notify was called
|
||||
# when starting and completing the sync
|
||||
def checkDBusLog(self, content):
|
||||
notifications = GrepNotifications(content)
|
||||
self.failUnlessEqual(notifications,
|
||||
[' string "SyncEvolution"\n'
|
||||
' uint32 0\n'
|
||||
' string ""\n'
|
||||
' string "dummy-test is syncing"\n'
|
||||
' string "We have just started to sync your computer with the dummy-test sync service."\n'
|
||||
' array [\n'
|
||||
' string "view"\n'
|
||||
' string "View"\n'
|
||||
' string "default"\n'
|
||||
' string "Dismiss"\n'
|
||||
' ]\n'
|
||||
' array [\n'
|
||||
' ]\n'
|
||||
' int32 -1\n',
|
||||
|
||||
' string "SyncEvolution"\n'
|
||||
' uint32 0\n'
|
||||
' string ""\n'
|
||||
' string "dummy-test sync complete"\n'
|
||||
' string "We have just finished syncing your computer with the dummy-test sync service."\n'
|
||||
' array [\n'
|
||||
' string "view"\n'
|
||||
' string "View"\n'
|
||||
' string "default"\n'
|
||||
' string "Dismiss"\n'
|
||||
' ]\n'
|
||||
' array [\n'
|
||||
' ]\n'
|
||||
' int32 -1\n'])
|
||||
|
||||
# done as part of post-processing in runTest()
|
||||
self.runTestDBusCheck = checkDBusLog
|
||||
|
||||
|
||||
class TestSessionAPIsReal(unittest.TestCase, DBusUtil):
|
||||
""" This class is used to test those unit tests of session APIs, depending on doing sync.
|
||||
|
@ -2302,6 +2488,7 @@ class TestConnection(unittest.TestCase, DBusUtil):
|
|||
"connection " + conpath + " got final reply",
|
||||
"session done"])
|
||||
|
||||
@timeout(20)
|
||||
def testCredentialsRight(self):
|
||||
"""TestConnection.testCredentialsRight - send correct credentials"""
|
||||
self.setupConfig()
|
||||
|
|
|
@ -3,7 +3,7 @@ VERSION:3.0
|
|||
NICKNAME:user17
|
||||
NOTE:triggers parser bug in Funambol 3.0: trailing = is mistaken for soft line break=
|
||||
FN:parserbug=
|
||||
N:parserbug=
|
||||
N:parserbug=;;;;
|
||||
X-EVOLUTION-FILE-AS:parserbug=
|
||||
END:VCARD
|
||||
|
||||
|
@ -12,7 +12,7 @@ VERSION:3.0
|
|||
NICKNAME:user16
|
||||
NOTE:test case with empty email
|
||||
FN:incomplete
|
||||
N:incomplete
|
||||
N:incomplete;;;;
|
||||
EMAIL:
|
||||
X-EVOLUTION-FILE-AS:incomplete
|
||||
END:VCARD
|
||||
|
@ -162,7 +162,7 @@ X-EVOLUTION-MANAGER:John Doe Senior
|
|||
X-EVOLUTION-ASSISTANT:John Doe Junior
|
||||
NICKNAME:user1
|
||||
BDAY:2006-01-08
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test; never sent to a peer
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
|
||||
X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
|
||||
X-EVOLUTION-ANNIVERSARY:2006-01-09
|
||||
X-EVOLUTION-SPOUSE:Joan Doe
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
@@ -147,7 +147,7 @@
|
||||
FBURL:
|
||||
X-EVOLUTION-VIDEO-URL:
|
||||
X-MOZILLA-HTML:FALSE
|
||||
-ADR;TYPE=HOME:;Address Line 2\nAddress Line 3;Address Line 1;;;;
|
||||
+ADR;TYPE=HOME:;Address Line 2 Address Line 3;Address Line 1;;;;
|
||||
LABEL;TYPE=HOME:Address Line 1\nAddress Line 2\nAddress Line 3
|
||||
UID:pas-id-43C15DFB000001AB
|
||||
END:VCARD
|
||||
@@ -163,7 +163,7 @@
|
||||
NICKNAME:user1
|
||||
BDAY:2006-01-08
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
|
||||
-X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
|
||||
+X-TEST;PARAMETER1=nonquoted:Content with\nMultiple\nText lines\nand national chars: äöü
|
||||
X-EVOLUTION-ANNIVERSARY:2006-01-09
|
||||
X-EVOLUTION-SPOUSE:Joan Doe
|
||||
NOTE:This is a test case which uses almost all Evolution fields.
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
@@ -4,6 +4,7 @@
|
||||
NOTE:triggers parser bug in Funambol 3.0: trailing = is mistaken for soft line break=
|
||||
FN:parserbug=
|
||||
N:parserbug=
|
||||
N:parserbug=;;;;
|
||||
+URL:http://john.doe.com
|
||||
X-EVOLUTION-FILE-AS:parserbug=
|
||||
END:VCARD
|
||||
|
||||
@@ -14,6 +15,7 @@
|
||||
FN:incomplete
|
||||
N:incomplete
|
||||
N:incomplete;;;;
|
||||
EMAIL:
|
||||
+URL:http://john.doe.com
|
||||
X-EVOLUTION-FILE-AS:incomplete
|
||||
|
@ -70,13 +70,19 @@
|
|||
X-EVOLUTION-FILE-AS:characters\, special
|
||||
X-EVOLUTION-BLOG-URL:
|
||||
CALURI:
|
||||
@@ -161,7 +170,7 @@
|
||||
@@ -156,12 +165,12 @@
|
||||
VERSION:3.0
|
||||
URL:http://john.doe.com
|
||||
TITLE:Senior Tester
|
||||
-ORG:Test Inc.;Testing;test#1
|
||||
+ORG:Test Inc.
|
||||
ROLE:professional test case
|
||||
X-EVOLUTION-MANAGER:John Doe Senior
|
||||
X-EVOLUTION-ASSISTANT:John Doe Junior
|
||||
NICKNAME:user1
|
||||
-BDAY:2006-01-08
|
||||
+BDAY:2007-03-01
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test; never sent to a peer
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
|
||||
X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
|
||||
X-EVOLUTION-ANNIVERSARY:2006-01-09
|
||||
@@ -184,7 +193,6 @@
|
||||
|
|
26
test/testcases/eds_contact.vcf.synthesis.tem.patch
Normal file
26
test/testcases/eds_contact.vcf.synthesis.tem.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
@@ -156,14 +156,14 @@
|
||||
VERSION:3.0
|
||||
URL:http://john.doe.com
|
||||
TITLE:Senior Tester
|
||||
-ORG:Test Inc.;Testing;test#1
|
||||
+ORG:Test Inc.;Testing
|
||||
ROLE:professional test case
|
||||
X-EVOLUTION-MANAGER:John Doe Senior
|
||||
X-EVOLUTION-ASSISTANT:John Doe Junior
|
||||
NICKNAME:user1
|
||||
BDAY:2006-01-08
|
||||
X-FOOBAR-EXTENSION;X-FOOBAR-PARAMETER=foobar:has to be stored internally by engine and preserved in testExtensions test\; never sent to a peer
|
||||
-X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Content with\nMultiple\nText lines\nand national chars: äöü
|
||||
+X-TEST;PARAMETER1=nonquoted;PARAMETER2="quoted because of spaces":Text with\nMultiple\nText lines\nand national chars: äöü
|
||||
X-EVOLUTION-ANNIVERSARY:2006-01-09
|
||||
X-EVOLUTION-SPOUSE:Joan Doe
|
||||
NOTE:This is a test case which uses almost all Evolution fields.
|
||||
@@ -198,8 +198,6 @@
|
||||
TEL;TYPE=WORK;TYPE=FAX;X-EVOLUTION-UI-SLOT=4:businessfax 4
|
||||
TEL;TYPE=HOME;TYPE=FAX;X-EVOLUTION-UI-SLOT=5:homefax 5
|
||||
TEL;TYPE=PAGER;X-EVOLUTION-UI-SLOT=6:pager 6
|
||||
-TEL;TYPE=CAR;X-EVOLUTION-UI-SLOT=7:car 7
|
||||
-TEL;TYPE=PREF;X-EVOLUTION-UI-SLOT=8:primary 8
|
||||
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
|
||||
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
|
||||
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
|
|
@ -150,7 +150,7 @@
|
|||
X-AIM;X-EVOLUTION-UI-SLOT=1:AIM JOHN
|
||||
X-YAHOO;X-EVOLUTION-UI-SLOT=2:YAHOO JDOE
|
||||
X-ICQ;X-EVOLUTION-UI-SLOT=3:ICQ JD
|
||||
@@ -211,226 +120,3 @@
|
||||
@@ -210,226 +119,3 @@
|
||||
X-SKYPE:SKYPE DOE
|
||||
X-SIP:SIP DOE
|
||||
END:VCARD
|
||||
|
|
|
@ -196,6 +196,7 @@ DESCRIPTION:this is an appointment with plenty of fields set\, and
|
|||
BEGIN:VALARM
|
||||
X-EVOLUTION-ALARM-UID:20060416T204833Z-4250-727-1-85@gollum
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:This is an event reminder
|
||||
TRIGGER;VALUE=DURATION;RELATED=START:-PT1H
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
|
@ -238,7 +239,7 @@ SUMMARY:Recurring
|
|||
DESCRIPTION:recurs each Sonday\, 10 times
|
||||
CLASS:PUBLIC
|
||||
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T090000Z
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193241
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
@ -255,13 +256,108 @@ TRANSP:OPAQUE
|
|||
SEQUENCE:7
|
||||
SUMMARY:Recurring: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID:20080413T090000Z
|
||||
DESCRIPTION:second instance modified
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080413T100000Z
|
||||
DTEND:20080413T103000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring: Modified II
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID:20080420T090000Z
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-XX@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080406T090000Z
|
||||
DTEND:20080406T093000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
SUMMARY:Recurring 2
|
||||
DESCRIPTION:recurs each Sunday\, 10 times
|
||||
CLASS:PUBLIC
|
||||
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T090000Z
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193241
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-XX@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080413T090000Z
|
||||
DTEND:20080413T093000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring 2: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID:20080413T090000Z
|
||||
DESCRIPTION:second instance modified\, single detached recurrence
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-YY@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080413T090000Z
|
||||
DTEND:20080413T093000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring 3: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID:20080413T090000Z
|
||||
DESCRIPTION:second instance modified
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-YY@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080413T100000Z
|
||||
DTEND:20080413T103000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring 3: Modified II
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID:20080420T090000Z
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
UID:20060416T204647Z-4272-727-1-248@gollum
|
||||
DTSTAMP:20060416T204647Z
|
||||
DTSTART:20060406T183000Z
|
||||
@@ -215,10 +104,6 @@
|
||||
@@ -216,10 +105,6 @@
|
||||
SUMMARY:meeting invitation
|
||||
CLASS:PUBLIC
|
||||
ORGANIZER;CN=Patrick Ohly:MAILTO:Patrick.Ohly@gmx.de
|
||||
|
@ -134,8 +134,8 @@
|
|||
CREATED:20060416T205003Z
|
||||
LAST-MODIFIED:20060416T205003Z
|
||||
END:VEVENT
|
||||
@@ -261,37 +146,3 @@
|
||||
DESCRIPTION:second instance modified
|
||||
@@ -357,37 +242,3 @@
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
-
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
CREATED:20060416T204808Z
|
||||
LAST-MODIFIED:20060416T204808Z
|
||||
END:VEVENT
|
||||
@@ -214,7 +196,6 @@
|
||||
@@ -215,7 +197,6 @@
|
||||
CATEGORIES:BUSINESS,MEETING
|
||||
SUMMARY:meeting invitation
|
||||
CLASS:PUBLIC
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
CREATED:20060416T204808Z
|
||||
LAST-MODIFIED:20060416T204808Z
|
||||
END:VEVENT
|
||||
@@ -196,7 +196,7 @@
|
||||
@@ -196,8 +196,7 @@
|
||||
BEGIN:VALARM
|
||||
X-EVOLUTION-ALARM-UID:20060416T204833Z-4250-727-1-85@gollum
|
||||
ACTION:DISPLAY
|
||||
-DESCRIPTION:This is an event reminder
|
||||
-TRIGGER;VALUE=DURATION;RELATED=START:-PT1H
|
||||
+TRIGGER;VALUE=DATE-TIME:20060406T180000Z
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -266,7 +266,7 @@
|
||||
@@ -362,7 +361,7 @@
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
|
@ -36,7 +37,7 @@
|
|||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
@@ -285,8 +285,8 @@
|
||||
@@ -381,8 +380,8 @@
|
||||
BEGIN:VEVENT
|
||||
UID:20060416T205224Z-4272-727-1-251@gollum
|
||||
DTSTAMP:20060416T205224Z
|
||||
|
|
|
@ -198,15 +198,7 @@
|
|||
TRANSP:TRANSPARENT
|
||||
SEQUENCE:4
|
||||
SUMMARY:all fields
|
||||
@@ -196,6 +304,7 @@
|
||||
BEGIN:VALARM
|
||||
X-EVOLUTION-ALARM-UID:20060416T204833Z-4250-727-1-85@gollum
|
||||
ACTION:DISPLAY
|
||||
+DESCRIPTION:This is an event reminder
|
||||
TRIGGER;VALUE=DURATION;RELATED=START:-PT1H
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
@@ -204,34 +313,29 @@
|
||||
@@ -205,34 +313,29 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
|
@ -261,7 +253,7 @@
|
|||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
SUMMARY:Recurring
|
||||
@@ -246,52 +350,36 @@
|
||||
@@ -247,18 +350,36 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
|
@ -294,13 +286,206 @@
|
|||
SEQUENCE:7
|
||||
SUMMARY:Recurring: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080413T090000Z
|
||||
+RECURRENCE-ID;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T110000
|
||||
DESCRIPTION:second instance modified
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -266,18 +387,36 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
+BEGIN:VTIMEZONE
|
||||
+TZID:/softwarestudio.org/Olson_20011030_5/Europe/Berlin
|
||||
+X-LIC-LOCATION:Europe/Berlin
|
||||
+BEGIN:DAYLIGHT
|
||||
+TZOFFSETFROM:+0100
|
||||
+TZOFFSETTO:+0200
|
||||
+TZNAME:CEST
|
||||
+DTSTART:19700329T020000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
|
||||
+END:DAYLIGHT
|
||||
+BEGIN:STANDARD
|
||||
+TZOFFSETFROM:+0200
|
||||
+TZOFFSETTO:+0100
|
||||
+TZNAME:CET
|
||||
+DTSTART:19701025T030000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
|
||||
+END:STANDARD
|
||||
+END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080413T100000Z
|
||||
-DTEND:20080413T103000Z
|
||||
+DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T120000
|
||||
+DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T123000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring: Modified II
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080420T090000Z
|
||||
+RECURRENCE-ID;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080420T110000
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -285,11 +424,29 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
+BEGIN:VTIMEZONE
|
||||
+TZID:/softwarestudio.org/Olson_20011030_5/Europe/Berlin
|
||||
+X-LIC-LOCATION:Europe/Berlin
|
||||
+BEGIN:DAYLIGHT
|
||||
+TZOFFSETFROM:+0100
|
||||
+TZOFFSETTO:+0200
|
||||
+TZNAME:CEST
|
||||
+DTSTART:19700329T020000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
|
||||
+END:DAYLIGHT
|
||||
+BEGIN:STANDARD
|
||||
+TZOFFSETFROM:+0200
|
||||
+TZOFFSETTO:+0100
|
||||
+TZNAME:CET
|
||||
+DTSTART:19701025T030000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
|
||||
+END:STANDARD
|
||||
+END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-XX@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080406T090000Z
|
||||
-DTEND:20080406T093000Z
|
||||
+DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080406T110000
|
||||
+DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080406T113000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
SUMMARY:Recurring 2
|
||||
@@ -304,18 +461,36 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
+BEGIN:VTIMEZONE
|
||||
+TZID:/softwarestudio.org/Olson_20011030_5/Europe/Berlin
|
||||
+X-LIC-LOCATION:Europe/Berlin
|
||||
+BEGIN:DAYLIGHT
|
||||
+TZOFFSETFROM:+0100
|
||||
+TZOFFSETTO:+0200
|
||||
+TZNAME:CEST
|
||||
+DTSTART:19700329T020000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
|
||||
+END:DAYLIGHT
|
||||
+BEGIN:STANDARD
|
||||
+TZOFFSETFROM:+0200
|
||||
+TZOFFSETTO:+0100
|
||||
+TZNAME:CET
|
||||
+DTSTART:19701025T030000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
|
||||
+END:STANDARD
|
||||
+END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-XX@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080413T090000Z
|
||||
-DTEND:20080413T093000Z
|
||||
+DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T110000
|
||||
+DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T113000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
-SUMMARY:Recurring 2: Modified
|
||||
+SUMMARY:Recurring: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080413T090000Z
|
||||
+RECURRENCE-ID;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T110000
|
||||
DESCRIPTION:second instance modified\, single detached recurrence
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -323,18 +498,36 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
+BEGIN:VTIMEZONE
|
||||
+TZID:/softwarestudio.org/Olson_20011030_5/Europe/Berlin
|
||||
+X-LIC-LOCATION:Europe/Berlin
|
||||
+BEGIN:DAYLIGHT
|
||||
+TZOFFSETFROM:+0100
|
||||
+TZOFFSETTO:+0200
|
||||
+TZNAME:CEST
|
||||
+DTSTART:19700329T020000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
|
||||
+END:DAYLIGHT
|
||||
+BEGIN:STANDARD
|
||||
+TZOFFSETFROM:+0200
|
||||
+TZOFFSETTO:+0100
|
||||
+TZNAME:CET
|
||||
+DTSTART:19701025T030000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
|
||||
+END:STANDARD
|
||||
+END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-YY@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080413T090000Z
|
||||
-DTEND:20080413T093000Z
|
||||
+DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T110000
|
||||
+DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T113000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring 3: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080413T090000Z
|
||||
+RECURRENCE-ID;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T110000
|
||||
DESCRIPTION:second instance modified
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -342,52 +535,36 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
+BEGIN:VTIMEZONE
|
||||
+TZID:/softwarestudio.org/Olson_20011030_5/Europe/Berlin
|
||||
+X-LIC-LOCATION:Europe/Berlin
|
||||
+BEGIN:DAYLIGHT
|
||||
+TZOFFSETFROM:+0100
|
||||
+TZOFFSETTO:+0200
|
||||
+TZNAME:CEST
|
||||
+DTSTART:19700329T020000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
|
||||
+END:DAYLIGHT
|
||||
+BEGIN:STANDARD
|
||||
+TZOFFSETFROM:+0200
|
||||
+TZOFFSETTO:+0100
|
||||
+TZNAME:CET
|
||||
+DTSTART:19701025T030000
|
||||
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
|
||||
+END:STANDARD
|
||||
+END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-YY@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080413T100000Z
|
||||
-DTEND:20080413T103000Z
|
||||
+DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T120000
|
||||
+DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080413T123000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:7
|
||||
SUMMARY:Recurring 3: Modified II
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080420T090000Z
|
||||
+RECURRENCE-ID;TZID=/softwarestudio.org/Olson_20011030_5/Europe/Berlin:20080420T110000
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
-
|
||||
-BEGIN:VCALENDAR
|
||||
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
^\npercent %\ntilde ~\ntick `\nbacktick `\ndouble quotation - not tested
|
||||
because Evolution encodes it incorrectly\nsingle quotation '\ncolon :\n
|
||||
semicolon \;\ncomma \,\n
|
||||
@@ -211,7 +191,7 @@
|
||||
@@ -212,7 +192,7 @@
|
||||
DTEND:20060406T200000Z
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
|
@ -138,7 +138,7 @@
|
|||
SUMMARY:meeting invitation
|
||||
CLASS:PUBLIC
|
||||
ORGANIZER;CN=Patrick Ohly:MAILTO:Patrick.Ohly@gmx.de
|
||||
@@ -230,14 +210,14 @@
|
||||
@@ -231,14 +211,16 @@
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
|
@ -153,27 +153,49 @@
|
|||
CLASS:PUBLIC
|
||||
-RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T090000Z
|
||||
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T110000
|
||||
CREATED:20080407T193241
|
||||
+EXDATE;VALUE=DATE:20080413
|
||||
+EXDATE;VALUE=DATE:20080420
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193241
|
||||
END:VEVENT
|
||||
@@ -247,7 +227,7 @@
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
-UID:20080407T193125Z-19554-727-1-50@gollum
|
||||
+UID:20080407T193125Z-19554-727-1-50@gollum-mod
|
||||
DTSTAMP:20080407T193125Z
|
||||
DTSTART:20080413T090000Z
|
||||
DTEND:20080413T093000Z
|
||||
@@ -257,7 +237,6 @@
|
||||
@@ -258,7 +240,7 @@
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080413T090000Z
|
||||
+RECURRENCE-ID:20080413T110000
|
||||
DESCRIPTION:second instance modified
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -265,28 +244,11 @@
|
||||
@@ -277,7 +259,7 @@
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
-RECURRENCE-ID:20080420T090000Z
|
||||
+RECURRENCE-ID:20080420T110000
|
||||
DESCRIPTION:third instance modified\, different time
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -288,14 +270,15 @@
|
||||
BEGIN:VEVENT
|
||||
UID:20080407T193125Z-19554-727-1-50-XX@gollum
|
||||
DTSTAMP:20080407T193125Z
|
||||
-DTSTART:20080406T090000Z
|
||||
-DTEND:20080406T093000Z
|
||||
+DTSTART:20080406T110000
|
||||
+DTEND:20080406T113000
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:2
|
||||
SUMMARY:Recurring 2
|
||||
DESCRIPTION:recurs each Sunday\, 10 times
|
||||
CLASS:PUBLIC
|
||||
-RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T090000Z
|
||||
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T110000
|
||||
+EXDATE;VALUE=DATE:20080413
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193241
|
||||
END:VEVENT
|
||||
@@ -361,28 +344,11 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
UID:20060406T211449Z-4562-727-1-63@gollum
|
||||
DTSTAMP:20060406T211449Z
|
||||
LAST-MODIFIED:20060416T203532Z
|
||||
@@ -90,25 +70,7 @@
|
||||
@@ -90,59 +70,7 @@
|
||||
CLASS:PUBLIC
|
||||
CREATED:20060416T203924Z
|
||||
LAST-MODIFIED:20060416T203949Z
|
||||
|
@ -56,23 +56,67 @@
|
|||
-RRULE:FREQ=YEARLY;INTERVAL=1;UNTIL=20070406T180000Z
|
||||
-CREATED:20060416T204021Z
|
||||
-LAST-MODIFIED:20060416T204021Z
|
||||
-END:VEVENT
|
||||
-END:VCALENDAR
|
||||
-
|
||||
-BEGIN:VCALENDAR
|
||||
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
-VERSION:2.0
|
||||
-BEGIN:VEVENT
|
||||
-UID:20060416T204026Z-4272-727-1-244@gollum
|
||||
-DTSTAMP:20060416T204026Z
|
||||
-DTSTART;VALUE=DATE:20060406
|
||||
-DTEND;VALUE=DATE:20060407
|
||||
-TRANSP:TRANSPARENT
|
||||
-SEQUENCE:2
|
||||
-SUMMARY:all day event
|
||||
-CLASS:PUBLIC
|
||||
-CREATED:20060416T204042Z
|
||||
-LAST-MODIFIED:20060416T204042Z
|
||||
-END:VEVENT
|
||||
-END:VCALENDAR
|
||||
-
|
||||
-BEGIN:VCALENDAR
|
||||
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
-VERSION:2.0
|
||||
-BEGIN:VEVENT
|
||||
-UID:20060416T204047Z-4272-727-1-245@gollum
|
||||
-DTSTAMP:20060416T204047Z
|
||||
-DTSTART;VALUE=DATE:20060406
|
||||
-DTEND;VALUE=DATE:20060408
|
||||
-TRANSP:TRANSPARENT
|
||||
-SEQUENCE:2
|
||||
-SUMMARY:two day event
|
||||
-CLASS:PUBLIC
|
||||
-CREATED:20060416T204104Z
|
||||
-LAST-MODIFIED:20060416T204104Z
|
||||
+RRULE:FREQ=MONTHLY;BYMONTHDAY=6;INTERVAL=1;UNTIL=20060606T173000Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
@@ -193,11 +155,6 @@
|
||||
@@ -161,8 +89,6 @@
|
||||
Saturday
|
||||
CLASS:PUBLIC
|
||||
RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20060412T183000Z
|
||||
-EXDATE;VALUE=DATE:20060408
|
||||
-EXDATE;VALUE=DATE:20060407
|
||||
CREATED:20060416T204808Z
|
||||
LAST-MODIFIED:20060416T204808Z
|
||||
END:VEVENT
|
||||
@@ -193,12 +119,6 @@
|
||||
^\npercent %\ntilde ~\ntick `\nbacktick `\ndouble quotation - not tested
|
||||
because Evolution encodes it incorrectly\nsingle quotation '\ncolon :\n
|
||||
semicolon \;\ncomma \,\n
|
||||
-BEGIN:VALARM
|
||||
-X-EVOLUTION-ALARM-UID:20060416T204833Z-4250-727-1-85@gollum
|
||||
-ACTION:DISPLAY
|
||||
-DESCRIPTION:This is an event reminder
|
||||
-TRIGGER;VALUE=DURATION;RELATED=START:-PT1H
|
||||
-END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
||||
@@ -265,28 +222,11 @@
|
||||
@@ -361,28 +281,11 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
|
|
|
@ -193,7 +193,7 @@
|
|||
TRANSP:TRANSPARENT
|
||||
SEQUENCE:4
|
||||
SUMMARY:all fields
|
||||
@@ -185,40 +265,43 @@
|
||||
@@ -185,41 +265,43 @@
|
||||
CREATED:20060416T204625Z
|
||||
LAST-MODIFIED:20060416T204833Z
|
||||
DESCRIPTION:this is an appointment with plenty of fields set\, and
|
||||
|
@ -208,6 +208,7 @@
|
|||
-BEGIN:VALARM
|
||||
-X-EVOLUTION-ALARM-UID:20060416T204833Z-4250-727-1-85@gollum
|
||||
-ACTION:DISPLAY
|
||||
-DESCRIPTION:This is an event reminder
|
||||
-TRIGGER;VALUE=DURATION;RELATED=START:-PT1H
|
||||
-END:VALARM
|
||||
+ special attributes...
|
||||
|
|
|
@ -324,7 +324,7 @@ SUMMARY:Recurring
|
|||
DESCRIPTION:recurs each Sonday\, 10 times
|
||||
CLASS:PUBLIC
|
||||
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SU;UNTIL=20080608T090000Z
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193241
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
@ -359,7 +359,7 @@ TRANSP:OPAQUE
|
|||
SEQUENCE:7
|
||||
SUMMARY:Recurring: Modified
|
||||
CLASS:PUBLIC
|
||||
CREATED:20080407T193241
|
||||
CREATED:20080407T193241Z
|
||||
LAST-MODIFIED:20080407T193647
|
||||
RECURRENCE-ID;TZID=Europe/Berlin:20080413T110000
|
||||
DESCRIPTION:second instance modified
|
||||
|
|
|
@ -147,10 +147,12 @@ perl \
|
|||
$LOGFILE
|
||||
SUBRET=$?
|
||||
|
||||
# bad valgrind log result overrides successful completion or being killed by SIGTERM (143) or SIGINT (130)
|
||||
if ( [ $RET -eq 0 ] || [ $RET -eq 130 ] || [ $RET -eq 143 ] ) && [ $SUBRET -ne 0 ]; then
|
||||
# bad valgrind log result always overrides normal completion status:
|
||||
# that way the valgrind errors also show up in the nightly test summary
|
||||
# in the case where some other test already failed
|
||||
if [ $SUBRET -ne 0 ]; then
|
||||
RET=$SUBRET
|
||||
echo valgrindcheck: "$@": log analysis overrides return code with $SUBRET >&2
|
||||
echo valgrindcheck: "$@": log analysis overrides return code $RET with $SUBRET >&2
|
||||
fi
|
||||
rm $LOGFILE
|
||||
|
||||
|
|
Loading…
Reference in a new issue