Merge lp:~ted/indicator-sound/eventually-testing into lp:indicator-sound/15.10
- eventually-testing
- Merge into trunk.15.10
Status: | Merged |
---|---|
Approved by: | Charles Kerr |
Approved revision: | 505 |
Merged at revision: | 497 |
Proposed branch: | lp:~ted/indicator-sound/eventually-testing |
Merge into: | lp:indicator-sound/15.10 |
Diff against target: |
249 lines (+142/-20) 2 files modified
debian/changelog (+6/-0) tests/media-player-user.cc (+136/-20) |
To merge this branch: | bzr merge lp:~ted/indicator-sound/eventually-testing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Charles Kerr (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+260373@code.launchpad.net |
Commit message
Using eventually to avoid arbitrary timeouts in tests
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:503
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:505
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Charles Kerr (charlesk) wrote : | # |
Nice improvements all around.
Preview Diff
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2015-05-07 15:27:00 +0000 | |||
3 | +++ debian/changelog 2015-05-28 15:03:10 +0000 | |||
4 | @@ -1,3 +1,9 @@ | |||
5 | 1 | indicator-sound (12.10.2+15.10.20150507+eventually4-0ubuntu1) wily; urgency=medium | ||
6 | 2 | |||
7 | 3 | * Using eventually to avoid arbitrary timeouts in tests | ||
8 | 4 | |||
9 | 5 | -- Ted Gould <ted@ubuntu.com> Wed, 27 May 2015 11:11:19 -0500 | ||
10 | 6 | |||
11 | 1 | indicator-sound (12.10.2+15.10.20150507-0ubuntu1) wily; urgency=medium | 7 | indicator-sound (12.10.2+15.10.20150507-0ubuntu1) wily; urgency=medium |
12 | 2 | 8 | ||
13 | 3 | [ Charles Kerr ] | 9 | [ Charles Kerr ] |
14 | 4 | 10 | ||
15 | === modified file 'tests/media-player-user.cc' | |||
16 | --- tests/media-player-user.cc 2015-01-30 16:05:10 +0000 | |||
17 | +++ tests/media-player-user.cc 2015-05-28 15:03:10 +0000 | |||
18 | @@ -17,6 +17,9 @@ | |||
19 | 17 | * Ted Gould <ted@canonical.com> | 17 | * Ted Gould <ted@canonical.com> |
20 | 18 | */ | 18 | */ |
21 | 19 | 19 | ||
22 | 20 | #include <chrono> | ||
23 | 21 | #include <future> | ||
24 | 22 | |||
25 | 20 | #include <gtest/gtest.h> | 23 | #include <gtest/gtest.h> |
26 | 21 | #include <gio/gio.h> | 24 | #include <gio/gio.h> |
27 | 22 | #include <libdbustest/dbus-test.h> | 25 | #include <libdbustest/dbus-test.h> |
28 | @@ -31,24 +34,55 @@ | |||
29 | 31 | { | 34 | { |
30 | 32 | 35 | ||
31 | 33 | protected: | 36 | protected: |
33 | 34 | DbusTestService * service = NULL; | 37 | DbusTestService * testsystem = NULL; |
34 | 35 | AccountsServiceMock service_mock; | 38 | AccountsServiceMock service_mock; |
35 | 36 | 39 | ||
36 | 40 | DbusTestService * testsession = NULL; | ||
37 | 41 | |||
38 | 42 | DbusTestProcess * systemmonitor = nullptr; | ||
39 | 43 | DbusTestProcess * sessionmonitor = nullptr; | ||
40 | 44 | |||
41 | 37 | GDBusConnection * system = NULL; | 45 | GDBusConnection * system = NULL; |
42 | 46 | GDBusConnection * session = NULL; | ||
43 | 38 | GDBusProxy * proxy = NULL; | 47 | GDBusProxy * proxy = NULL; |
44 | 39 | 48 | ||
45 | 49 | std::chrono::milliseconds _eventuallyTime = std::chrono::seconds{5}; | ||
46 | 50 | |||
47 | 40 | virtual void SetUp() { | 51 | virtual void SetUp() { |
53 | 41 | service = dbus_test_service_new(NULL); | 52 | /* System Bus */ |
54 | 42 | dbus_test_service_set_bus(service, DBUS_TEST_SERVICE_BUS_SYSTEM); | 53 | testsystem = dbus_test_service_new(NULL); |
55 | 43 | 54 | dbus_test_service_set_bus(testsystem, DBUS_TEST_SERVICE_BUS_SYSTEM); | |
56 | 44 | dbus_test_service_add_task(service, (DbusTestTask*)service_mock); | 55 | |
57 | 45 | dbus_test_service_start_tasks(service); | 56 | systemmonitor = dbus_test_process_new("dbus-monitor"); |
58 | 57 | dbus_test_process_append_param(systemmonitor, "--system"); | ||
59 | 58 | dbus_test_task_set_name(DBUS_TEST_TASK(systemmonitor), "System"); | ||
60 | 59 | dbus_test_service_add_task(testsystem, DBUS_TEST_TASK(systemmonitor)); | ||
61 | 60 | |||
62 | 61 | dbus_test_service_add_task(testsystem, (DbusTestTask*)service_mock); | ||
63 | 62 | dbus_test_service_start_tasks(testsystem); | ||
64 | 46 | 63 | ||
65 | 47 | system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); | 64 | system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); |
66 | 48 | ASSERT_NE(nullptr, system); | 65 | ASSERT_NE(nullptr, system); |
67 | 49 | g_dbus_connection_set_exit_on_close(system, FALSE); | 66 | g_dbus_connection_set_exit_on_close(system, FALSE); |
68 | 50 | g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); | 67 | g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); |
69 | 51 | 68 | ||
70 | 69 | /* Session Bus */ | ||
71 | 70 | testsession = dbus_test_service_new(NULL); | ||
72 | 71 | dbus_test_service_set_bus(testsession, DBUS_TEST_SERVICE_BUS_SESSION); | ||
73 | 72 | |||
74 | 73 | sessionmonitor = dbus_test_process_new("dbus-monitor"); | ||
75 | 74 | dbus_test_process_append_param(sessionmonitor, "--session"); | ||
76 | 75 | dbus_test_task_set_name(DBUS_TEST_TASK(sessionmonitor), "Session"); | ||
77 | 76 | dbus_test_service_add_task(testsession, DBUS_TEST_TASK(sessionmonitor)); | ||
78 | 77 | |||
79 | 78 | dbus_test_service_start_tasks(testsession); | ||
80 | 79 | |||
81 | 80 | session = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); | ||
82 | 81 | ASSERT_NE(nullptr, session); | ||
83 | 82 | g_dbus_connection_set_exit_on_close(session, FALSE); | ||
84 | 83 | g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session); | ||
85 | 84 | |||
86 | 85 | /* Setup proxy */ | ||
87 | 52 | proxy = g_dbus_proxy_new_sync(system, | 86 | proxy = g_dbus_proxy_new_sync(system, |
88 | 53 | G_DBUS_PROXY_FLAGS_NONE, | 87 | G_DBUS_PROXY_FLAGS_NONE, |
89 | 54 | NULL, | 88 | NULL, |
90 | @@ -60,10 +94,15 @@ | |||
91 | 60 | } | 94 | } |
92 | 61 | 95 | ||
93 | 62 | virtual void TearDown() { | 96 | virtual void TearDown() { |
94 | 97 | g_clear_object(&sessionmonitor); | ||
95 | 98 | g_clear_object(&systemmonitor); | ||
96 | 99 | |||
97 | 63 | g_clear_object(&proxy); | 100 | g_clear_object(&proxy); |
99 | 64 | g_clear_object(&service); | 101 | g_clear_object(&testsystem); |
100 | 102 | g_clear_object(&testsession); | ||
101 | 65 | 103 | ||
102 | 66 | g_object_unref(system); | 104 | g_object_unref(system); |
103 | 105 | g_object_unref(session); | ||
104 | 67 | 106 | ||
105 | 68 | #if 0 | 107 | #if 0 |
106 | 69 | /* Accounts Service keeps a bunch of references around so we | 108 | /* Accounts Service keeps a bunch of references around so we |
107 | @@ -95,8 +134,78 @@ | |||
108 | 95 | void set_property (const gchar * name, GVariant * value) { | 134 | void set_property (const gchar * name, GVariant * value) { |
109 | 96 | dbus_test_dbus_mock_object_update_property((DbusTestDbusMock *)service_mock, service_mock.get_sound(), name, value, NULL); | 135 | dbus_test_dbus_mock_object_update_property((DbusTestDbusMock *)service_mock, service_mock.get_sound(), name, value, NULL); |
110 | 97 | } | 136 | } |
111 | 137 | |||
112 | 138 | testing::AssertionResult expectEventually (std::function<testing::AssertionResult(void)> &testfunc) { | ||
113 | 139 | auto loop = std::shared_ptr<GMainLoop>(g_main_loop_new(nullptr, FALSE), [](GMainLoop * loop) { if (loop != nullptr) g_main_loop_unref(loop); }); | ||
114 | 140 | |||
115 | 141 | std::promise<testing::AssertionResult> retpromise; | ||
116 | 142 | auto retfuture = retpromise.get_future(); | ||
117 | 143 | auto start = std::chrono::steady_clock::now(); | ||
118 | 144 | |||
119 | 145 | /* The core of the idle function as an object so we can use the C++-isms | ||
120 | 146 | of attaching the variables and make this code reasonably readable */ | ||
121 | 147 | std::function<void(void)> idlefunc = [&loop, &retpromise, &testfunc, &start, this]() -> void { | ||
122 | 148 | auto result = testfunc(); | ||
123 | 149 | |||
124 | 150 | if (result == false && _eventuallyTime > (std::chrono::steady_clock::now() - start)) { | ||
125 | 151 | return; | ||
126 | 152 | } | ||
127 | 153 | |||
128 | 154 | retpromise.set_value(result); | ||
129 | 155 | g_main_loop_quit(loop.get()); | ||
130 | 156 | }; | ||
131 | 157 | |||
132 | 158 | auto idlesrc = g_idle_add([](gpointer data) -> gboolean { | ||
133 | 159 | auto func = reinterpret_cast<std::function<void(void)> *>(data); | ||
134 | 160 | (*func)(); | ||
135 | 161 | return G_SOURCE_CONTINUE; | ||
136 | 162 | }, &idlefunc); | ||
137 | 163 | |||
138 | 164 | g_main_loop_run(loop.get()); | ||
139 | 165 | g_source_remove(idlesrc); | ||
140 | 166 | |||
141 | 167 | return retfuture.get(); | ||
142 | 168 | } | ||
143 | 169 | |||
144 | 170 | /* Eventually Helpers */ | ||
145 | 171 | #define _EVENTUALLY_HELPER(oper) \ | ||
146 | 172 | template <typename... Args> testing::AssertionResult expectEventually##oper (Args&& ... args) { \ | ||
147 | 173 | std::function<testing::AssertionResult(void)> func = [&]() { \ | ||
148 | 174 | return testing::internal::CmpHelper##oper(std::forward<Args>(args)...); \ | ||
149 | 175 | }; \ | ||
150 | 176 | return expectEventually(func); \ | ||
151 | 177 | } | ||
152 | 178 | |||
153 | 179 | _EVENTUALLY_HELPER(EQ); | ||
154 | 180 | _EVENTUALLY_HELPER(NE); | ||
155 | 181 | _EVENTUALLY_HELPER(LT); | ||
156 | 182 | _EVENTUALLY_HELPER(GT); | ||
157 | 183 | _EVENTUALLY_HELPER(STREQ); | ||
158 | 184 | _EVENTUALLY_HELPER(STRNE); | ||
159 | 185 | |||
160 | 186 | #undef _EVENTUALLY_HELPER | ||
161 | 98 | }; | 187 | }; |
162 | 99 | 188 | ||
163 | 189 | /* Helpers */ | ||
164 | 190 | #define EXPECT_EVENTUALLY_EQ(expected, actual) \ | ||
165 | 191 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyEQ, expected, actual) | ||
166 | 192 | |||
167 | 193 | #define EXPECT_EVENTUALLY_NE(expected, actual) \ | ||
168 | 194 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyNE, expected, actual) | ||
169 | 195 | |||
170 | 196 | #define EXPECT_EVENTUALLY_LT(expected, actual) \ | ||
171 | 197 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyLT, expected, actual) | ||
172 | 198 | |||
173 | 199 | #define EXPECT_EVENTUALLY_GT(expected, actual) \ | ||
174 | 200 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyGT, expected, actual) | ||
175 | 201 | |||
176 | 202 | #define EXPECT_EVENTUALLY_STREQ(expected, actual) \ | ||
177 | 203 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTREQ, expected, actual) | ||
178 | 204 | |||
179 | 205 | #define EXPECT_EVENTUALLY_STRNE(expected, actual) \ | ||
180 | 206 | EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTRNE, expected, actual) | ||
181 | 207 | |||
182 | 208 | |||
183 | 100 | TEST_F(MediaPlayerUserTest, BasicObject) { | 209 | TEST_F(MediaPlayerUserTest, BasicObject) { |
184 | 101 | MediaPlayerUser * player = media_player_user_new("user"); | 210 | MediaPlayerUser * player = media_player_user_new("user"); |
185 | 102 | ASSERT_NE(nullptr, player); | 211 | ASSERT_NE(nullptr, player); |
186 | @@ -125,6 +234,11 @@ | |||
187 | 125 | g_clear_object(&player); | 234 | g_clear_object(&player); |
188 | 126 | } | 235 | } |
189 | 127 | 236 | ||
190 | 237 | void | ||
191 | 238 | running_update (GObject * obj, GParamSpec * pspec, bool * running) { | ||
192 | 239 | *running = media_player_get_is_running(MEDIA_PLAYER(obj)) == TRUE; | ||
193 | 240 | }; | ||
194 | 241 | |||
195 | 128 | TEST_F(MediaPlayerUserTest, DataSet) { | 242 | TEST_F(MediaPlayerUserTest, DataSet) { |
196 | 129 | /* Put data into Acts */ | 243 | /* Put data into Acts */ |
197 | 130 | set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); | 244 | set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); |
198 | @@ -141,11 +255,11 @@ | |||
199 | 141 | MediaPlayerUser * player = media_player_user_new("user"); | 255 | MediaPlayerUser * player = media_player_user_new("user"); |
200 | 142 | ASSERT_NE(nullptr, player); | 256 | ASSERT_NE(nullptr, player); |
201 | 143 | 257 | ||
202 | 144 | /* Get the proxy -- and it's precious precious data -- oh, my, precious! */ | ||
203 | 145 | loop(100); | ||
204 | 146 | |||
205 | 147 | /* Ensure even with the proxy we don't have anything */ | 258 | /* Ensure even with the proxy we don't have anything */ |
207 | 148 | EXPECT_TRUE(media_player_get_is_running(MEDIA_PLAYER(player))); | 259 | bool running = false; |
208 | 260 | g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); | ||
209 | 261 | running_update(G_OBJECT(player), nullptr, &running); | ||
210 | 262 | EXPECT_EVENTUALLY_EQ(true, running); | ||
211 | 149 | EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); | 263 | EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); |
212 | 150 | EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); | 264 | EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); |
213 | 151 | EXPECT_STREQ("The Player Formerly Known as Prince", media_player_get_name(MEDIA_PLAYER(player))); | 265 | EXPECT_STREQ("The Player Formerly Known as Prince", media_player_get_name(MEDIA_PLAYER(player))); |
214 | @@ -180,24 +294,26 @@ | |||
215 | 180 | set_property("Album", g_variant_new_string("Vinyl is dead")); | 294 | set_property("Album", g_variant_new_string("Vinyl is dead")); |
216 | 181 | set_property("ArtUrl", g_variant_new_string("http://art.url")); | 295 | set_property("ArtUrl", g_variant_new_string("http://art.url")); |
217 | 182 | 296 | ||
218 | 183 | /* Ensure the properties get set before we pull them */ | ||
219 | 184 | loop(100); | ||
220 | 185 | |||
221 | 186 | /* Build our media player */ | 297 | /* Build our media player */ |
222 | 187 | MediaPlayerUser * player = media_player_user_new("user"); | 298 | MediaPlayerUser * player = media_player_user_new("user"); |
223 | 188 | ASSERT_NE(nullptr, player); | 299 | ASSERT_NE(nullptr, player); |
224 | 189 | 300 | ||
227 | 190 | /* Get the proxy -- and the old data, so old, like forever */ | 301 | bool running = false; |
228 | 191 | loop(100); | 302 | g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); |
229 | 303 | running_update(G_OBJECT(player), nullptr, &running); | ||
230 | 192 | 304 | ||
231 | 193 | /* Ensure that we show up as not running */ | 305 | /* Ensure that we show up as not running */ |
233 | 194 | EXPECT_FALSE(media_player_get_is_running(MEDIA_PLAYER(player))); | 306 | EXPECT_EVENTUALLY_EQ(false, running); |
234 | 195 | 307 | ||
235 | 196 | /* Update to make running */ | 308 | /* Update to make running */ |
236 | 197 | set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); | 309 | set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); |
240 | 198 | loop(100); | 310 | |
241 | 199 | 311 | EXPECT_EVENTUALLY_EQ(true, running); | |
242 | 200 | EXPECT_TRUE(media_player_get_is_running(MEDIA_PLAYER(player))); | 312 | |
243 | 313 | /* Clear to not run */ | ||
244 | 314 | set_property("Timestamp", g_variant_new_uint64(1)); | ||
245 | 315 | |||
246 | 316 | EXPECT_EVENTUALLY_EQ(false, running); | ||
247 | 201 | 317 | ||
248 | 202 | g_clear_object(&in_icon); | 318 | g_clear_object(&in_icon); |
249 | 203 | g_clear_object(&player); | 319 | g_clear_object(&player); |
FAILED: Continuous integration, rev:503 /code.launchpad .net/~ted/ indicator- sound/eventuall y-testing/ +merge/ 260373/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ indicator- sound-ci/ 225/ jenkins. qa.ubuntu. com/job/ indicator- sound-wily- amd64-ci/ 1/console jenkins. qa.ubuntu. com/job/ indicator- sound-wily- armhf-ci/ 1 jenkins. qa.ubuntu. com/job/ indicator- sound-wily- armhf-ci/ 1/artifact/ work/output/ *zip*/output. zip
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- sound-ci/ 225/rebuild
http://