Merge lp:~charlesk/indicator-datetime/lp-1560960-use-dbusmock-timedated-template into lp:indicator-datetime/15.10
- lp-1560960-use-dbusmock-timedated-template
- Merge into trunk.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 |
Related bugs: |
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:/
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 | + |
PASSED: Continuous integration, rev:448 jenkins. qa.ubuntu. com/job/ indicator- datetime- ci/372/ jenkins. qa.ubuntu. com/job/ indicator- datetime- wily-amd64- ci/62 jenkins. qa.ubuntu. com/job/ indicator- datetime- wily-armhf- ci/62 jenkins. qa.ubuntu. com/job/ indicator- datetime- wily-armhf- ci/62/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- datetime- ci/372/ rebuild
http://