aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIain Lane <iain.lane@canonical.com>2015-09-09 16:40:41 +0000
committerCI Train Bot <ci-train-bot@canonical.com>2015-09-09 16:40:41 +0000
commit13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee (patch)
tree30705f0a3f047a46020c7204397649ff2c609936 /tests
parentad2d17a82ebe369adca6b477d5ecb362e243f585 (diff)
parentec001e64b2225a3c80b7e89d9a570728fcbca830 (diff)
downloadayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.tar.gz
ayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.tar.bz2
ayatana-indicator-datetime-13bcfccd0c9038c4b4c20c37c8d3267a5e6fbfee.zip
Remove warnings from test logs. Swallow the ones that are expected and fail the test if they don't show up. In addition, fail tests if unexpected warnings show up again.
Approved by: Charles Kerr
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt3
-rw-r--r--tests/glib-fixture.h50
-rw-r--r--tests/state-fixture.h6
-rw-r--r--tests/test-live-actions.cpp238
-rw-r--r--tests/test-timezone-timedated.cpp (renamed from tests/test-timezone-file.cpp)68
-rw-r--r--tests/test-utils.cpp2
-rw-r--r--tests/timedated-fixture.h301
7 files changed, 364 insertions, 304 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9d26484..0302da9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -38,6 +38,7 @@ include_directories (${DBUSTEST_INCLUDE_DIRS})
add_definitions (-DSANDBOX="${CMAKE_CURRENT_BINARY_DIR}")
+add_definitions (-DG_LOG_DOMAIN="Indicator-Datetime")
function(add_test_by_name name)
set (TEST_NAME ${name})
@@ -58,7 +59,7 @@ add_test_by_name(test-locations)
add_test_by_name(test-menus)
add_test_by_name(test-planner)
add_test_by_name(test-settings)
-add_test_by_name(test-timezone-file)
+add_test_by_name(test-timezone-timedated)
add_test_by_name(test-utils)
set (TEST_NAME manual-test-snap)
diff --git a/tests/glib-fixture.h b/tests/glib-fixture.h
index f888c59..4d309e6 100644
--- a/tests/glib-fixture.h
+++ b/tests/glib-fixture.h
@@ -36,34 +36,6 @@ class GlibFixture : public ::testing::Test
virtual ~GlibFixture() =default;
- private:
-
- //GLogFunc realLogHandler;
-
- protected:
-
- std::map<GLogLevelFlags,int> logCounts;
-
- void testLogCount(GLogLevelFlags log_level, int /*expected*/)
- {
-#if 0
- EXPECT_EQ(expected, logCounts[log_level]);
-#endif
-
- logCounts.erase(log_level);
- }
-
- private:
-
- static void default_log_handler(const gchar * log_domain,
- GLogLevelFlags log_level,
- const gchar * message,
- gpointer self)
- {
- g_print("%s - %d - %s\n", log_domain, (int)log_level, message);
- static_cast<GlibFixture*>(self)->logCounts[log_level]++;
- }
-
protected:
virtual void SetUp() override
@@ -72,34 +44,30 @@ class GlibFixture : public ::testing::Test
loop = g_main_loop_new(nullptr, false);
- //g_log_set_default_handler(default_log_handler, this);
-
// only use local, temporary settings
g_assert(g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, true));
g_assert(g_setenv("GSETTINGS_BACKEND", "memory", true));
g_debug("SCHEMA_DIR is %s", SCHEMA_DIR);
+ // fail on unexpected messages from this domain
+ g_log_set_fatal_mask(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING);
+
g_unsetenv("DISPLAY");
}
virtual void TearDown() override
{
-#if 0
- // confirm there aren't any unexpected log messages
- EXPECT_EQ(0, logCounts[G_LOG_LEVEL_ERROR]);
- EXPECT_EQ(0, logCounts[G_LOG_LEVEL_CRITICAL]);
- EXPECT_EQ(0, logCounts[G_LOG_LEVEL_WARNING]);
- EXPECT_EQ(0, logCounts[G_LOG_LEVEL_MESSAGE]);
- EXPECT_EQ(0, logCounts[G_LOG_LEVEL_INFO]);
-#endif
-
- // revert to glib's log handler
- //g_log_set_default_handler(realLogHandler, this);
+ g_test_assert_expected_messages ();
g_clear_pointer(&loop, g_main_loop_unref);
}
+ void expectLogMessage (const gchar *domain, GLogLevelFlags level, const gchar *pattern)
+ {
+ g_test_expect_message (domain, level, pattern);
+ }
+
private:
static gboolean
diff --git a/tests/state-fixture.h b/tests/state-fixture.h
index e466a79..341df8b 100644
--- a/tests/state-fixture.h
+++ b/tests/state-fixture.h
@@ -20,7 +20,7 @@
#ifndef INDICATOR_DATETIME_TESTS_STATE_FIXTURE_H
#define INDICATOR_DATETIME_TESTS_STATE_FIXTURE_H
-#include "glib-fixture.h"
+#include "test-dbus-fixture.h"
#include "actions-mock.h"
#include "state-mock.h"
@@ -33,10 +33,10 @@ namespace datetime {
****
***/
-class StateFixture: public GlibFixture
+class StateFixture: public TestDBusFixture
{
private:
- typedef GlibFixture super;
+ typedef TestDBusFixture super;
public:
virtual ~StateFixture() =default;
diff --git a/tests/test-live-actions.cpp b/tests/test-live-actions.cpp
index 4f84f25..9f17001 100644
--- a/tests/test-live-actions.cpp
+++ b/tests/test-live-actions.cpp
@@ -17,228 +17,18 @@
* Charles Kerr <charles.kerr@canonical.com>
*/
-#include <datetime/actions-live.h>
-
-#include "state-mock.h"
-#include "glib-fixture.h"
-
-/***
-****
-***/
-
-using namespace unity::indicator::datetime;
-
-class MockLiveActions: public LiveActions
-{
-public:
- std::string last_cmd;
- std::string last_url;
- explicit MockLiveActions(const std::shared_ptr<State>& state_in): LiveActions(state_in) {}
- ~MockLiveActions() {}
-
-protected:
- void dispatch_url(const std::string& url) override { last_url = url; }
- void execute_command(const std::string& cmd) override { last_cmd = cmd; }
-};
-
-/***
-****
-***/
-
-using namespace unity::indicator::datetime;
-
-class LiveActionsFixture: public GlibFixture
-{
-private:
-
- typedef GlibFixture super;
-
- static void on_bus_acquired(GDBusConnection* conn,
- const gchar* name,
- gpointer gself)
- {
- auto self = static_cast<LiveActionsFixture*>(gself);
- g_debug("bus acquired: %s, connection is %p", name, conn);
-
- // Set up a mock GSD.
- // All it really does is wait for calls to GetDevice and
- // returns the get_devices_retval variant
- static const GDBusInterfaceVTable vtable = {
- timedate1_handle_method_call,
- nullptr, /* GetProperty */
- nullptr, /* SetProperty */
- };
-
- self->connection = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(conn)));
-
- GError* error = nullptr;
- self->object_register_id = g_dbus_connection_register_object(
- conn,
- "/org/freedesktop/timedate1",
- self->node_info->interfaces[0],
- &vtable,
- self,
- nullptr,
- &error);
- g_assert_no_error(error);
- }
-
- static void on_name_acquired(GDBusConnection* /*conn*/,
- const gchar* /*name*/,
- gpointer gself)
- {
- auto self = static_cast<LiveActionsFixture*>(gself);
- self->name_acquired = true;
- g_main_loop_quit(self->loop);
- }
-
- static void on_name_lost(GDBusConnection* /*conn*/,
- const gchar* /*name*/,
- gpointer gself)
- {
- auto self = static_cast<LiveActionsFixture*>(gself);
- self->name_acquired = false;
- }
-
- static void on_bus_closed(GObject* /*object*/,
- GAsyncResult* res,
- gpointer gself)
- {
- auto self = static_cast<LiveActionsFixture*>(gself);
- GError* err = nullptr;
- g_dbus_connection_close_finish(self->connection, res, &err);
- g_assert_no_error(err);
- g_main_loop_quit(self->loop);
- }
-
- static void
- timedate1_handle_method_call(GDBusConnection * /*connection*/,
- const gchar * /*sender*/,
- const gchar * /*object_path*/,
- const gchar * /*interface_name*/,
- const gchar * method_name,
- GVariant * parameters,
- GDBusMethodInvocation * invocation,
- gpointer gself)
- {
- g_assert(!g_strcmp0(method_name, "SetTimezone"));
- g_assert(g_variant_is_of_type(parameters, G_VARIANT_TYPE_TUPLE));
- g_assert(2 == g_variant_n_children(parameters));
-
- auto child = g_variant_get_child_value(parameters, 0);
- g_assert(g_variant_is_of_type(child, G_VARIANT_TYPE_STRING));
- auto self = static_cast<LiveActionsFixture*>(gself);
- self->attempted_tzid = g_variant_get_string(child, nullptr);
- g_variant_unref(child);
-
- g_dbus_method_invocation_return_value(invocation, nullptr);
- g_main_loop_quit(self->loop);
- }
-
-protected:
-
- std::shared_ptr<MockState> m_mock_state;
- std::shared_ptr<State> m_state;
- std::shared_ptr<MockLiveActions> m_live_actions;
- std::shared_ptr<Actions> m_actions;
-
- bool name_acquired;
- std::string attempted_tzid;
-
- GTestDBus* bus;
- guint own_name;
- GDBusConnection* connection;
- GDBusNodeInfo* node_info;
- int object_register_id;
-
- void SetUp()
- {
- super::SetUp();
-
- name_acquired = false;
- attempted_tzid.clear();
- connection = nullptr;
- node_info = nullptr;
- object_register_id = 0;
- own_name = 0;
-
- // bring up the test bus
- bus = g_test_dbus_new(G_TEST_DBUS_NONE);
- g_test_dbus_up(bus);
- const auto address = g_test_dbus_get_bus_address(bus);
- g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true);
- g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true);
- g_debug("test_dbus's address is %s", address);
-
- // parse the org.freedesktop.timedate1 interface
- const gchar introspection_xml[] =
- "<node>"
- " <interface name='org.freedesktop.timedate1'>"
- " <method name='SetTimezone'>"
- " <arg name='timezone' type='s' direction='in'/>"
- " <arg name='user_interaction' type='b' direction='in'/>"
- " </method>"
- " </interface>"
- "</node>";
- node_info = g_dbus_node_info_new_for_xml(introspection_xml, nullptr);
- ASSERT_TRUE(node_info != nullptr);
- ASSERT_TRUE(node_info->interfaces != nullptr);
- ASSERT_TRUE(node_info->interfaces[0] != nullptr);
- ASSERT_TRUE(node_info->interfaces[1] == nullptr);
- ASSERT_STREQ("org.freedesktop.timedate1", node_info->interfaces[0]->name);
-
- // own the bus
- own_name = g_bus_own_name(G_BUS_TYPE_SYSTEM,
- "org.freedesktop.timedate1",
- G_BUS_NAME_OWNER_FLAGS_NONE,
- on_bus_acquired, on_name_acquired, on_name_lost,
- this, nullptr);
- ASSERT_TRUE(object_register_id == 0);
- ASSERT_FALSE(name_acquired);
- ASSERT_TRUE(connection == nullptr);
- g_main_loop_run(loop);
- ASSERT_TRUE(object_register_id != 0);
- ASSERT_TRUE(name_acquired);
- ASSERT_TRUE(G_IS_DBUS_CONNECTION(connection));
-
- // create the State and Actions
- m_mock_state.reset(new MockState);
- m_mock_state->settings.reset(new Settings);
- m_state = std::dynamic_pointer_cast<State>(m_mock_state);
- m_live_actions.reset(new MockLiveActions(m_state));
- m_actions = std::dynamic_pointer_cast<Actions>(m_live_actions);
- }
-
- void TearDown()
- {
- m_actions.reset();
- m_live_actions.reset();
- m_state.reset();
- m_mock_state.reset();
-
- g_dbus_connection_unregister_object(connection, object_register_id);
- g_dbus_node_info_unref(node_info);
- g_bus_unown_name(own_name);
- g_dbus_connection_close(connection, nullptr, on_bus_closed, this);
- g_main_loop_run(loop);
- g_clear_object(&connection);
- g_test_dbus_down(bus);
- g_clear_object(&bus);
-
- super::TearDown();
- }
-};
+#include "timedated-fixture.h"
/***
****
***/
-TEST_F(LiveActionsFixture, HelloWorld)
+TEST_F(TimedateFixture, HelloWorld)
{
EXPECT_TRUE(true);
}
-TEST_F(LiveActionsFixture, SetLocation)
+TEST_F(TimedateFixture, SetLocation)
{
const std::string tzid = "America/Chicago";
const std::string name = "Oklahoma City";
@@ -247,6 +37,10 @@ TEST_F(LiveActionsFixture, SetLocation)
EXPECT_NE(expected, m_state->settings->timezone_name.get());
m_actions->set_location(tzid, name);
+ m_state->settings->timezone_name.changed().connect(
+ [this](const std::string&){
+ g_main_loop_quit(loop);
+ });
g_main_loop_run(loop);
EXPECT_EQ(attempted_tzid, tzid);
wait_msec();
@@ -258,14 +52,14 @@ TEST_F(LiveActionsFixture, SetLocation)
****
***/
-TEST_F(LiveActionsFixture, DesktopOpenAlarmApp)
+TEST_F(TimedateFixture, DesktopOpenAlarmApp)
{
m_actions->desktop_open_alarm_app();
const std::string expected = "evolution -c calendar";
EXPECT_EQ(expected, m_live_actions->last_cmd);
}
-TEST_F(LiveActionsFixture, DesktopOpenAppointment)
+TEST_F(TimedateFixture, DesktopOpenAppointment)
{
Appointment a;
a.uid = "some-uid";
@@ -275,14 +69,14 @@ TEST_F(LiveActionsFixture, DesktopOpenAppointment)
EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
}
-TEST_F(LiveActionsFixture, DesktopOpenCalendarApp)
+TEST_F(TimedateFixture, DesktopOpenCalendarApp)
{
m_actions->desktop_open_calendar_app(DateTime::NowLocal());
const std::string expected_substr = "evolution \"calendar:///?startdate=";
EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
}
-TEST_F(LiveActionsFixture, DesktopOpenSettingsApp)
+TEST_F(TimedateFixture, DesktopOpenSettingsApp)
{
m_actions->desktop_open_settings_app();
const std::string expected_substr = "control-center";
@@ -300,13 +94,13 @@ namespace
const std::string calendar_app_url = "appid://com.ubuntu.calendar/calendar/current-user-version";
}
-TEST_F(LiveActionsFixture, PhoneOpenAlarmApp)
+TEST_F(TimedateFixture, PhoneOpenAlarmApp)
{
m_actions->phone_open_alarm_app();
EXPECT_EQ(clock_app_url, m_live_actions->last_url);
}
-TEST_F(LiveActionsFixture, PhoneOpenAppointment)
+TEST_F(TimedateFixture, PhoneOpenAppointment)
{
Appointment a;
@@ -321,14 +115,14 @@ TEST_F(LiveActionsFixture, PhoneOpenAppointment)
EXPECT_EQ(clock_app_url, m_live_actions->last_url);
}
-TEST_F(LiveActionsFixture, PhoneOpenCalendarApp)
+TEST_F(TimedateFixture, PhoneOpenCalendarApp)
{
m_actions->phone_open_calendar_app(DateTime::NowLocal());
const std::string expected = "appid://com.ubuntu.calendar/calendar/current-user-version";
EXPECT_EQ(expected, m_live_actions->last_url);
}
-TEST_F(LiveActionsFixture, PhoneOpenSettingsApp)
+TEST_F(TimedateFixture, PhoneOpenSettingsApp)
{
m_actions->phone_open_settings_app();
const std::string expected = "settings:///system/time-date";
@@ -339,7 +133,7 @@ TEST_F(LiveActionsFixture, PhoneOpenSettingsApp)
****
***/
-TEST_F(LiveActionsFixture, CalendarState)
+TEST_F(TimedateFixture, CalendarState)
{
// init the clock
auto now = DateTime::Local(2014, 1, 1, 0, 0, 0);
diff --git a/tests/test-timezone-file.cpp b/tests/test-timezone-timedated.cpp
index 8968429..7300649 100644
--- a/tests/test-timezone-file.cpp
+++ b/tests/test-timezone-timedated.cpp
@@ -18,25 +18,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "glib-fixture.h"
+#include "timedated-fixture.h"
-#include <datetime/timezone-file.h>
-
-//#include <condition_variable>
-//#include <mutex>
-//#include <queue>
-//#include <string>
-//#include <thread>
-//#include <iostream>
-//#include <istream>
-//#include <fstream>
-
-#include <cstdio> // fopen()
-//#include <sys/stat.h> // chmod()
-#include <unistd.h> // sync()
-
-using unity::indicator::datetime::FileTimezone;
+#include <datetime/timezone-timedated.h>
+using unity::indicator::datetime::TimedatedTimezone;
/***
****
@@ -44,11 +30,11 @@ using unity::indicator::datetime::FileTimezone;
#define TIMEZONE_FILE (SANDBOX"/timezone")
-class TimezoneFixture: public GlibFixture
+class TimezoneFixture: public TimedateFixture
{
private:
- typedef GlibFixture super;
+ typedef TimedateFixture super;
protected:
@@ -67,6 +53,7 @@ class TimezoneFixture: public GlibFixture
/* convenience func to set the timezone file */
void set_file(const std::string& text)
{
+ g_debug("set_file %s %s", TIMEZONE_FILE, text.c_str());
auto fp = fopen(TIMEZONE_FILE, "w+");
fprintf(fp, "%s\n", text.c_str());
fclose(fp);
@@ -74,46 +61,57 @@ class TimezoneFixture: public GlibFixture
}
};
-
/**
- * Test that timezone-file warns, but doesn't crash, if the timezone file doesn't exist
+ * Test that timezone-timedated warns, but doesn't crash, if the timezone file doesn't exist
*/
TEST_F(TimezoneFixture, NoFile)
{
remove(TIMEZONE_FILE);
ASSERT_FALSE(g_file_test(TIMEZONE_FILE, G_FILE_TEST_EXISTS));
- FileTimezone tz(TIMEZONE_FILE);
- testLogCount(G_LOG_LEVEL_WARNING, 1);
+ expectLogMessage(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*No such file or directory*");
+ TimedatedTimezone tz(TIMEZONE_FILE);
}
+/**
+ * Test that timezone-timedated gives a default of UTC if the file doesn't exist
+ */
+TEST_F(TimezoneFixture, DefaultValueNoFile)
+{
+ const std::string expected_timezone = "Etc/Utc";
+ remove(TIMEZONE_FILE);
+ ASSERT_FALSE(g_file_test(TIMEZONE_FILE, G_FILE_TEST_EXISTS));
+
+ expectLogMessage(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*No such file or directory*");
+ TimedatedTimezone tz(TIMEZONE_FILE);
+ ASSERT_EQ(expected_timezone, tz.timezone.get());
+}
/**
- * Test that timezone-file picks up the initial value
+ * Test that timezone-timedated picks up the initial value
*/
TEST_F(TimezoneFixture, InitialValue)
{
const std::string expected_timezone = "America/Chicago";
set_file(expected_timezone);
- FileTimezone tz(TIMEZONE_FILE);
- ASSERT_EQ(expected_timezone, tz.timezone.get());
+ TimedatedTimezone tz(TIMEZONE_FILE);
}
-
/**
- * Test that clearing the timezone results in an empty string
+ * Test that changing the tz after we are running works.
*/
TEST_F(TimezoneFixture, ChangedValue)
{
const std::string initial_timezone = "America/Chicago";
const std::string changed_timezone = "America/New_York";
+
set_file(initial_timezone);
- FileTimezone tz(TIMEZONE_FILE);
+ TimedatedTimezone tz(TIMEZONE_FILE);
ASSERT_EQ(initial_timezone, tz.timezone.get());
bool changed = false;
- auto connection = tz.timezone.changed().connect(
+ tz.timezone.changed().connect(
[&changed, this](const std::string& s){
g_message("timezone changed to %s", s.c_str());
changed = true;
@@ -121,10 +119,9 @@ TEST_F(TimezoneFixture, ChangedValue)
});
g_idle_add([](gpointer gself){
- static_cast<TimezoneFixture*>(gself)->set_file("America/New_York");
- // static_cast<FileTimezone*>(gtz)->timezone.set("America/New_York");
+ static_cast<TimedateFixture*>(gself)->set_timezone("America/New_York");
return G_SOURCE_REMOVE;
- }, this);//&tz);
+ }, this);
g_main_loop_run(loop);
@@ -132,15 +129,14 @@ TEST_F(TimezoneFixture, ChangedValue)
ASSERT_EQ(changed_timezone, tz.timezone.get());
}
-
/**
- * Test that timezone-file picks up the initial value
+ * Test that timezone-timedated picks up the initial value
*/
TEST_F(TimezoneFixture, IgnoreComments)
{
const std::string comment = "# Created by cloud-init v. 0.7.5 on Thu, 24 Apr 2014 14:03:29 +0000";
const std::string expected_timezone = "Europe/Berlin";
set_file(comment + "\n" + expected_timezone);
- FileTimezone tz(TIMEZONE_FILE);
+ TimedatedTimezone tz(TIMEZONE_FILE);
ASSERT_EQ(expected_timezone, tz.timezone.get());
}
diff --git a/tests/test-utils.cpp b/tests/test-utils.cpp
index 97f07ed..f5c14d4 100644
--- a/tests/test-utils.cpp
+++ b/tests/test-utils.cpp
@@ -59,7 +59,7 @@ namespace
const char* location;
const char* expected_name;
} beautify_timezone_test_cases[] = {
- { "America/Chicago", nullptr, "Chicago" },
+ { "America/Chicago", "", "Chicago" },
{ "America/Chicago", "America/Chicago", "Chicago" },
{ "America/Chicago", "America/Chigago Chicago", "Chicago" },
{ "America/Chicago", "America/Chicago Oklahoma City", "Oklahoma City" },
diff --git a/tests/timedated-fixture.h b/tests/timedated-fixture.h
new file mode 100644
index 0000000..5ec425d
--- /dev/null
+++ b/tests/timedated-fixture.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2013 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_TESTS_TIMEDATED_FIXTURE_H
+#define INDICATOR_DATETIME_TESTS_TIMEDATED_FIXTURE_H
+
+#include <datetime/actions-live.h>
+
+#include "state-mock.h"
+#include "glib-fixture.h"
+
+using namespace unity::indicator::datetime;
+
+class MockLiveActions: public LiveActions
+{
+public:
+ std::string last_cmd;
+ std::string last_url;
+ explicit MockLiveActions(const std::shared_ptr<State>& state_in): LiveActions(state_in) {}
+ ~MockLiveActions() {}
+
+protected:
+ void dispatch_url(const std::string& url) override { last_url = url; }
+ void execute_command(const std::string& cmd) override { last_cmd = cmd; }
+};
+
+/***
+****
+***/
+
+using namespace unity::indicator::datetime;
+
+class TimedateFixture: public GlibFixture
+{
+private:
+
+ typedef GlibFixture super;
+
+ static GVariant * timedate1_get_properties (GDBusConnection * /*connection*/ ,
+ const gchar * /*sender*/,
+ const gchar * /*object_path*/,
+ const gchar * /*interface_name*/,
+ const gchar *property_name,
+ GError ** /*error*/,
+ gpointer gself)
+
+ {
+ auto self = static_cast<TimedateFixture*>(gself);
+ g_debug("get_properties called");
+ if (g_strcmp0(property_name, "Timezone") == 0)
+ {
+ g_debug("timezone requested, giving '%s'",
+ self->attempted_tzid.c_str());
+ return g_variant_new_string(self->attempted_tzid.c_str());
+ }
+ return nullptr;
+ }
+
+
+ static void on_bus_acquired(GDBusConnection* conn,
+ const gchar* name,
+ gpointer gself)
+ {
+ auto self = static_cast<TimedateFixture*>(gself);
+ g_debug("bus acquired: %s, connection is %p", name, conn);
+
+ /* Set up a fake timedated which handles setting and getting the
+ ** timezone
+ */
+ static const GDBusInterfaceVTable vtable = {
+ timedate1_handle_method_call,
+ timedate1_get_properties, /* GetProperty */
+ nullptr, /* SetProperty */
+ };
+
+ self->connection = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(conn)));
+
+ GError* error = nullptr;
+ self->object_register_id = g_dbus_connection_register_object(
+ conn,
+ "/org/freedesktop/timedate1",
+ self->node_info->interfaces[0],
+ &vtable,
+ self,
+ nullptr,
+ &error);
+ g_assert_no_error(error);
+ }
+
+ static void on_name_acquired(GDBusConnection* conn,
+ const gchar* name,
+ gpointer gself)
+ {
+ g_debug("on_name_acquired");
+ auto self = static_cast<TimedateFixture*>(gself);
+ self->name_acquired = true;
+ self->proxy = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ nullptr,
+ name,
+ "/org/freedesktop/timedate1",
+ "org.freedesktop.timedate1",
+ nullptr,
+ nullptr);
+ g_main_loop_quit(self->loop);
+ }
+
+ static void on_name_lost(GDBusConnection* /*conn*/,
+ const gchar* /*name*/,
+ gpointer gself)
+ {
+ g_debug("on_name_lost");
+ auto self = static_cast<TimedateFixture*>(gself);
+ self->name_acquired = false;
+ }
+
+ static void on_bus_closed(GObject* /*object*/,
+ GAsyncResult* res,
+ gpointer gself)
+ {
+ g_debug("on_bus_closed");
+ auto self = static_cast<TimedateFixture*>(gself);
+ GError* err = nullptr;
+ g_dbus_connection_close_finish(self->connection, res, &err);
+ g_assert_no_error(err);
+ g_main_loop_quit(self->loop);
+ }
+
+ static void
+ timedate1_handle_method_call(GDBusConnection * connection,
+ const gchar * /*sender*/,
+ const gchar * object_path,
+ const gchar * interface_name,
+ const gchar * method_name,
+ GVariant * parameters,
+ GDBusMethodInvocation * invocation,
+ gpointer gself)
+ {
+ g_assert(!g_strcmp0(method_name, "SetTimezone"));
+ g_assert(g_variant_is_of_type(parameters, G_VARIANT_TYPE_TUPLE));
+ g_assert(2 == g_variant_n_children(parameters));
+
+ auto child = g_variant_get_child_value(parameters, 0);
+ g_assert(g_variant_is_of_type(child, G_VARIANT_TYPE_STRING));
+ auto self = static_cast<TimedateFixture*>(gself);
+ self->attempted_tzid = g_variant_get_string(child, nullptr);
+ g_debug("set tz (dbus side): '%s'", self->attempted_tzid.c_str());
+ g_dbus_method_invocation_return_value(invocation, nullptr);
+
+ /* Send PropertiesChanged */
+ GError * local_error = nullptr;
+ auto builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (builder,
+ "{sv}",
+ "Timezone",
+ g_variant_new_string(
+ self->attempted_tzid.c_str()));
+ g_dbus_connection_emit_signal (connection,
+ NULL,
+ object_path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)",
+ interface_name,
+ builder,
+ NULL),
+ &local_error);
+ g_assert_no_error (local_error);
+ g_variant_unref(child);
+ }
+
+protected:
+
+ std::shared_ptr<MockState> m_mock_state;
+ std::shared_ptr<State> m_state;
+ std::shared_ptr<MockLiveActions> m_live_actions;
+ std::shared_ptr<Actions> m_actions;
+
+ bool name_acquired;
+ std::string attempted_tzid;
+
+ GTestDBus* bus;
+ guint own_name;
+ GDBusConnection* connection;
+ GDBusNodeInfo* node_info;
+ int object_register_id;
+ GDBusProxy *proxy;
+
+ void SetUp()
+ {
+ super::SetUp();
+ g_debug("SetUp");
+
+ name_acquired = false;
+ attempted_tzid.clear();
+ connection = nullptr;
+ node_info = nullptr;
+ object_register_id = 0;
+ own_name = 0;
+ proxy = nullptr;
+
+ // bring up the test bus
+ bus = g_test_dbus_new(G_TEST_DBUS_NONE);
+ g_test_dbus_up(bus);
+ const auto address = g_test_dbus_get_bus_address(bus);
+ g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true);
+ g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true);
+ g_debug("test_dbus's address is %s", address);
+
+ // parse the org.freedesktop.timedate1 interface
+ const gchar introspection_xml[] =
+ "<node>"
+ " <interface name='org.freedesktop.timedate1'>"
+ " <property name='Timezone' type='s' access='read' />"
+ " <method name='SetTimezone'>"
+ " <arg name='timezone' type='s' direction='in'/>"
+ " <arg name='user_interaction' type='b' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+ node_info = g_dbus_node_info_new_for_xml(introspection_xml, nullptr);
+ ASSERT_TRUE(node_info != nullptr);
+ ASSERT_TRUE(node_info->interfaces != nullptr);
+ ASSERT_TRUE(node_info->interfaces[0] != nullptr);
+ ASSERT_TRUE(node_info->interfaces[1] == nullptr);
+ ASSERT_STREQ("org.freedesktop.timedate1", node_info->interfaces[0]->name);
+
+ // own the bus
+ own_name = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ "org.freedesktop.timedate1",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired, on_name_acquired, on_name_lost,
+ this, nullptr);
+ ASSERT_TRUE(object_register_id == 0);
+ ASSERT_FALSE(name_acquired);
+ ASSERT_TRUE(connection == nullptr);
+ g_main_loop_run(loop);
+ ASSERT_TRUE(object_register_id != 0);
+ ASSERT_TRUE(name_acquired);
+ ASSERT_TRUE(G_IS_DBUS_CONNECTION(connection));
+
+ // create the State and Actions
+ m_mock_state.reset(new MockState);
+ m_mock_state->settings.reset(new Settings);
+ m_state = std::dynamic_pointer_cast<State>(m_mock_state);
+ m_live_actions.reset(new MockLiveActions(m_state));
+ m_actions = std::dynamic_pointer_cast<Actions>(m_live_actions);
+ }
+
+ void TearDown()
+ {
+ g_debug("TearDown");
+ m_actions.reset();
+ m_live_actions.reset();
+ m_state.reset();
+ m_mock_state.reset();
+ g_dbus_connection_unregister_object(connection, object_register_id);
+ g_object_unref(proxy);
+ g_dbus_node_info_unref(node_info);
+ g_bus_unown_name(own_name);
+ g_dbus_connection_close(connection, nullptr, on_bus_closed, this);
+ g_main_loop_run(loop);
+ g_clear_object(&connection);
+ g_test_dbus_down(bus);
+ g_clear_object(&bus);
+
+ super::TearDown();
+ }
+public:
+ void set_timezone(std::string tz)
+ {
+ g_debug("set_timezone: '%s'", tz.c_str());
+ g_dbus_proxy_call_sync(proxy,
+ "SetTimezone",
+ g_variant_new("(sb)",
+ tz.c_str(),
+ FALSE),
+ G_DBUS_CALL_FLAGS_NONE,
+ 500,
+ nullptr,
+ nullptr);
+ }
+};
+
+#endif