Merge lp:~charlesk/indicator-datetime/lp-1560960-use-dbusmock-timedated-template into lp:indicator-datetime/15.10

Proposed by Charles Kerr
Status: Merged
Approved by: Renato Araujo Oliveira Filho
Approved revision: 448
Merged at revision: 443
Proposed branch: lp:~charlesk/indicator-datetime/lp-1560960-use-dbusmock-timedated-template
Merge into: lp:indicator-datetime/15.10
Prerequisite: lp:~charlesk/indicator-datetime/always-get-initial-tzid-from-timedate1
Diff against target: 847 lines (+212/-394)
6 files modified
include/datetime/dbus-shared.h (+0/-8)
src/actions-live.cpp (+5/-4)
tests/glib-fixture.h (+16/-13)
tests/test-live-actions.cpp (+76/-18)
tests/test-timezone-timedated.cpp (+7/-100)
tests/timedated-fixture.h (+108/-251)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1560960-use-dbusmock-timedated-template
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
Renato Araujo Oliveira Filho (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+291446@code.launchpad.net

Commit message

Use dbusmock's timedated template in our tests

Description of the change

Minor patch on top of https://code.launchpad.net/~charlesk/indicator-datetime/always-get-initial-tzid-from-timedate1/+merge/291421 .

That branch added a test fixture which uses dbusmock's timedated template. This branch promotes that up to a shared test header where it can be reused by test-live-actions, and removes test-live-actions' previous handrolled timedated mock.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

looks good.

review: Approve
Revision history for this message
Charles Kerr (charlesk) wrote :

re-approving because the r449 was already approved in prerequisite branch

Revision history for this message
Charles Kerr (charlesk) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/datetime/dbus-shared.h'
2--- include/datetime/dbus-shared.h 2016-04-12 17:27:17 +0000
3+++ include/datetime/dbus-shared.h 2016-04-12 17:27:17 +0000
4@@ -28,10 +28,6 @@
5 #define BUS_POWERD_PATH "/com/canonical/powerd"
6 #define BUS_POWERD_INTERFACE "com.canonical.powerd"
7
8-namespace unity {
9-namespace indicator {
10-namespace datetime {
11-
12 namespace Bus
13 {
14 namespace Timedate1
15@@ -67,8 +63,4 @@
16 }
17 }
18
19-} // namespace datetime
20-} // namespace indicator
21-} // namespace unity
22-
23 #endif /* INDICATOR_DATETIME_DBUS_SHARED_H */
24
25=== modified file 'src/actions-live.cpp'
26--- src/actions-live.cpp 2016-04-05 21:00:09 +0000
27+++ src/actions-live.cpp 2016-04-12 17:27:17 +0000
28@@ -17,6 +17,7 @@
29 * Charles Kerr <charles.kerr@canonical.com>
30 */
31
32+#include <datetime/dbus-shared.h>
33 #include <datetime/actions-live.h>
34
35 #include <url-dispatcher.h>
36@@ -252,7 +253,7 @@
37 else
38 {
39 g_dbus_proxy_call(proxy,
40- "SetTimezone",
41+ Bus::Timedate1::Methods::SET_TIMEZONE,
42 g_variant_new ("(sb)", data->tzid.c_str(), TRUE),
43 G_DBUS_CALL_FLAGS_NONE,
44 -1,
45@@ -280,9 +281,9 @@
46 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
47 G_DBUS_PROXY_FLAGS_NONE,
48 nullptr,
49- "org.freedesktop.timedate1",
50- "/org/freedesktop/timedate1",
51- "org.freedesktop.timedate1",
52+ Bus::Timedate1::BUSNAME,
53+ Bus::Timedate1::ADDR,
54+ Bus::Timedate1::IFACE,
55 nullptr,
56 on_datetime1_proxy_ready,
57 data);
58
59=== modified file 'tests/glib-fixture.h'
60--- tests/glib-fixture.h 2016-02-10 20:47:39 +0000
61+++ tests/glib-fixture.h 2016-04-12 17:27:17 +0000
62@@ -125,10 +125,11 @@
63 }
64 }
65
66- bool wait_for_name_owned(GDBusConnection* connection,
67- const gchar* name,
68- guint timeout_msec=1000,
69- GBusNameWatcherFlags flags=G_BUS_NAME_WATCHER_FLAGS_AUTO_START)
70+ bool wait_for_name_owned(
71+ GDBusConnection* connection,
72+ const gchar* name,
73+ guint timeout_msec=1000,
74+ GBusNameWatcherFlags flags=G_BUS_NAME_WATCHER_FLAGS_AUTO_START)
75 {
76 struct Data {
77 GMainLoop* loop = nullptr;
78@@ -139,8 +140,7 @@
79 auto on_name_appeared = [](GDBusConnection* /*connection*/,
80 const gchar* /*name_*/,
81 const gchar* name_owner,
82- gpointer gdata)
83- {
84+ gpointer gdata){
85 if (name_owner == nullptr)
86 return;
87 auto tmp = static_cast<Data*>(gdata);
88@@ -150,13 +150,16 @@
89
90 const auto timeout_id = g_timeout_add(timeout_msec, wait_msec__timeout, loop);
91 data.loop = loop;
92- const auto watch_id = g_bus_watch_name_on_connection(connection,
93- name,
94- flags,
95- on_name_appeared,
96- nullptr, /* name_vanished */
97- &data,
98- nullptr); /* user_data_free_func */
99+ const auto watch_id = g_bus_watch_name_on_connection(
100+ connection,
101+ name,
102+ flags,
103+ on_name_appeared,
104+ nullptr, // name_vanished
105+ &data,
106+ nullptr // user_data_free_func
107+ );
108+
109 g_main_loop_run(loop);
110
111 g_bus_unwatch_name(watch_id);
112
113=== modified file 'tests/test-live-actions.cpp'
114--- tests/test-live-actions.cpp 2016-03-21 17:32:39 +0000
115+++ tests/test-live-actions.cpp 2016-04-12 17:27:17 +0000
116@@ -17,18 +17,75 @@
117 * Charles Kerr <charles.kerr@canonical.com>
118 */
119
120+#include "state-mock.h"
121 #include "timedated-fixture.h"
122
123+#include <datetime/actions-live.h>
124+
125+using namespace unity::indicator::datetime;
126+
127+class MockLiveActions: public LiveActions
128+{
129+public:
130+ std::string last_cmd;
131+ std::string last_url;
132+ explicit MockLiveActions(const std::shared_ptr<State>& state_in): LiveActions(state_in) {}
133+ ~MockLiveActions() {}
134+
135+protected:
136+ void dispatch_url(const std::string& url) override { last_url = url; }
137+ void execute_command(const std::string& cmd) override { last_cmd = cmd; }
138+};
139+
140+class TestLiveActionsFixture: public TimedatedFixture
141+{
142+private:
143+
144+ using super = TimedatedFixture;
145+
146+protected:
147+
148+ std::shared_ptr<MockState> m_mock_state;
149+ std::shared_ptr<State> m_state;
150+ std::shared_ptr<MockLiveActions> m_live_actions;
151+ std::shared_ptr<Actions> m_actions;
152+
153+ void SetUp() override
154+ {
155+ super::SetUp();
156+
157+ // create the State and Actions
158+ m_mock_state.reset(new MockState);
159+ m_mock_state->settings.reset(new Settings);
160+ m_state = std::dynamic_pointer_cast<State>(m_mock_state);
161+ m_live_actions.reset(new MockLiveActions(m_state));
162+ m_actions = std::dynamic_pointer_cast<Actions>(m_live_actions);
163+
164+ // start the timedate1 dbusmock
165+ start_timedate1("Etc/Utc");
166+ }
167+
168+ void TearDown() override
169+ {
170+ m_actions.reset();
171+ m_live_actions.reset();
172+ m_state.reset();
173+ m_mock_state.reset();
174+
175+ super::TearDown();
176+ }
177+};
178+
179 /***
180 ****
181 ***/
182
183-TEST_F(TimedateFixture, HelloWorld)
184+TEST_F(TestLiveActionsFixture, HelloWorld)
185 {
186 EXPECT_TRUE(true);
187 }
188
189-TEST_F(TimedateFixture, SetLocation)
190+TEST_F(TestLiveActionsFixture, SetLocation)
191 {
192 const std::string tzid = "America/Chicago";
193 const std::string name = "Oklahoma City";
194@@ -36,30 +93,31 @@
195
196 EXPECT_NE(expected, m_state->settings->timezone_name.get());
197
198+ std::string new_name;
199+ m_state->settings->timezone_name.changed().connect(
200+ [&new_name](const std::string& n){new_name = n;}
201+ );
202+
203 m_actions->set_location(tzid, name);
204- m_state->settings->timezone_name.changed().connect(
205- [this](const std::string&){
206- g_main_loop_quit(loop);
207- });
208- g_main_loop_run(loop);
209- EXPECT_EQ(attempted_tzid, tzid);
210- wait_msec();
211
212+ EXPECT_TRUE(wait_for([&new_name](){return !new_name.empty();}));
213+ EXPECT_EQ(expected, new_name);
214 EXPECT_EQ(expected, m_state->settings->timezone_name.get());
215+ EXPECT_EQ(tzid, get_timedate1_timezone());
216 }
217
218 /***
219 ****
220 ***/
221
222-TEST_F(TimedateFixture, DesktopOpenAlarmApp)
223+TEST_F(TestLiveActionsFixture, DesktopOpenAlarmApp)
224 {
225 m_actions->desktop_open_alarm_app();
226 const std::string expected = "evolution -c calendar";
227 EXPECT_EQ(expected, m_live_actions->last_cmd);
228 }
229
230-TEST_F(TimedateFixture, DesktopOpenAppointment)
231+TEST_F(TestLiveActionsFixture, DesktopOpenAppointment)
232 {
233 Appointment a;
234 a.uid = "some-uid";
235@@ -69,14 +127,14 @@
236 EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
237 }
238
239-TEST_F(TimedateFixture, DesktopOpenCalendarApp)
240+TEST_F(TestLiveActionsFixture, DesktopOpenCalendarApp)
241 {
242 m_actions->desktop_open_calendar_app(DateTime::NowLocal());
243 const std::string expected_substr = "evolution \"calendar:///?startdate=";
244 EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos);
245 }
246
247-TEST_F(TimedateFixture, DesktopOpenSettingsApp)
248+TEST_F(TestLiveActionsFixture, DesktopOpenSettingsApp)
249 {
250 m_actions->desktop_open_settings_app();
251 const std::string expected_substr = "control-center";
252@@ -92,13 +150,13 @@
253 const std::string clock_app_url = "appid://com.ubuntu.clock/clock/current-user-version";
254 }
255
256-TEST_F(TimedateFixture, PhoneOpenAlarmApp)
257+TEST_F(TestLiveActionsFixture, PhoneOpenAlarmApp)
258 {
259 m_actions->phone_open_alarm_app();
260 EXPECT_EQ(clock_app_url, m_live_actions->last_url);
261 }
262
263-TEST_F(TimedateFixture, PhoneOpenAppointment)
264+TEST_F(TestLiveActionsFixture, PhoneOpenAppointment)
265 {
266 Appointment a;
267
268@@ -116,7 +174,7 @@
269 EXPECT_EQ(clock_app_url, m_live_actions->last_url);
270 }
271
272-TEST_F(TimedateFixture, PhoneOpenCalendarApp)
273+TEST_F(TestLiveActionsFixture, PhoneOpenCalendarApp)
274 {
275 auto now = DateTime::NowLocal();
276 m_actions->phone_open_calendar_app(now);
277@@ -125,7 +183,7 @@
278 }
279
280
281-TEST_F(TimedateFixture, PhoneOpenSettingsApp)
282+TEST_F(TestLiveActionsFixture, PhoneOpenSettingsApp)
283 {
284 m_actions->phone_open_settings_app();
285 const std::string expected = "settings:///system/time-date";
286@@ -136,7 +194,7 @@
287 ****
288 ***/
289
290-TEST_F(TimedateFixture, CalendarState)
291+TEST_F(TestLiveActionsFixture, CalendarState)
292 {
293 // init the clock
294 auto now = DateTime::Local(2014, 1, 1, 0, 0, 0);
295
296=== modified file 'tests/test-timezone-timedated.cpp'
297--- tests/test-timezone-timedated.cpp 2016-04-12 17:27:17 +0000
298+++ tests/test-timezone-timedated.cpp 2016-04-12 17:27:17 +0000
299@@ -18,119 +18,26 @@
300 * Ted Gould <ted.gould@canonical.com>
301 */
302
303-#include "glib-fixture.h"
304+#include "timedated-fixture.h"
305
306-#include <datetime/dbus-shared.h>
307 #include <datetime/timezone-timedated.h>
308
309-#include <gio/gio.h>
310-
311-
312 using namespace unity::indicator::datetime;
313
314-
315-struct Timedate1Fixture: public GlibFixture
316-{
317-private:
318-
319- typedef GlibFixture super;
320-
321-protected:
322-
323- GDBusConnection* m_bus {};
324- GTestDBus* m_test_bus {};
325-
326- void SetUp() override
327- {
328- super::SetUp();
329-
330- // use a fake bus
331- m_test_bus = g_test_dbus_new(G_TEST_DBUS_NONE);
332- g_test_dbus_up(m_test_bus);
333- const char * address = g_test_dbus_get_bus_address(m_test_bus);
334- g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true);
335- g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true);
336- g_debug("test_dbus's address is %s", address);
337-
338- // get the bus
339- m_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
340- g_dbus_connection_set_exit_on_close(m_bus, FALSE);
341- }
342-
343- void TearDown() override
344- {
345- // tear down the bus
346- bool bus_finished = false;
347- g_object_weak_ref(
348- G_OBJECT(m_bus),
349- [](gpointer gbus_finished, GObject*){*static_cast<bool*>(gbus_finished) = true;},
350- &bus_finished
351- );
352- g_clear_object(&m_bus);
353- EXPECT_TRUE(wait_for([&bus_finished](){return bus_finished;}));
354-
355- // tear down test bus
356- g_clear_object(&m_test_bus);
357-
358- super::TearDown();
359- }
360-
361- void start_timedate1(const std::string& tzid)
362- {
363- // start dbusmock with the timedated template
364- auto json_parameters = g_strdup_printf("{\"Timezone\": \"%s\"}", tzid.c_str());
365- const gchar* child_argv[] = { "python3", "-m", "dbusmock", "--template", "timedated", "--parameters", json_parameters, nullptr };
366- GError* error = nullptr;
367- g_spawn_async(nullptr, (gchar**)child_argv, nullptr, G_SPAWN_SEARCH_PATH, nullptr, nullptr, nullptr, &error);
368- g_assert_no_error(error);
369- g_free(json_parameters);
370-
371- // wait for it to appear on the bus
372- wait_for_name_owned(m_bus, Bus::Timedate1::BUSNAME);
373- }
374-
375- bool wait_for_tzid(const std::string& tzid, Timezone& tz)
376- {
377- return wait_for([&tzid, &tz](){return tzid == tz.timezone.get();});
378- }
379-
380- void set_timedate1_timezone(const std::string& tzid)
381- {
382- GError* error {};
383- auto v = g_dbus_connection_call_sync(
384- m_bus,
385- Bus::Timedate1::BUSNAME,
386- Bus::Timedate1::ADDR,
387- Bus::Timedate1::IFACE,
388- Bus::Timedate1::Methods::SET_TIMEZONE,
389- g_variant_new("(sb)", tzid.c_str(), FALSE),
390- nullptr,
391- G_DBUS_CALL_FLAGS_NONE,
392- -1,
393- nullptr,
394- &error);
395- g_clear_pointer(&v, g_variant_unref);
396- g_assert_no_error(error);
397- }
398-};
399-
400-#define EXPECT_TZID(expected_tzid, tmp) \
401- EXPECT_TRUE(wait_for_tzid(expected_tzid, tmp)) \
402- << "expected " << expected_tzid \
403- << " got " << tmp.timezone.get();
404+using TestTimedatedFixture = TimedatedFixture;
405
406 /***
407 ****
408 ***/
409
410-TEST_F(Timedate1Fixture, HelloWorld)
411+TEST_F(TestTimedatedFixture, HelloWorld)
412 {
413 }
414
415 /**
416 * Test that the tzid is right if timedated isn't available
417 */
418-TEST_F(Timedate1Fixture, DefaultTimezone)
419+TEST_F(TestTimedatedFixture, DefaultTimezone)
420 {
421 const std::string expected_tzid{"Etc/Utc"};
422
423@@ -141,7 +48,7 @@
424 /**
425 * Test that the tzid is right if timedated shows BEFORE we start
426 */
427-TEST_F(Timedate1Fixture, Timedate1First)
428+TEST_F(TestTimedatedFixture, Timedate1First)
429 {
430 const std::string expected_tzid{"America/Chicago"};
431
432@@ -153,7 +60,7 @@
433 /**
434 * Test that the tzid is right if timedated shows AFTER we start
435 */
436-TEST_F(Timedate1Fixture, Timedate1Last)
437+TEST_F(TestTimedatedFixture, Timedate1Last)
438 {
439 const std::string expected_tzid("America/Los_Angeles");
440
441@@ -165,7 +72,7 @@
442 /**
443 * Test that the tzid is right if timedated's property changes
444 */
445-TEST_F(Timedate1Fixture, TimezoneChange)
446+TEST_F(TestTimedatedFixture, TimezoneChange)
447 {
448 const std::vector<std::string> expected_tzids{"America/Los_Angeles", "America/Chicago", "Etc/Utc"};
449
450
451=== modified file 'tests/timedated-fixture.h'
452--- tests/timedated-fixture.h 2015-09-03 09:54:20 +0000
453+++ tests/timedated-fixture.h 2016-04-12 17:27:17 +0000
454@@ -17,285 +17,142 @@
455 * Charles Kerr <charles.kerr@canonical.com>
456 */
457
458-#ifndef INDICATOR_DATETIME_TESTS_TIMEDATED_FIXTURE_H
459-#define INDICATOR_DATETIME_TESTS_TIMEDATED_FIXTURE_H
460+#pragma once
461
462 #include <datetime/actions-live.h>
463
464-#include "state-mock.h"
465 #include "glib-fixture.h"
466
467-using namespace unity::indicator::datetime;
468-
469-class MockLiveActions: public LiveActions
470-{
471-public:
472- std::string last_cmd;
473- std::string last_url;
474- explicit MockLiveActions(const std::shared_ptr<State>& state_in): LiveActions(state_in) {}
475- ~MockLiveActions() {}
476-
477-protected:
478- void dispatch_url(const std::string& url) override { last_url = url; }
479- void execute_command(const std::string& cmd) override { last_cmd = cmd; }
480-};
481+#include <datetime/dbus-shared.h>
482+#include <datetime/timezone.h>
483
484 /***
485 ****
486 ***/
487
488-using namespace unity::indicator::datetime;
489-
490-class TimedateFixture: public GlibFixture
491+struct TimedatedFixture: public GlibFixture
492 {
493 private:
494
495- typedef GlibFixture super;
496-
497- static GVariant * timedate1_get_properties (GDBusConnection * /*connection*/ ,
498- const gchar * /*sender*/,
499- const gchar * /*object_path*/,
500- const gchar * /*interface_name*/,
501- const gchar *property_name,
502- GError ** /*error*/,
503- gpointer gself)
504-
505- {
506- auto self = static_cast<TimedateFixture*>(gself);
507- g_debug("get_properties called");
508- if (g_strcmp0(property_name, "Timezone") == 0)
509- {
510- g_debug("timezone requested, giving '%s'",
511- self->attempted_tzid.c_str());
512- return g_variant_new_string(self->attempted_tzid.c_str());
513- }
514- return nullptr;
515- }
516-
517-
518- static void on_bus_acquired(GDBusConnection* conn,
519- const gchar* name,
520- gpointer gself)
521- {
522- auto self = static_cast<TimedateFixture*>(gself);
523- g_debug("bus acquired: %s, connection is %p", name, conn);
524-
525- /* Set up a fake timedated which handles setting and getting the
526- ** timezone
527- */
528- static const GDBusInterfaceVTable vtable = {
529- timedate1_handle_method_call,
530- timedate1_get_properties, /* GetProperty */
531- nullptr, /* SetProperty */
532- };
533-
534- self->connection = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(conn)));
535-
536- GError* error = nullptr;
537- self->object_register_id = g_dbus_connection_register_object(
538- conn,
539- "/org/freedesktop/timedate1",
540- self->node_info->interfaces[0],
541- &vtable,
542- self,
543- nullptr,
544- &error);
545- g_assert_no_error(error);
546- }
547-
548- static void on_name_acquired(GDBusConnection* conn,
549- const gchar* name,
550- gpointer gself)
551- {
552- g_debug("on_name_acquired");
553- auto self = static_cast<TimedateFixture*>(gself);
554- self->name_acquired = true;
555- self->proxy = g_dbus_proxy_new_sync(conn,
556- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
557- nullptr,
558- name,
559- "/org/freedesktop/timedate1",
560- "org.freedesktop.timedate1",
561- nullptr,
562- nullptr);
563- g_main_loop_quit(self->loop);
564- }
565-
566- static void on_name_lost(GDBusConnection* /*conn*/,
567- const gchar* /*name*/,
568- gpointer gself)
569- {
570- g_debug("on_name_lost");
571- auto self = static_cast<TimedateFixture*>(gself);
572- self->name_acquired = false;
573- }
574-
575- static void on_bus_closed(GObject* /*object*/,
576- GAsyncResult* res,
577- gpointer gself)
578- {
579- g_debug("on_bus_closed");
580- auto self = static_cast<TimedateFixture*>(gself);
581- GError* err = nullptr;
582- g_dbus_connection_close_finish(self->connection, res, &err);
583- g_assert_no_error(err);
584- g_main_loop_quit(self->loop);
585- }
586-
587- static void
588- timedate1_handle_method_call(GDBusConnection * connection,
589- const gchar * /*sender*/,
590- const gchar * object_path,
591- const gchar * interface_name,
592- const gchar * method_name,
593- GVariant * parameters,
594- GDBusMethodInvocation * invocation,
595- gpointer gself)
596- {
597- g_assert(!g_strcmp0(method_name, "SetTimezone"));
598- g_assert(g_variant_is_of_type(parameters, G_VARIANT_TYPE_TUPLE));
599- g_assert(2 == g_variant_n_children(parameters));
600-
601- auto child = g_variant_get_child_value(parameters, 0);
602- g_assert(g_variant_is_of_type(child, G_VARIANT_TYPE_STRING));
603- auto self = static_cast<TimedateFixture*>(gself);
604- self->attempted_tzid = g_variant_get_string(child, nullptr);
605- g_debug("set tz (dbus side): '%s'", self->attempted_tzid.c_str());
606- g_dbus_method_invocation_return_value(invocation, nullptr);
607-
608- /* Send PropertiesChanged */
609- GError * local_error = nullptr;
610- auto builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
611- g_variant_builder_add (builder,
612- "{sv}",
613- "Timezone",
614- g_variant_new_string(
615- self->attempted_tzid.c_str()));
616- g_dbus_connection_emit_signal (connection,
617- NULL,
618- object_path,
619- "org.freedesktop.DBus.Properties",
620- "PropertiesChanged",
621- g_variant_new ("(sa{sv}as)",
622- interface_name,
623- builder,
624- NULL),
625- &local_error);
626- g_assert_no_error (local_error);
627- g_variant_unref(child);
628- }
629+ using super = GlibFixture;
630
631 protected:
632
633- std::shared_ptr<MockState> m_mock_state;
634- std::shared_ptr<State> m_state;
635- std::shared_ptr<MockLiveActions> m_live_actions;
636- std::shared_ptr<Actions> m_actions;
637-
638- bool name_acquired;
639- std::string attempted_tzid;
640-
641- GTestDBus* bus;
642- guint own_name;
643- GDBusConnection* connection;
644- GDBusNodeInfo* node_info;
645- int object_register_id;
646- GDBusProxy *proxy;
647-
648- void SetUp()
649+ GDBusConnection* m_bus {};
650+ GTestDBus* m_test_bus {};
651+
652+ virtual void SetUp() override
653 {
654 super::SetUp();
655- g_debug("SetUp");
656-
657- name_acquired = false;
658- attempted_tzid.clear();
659- connection = nullptr;
660- node_info = nullptr;
661- object_register_id = 0;
662- own_name = 0;
663- proxy = nullptr;
664-
665- // bring up the test bus
666- bus = g_test_dbus_new(G_TEST_DBUS_NONE);
667- g_test_dbus_up(bus);
668- const auto address = g_test_dbus_get_bus_address(bus);
669+
670+ // use a fake bus
671+ m_test_bus = g_test_dbus_new(G_TEST_DBUS_NONE);
672+ g_test_dbus_up(m_test_bus);
673+ const char * address = g_test_dbus_get_bus_address(m_test_bus);
674 g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true);
675 g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true);
676 g_debug("test_dbus's address is %s", address);
677
678- // parse the org.freedesktop.timedate1 interface
679- const gchar introspection_xml[] =
680- "<node>"
681- " <interface name='org.freedesktop.timedate1'>"
682- " <property name='Timezone' type='s' access='read' />"
683- " <method name='SetTimezone'>"
684- " <arg name='timezone' type='s' direction='in'/>"
685- " <arg name='user_interaction' type='b' direction='in'/>"
686- " </method>"
687- " </interface>"
688- "</node>";
689- node_info = g_dbus_node_info_new_for_xml(introspection_xml, nullptr);
690- ASSERT_TRUE(node_info != nullptr);
691- ASSERT_TRUE(node_info->interfaces != nullptr);
692- ASSERT_TRUE(node_info->interfaces[0] != nullptr);
693- ASSERT_TRUE(node_info->interfaces[1] == nullptr);
694- ASSERT_STREQ("org.freedesktop.timedate1", node_info->interfaces[0]->name);
695-
696- // own the bus
697- own_name = g_bus_own_name(G_BUS_TYPE_SYSTEM,
698- "org.freedesktop.timedate1",
699- G_BUS_NAME_OWNER_FLAGS_NONE,
700- on_bus_acquired, on_name_acquired, on_name_lost,
701- this, nullptr);
702- ASSERT_TRUE(object_register_id == 0);
703- ASSERT_FALSE(name_acquired);
704- ASSERT_TRUE(connection == nullptr);
705- g_main_loop_run(loop);
706- ASSERT_TRUE(object_register_id != 0);
707- ASSERT_TRUE(name_acquired);
708- ASSERT_TRUE(G_IS_DBUS_CONNECTION(connection));
709-
710- // create the State and Actions
711- m_mock_state.reset(new MockState);
712- m_mock_state->settings.reset(new Settings);
713- m_state = std::dynamic_pointer_cast<State>(m_mock_state);
714- m_live_actions.reset(new MockLiveActions(m_state));
715- m_actions = std::dynamic_pointer_cast<Actions>(m_live_actions);
716+ // get the bus
717+ m_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
718+ g_dbus_connection_set_exit_on_close(m_bus, FALSE);
719+ g_object_add_weak_pointer(G_OBJECT(m_bus), (gpointer*)&m_bus);
720 }
721
722- void TearDown()
723+ virtual void TearDown() override
724 {
725- g_debug("TearDown");
726- m_actions.reset();
727- m_live_actions.reset();
728- m_state.reset();
729- m_mock_state.reset();
730- g_dbus_connection_unregister_object(connection, object_register_id);
731- g_object_unref(proxy);
732- g_dbus_node_info_unref(node_info);
733- g_bus_unown_name(own_name);
734- g_dbus_connection_close(connection, nullptr, on_bus_closed, this);
735- g_main_loop_run(loop);
736- g_clear_object(&connection);
737- g_test_dbus_down(bus);
738- g_clear_object(&bus);
739+ // take down the bus
740+ bool bus_finished = false;
741+ g_object_weak_ref(
742+ G_OBJECT(m_bus),
743+ [](gpointer gbus_finished, GObject*){*static_cast<bool*>(gbus_finished) = true;},
744+ &bus_finished
745+ );
746+ g_clear_object(&m_bus);
747+ EXPECT_TRUE(wait_for([&bus_finished](){return bus_finished;}));
748+
749+ // take down the GTestBus
750+ g_clear_object(&m_test_bus);
751
752 super::TearDown();
753 }
754-public:
755- void set_timezone(std::string tz)
756- {
757- g_debug("set_timezone: '%s'", tz.c_str());
758- g_dbus_proxy_call_sync(proxy,
759- "SetTimezone",
760- g_variant_new("(sb)",
761- tz.c_str(),
762- FALSE),
763- G_DBUS_CALL_FLAGS_NONE,
764- 500,
765- nullptr,
766- nullptr);
767+
768+ void start_timedate1(const std::string& tzid)
769+ {
770+ // start dbusmock with the timedated template
771+ auto json_parameters = g_strdup_printf("{\"Timezone\": \"%s\"}", tzid.c_str());
772+ const gchar* child_argv[] = {
773+ "python3", "-m", "dbusmock",
774+ "--template", "timedated",
775+ "--parameters", json_parameters,
776+ nullptr
777+ };
778+ GError* error = nullptr;
779+ g_spawn_async(nullptr, (gchar**)child_argv, nullptr, G_SPAWN_SEARCH_PATH, nullptr, nullptr, nullptr, &error);
780+ g_assert_no_error(error);
781+ g_free(json_parameters);
782+
783+ // wait for it to appear on the bus
784+ wait_for_name_owned(m_bus, Bus::Timedate1::BUSNAME);
785+ }
786+
787+ bool wait_for_tzid(const std::string& tzid, unity::indicator::datetime::Timezone& tz)
788+ {
789+ return wait_for([&tzid, &tz](){return tzid == tz.timezone.get();});
790+ }
791+
792+ void set_timedate1_timezone(const std::string& tzid)
793+ {
794+ GError* error {};
795+ auto v = g_dbus_connection_call_sync(
796+ m_bus,
797+ Bus::Timedate1::BUSNAME,
798+ Bus::Timedate1::ADDR,
799+ Bus::Timedate1::IFACE,
800+ Bus::Timedate1::Methods::SET_TIMEZONE,
801+ g_variant_new("(sb)", tzid.c_str(), FALSE),
802+ nullptr,
803+ G_DBUS_CALL_FLAGS_NONE,
804+ -1,
805+ nullptr,
806+ &error);
807+ g_assert_no_error(error);
808+
809+ g_clear_pointer(&v, g_variant_unref);
810+ }
811+
812+ std::string get_timedate1_timezone()
813+ {
814+ GError* error {};
815+ auto v = g_dbus_connection_call_sync(
816+ m_bus,
817+ Bus::Timedate1::BUSNAME,
818+ Bus::Timedate1::ADDR,
819+ Bus::Properties::IFACE,
820+ Bus::Properties::Methods::GET,
821+ g_variant_new("(ss)", Bus::Timedate1::IFACE, Bus::Timedate1::Properties::TIMEZONE),
822+ G_VARIANT_TYPE("(v)"),
823+ G_DBUS_CALL_FLAGS_NONE,
824+ -1,
825+ nullptr,
826+ &error);
827+ g_assert_no_error(error);
828+
829+ GVariant* tzv {};
830+ g_variant_get(v, "(v)", &tzv);
831+ std::string tzid;
832+ const char* tz = g_variant_get_string(tzv, nullptr);
833+ if (tz != nullptr)
834+ tzid = tz;
835+
836+ g_clear_pointer(&tzv, g_variant_unref);
837+ g_clear_pointer(&v, g_variant_unref);
838+ return tzid;
839 }
840 };
841
842-#endif
843+#define EXPECT_TZID(expected_tzid, tmp) \
844+ EXPECT_TRUE(wait_for_tzid(expected_tzid, tmp)) \
845+ << "expected " << expected_tzid \
846+ << " got " << tmp.timezone.get();
847+

Subscribers

People subscribed via source and target branches