Merge lp:~charlesk/indicator-power/lp-1373511-low-battery-warning into lp:indicator-power/14.10
- lp-1373511-low-battery-warning
- Merge into trunk.14.10
Status: | Merged |
---|---|
Approved by: | Ted Gould |
Approved revision: | 276 |
Merged at revision: | 269 |
Proposed branch: | lp:~charlesk/indicator-power/lp-1373511-low-battery-warning |
Merge into: | lp:indicator-power/14.10 |
Diff against target: |
917 lines (+547/-183) 11 files modified
data/com.canonical.indicator.power.Testing.xml (+39/-0) src/CMakeLists.txt (+6/-0) src/device-provider-mock.c (+1/-1) src/main.c (+6/-7) src/notifier.c (+34/-24) src/service.c (+13/-0) src/testing.c (+351/-0) src/testing.h (+66/-0) tests/CMakeLists.txt (+0/-9) tests/indicator-power-service-cmdline-battery.cc (+0/-127) tests/manual (+31/-15) |
To merge this branch: | bzr merge lp:~charlesk/indicator-power/lp-1373511-low-battery-warning |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Antti Kaijanmäki (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+238034@code.launchpad.net |
Commit message
Add mock battery support to make QA testing easier.
Description of the change
Add mock battery support for QA testing.
From the tests/manual's notes:
The indicator's schema name is "com.canonical.
Example use:
$ gsettings list-recursively com.canonical.
$ gsettings set com.canonical.
$ gsettings set com.canonical.
$ gsettings reset-recursively com.canonical.
PS Jenkins bot (ps-jenkins) wrote : | # |
Ted Gould (ted) wrote : | # |
I like the idea, but I don't love using gsettings. I think that the
problem could be that if a test fails half way, without its cleanup
step, things could be in a confusing state. I think we want a reboot "to
solve all ills." I think perhaps a couple of GActions or a DBus testing
interface would make more sense.
Charles Kerr (charlesk) wrote : | # |
Ted, that was my first thought as well but the problem with implementing that is the service handles acquiring / owning the bus, and we don't necessarily want it to know anything about where the DeviceProvider is coming from.
To use GActions and a DBus interface for this, we'd need to pull name ownership out of the service, and sync the tests to match that too.
IMO there are positive arguments for that, but the refactoring would be much larger and would drift away from the goal of "let's make short-term QA testing easier".
Ted Gould (ted) wrote : | # |
I'm not sure we're talking about the same thing, I was thinking,
modifying your example, of something like this:
- gsettings list-recursively com.canonical.
show the current mock settings
+ gdbus call --session --dest com.canonical.
--object-path /com/canonical/
org.freedesktop
- gsettings set com.canonical.
+ gdbus call --session --dest com.canonical.
--object-path /com/canonical/
org.freedesktop
- gsettings set com.canonical.
+ gdbus call --session --dest com.canonical.
--object-path /com/canonical/
org.freedesktop
So it'd still be the same process, just not stored anywhere on disk.
Ted Gould (ted) : | # |
- 271. By Charles Kerr
-
move the testing settings to a DBus interface
- 272. By Charles Kerr
-
make service's bus connection a property so that IndicatorPowerT
esting can listen for it and export an object before the name is acquired - 273. By Charles Kerr
-
fix notify get-capabilities startup blocking bug found in testing
- 274. By Charles Kerr
-
move the mock battery from GSettings to DBus
Charles Kerr (charlesk) wrote : | # |
Ted, okay here you go. :)
- 275. By Charles Kerr
-
in testing.c, make 'bus' a private field instead of a public GObject property
Ted Gould (ted) : | # |
- 276. By Charles Kerr
-
r273 tried to fix the blocking bug listed at http://
paste.ubuntu. com/8562226/, but in the process introduced a new bug that manifested in RTM. This removes r273 and uses a different fix.
Charles Kerr (charlesk) wrote : | # |
Ted/Antti, r276 was needed to fix a bug that showed up when I tested the silo on RTM.
Commit r276 tested & works -- mako + rtm r87
Preview Diff
1 | === added file 'data/com.canonical.indicator.power.Testing.xml' |
2 | --- data/com.canonical.indicator.power.Testing.xml 1970-01-01 00:00:00 +0000 |
3 | +++ data/com.canonical.indicator.power.Testing.xml 2014-10-15 01:58:54 +0000 |
4 | @@ -0,0 +1,39 @@ |
5 | +<?xml version="1.0" encoding="UTF-8" ?> |
6 | +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> |
7 | +<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> |
8 | + <interface name="com.canonical.indicator.power.Testing"> |
9 | + |
10 | + <property name="MockBatteryEnabled" type="b" access="readwrite"> |
11 | + <doc:doc> |
12 | + <doc:description> |
13 | + <doc:para>Whether or not the mock battery is enabled. (Default: false)</doc:para> |
14 | + </doc:description> |
15 | + </doc:doc> |
16 | + </property> |
17 | + |
18 | + <property name="MockBatteryLevel" type="u" access="readwrite"> |
19 | + <doc:doc> |
20 | + <doc:description> |
21 | + <doc:para>The charge level of the mock battery (0-100%, Default: 50%)</doc:para> |
22 | + </doc:description> |
23 | + </doc:doc> |
24 | + </property> |
25 | + |
26 | + <property name="MockBatteryState" type="s" access="readwrite"> |
27 | + <doc:doc> |
28 | + <doc:description> |
29 | + <doc:para>The mock battery's state. Possible values: 'charging', 'discharging' (Defualt: 'discharging')</doc:para> |
30 | + </doc:description> |
31 | + </doc:doc> |
32 | + </property> |
33 | + |
34 | + <property name="MockBatteryMinutesLeft" type="u" access="readwrite"> |
35 | + <doc:doc> |
36 | + <doc:description> |
37 | + <doc:para>Muntes left until the mock battery finishes charging/dischargin (Default: 30)</doc:para> |
38 | + </doc:description> |
39 | + </doc:doc> |
40 | + </property> |
41 | + |
42 | + </interface> |
43 | +</node> |
44 | |
45 | === modified file 'src/CMakeLists.txt' |
46 | --- src/CMakeLists.txt 2014-09-10 21:28:42 +0000 |
47 | +++ src/CMakeLists.txt 2014-10-15 01:58:54 +0000 |
48 | @@ -6,10 +6,12 @@ |
49 | # handwritten sources |
50 | set(SERVICE_MANUAL_SOURCES |
51 | brightness.c |
52 | + device-provider-mock.c |
53 | device-provider-upower.c |
54 | device-provider.c |
55 | device.c |
56 | notifier.c |
57 | + testing.c |
58 | service.c) |
59 | |
60 | # generated sources |
61 | @@ -19,6 +21,10 @@ |
62 | com.canonical.indicator.power |
63 | Dbus |
64 | ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Battery.xml) |
65 | +add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-testing |
66 | + com.canonical.indicator.power |
67 | + Dbus |
68 | + ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Testing.xml) |
69 | # add the bin dir to our include path so the code can find the generated header files |
70 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
71 | |
72 | |
73 | === renamed file 'tests/device-provider-mock.c' => 'src/device-provider-mock.c' |
74 | --- tests/device-provider-mock.c 2014-07-22 14:58:29 +0000 |
75 | +++ src/device-provider-mock.c 2014-10-15 01:58:54 +0000 |
76 | @@ -81,7 +81,7 @@ |
77 | } |
78 | |
79 | static void |
80 | -indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self) |
81 | +indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self G_GNUC_UNUSED) |
82 | { |
83 | } |
84 | |
85 | |
86 | === renamed file 'tests/device-provider-mock.h' => 'src/device-provider-mock.h' |
87 | === modified file 'src/main.c' |
88 | --- src/main.c 2014-07-21 05:50:24 +0000 |
89 | +++ src/main.c 2014-10-15 01:58:54 +0000 |
90 | @@ -18,14 +18,13 @@ |
91 | */ |
92 | |
93 | #include <locale.h> |
94 | -#include <stdlib.h> /* exit() */ |
95 | |
96 | +#include <glib.h> |
97 | #include <glib/gi18n.h> |
98 | -#include <gio/gio.h> |
99 | |
100 | #include "device.h" |
101 | -#include "device-provider-upower.h" |
102 | #include "service.h" |
103 | +#include "testing.h" |
104 | |
105 | /*** |
106 | **** |
107 | @@ -41,8 +40,8 @@ |
108 | int |
109 | main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) |
110 | { |
111 | - IndicatorPowerDeviceProvider * device_provider; |
112 | IndicatorPowerService * service; |
113 | + IndicatorPowerTesting * testing; |
114 | GMainLoop * loop; |
115 | |
116 | /* boilerplate i18n */ |
117 | @@ -51,8 +50,8 @@ |
118 | textdomain (GETTEXT_PACKAGE); |
119 | |
120 | /* run */ |
121 | - device_provider = indicator_power_device_provider_upower_new (); |
122 | - service = indicator_power_service_new (device_provider); |
123 | + service = indicator_power_service_new (NULL); |
124 | + testing = indicator_power_testing_new (service); |
125 | loop = g_main_loop_new (NULL, FALSE); |
126 | g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, |
127 | G_CALLBACK(on_name_lost), loop); |
128 | @@ -61,6 +60,6 @@ |
129 | /* cleanup */ |
130 | g_main_loop_unref (loop); |
131 | g_clear_object (&service); |
132 | - g_clear_object (&device_provider); |
133 | + g_clear_object (&testing); |
134 | return 0; |
135 | } |
136 | |
137 | === modified file 'src/notifier.c' |
138 | --- src/notifier.c 2014-10-07 15:58:22 +0000 |
139 | +++ src/notifier.c 2014-10-15 01:58:54 +0000 |
140 | @@ -55,8 +55,6 @@ |
141 | |
142 | static int instance_count = 0; |
143 | |
144 | -static gboolean actions_supported = FALSE; |
145 | - |
146 | /** |
147 | *** |
148 | **/ |
149 | @@ -76,6 +74,9 @@ |
150 | |
151 | GDBusConnection * bus; |
152 | DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ |
153 | + |
154 | + gboolean caps_queried; |
155 | + gboolean actions_supported; |
156 | } |
157 | IndicatorPowerNotifierPrivate; |
158 | |
159 | @@ -182,6 +183,33 @@ |
160 | /* no-op; libnotify warns if we have a NULL action callback */ |
161 | } |
162 | |
163 | +static gboolean |
164 | +are_actions_supported(IndicatorPowerNotifier * self) |
165 | +{ |
166 | + priv_t * const p = get_priv(self); |
167 | + |
168 | + if (!p->caps_queried) |
169 | + { |
170 | + gboolean actions_supported; |
171 | + GList * caps; |
172 | + GList * l; |
173 | + |
174 | + /* see if actions are supported */ |
175 | + actions_supported = FALSE; |
176 | + caps = notify_get_server_caps(); |
177 | + for (l=caps; l!=NULL && !actions_supported; l=l->next) |
178 | + if (!g_strcmp0(l->data, "actions")) |
179 | + actions_supported = TRUE; |
180 | + |
181 | + p->actions_supported = actions_supported; |
182 | + p->caps_queried = TRUE; |
183 | + |
184 | + g_list_free_full(caps, g_free); |
185 | + } |
186 | + |
187 | + return p->actions_supported; |
188 | +} |
189 | + |
190 | static void |
191 | notification_show(IndicatorPowerNotifier * self) |
192 | { |
193 | @@ -214,7 +242,7 @@ |
194 | g_strfreev (icon_names); |
195 | g_free (body); |
196 | |
197 | - if (actions_supported) |
198 | + if (are_actions_supported(self)) |
199 | { |
200 | notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_string("true")); |
201 | notify_notification_set_hint(nn, "x-canonical-non-shaped-icon", g_variant_new_string("true")); |
202 | @@ -354,6 +382,7 @@ |
203 | **** Instantiation |
204 | ***/ |
205 | |
206 | + |
207 | static void |
208 | indicator_power_notifier_init (IndicatorPowerNotifier * self) |
209 | { |
210 | @@ -365,27 +394,8 @@ |
211 | |
212 | p->power_level = POWER_LEVEL_OK; |
213 | |
214 | - if (!instance_count++) |
215 | - { |
216 | - actions_supported = FALSE; |
217 | - |
218 | - if (!notify_init("indicator-power-service")) |
219 | - { |
220 | - g_critical("Unable to initialize libnotify! Notifications might not be shown."); |
221 | - } |
222 | - else |
223 | - { |
224 | - GList * caps; |
225 | - GList * l; |
226 | - |
227 | - /* see if actions are supported */ |
228 | - caps = notify_get_server_caps(); |
229 | - for (l=caps; l!=NULL && !actions_supported; l=l->next) |
230 | - if (!g_strcmp0(l->data, "actions")) |
231 | - actions_supported = TRUE; |
232 | - g_list_free_full(caps, g_free); |
233 | - } |
234 | - } |
235 | + if (!instance_count++ && !notify_init("indicator-power-service")) |
236 | + g_critical("Unable to initialize libnotify! Notifications might not be shown."); |
237 | } |
238 | |
239 | static void |
240 | |
241 | === modified file 'src/service.c' |
242 | --- src/service.c 2014-10-09 13:42:03 +0000 |
243 | +++ src/service.c 2014-10-15 01:58:54 +0000 |
244 | @@ -51,6 +51,7 @@ |
245 | enum |
246 | { |
247 | PROP_0, |
248 | + PROP_BUS, |
249 | PROP_DEVICE_PROVIDER, |
250 | LAST_PROP |
251 | }; |
252 | @@ -839,6 +840,7 @@ |
253 | g_debug ("bus acquired: %s", name); |
254 | |
255 | p->conn = g_object_ref (G_OBJECT (connection)); |
256 | + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_BUS]); |
257 | |
258 | /* export the battery properties */ |
259 | indicator_power_notifier_set_bus (p->notifier, connection); |
260 | @@ -977,6 +979,10 @@ |
261 | |
262 | switch (property_id) |
263 | { |
264 | + case PROP_BUS: |
265 | + g_value_set_object (value, p->conn); |
266 | + break; |
267 | + |
268 | case PROP_DEVICE_PROVIDER: |
269 | g_value_set_object (value, p->device_provider); |
270 | break; |
271 | @@ -1113,6 +1119,13 @@ |
272 | |
273 | properties[PROP_0] = NULL; |
274 | |
275 | + properties[PROP_BUS] = g_param_spec_object ( |
276 | + "bus", |
277 | + "Bus", |
278 | + "GDBusConnection for exporting menus/actions", |
279 | + G_TYPE_OBJECT, |
280 | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); |
281 | + |
282 | properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( |
283 | "device-provider", |
284 | "Device Provider", |
285 | |
286 | === added file 'src/testing.c' |
287 | --- src/testing.c 1970-01-01 00:00:00 +0000 |
288 | +++ src/testing.c 2014-10-15 01:58:54 +0000 |
289 | @@ -0,0 +1,351 @@ |
290 | +/* |
291 | + * Copyright 2014 Canonical Ltd. |
292 | + * |
293 | + * This program is free software: you can redistribute it and/or modify it |
294 | + * under the terms of the GNU General Public License version 3, as published |
295 | + * by the Free Software Foundation. |
296 | + * |
297 | + * This program is distributed in the hope that it will be useful, but |
298 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
299 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
300 | + * PURPOSE. See the GNU General Public License for more details. |
301 | + * |
302 | + * You should have received a copy of the GNU General Public License along |
303 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
304 | + * |
305 | + * Authors: |
306 | + * Charles Kerr <charles.kerr@canonical.com> |
307 | + */ |
308 | + |
309 | +#include "dbus-shared.h" |
310 | +#include "device-provider-mock.h" |
311 | +#include "device-provider-upower.h" |
312 | +#include "dbus-testing.h" |
313 | +#include "service.h" |
314 | +#include "testing.h" |
315 | + |
316 | +#include <glib-object.h> |
317 | + |
318 | +/** |
319 | +*** GObject Properties |
320 | +**/ |
321 | + |
322 | +enum |
323 | +{ |
324 | + PROP_0, |
325 | + PROP_SERVICE, |
326 | + LAST_PROP |
327 | +}; |
328 | + |
329 | +static GParamSpec * properties[LAST_PROP]; |
330 | + |
331 | +/** |
332 | +*** |
333 | +**/ |
334 | + |
335 | +typedef struct |
336 | +{ |
337 | + GDBusConnection * bus; |
338 | + DbusTesting * skeleton; |
339 | + IndicatorPowerService * service; |
340 | + IndicatorPowerDevice * battery_mock; |
341 | + gpointer provider_mock; |
342 | + gpointer provider_upower; |
343 | +} |
344 | +IndicatorPowerTestingPrivate; |
345 | + |
346 | +typedef IndicatorPowerTestingPrivate priv_t; |
347 | + |
348 | +G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerTesting, |
349 | + indicator_power_testing, |
350 | + G_TYPE_OBJECT) |
351 | + |
352 | +#define get_priv(o) ((priv_t*)indicator_power_testing_get_instance_private(o)) |
353 | + |
354 | +/*** |
355 | +**** |
356 | +***/ |
357 | + |
358 | +static void |
359 | +update_device_provider (IndicatorPowerTesting * self) |
360 | +{ |
361 | + priv_t * const p = get_priv(self); |
362 | + IndicatorPowerDeviceProvider * device_provider; |
363 | + |
364 | + device_provider = dbus_testing_get_mock_battery_enabled(p->skeleton) |
365 | + ? p->provider_mock |
366 | + : p->provider_upower; |
367 | + indicator_power_service_set_device_provider(p->service, device_provider); |
368 | +} |
369 | + |
370 | +static void |
371 | +set_bus(IndicatorPowerTesting * self, GDBusConnection * bus) |
372 | +{ |
373 | + priv_t * p; |
374 | + GDBusInterfaceSkeleton * skel; |
375 | + |
376 | + g_return_if_fail(INDICATOR_IS_POWER_TESTING(self)); |
377 | + g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); |
378 | + |
379 | + p = get_priv (self); |
380 | + |
381 | + if (p->bus == bus) |
382 | + return; |
383 | + |
384 | + skel = G_DBUS_INTERFACE_SKELETON(p->skeleton); |
385 | + |
386 | + if (p->bus != NULL) |
387 | + { |
388 | + if (skel != NULL) |
389 | + g_dbus_interface_skeleton_unexport (skel); |
390 | + |
391 | + g_clear_object (&p->bus); |
392 | + } |
393 | + |
394 | + if (bus != NULL) |
395 | + { |
396 | + GError * error; |
397 | + |
398 | + p->bus = g_object_ref (bus); |
399 | + |
400 | + error = NULL; |
401 | + if (!g_dbus_interface_skeleton_export(skel, |
402 | + bus, |
403 | + BUS_PATH"/Testing", |
404 | + &error)) |
405 | + { |
406 | + g_warning ("Unable to export Testing properties: %s", error->message); |
407 | + g_error_free (error); |
408 | + } |
409 | + } |
410 | +} |
411 | + |
412 | +/*** |
413 | +**** |
414 | +***/ |
415 | + |
416 | +static void |
417 | +on_mock_battery_enabled_changed(DbusTesting * skeleton G_GNUC_UNUSED, |
418 | + GParamSpec * pspec G_GNUC_UNUSED, |
419 | + IndicatorPowerTesting * self) |
420 | +{ |
421 | + update_device_provider (self); |
422 | +} |
423 | + |
424 | +static void |
425 | +on_mock_battery_level_changed(DbusTesting * skeleton, |
426 | + GParamSpec * pspec G_GNUC_UNUSED, |
427 | + IndicatorPowerTesting * self) |
428 | +{ |
429 | + g_object_set(get_priv(self)->battery_mock, |
430 | + INDICATOR_POWER_DEVICE_PERCENTAGE, (gdouble)dbus_testing_get_mock_battery_level(skeleton), |
431 | + NULL); |
432 | +} |
433 | + |
434 | +static void |
435 | +on_mock_battery_state_changed(DbusTesting * skeleton, |
436 | + GParamSpec * pspec G_GNUC_UNUSED, |
437 | + IndicatorPowerTesting * self) |
438 | +{ |
439 | + const gchar* state_str = dbus_testing_get_mock_battery_state(skeleton); |
440 | + UpDeviceState state; |
441 | + |
442 | + if (!g_strcmp0(state_str, "charging")) |
443 | + { |
444 | + state = UP_DEVICE_STATE_CHARGING; |
445 | + } |
446 | + else if (!g_strcmp0(state_str, "discharging")) |
447 | + { |
448 | + state = UP_DEVICE_STATE_DISCHARGING; |
449 | + } |
450 | + else |
451 | + { |
452 | + g_warning("%s unsupported state: '%s'", G_STRLOC, state_str); |
453 | + state = UP_DEVICE_STATE_UNKNOWN; |
454 | + } |
455 | + |
456 | + g_object_set(get_priv(self)->battery_mock, |
457 | + INDICATOR_POWER_DEVICE_STATE, (gint)state, |
458 | + NULL); |
459 | +} |
460 | + |
461 | +static void |
462 | +on_mock_battery_minutes_left_changed(DbusTesting * skeleton, |
463 | + GParamSpec * pspec G_GNUC_UNUSED, |
464 | + IndicatorPowerTesting * self) |
465 | +{ |
466 | + g_object_set(get_priv(self)->battery_mock, |
467 | + INDICATOR_POWER_DEVICE_TIME, (guint64)dbus_testing_get_mock_battery_minutes_left(skeleton), |
468 | + NULL); |
469 | +} |
470 | + |
471 | +static void |
472 | +on_bus_changed(IndicatorPowerService * service, |
473 | + GParamSpec * spec G_GNUC_UNUSED, |
474 | + IndicatorPowerTesting * self) |
475 | +{ |
476 | + GObject * bus = NULL; |
477 | + g_object_get(service, "bus", &bus, NULL); |
478 | + set_bus(self, G_DBUS_CONNECTION(bus)); |
479 | + g_clear_object(&bus); |
480 | +} |
481 | + |
482 | +/*** |
483 | +**** GObject virtual functions |
484 | +***/ |
485 | + |
486 | +static void |
487 | +my_get_property(GObject * o, |
488 | + guint property_id, |
489 | + GValue * value, |
490 | + GParamSpec * pspec) |
491 | +{ |
492 | + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o); |
493 | + priv_t * const p = get_priv(self); |
494 | + |
495 | + switch (property_id) |
496 | + { |
497 | + case PROP_SERVICE: |
498 | + g_value_set_object(value, p->service); |
499 | + break; |
500 | + |
501 | + default: |
502 | + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec); |
503 | + } |
504 | +} |
505 | + |
506 | +static void |
507 | +my_set_property(GObject * o, |
508 | + guint property_id, |
509 | + const GValue * value, |
510 | + GParamSpec * pspec) |
511 | +{ |
512 | + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o); |
513 | + priv_t * const p = get_priv(self); |
514 | + |
515 | + switch (property_id) |
516 | + { |
517 | + case PROP_SERVICE: |
518 | + g_assert(p->service == NULL); /* G_PARAM_CONSTRUCT_ONLY */ |
519 | + p->service = g_value_dup_object(value); |
520 | + break; |
521 | + |
522 | + default: |
523 | + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec); |
524 | + } |
525 | +} |
526 | + |
527 | +static void |
528 | +my_dispose(GObject * o) |
529 | +{ |
530 | + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o); |
531 | + priv_t * const p = get_priv (self); |
532 | + |
533 | + set_bus(self, NULL); |
534 | + g_clear_object(&p->skeleton); |
535 | + g_clear_object(&p->provider_upower); |
536 | + g_clear_object(&p->provider_mock); |
537 | + g_clear_object(&p->battery_mock); |
538 | + g_clear_object(&p->service); |
539 | + |
540 | + G_OBJECT_CLASS (indicator_power_testing_parent_class)->dispose(o); |
541 | +} |
542 | + |
543 | +static void |
544 | +my_finalize (GObject * o G_GNUC_UNUSED) |
545 | +{ |
546 | +} |
547 | + |
548 | +static void |
549 | +my_constructed (GObject * o) |
550 | +{ |
551 | + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o); |
552 | + priv_t * const p = get_priv (self); |
553 | + |
554 | + g_assert(p->service != NULL); /* G_PARAM_CONSTRUCT_ONLY */ |
555 | + g_signal_connect(p->service, "notify::bus", G_CALLBACK(on_bus_changed), o); |
556 | + on_bus_changed(p->service, NULL, self); |
557 | + update_device_provider(self); |
558 | +} |
559 | + |
560 | + |
561 | +/*** |
562 | +**** Instantiation |
563 | +***/ |
564 | + |
565 | +static void |
566 | +indicator_power_testing_init (IndicatorPowerTesting * self) |
567 | +{ |
568 | + priv_t * const p = get_priv (self); |
569 | + |
570 | + /* DBus Skeleton */ |
571 | + |
572 | + p->skeleton = dbus_testing_skeleton_new(); |
573 | + dbus_testing_set_mock_battery_level(p->skeleton, 50u); |
574 | + dbus_testing_set_mock_battery_state(p->skeleton, "discharging"); |
575 | + dbus_testing_set_mock_battery_enabled(p->skeleton, FALSE); |
576 | + dbus_testing_set_mock_battery_minutes_left(p->skeleton, 30); |
577 | + |
578 | + g_signal_connect(p->skeleton, "notify::mock-battery-enabled", |
579 | + G_CALLBACK(on_mock_battery_enabled_changed), self); |
580 | + g_signal_connect(p->skeleton, "notify::mock-battery-level", |
581 | + G_CALLBACK(on_mock_battery_level_changed), self); |
582 | + g_signal_connect(p->skeleton, "notify::mock-battery-state", |
583 | + G_CALLBACK(on_mock_battery_state_changed), self); |
584 | + g_signal_connect(p->skeleton, "notify::mock-battery-minutes-left", |
585 | + G_CALLBACK(on_mock_battery_minutes_left_changed), self); |
586 | + |
587 | + /* Mock Battery */ |
588 | + |
589 | + p->battery_mock = indicator_power_device_new("/some/path", |
590 | + UP_DEVICE_KIND_BATTERY, |
591 | + 50.0, |
592 | + UP_DEVICE_STATE_DISCHARGING, |
593 | + 60*30); |
594 | + |
595 | + |
596 | + /* Mock Provider */ |
597 | + |
598 | + p->provider_mock = indicator_power_device_provider_mock_new(); |
599 | + |
600 | + indicator_power_device_provider_add_device(INDICATOR_POWER_DEVICE_PROVIDER_MOCK(p->provider_mock), |
601 | + p->battery_mock); |
602 | + |
603 | + /* UPower Provider */ |
604 | + |
605 | + p->provider_upower = indicator_power_device_provider_upower_new(); |
606 | +} |
607 | + |
608 | +static void |
609 | +indicator_power_testing_class_init (IndicatorPowerTestingClass * klass) |
610 | +{ |
611 | + GObjectClass * object_class = G_OBJECT_CLASS (klass); |
612 | + |
613 | + object_class->dispose = my_dispose; |
614 | + object_class->finalize = my_finalize; |
615 | + object_class->constructed = my_constructed; |
616 | + object_class->get_property = my_get_property; |
617 | + object_class->set_property = my_set_property; |
618 | + |
619 | + properties[PROP_SERVICE] = g_param_spec_object ( |
620 | + "service", |
621 | + "Servie", |
622 | + "The IndicatorPower Service", |
623 | + G_TYPE_OBJECT, |
624 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); |
625 | + |
626 | + g_object_class_install_properties (object_class, LAST_PROP, properties); |
627 | +} |
628 | + |
629 | +/*** |
630 | +**** Public API |
631 | +***/ |
632 | + |
633 | +IndicatorPowerTesting * |
634 | +indicator_power_testing_new (IndicatorPowerService * service) |
635 | +{ |
636 | + GObject * o = g_object_new (INDICATOR_TYPE_POWER_TESTING, "service", service, NULL); |
637 | + |
638 | + return INDICATOR_POWER_TESTING (o); |
639 | +} |
640 | + |
641 | |
642 | === added file 'src/testing.h' |
643 | --- src/testing.h 1970-01-01 00:00:00 +0000 |
644 | +++ src/testing.h 2014-10-15 01:58:54 +0000 |
645 | @@ -0,0 +1,66 @@ |
646 | +/* |
647 | + * Copyright 2014 Canonical Ltd. |
648 | + * |
649 | + * This program is free software: you can redistribute it and/or modify it |
650 | + * under the terms of the GNU General Public License version 3, as published |
651 | + * by the Free Software Foundation. |
652 | + * |
653 | + * This program is distributed in the hope that it will be useful, but |
654 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
655 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
656 | + * PURPOSE. See the GNU General Public License for more details. |
657 | + * |
658 | + * You should have received a copy of the GNU General Public License along |
659 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
660 | + * |
661 | + * Authors: |
662 | + * Charles Kerr <charles.kerr@canonical.com> |
663 | + */ |
664 | + |
665 | +#ifndef __INDICATOR_POWER_TESTING_H__ |
666 | +#define __INDICATOR_POWER_TESTING_H__ |
667 | + |
668 | +#include <gio/gio.h> |
669 | + |
670 | +#include "service.h" |
671 | + |
672 | +G_BEGIN_DECLS |
673 | + |
674 | +/* standard GObject macros */ |
675 | +#define INDICATOR_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTesting)) |
676 | +#define INDICATOR_TYPE_POWER_TESTING (indicator_power_testing_get_type()) |
677 | +#define INDICATOR_IS_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_TESTING)) |
678 | +#define INDICATOR_POWER_TESTING_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTestingClass)) |
679 | + |
680 | +typedef struct _IndicatorPowerTesting IndicatorPowerTesting; |
681 | +typedef struct _IndicatorPowerTestingClass IndicatorPowerTestingClass; |
682 | + |
683 | +/** |
684 | + * The Indicator Power Testing. |
685 | + */ |
686 | +struct _IndicatorPowerTesting |
687 | +{ |
688 | + /*< private >*/ |
689 | + GObject parent; |
690 | +}; |
691 | + |
692 | +struct _IndicatorPowerTestingClass |
693 | +{ |
694 | + GObjectClass parent_class; |
695 | +}; |
696 | + |
697 | +/*** |
698 | +**** |
699 | +***/ |
700 | + |
701 | +GType indicator_power_testing_get_type (void); |
702 | + |
703 | +IndicatorPowerTesting * indicator_power_testing_new (IndicatorPowerService * service); |
704 | + |
705 | +void indicator_power_testing_set_bus (IndicatorPowerTesting * self, |
706 | + GDBusConnection * connection); |
707 | + |
708 | + |
709 | +G_END_DECLS |
710 | + |
711 | +#endif /* __INDICATOR_POWER_TESTING_H__ */ |
712 | |
713 | === modified file 'tests/CMakeLists.txt' |
714 | --- tests/CMakeLists.txt 2014-07-22 14:58:29 +0000 |
715 | +++ tests/CMakeLists.txt 2014-10-15 01:58:54 +0000 |
716 | @@ -50,12 +50,3 @@ |
717 | add_test_by_name(test-notify) |
718 | add_test(NAME dear-reader-the-next-test-takes-80-seconds COMMAND true) |
719 | add_test_by_name(test-device) |
720 | - |
721 | -### |
722 | -### |
723 | - |
724 | -set (APP_NAME indicator-power-service-cmdline-battery) |
725 | -add_executable (${APP_NAME} ${APP_NAME}.cc device-provider-mock.c) |
726 | -add_dependencies (${APP_NAME} libindicatorpowerservice) |
727 | -target_link_libraries (${APP_NAME} indicatorpowerservice ${SERVICE_DEPS_LIBRARIES}) |
728 | - |
729 | |
730 | === removed file 'tests/indicator-power-service-cmdline-battery.cc' |
731 | --- tests/indicator-power-service-cmdline-battery.cc 2014-09-09 04:22:39 +0000 |
732 | +++ tests/indicator-power-service-cmdline-battery.cc 1970-01-01 00:00:00 +0000 |
733 | @@ -1,127 +0,0 @@ |
734 | -/* |
735 | - * Copyright 2014 Canonical Ltd. |
736 | - * |
737 | - * This program is free software: you can redistribute it and/or modify it |
738 | - * under the terms of the GNU General Public License version 3, as published |
739 | - * by the Free Software Foundation. |
740 | - * |
741 | - * This program is distributed in the hope that it will be useful, but |
742 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
743 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
744 | - * PURPOSE. See the GNU General Public License for more details. |
745 | - * |
746 | - * You should have received a copy of the GNU General Public License along |
747 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
748 | - * |
749 | - * Authors: |
750 | - * Charles Kerr <charles.kerr@canonical.com> |
751 | - */ |
752 | - |
753 | -#include <cstdlib> |
754 | - |
755 | -#include <locale.h> // setlocale() |
756 | -#include <libintl.h> // bindtextdomain() |
757 | -#include <unistd.h> // STDIN_FILENO |
758 | - |
759 | -#include <gio/gio.h> |
760 | - |
761 | -#include "device-provider-mock.h" |
762 | - |
763 | -#include "service.h" |
764 | - |
765 | -/*** |
766 | -**** |
767 | -***/ |
768 | - |
769 | -static void |
770 | -on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) |
771 | -{ |
772 | - g_message ("exiting: service couldn't acquire or lost ownership of busname"); |
773 | - g_main_loop_quit (static_cast<GMainLoop*>(loop)); |
774 | -} |
775 | - |
776 | -static IndicatorPowerDevice * battery = nullptr; |
777 | - |
778 | -static GMainLoop * loop = nullptr; |
779 | - |
780 | -static gboolean on_command_stream_available (GIOChannel *source, |
781 | - GIOCondition /*condition*/, |
782 | - gpointer /*user_data*/) |
783 | -{ |
784 | - gchar * str = nullptr; |
785 | - GError * error = nullptr; |
786 | - auto status = g_io_channel_read_line (source, &str, nullptr, nullptr, &error); |
787 | - g_assert_no_error (error); |
788 | - |
789 | - if (status == G_IO_STATUS_NORMAL) |
790 | - { |
791 | - g_strstrip (str); |
792 | - |
793 | - if (!g_strcmp0 (str, "charging")) |
794 | - { |
795 | - g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_CHARGING, nullptr); |
796 | - } |
797 | - else if (!g_strcmp0 (str, "discharging")) |
798 | - { |
799 | - g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_DISCHARGING, nullptr); |
800 | - } |
801 | - else |
802 | - { |
803 | - g_object_set (battery, INDICATOR_POWER_DEVICE_PERCENTAGE, atof(str), nullptr); |
804 | - } |
805 | - } |
806 | - else if (status == G_IO_STATUS_EOF) |
807 | - { |
808 | - g_main_loop_quit (loop); |
809 | - } |
810 | - |
811 | - g_free (str); |
812 | - return G_SOURCE_CONTINUE; |
813 | -} |
814 | - |
815 | -/* this is basically indicator-power-service with a custom provider */ |
816 | -int |
817 | -main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) |
818 | -{ |
819 | - g_print("This test app has the same code as indicator-power-service\n" |
820 | - "except instead of listening to UPower, it has a fake battery\n" |
821 | - "which you can edit with keyboard inputs. Supported commands:\n" |
822 | - "1. A number in [0..100] to set battery level\n" |
823 | - "2. 'charging'\n" |
824 | - "3. 'discharging'\n" |
825 | - "4. ctrl-c to exit\n"); |
826 | - |
827 | - IndicatorPowerDeviceProvider * device_provider; |
828 | - IndicatorPowerService * service; |
829 | - |
830 | - g_assert(g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, true)); |
831 | - g_assert(g_setenv("GSETTINGS_BACKEND", "memory", true)); |
832 | - |
833 | - /* boilerplate i18n */ |
834 | - setlocale (LC_ALL, ""); |
835 | - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); |
836 | - textdomain (GETTEXT_PACKAGE); |
837 | - |
838 | - /* read lines from the command line */ |
839 | - auto channel = g_io_channel_unix_new (STDIN_FILENO); |
840 | - auto watch_tag = g_io_add_watch (channel, G_IO_IN, on_command_stream_available, nullptr); |
841 | - |
842 | - /* run */ |
843 | - battery = indicator_power_device_new ("/some/path", UP_DEVICE_KIND_BATTERY, 50.0, UP_DEVICE_STATE_DISCHARGING, 30*60); |
844 | - device_provider = indicator_power_device_provider_mock_new (); |
845 | - indicator_power_device_provider_add_device (INDICATOR_POWER_DEVICE_PROVIDER_MOCK(device_provider), battery); |
846 | - service = indicator_power_service_new (device_provider); |
847 | - loop = g_main_loop_new (NULL, FALSE); |
848 | - g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, |
849 | - G_CALLBACK(on_name_lost), loop); |
850 | - g_main_loop_run (loop); |
851 | - |
852 | - /* cleanup */ |
853 | - g_main_loop_unref (loop); |
854 | - g_source_remove (watch_tag); |
855 | - g_io_channel_unref (channel); |
856 | - g_clear_object (&service); |
857 | - g_clear_object (&device_provider); |
858 | - g_clear_object (&battery); |
859 | - return 0; |
860 | -} |
861 | |
862 | === modified file 'tests/manual' |
863 | --- tests/manual 2014-09-11 20:02:31 +0000 |
864 | +++ tests/manual 2014-10-15 01:58:54 +0000 |
865 | @@ -1,21 +1,37 @@ |
866 | |
867 | Notes on Battery Testing |
868 | |
869 | -When building from source, an executable 'indicator-power-service-cmdline-battery' will be built in the tests/ directory. This has the same code as indicator-power-service, except instead of listening to UPower it has a single fake battery that can be set from the command line to set its charge level and whether it's charging or discharging. |
870 | - |
871 | -You'll need to stop the current indicator-power-service before starting the test one. After that, you enter in a number, or 'charging', or 'discharging', to set the fake battery. ctrl-c exits. |
872 | - |
873 | -Example: |
874 | - |
875 | -$ stop indicator-power # stop the real indicator-power service |
876 | -$ build/tests/indicator-power-service-cmdline-battery # start the test service |
877 | -50 # sets the fake battery level to 50% |
878 | -30 # sets the fake battery level to 30% |
879 | -charging # sets the fake battery to charging |
880 | -discharging # sets the fake battery to discharging |
881 | -ctrl-c # exits the test service |
882 | -$ start indicator-power # restart the real service |
883 | - |
884 | +Mock battery propreties are available for testing purposes. |
885 | + |
886 | +The testing properties are DBus properties published on busname "com.canonical.indicator.power", object path "/com/canonical/indicator/power/Testing", and interface "com.canonical.indicator.power.Testing". The four properties are "MockBatteryEnabled" (boolean, default false), "MockBatteryLevel" (uint32 [0-100], default 50), "MockBatteryState" (string, default 'discharging'), "MockBatteryMinutesLeft" (minutes remaining to charge/discharge, uint32, default 30). |
887 | + |
888 | +Example use: |
889 | + |
890 | +Show the testing properties: |
891 | + |
892 | +$ gdbus call --session --dest "com.canonical.indicator.power" \ |
893 | + --object-path /com/canonical/indicator/power/Testing \ |
894 | + --method org.freedesktop.DBus.Properties.GetAll \ |
895 | + com.canonical.indicator.power.Testing |
896 | +({'MockBatteryEnabled': <false>, 'MockBatteryLevel': <uint32 50>, 'MockBatteryState': <'discharging'>, 'MockBatteryMinutesLeft': <uint32 30>},) |
897 | + |
898 | +Enable the mock battery: |
899 | + |
900 | +$ gdbus call --session --dest "com.canonical.indicator.power" \ |
901 | + --object-path /com/canonical/indicator/power/Testing \ |
902 | + --method org.freedesktop.DBus.Properties.Set \ |
903 | + com.canonical.indicator.power.Testing \ |
904 | + MockBatteryEnabled \ |
905 | + "<true>" |
906 | + |
907 | +Set the mock battery's charge to 10% |
908 | + |
909 | +$ gdbus call --session --dest "com.canonical.indicator.power" \ |
910 | + --object-path /com/canonical/indicator/power/Testing \ |
911 | + --method org.freedesktop.DBus.Properties.Set \ |
912 | + com.canonical.indicator.power.Testing \ |
913 | + MockBatteryLevel \ |
914 | + "<uint32 10>" |
915 | |
916 | |
917 | Test-case indicator-power/unity7-items-check |
PASSED: Continuous integration, rev:270 jenkins. qa.ubuntu. com/job/ indicator- power-ci/ 140/ jenkins. qa.ubuntu. com/job/ indicator- power-utopic- amd64-ci/ 41 jenkins. qa.ubuntu. com/job/ indicator- power-utopic- armhf-ci/ 41 jenkins. qa.ubuntu. com/job/ indicator- power-utopic- armhf-ci/ 41/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- power-ci/ 140/rebuild
http://