On current Debian Testing, boost libraries are installed in /usr/lib/<arch>
directories where they are not found by the Boost m4 macros. This breaks the
boost-locale detection because it only tries linking against libs that it
finds in the file system first.
To fix this, at least try linking with -lboost-locale and use that if it
works.
At least on OpenSUSE, ldconfig must be run after installing
SyncEvolution to update the shared library information cache.
Do that automatically as part of the rpm's post and postun steps.
The syncevolution-bundle description was wrong. It incorrectly
used the description of a meta package.
Sometimes, on a more recent Linux distro, the helper is said to terminate
with SIGKILL although we only sent a SIGTERM. Not sure why that happens.
It randomly breaks tests, so let's ignore the unexpected signal. Everything
else seems to work correctly.
When timing out, SyncContext nevertheless sometimes resent a message despite
being close to the final timeout deadline. Relax the math further so that more
time must remain before the deadline when attempting a resend.
The earlier behavior randomly broke some of the resend tests.
When testLocaledPhone was run after testLocale, it used the localed installed
by the earlier test. We must ensure that daemons on the system bus get removed
after each test.
Picking a port dynamically was broken: if 9999 was in use, the test script
connected to the wrong process and then incorrectly continued, instead of
detecting that syncevo-http-server failed. Use the auto-alloc feature
of syncevo-http-server (port == 0) instead and get the actual port
from the output.
Now that we redirect that output into a file, it makes sense to also include
that log in test failure reports.
When an assert triggers, the following code does not get executed.
clang's scan-tool could not detect that because CppUnit's templates
are not annotated with the "noreturn" attribute. We already use
wrappers around CppUnit, so we can fairly easily add a fake "noreturn"
call to exit() to the assertion failure path.
While at it, avoid unnecessary inlining and update the macros to
handle parameters with commans (the necessary brackets were missing).
With this and the preceeding changes, a build with most SyncEvolution features
enabled passes scan-build without errors. There are still errors in
libsynthesis, though. See https://bugs.freedesktop.org/show_bug.cgi?id=73393
clang's scan-tool fails to detect that the variable is bound
to a boost::lambda expression and indeed does get read later on.
Hide the write via ifdefs to suppress the warning when doing
static code analysis.
Control flow analysis from clang's own C++ compiler and clang's
scan-tool come to different results: the compiler fails to detect
that the variable will be initialized in all cases and thus requires
a redundant initialization to avoid an "uninitialized memory read"
error with -Wall, while scan-tool complains about the redundant write.
To satisfy both, avoid the initialization when doing static code analysis.
The intermediate "msg" variable caused a warning from clang's scan-build about
setting but not reading it. To get rid of the warning we are now writing into
the final buffer directly.
From scan-build: size argument is greater than the free space in the
destination buffer, for the line with strncat().
This might be a false positive in scan-build, the size looks right
at first glance. To be on the safe side and get rid of the warning,
allocate one one more byte...
clang's scan-tool complains about keeping a local address stored
in a global structure, the argument description. This is not a real
problem because the structure is not going to be used after leaving
main(), but perhaps it is cleaner nevertheless to allocate the
structure on the stack.
Allow marking methods and functions as "does not return". This may
help static code analysis tools to determine that certain code paths
will not be taken.
The new runtest.py --cppcheck flag can be used in combination with
sources checked out earlier. The source checkout actions then
run cppcheck on each source tree and fail if cppcheck finds any
non-suppressed problems.
A wrapper around cppcheck must be used because --error-exitcode caused
non-zero exit codes also when errors where suppressed, at least in cppcheck
1.61.
We check the SyncEvolution source a bit more thoroughly than the rest because
we can fix or suppress issues inline, which might not be acceptable for
libsynthesis or activesyncd.
The remaining warnings are either not valid or refer to code which
is intentionally broken. Suppress these warnings.
SyncEvolution now passes scanning with cppcheck 1.61 without warnings.
The log file guard instance which should have added a "copy" part to log files
was deleted again before it could have the desired effect. Found by cppcheck
("Instance of 'SyncPrefix' object is destroyed immediately.").
cppcheck warned about this. This wasn't actually a problem (one member
was not used at all, the other was set later), but for the sake of
clean cppcheck scans let's fix it.
When configuring a local sync on the target side, the code in
SyncConfig::getSyncSourceNodes() created redundant ConfigNode instances. This
was pointed out by cppcheck as redundant variable assignments. The code which
created these additional instances may have had side-effects, but it doesn't
look like these were desired and/or relevant.
In this case it is fairly obvious that new_active and old_active
will both be set before use. There is no need for setting old_active
to FALSE. cppcheck warned about this.
cppcheck cannot know that one of the two if checks must succeed
and warns about the case when both are false. This shouldn't
happen, but it doesn't hurt to initialize the const char * pointer
to a default value.
cppcheck complained about "con" not being initialized in the constructor.
In general it is better to fully initialize all members, even if (as in this
case) they are not used outside of a second initialization step (open/close).
This warning pointed to a second potential problem: should SyncEvolution ever
fail to call close() after open(), resources would leak because all allocated
resources get freed in close(). For the sake of defensive programming it is
better to initialize in the constructor, then free in both close() and the
destructor.
That way we can initialize m_accessMode immediately in the constructor,
which keeps cppcheck happy and avoids uninitalized data in the instance
between creation and open(), which is better than before.
cppcheck correctly identified some places where the weaker empty()
call can be used instead of size() to determine whether an STL
data structure contains something.
None of them were really performance critical, but let's fix them
anyway for the sake of clean cppcheck scan results.
cppcheck complains about sub-optimal performance (std::string should be passed
via const reference, not by value). It is not critical here, but for the sake
of getting clean scan results let's fix the issues...
One of the offending methods was never implemented, nor called. Removed.
The Collection class did not initialize all its members. Even if the code
never relied on them being initialized (not checked), it is better to be
safe and predictable, which means initializing all members in the constructor.
Renaming the backends now needs to be done before calling make.
This is used to include two versions of syncecal.so:
- one for EDS >= 3.6 < 3.10
- one for EDS >= 3.10 with the libecal-1.2 soname patched
The second flavor became necessary because EDS 3.10 accidentally
changed the soname. The API and ABI actually is the same, so
we don't need to compile twice.
The package meta data must include additional alternatives for
libecal and libebook when including extra backends. This must
be passed in via EXTRA_BACKENDS_ECAL/EBOOK_REQUIRES; the makefile
does not attempt to determine what those are.
kdebase-runtime became kde-runtime in Debian Wheezy. Accept both
as prerequisite of syncevolution-kde to allow installation on
newer distros without pulling in the transitional kdebase-runtime
package.
"dist" must complete before being able to install and test packages on
different platforms. By running "make distcheck" separately, we can
start with parallel testing sooner and separately enable/disable
distcheck testing.
When run with an existing resultdir, do not remove the resultdir
and append to output.txt. This is useful for splitting compilation and
testing into two separate phases where testing on other platforms
can be started in parallel once compilation is complete.
Depends on the enhanced resultchecker.py.
Compilation and actual testing will be split into two runtest.py invocations
to support parallelizing of testing. resultchecker.py must handle the
resulting output.txt, which will have multiple entries for for each action:
first compilation followed by skipped testing, then skipped compilation
followed by testing. resultcheckper.py must report the non-skipped
results and only fall back to "skipped" if none are found.
In addition, make it clear that the initial steps are about the source code by
renaming the step in the report with a "-source" suffix.
When testing pre-compiled binaries it may happen that we cannot
determine library versions with pkg-config because development
files are not installed. Ignore these errors and skip adding
library version numbers.
When already started with D-Bus env variables, do not kill those
daemons. When killing daemons, report it on stderr so that it can
be tracked down who killed which processes.
Compile jobs are not timing sensitive, so run them with lower priority than
test jobs. This becomes relevant when multiple runtests.py instances are
active.
Reordering the command line just cannot cope with the complex command line
setup for checking out source code. Disable the reordering for that command.
Both env variables might be set multiple times, once as part of the shell
prefix and again for the specific test. The second instance used to overwrite
the previous one unless one was very careful about embedding the environment's
current value of these variables.
The problem with that was that LD_LIBRARY_PATH had to be set in the
environment of runtest.py, where it may break running other commands outside
of the test shell.
Better be a bit more smart about the final command and merge the two values
into one.
When multiple different runtests.py instances are active, they must coordinate
access to shared resources like accounts on servers. We can use Murphy
(https://01.org/murphy/) for that.
If runtest.py is started with a D-Bus session address set in the environment,
it expects Murphy to be running there and will lock a resource named after
each operation before running the operation. Some operations (like "compile")
can be granted to each instance, but some (like "memotoo") must be exclusive.
Here's a complete Murphy lua config:
m = murphy.get()
-- try loading console plugin
m:try_load_plugin('console')
-- load the native resource plugin
if m:plugin_exists('resource-native') then
m:load_plugin('resource-native')
m:info("native resource plugin loaded")
else
m:info("No native resource plugin found...")
end
-- load the dbus resource plugin
m:try_load_plugin('resource-dbus', {
dbus_bus = "session",
dbus_service = "org.Murphy",
dbus_track = true,
default_zone = "driver",
default_class = "implicit"
})
m:info("dbus resource plugin loaded")
-- define application classes
application_class { name="implicit" , priority=0 , modal=false, share=true ,
order="fifo" }
-- define zone attributes
zone.attributes {
}
-- define zones
zone {
name = "driver"
}
-- define resource classes
resource.class {
name = "audio_playback",
shareable = true,
attributes = {
role = { mdb.string, "music", "rw" },
pid = { mdb.string, "<unknown>", "rw" },
policy = { mdb.string, "relaxed", "rw" }
}
}
-- SyncEvolution resources: one per runtest.py
-- Some tests can run in parallel. Those resources are shareable.
for i,v in pairs {
-- compiling the source on one platform
"compile",
"install",
"dist",
-- checking out source
"libsynthesis",
"syncevolution",
"activesyncd",
-- local tests
"evolution",
"dbus",
"pim",
} do
resource.class {
name = v,
shareable = true
}
end
-- TODO (in runtests.py): some of these resources overlap
for i,v in pairs {
-- tests involving unique peers
"googlecalendar",
"googlecontacts",
"owndrive",
"yahoo",
"oracle",
"davical",
"apple",
"googleeas",
"exchange",
"edsfile",
"edseds",
"edsxfile",
"davfile",
"edsdav",
"mobical",
"memotoo",
} do
resource.class {
name = v,
shareable = false
}
end
-- test for creating selections: don't remove, murphyd won't start without it
-- (E: Failed to enable resolver autoupdate.)
mdb.select {
name = "audio_owner",
table = "audio_playback_owner",
columns = {"application_class"},
condition = "zone_name = 'driver'",
}