diff options
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 37 | ||||
-rwxr-xr-x | tests/run-eds-test.sh | 48 | ||||
-rw-r--r-- | tests/test-eds-valarms-config-files/.config/evolution/sources/system-proxy.source | 21 | ||||
-rw-r--r-- | tests/test-eds-valarms-config-files/.local/share/evolution/calendar/system/calendar.ics | 47 | ||||
-rw-r--r-- | tests/test-eds-valarms.cpp | 113 | ||||
-rw-r--r-- | tests/timezone-mock.h | 1 | ||||
-rw-r--r-- | tests/wakeup-timer-mock.h | 78 |
8 files changed, 342 insertions, 4 deletions
diff --git a/debian/control b/debian/control index 4b5f893..1532ec8 100644 --- a/debian/control +++ b/debian/control @@ -24,6 +24,7 @@ Build-Depends: cmake, libproperties-cpp-dev, libdbustest1-dev, locales, + gvfs-daemons Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-datetime # If you aren't a member of ~indicator-applet-developers but need to upload diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 25fe5dc..8b6ec5d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,12 +39,10 @@ include_directories (${DBUSTEST_INCLUDE_DIRS}) add_definitions (-DSANDBOX="${CMAKE_CURRENT_BINARY_DIR}") - function(add_test_by_name name) set (TEST_NAME ${name}) add_executable (${TEST_NAME} ${TEST_NAME}.cpp gschemas.compiled) add_test (${TEST_NAME} ${TEST_NAME}) - add_dependencies (${TEST_NAME} libindicatordatetimeservice) target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${DBUSTEST_LIBRARIES} ${SERVICE_DEPS_LIBRARIES} ${GTEST_LIBS}) endfunction() add_test_by_name(test-datetime) @@ -65,9 +63,41 @@ add_test_by_name(test-utils) set (TEST_NAME manual-test-snap) add_executable (${TEST_NAME} ${TEST_NAME}.cpp) -add_dependencies (${TEST_NAME} libindicatordatetimeservice) target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${SERVICE_DEPS_LIBRARIES} ${GTEST_LIBS}) +## +## EDS Tests +## + +find_program(DBUS_RUNNER dbus-test-runner) +find_program(EVOLUTION_CALENDAR_FACTORY evolution-calendar-factory PATHS /usr/lib/evolution/) +find_program(EVOLUTION_SOURCE_REGISTRY evolution-source-registry PATHS /usr/lib/evolution/) +find_program(GVFSD gvfsd PATHS /usr/lib/gvfs/) +OPTION(EVOLUTION_SOURCE_SERVICE_NAME "DBus name for source registry") +if(NOT EVOLUTION_SOURCE_SERVICE_NAME) + set(EVOLUTION_SOURCE_SERVICE_NAME "org.gnome.evolution.dataserver.Sources3") +endif() + +function(add_eds_test_by_name name) + set (TEST_NAME ${name}) + add_executable(${TEST_NAME} ${TEST_NAME}.cpp gschemas.compiled) + target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${DBUSTEST_LIBRARIES} ${SERVICE_DEPS_LIBRARIES} ${GTEST_LIBS}) + add_test (${TEST_NAME} + ${CMAKE_CURRENT_SOURCE_DIR}/run-eds-test.sh + ${DBUS_RUNNER} # arg1: dbus-test-runner exec + ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} # arg2: test executable path + ${TEST_NAME} # arg3: test name + ${EVOLUTION_CALENDAR_FACTORY} # arg4: evolution-calendar-factory exec + ${EVOLUTION_SOURCE_SERVICE_NAME} # arg5: dbus name for source registry + ${EVOLUTION_SOURCE_REGISTRY} # arg6: evolution-source-registry exec + ${GVFSD} # arg7: gvfsd exec + ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}-config-files) # arg8: canned config files +endfunction() +add_eds_test_by_name(test-eds-valarms) + + + + # disabling the timezone unit tests because they require # https://code.launchpad.net/~ted/dbus-test-runner/multi-interface-test/+merge/199724 # which hasn't landed yet. These can be re-enabled as soon as that lands. @@ -75,7 +105,6 @@ target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${SERVICE_DEP # set (TEST_NAME ${name}) # add_executable (${TEST_NAME} ${TEST_NAME}.cpp gschemas.compiled) # add_test (${TEST_NAME} ${TEST_NAME}) -# add_dependencies (${TEST_NAME} libindicatordatetimeservice) # target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${SERVICE_DEPS_LIBRARIES} ${DBUSTEST_LIBRARIES} ${GTEST_LIBS}) #endfunction() #add_dbusmock_test_by_name(test-timezone-geoclue) diff --git a/tests/run-eds-test.sh b/tests/run-eds-test.sh new file mode 100755 index 0000000..6e6f575 --- /dev/null +++ b/tests/run-eds-test.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +echo ARG0=$0 # this script +echo ARG1=$1 # full executable path of dbus-test-runner +echo ARG2=$2 # full executable path of test app +echo ARG3=$3 # test name +echo ARG4=$4 # full executable path of evolution-calendar-factory +echo ARG5=$5 # bus service name of calendar factory +echo ARG6=$6 # full exectuable path of evolution-source-registry +echo ARG7=$7 # full executable path of gvfs +echo ARG8=$8 # config files + +export TEST_TMP_DIR=$(mktemp -p "${TMPDIR:-.}" -d $3-XXXXXXXXXX) || exit 1 +trap 'rm -rf $TEST_TMP_DIR' EXIT +echo "running test '$3' in ${TEST_TMP_DIR}" + +export QT_QPA_PLATFORM=minimal +export HOME=${TEST_TMP_DIR} +export XDG_RUNTIME_DIR=${TEST_TMP_DIR} +export XDG_CACHE_HOME=${TEST_TMP_DIR}/.cache +export XDG_CONFIG_HOME=${TEST_TMP_DIR}/.config +export XDG_DATA_HOME=${TEST_TMP_DIR}/.local/share +export XDG_DESKTOP_DIR=${TEST_TMP_DIR} +export XDG_DOCUMENTS_DIR=${TEST_TMP_DIR} +export XDG_DOWNLOAD_DIR=${TEST_TMP_DIR} +export XDG_MUSIC_DIR=${TEST_TMP_DIR} +export XDG_PICTURES_DIR=${TEST_TMP_DIR} +export XDG_PUBLICSHARE_DIR=${TEST_TMP_DIR} +export XDG_TEMPLATES_DIR=${TEST_TMP_DIR} +export XDG_VIDEOS_DIR=${TEST_TMP_DIR} +export QORGANIZER_EDS_DEBUG=On +export GIO_USE_VFS=local # needed to ensure GVFS shuts down cleanly after the test is over + +echo HOMEDIR=${HOME} +rm -rf ${XDG_DATA_HOME} + +# if there are canned config files for this test, move them into place now +if [ -d $8 ]; then + echo "copying files from $8 to $HOME" + cp --verbose --archive $8/. $HOME +fi + +$1 --keep-env --max-wait=90 \ +--task $2 --task-name $3 --wait-until-complete --wait-for=org.gnome.evolution.dataserver.Calendar4 \ +--task $4 --task-name "evolution" --wait-until-complete -r +#--task $6 --task-name "source-registry" --wait-for=org.gtk.vfs.Daemon -r \ +#--task $7 --task-name "gvfsd" -r +return $? diff --git a/tests/test-eds-valarms-config-files/.config/evolution/sources/system-proxy.source b/tests/test-eds-valarms-config-files/.config/evolution/sources/system-proxy.source new file mode 100644 index 0000000..4b2f666 --- /dev/null +++ b/tests/test-eds-valarms-config-files/.config/evolution/sources/system-proxy.source @@ -0,0 +1,21 @@ + +[Data Source] +DisplayName=Default Proxy Settings +Enabled=true +Parent= + +[Proxy] +Method=default +IgnoreHosts=localhost;127.0.0.0/8;::1; +AutoconfigUrl= +FtpHost= +FtpPort=0 +HttpAuthPassword= +HttpAuthUser= +HttpHost= +HttpPort=8080 +HttpUseAuth=false +HttpsHost= +HttpsPort=0 +SocksHost= +SocksPort=0 diff --git a/tests/test-eds-valarms-config-files/.local/share/evolution/calendar/system/calendar.ics b/tests/test-eds-valarms-config-files/.local/share/evolution/calendar/system/calendar.ics new file mode 100644 index 0000000..fe526f4 --- /dev/null +++ b/tests/test-eds-valarms-config-files/.local/share/evolution/calendar/system/calendar.ics @@ -0,0 +1,47 @@ +BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Ximian//NONSGML Evolution Calendar//EN
+VERSION:2.0
+X-EVOLUTION-DATA-REVISION:2015-04-05T21:32:47.354433Z(2)
+BEGIN:VEVENT
+UID:20150405T213247Z-4371-32011-1698-1@ubuntu-phablet
+DTSTAMP:20150405T213247Z
+DTSTART:20150424T183500Z
+DTEND:20150424T193554Z
+X-LIC-ERROR;X-LIC-ERRORTYPE=VALUE-PARSE-ERROR:Can't parse as RECUR value
+ in RRULE property. Removing entire property: ERROR: No Value
+SUMMARY:London Sprint Flight
+CREATED:20150405T213247Z
+LAST-MODIFIED:20150405T213247Z
+BEGIN:VALARM
+X-EVOLUTION-ALARM-UID:20150405T213247Z-4371-32011-1698-2@ubuntu-phablet
+ACTION:AUDIO
+TRIGGER;VALUE=DURATION;RELATED=START:-P1D
+REPEAT:3
+DURATION:PT2M
+END:VALARM
+BEGIN:VALARM
+X-EVOLUTION-ALARM-UID:20150405T213247Z-4371-32011-1698-3@ubuntu-phablet
+ACTION:DISPLAY
+DESCRIPTION:Time to pack!
+TRIGGER;VALUE=DURATION;RELATED=START:-P1D
+REPEAT:3
+DURATION:PT2M
+END:VALARM
+BEGIN:VALARM
+X-EVOLUTION-ALARM-UID:20150405T213247Z-4371-32011-1698-5@ubuntu-phablet
+ACTION:AUDIO
+TRIGGER;VALUE=DURATION;RELATED=START:-PT3H
+REPEAT:3
+DURATION:PT2M
+END:VALARM
+BEGIN:VALARM
+X-EVOLUTION-ALARM-UID:20150405T213247Z-4371-32011-1698-6@ubuntu-phablet
+ACTION:DISPLAY
+DESCRIPTION:Go to the airport!
+TRIGGER;VALUE=DURATION;RELATED=START:-PT3H
+REPEAT:3
+DURATION:PT2M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
diff --git a/tests/test-eds-valarms.cpp b/tests/test-eds-valarms.cpp new file mode 100644 index 0000000..f30539a --- /dev/null +++ b/tests/test-eds-valarms.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2015 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#include <algorithm> + +#include <core/connection.h> + +#include <datetime/alarm-queue-simple.h> +#include <datetime/clock-mock.h> +#include <datetime/engine-eds.h> +#include <datetime/planner-range.h> + +#include <gtest/gtest.h> + +#include "glib-fixture.h" +#include "timezone-mock.h" +#include "wakeup-timer-mock.h" + + +using namespace unity::indicator::datetime; + +class VAlarmFixture: public GlibFixture +{ +private: + + typedef GlibFixture super; + +protected: + + void SetUp() + { + super::SetUp(); + } + + void TearDown() + { + super::TearDown(); + } +}; + +/*** +**** +***/ + +TEST_F(VAlarmFixture, MultipleAppointments) +{ + // start the EDS engine + auto engine = std::make_shared<EdsEngine>(); + + // make a planner that looks at the first half of 2015 in EDS + auto tz = std::make_shared<MockTimezone>("America/Chicago"); + auto planner = std::make_shared<SimpleRangePlanner>(engine, tz); + const auto range_begin = DateTime::Local(2015,1, 1, 0, 0, 0.0); + const auto range_end = DateTime::Local(2015,6,31,23,59,59.5); + planner->range().set(std::make_pair(range_begin, range_end)); + + // give EDS a moment to load + if (planner->appointments().get().empty()) { + g_debug("waiting a moment for EDS to load..."); + auto on_appointments_changed = [this](const std::vector<Appointment>& appointments){ + g_debug("ah, they loaded"); + if (!appointments.empty()) + g_main_loop_quit(loop); + }; + core::ScopedConnection conn(planner->appointments().changed().connect(on_appointments_changed)); + constexpr int max_wait_sec = 10; + wait_msec(max_wait_sec * G_TIME_SPAN_MILLISECOND); + } + + const auto appts = planner->appointments().get(); + ASSERT_EQ(1, appts.size()); + const auto& appt = appts.front(); + ASSERT_EQ(8, appt.alarms.size()); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime::Local(2015,4,23,13,35,0)}), appt.alarms[0]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime::Local(2015,4,23,13,37,0)}), appt.alarms[1]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime::Local(2015,4,23,13,39,0)}), appt.alarms[2]); + EXPECT_EQ(Alarm({"Time to pack!", "", DateTime::Local(2015,4,23,13,41,0)}), appt.alarms[3]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime::Local(2015,4,24,10,35,0)}), appt.alarms[4]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime::Local(2015,4,24,10,37,0)}), appt.alarms[5]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime::Local(2015,4,24,10,39,0)}), appt.alarms[6]); + EXPECT_EQ(Alarm({"Go to the airport!", "", DateTime::Local(2015,4,24,10,41,0)}), appt.alarms[7]); + + // now let's try this out with AlarmQueue... + // hook the planner up to a SimpleAlarmQueue and confirm that it triggers for each of the reminders + auto mock_clock = std::make_shared<MockClock>(range_begin); + std::shared_ptr<Clock> clock = mock_clock; + std::shared_ptr<WakeupTimer> wakeup_timer = std::make_shared<MockWakeupTimer>(clock); + auto alarm_queue = std::make_shared<SimpleAlarmQueue>(clock, planner, wakeup_timer); + int triggered_count = 0; + alarm_queue->alarm_reached().connect([&triggered_count, appt](const Appointment&, const Alarm& active_alarm) { + EXPECT_TRUE(std::find(appt.alarms.begin(), appt.alarms.end(), active_alarm) != appt.alarms.end()); + ++triggered_count; + }); + for (auto now=range_begin; now<range_end; now+=std::chrono::minutes{1}) + mock_clock->set_localtime(now); + EXPECT_EQ(appt.alarms.size(), triggered_count); +} diff --git a/tests/timezone-mock.h b/tests/timezone-mock.h index 67584cb..55151aa 100644 --- a/tests/timezone-mock.h +++ b/tests/timezone-mock.h @@ -30,6 +30,7 @@ class MockTimezone: public Timezone { public: MockTimezone() =default; + explicit MockTimezone(const std::string& zone) {timezone.set(zone);} ~MockTimezone() =default; }; diff --git a/tests/wakeup-timer-mock.h b/tests/wakeup-timer-mock.h new file mode 100644 index 0000000..8a59c97 --- /dev/null +++ b/tests/wakeup-timer-mock.h @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#ifndef INDICATOR_DATETIME_WAKEUP_TIMER_MOCK_H +#define INDICATOR_DATETIME_WAKEUP_TIMER_MOCK_H + +#include <datetime/clock.h> +#include <datetime/wakeup-timer.h> + +namespace unity { +namespace indicator { +namespace datetime { + +/*** +**** +***/ + +/** + * \brief A one-shot timer that emits a signal when its timeout is reached. + */ +class MockWakeupTimer: public WakeupTimer +{ +public: + explicit MockWakeupTimer(const std::shared_ptr<Clock>& clock): + m_clock(clock) + { + m_clock->minute_changed.connect([this](){ + test_for_wakeup(); + }); + } + + virtual ~MockWakeupTimer() =default; + + virtual void set_wakeup_time (const DateTime& wakeup_time) override { + m_wakeup_time = wakeup_time; + test_for_wakeup(); + } + + virtual core::Signal<>& timeout() override { return m_timeout; } + +private: + + void test_for_wakeup() + { + if (DateTime::is_same_minute(m_clock->localtime(), m_wakeup_time)) + m_timeout(); + } + + core::Signal<> m_timeout; + const std::shared_ptr<Clock>& m_clock; + DateTime m_wakeup_time; +}; + +/*** +**** +***/ + +} // namespace datetime +} // namespace indicator +} // namespace unity + +#endif // INDICATOR_DATETIME_WAKEUP_TIMER_MOCK_H |