on xenial help sign in
Unity8 tests now make use of the helper functions (added in the pre-req branch) so that the helper functions are tested as part of daily business.
03c4f5fChristopher Lee
tests/autopilot/unity8/process_helpers.py+65−38
@@ -21,18 +21,25 @@ from autopilot.introspection import (
21 get_proxy_object_for_existing_process,
21 get_proxy_object_for_existing_process,
22 ProcessSearchError,
22 ProcessSearchError,
23)
23)
24+import logging
24import subprocess
25import subprocess
25from unity8.shell.emulators import UnityEmulatorBase
26from unity8.shell.emulators import UnityEmulatorBase
26from unity8.shell.emulators.main_window import MainWindow
27from unity8.shell.emulators.main_window import MainWindow
27
28
29+logger = logging.getLogger(__name__)
30+
28
31
29class CannotAccessUnity(Exception):
32class CannotAccessUnity(Exception):
30 pass
33 pass
31
34
32
35
33−def unlock_unity():
36+def unlock_unity(unity_proxy_obj=None):
34 """Helper function that attempts to unlock the unity greeter.
37 """Helper function that attempts to unlock the unity greeter.
35
38
39+ If unity_proxy_object is None create a proxy object by querying for the
40+ running unity process.
41+ Otherwise re-use the passed proxy object.
42+
36 :raises RuntimeError: if the greeter attempts and fails to be unlocked.
43 :raises RuntimeError: if the greeter attempts and fails to be unlocked.
37
44
38 :raises RuntimeWarning: when the greeter cannot be found because it is
45 :raises RuntimeWarning: when the greeter cannot be found because it is
@@ -43,30 +50,42 @@ def unlock_unity():
43 upstart job cannot be found at all.
50 upstart job cannot be found at all.
44
51
45 """
52 """
46− pid = _get_unity_pid()
53+ if unity_proxy_obj is None:
47− try:
54+ try:
48− unity = get_proxy_object_for_existing_process(
55+ pid = _get_unity_pid()
49− pid=pid,
56+ unity = _get_unity_proxy_object(pid)
50− emulator_base=UnityEmulatorBase,
51− )
52− main_window = MainWindow(unity)
57+ main_window = MainWindow(unity)
53−
54− greeter = main_window.get_greeter()
55− if greeter is None:
56− raise RuntimeWarning("Greeter appears to be already unlocked.")
57− greeter.swipe()
58− except ProcessSearchError as e:
58+ except ProcessSearchError as e:
59− raise CannotAccessUnity(
59+ raise CannotAccessUnity(
60− "Cannot introspect unity, make sure that it has been started "
60+ "Cannot introspect unity, make sure that it has been started "
61− "with testability. Perhaps use the function "
61+ "with testability. Perhaps use the function "
62− "'restart_unity_with_testability' this module provides."
62+ "'restart_unity_with_testability' this module provides."
63− "(%s)"
63+ "(%s)"
64− % str(e)
64+ % str(e)
65− )
65+ )
66+ else:
67+ main_window = MainWindow(unity_proxy_obj)
68+
69+ greeter = main_window.get_greeter()
70+ if greeter is None:
71+ raise RuntimeWarning("Greeter appears to be already unlocked.")
72+ greeter.swipe()
73+
74+
75+def restart_unity_with_testability(*args):
76+ """Restarts (or starts) unity with testability enabled.
77+
78+ Passes *args arguments to the launched process.
79+
80+ """
81+ args += ("QT_LOAD_TESTABILITY=1",)
82+ return restart_unity(*args)
83+
66
84
85+def restart_unity(*args):
86+ """Restarts (or starts) unity8 using the provided arguments.
67
87
68−def restart_unity_with_testability():
88+ Passes *args arguments to the launched process.
69− """Restarts (or just starts) unity8 with the testability driver loaded
70
89
71 :raises subprocess.CalledProcessError: if unable to stop or start the
90 :raises subprocess.CalledProcessError: if unable to stop or start the
72 unity8 upstart job.
91 unity8 upstart job.
@@ -75,27 +94,28 @@ def restart_unity_with_testability():
75 status = _get_unity_status()
94 status = _get_unity_status()
76 if "start/" in status:
95 if "start/" in status:
77 try:
96 try:
78− print("Stopping unity.")
97+ output = subprocess.check_output(['initctl', 'stop', 'unity8'])
79− subprocess.check_call([
98+ logger.info(output)
80− 'initctl',
81− 'stop',
82− 'unity8',
83− ])
84 except subprocess.CalledProcessError as e:
99 except subprocess.CalledProcessError as e:
100+ e.args += (
85− e.args += ("Failed to stop running instance of unity8", )
101+ "Failed to stop running instance of unity8: %s" % e.output,
102+ )
86 raise
103 raise
87
104
88 try:
105 try:
89− print("Starting unity with testability.")
106+ command = ['initctl', 'start', 'unity8'] + list(args)
90− subprocess.check_call([
107+ output = subprocess.check_output(
91− 'initctl',
108+ command,
92− 'start',
109+ stderr=subprocess.STDOUT,
93− 'unity8',
110+ universal_newlines=True,
94− 'QT_LOAD_TESTABILITY=1',
111+ )
95− ])
112+ logger.info(output)
113+ pid = _get_unity_pid()
96 except subprocess.CalledProcessError as e:
114 except subprocess.CalledProcessError as e:
97− e.args += ("Failed to start unity8 with testability ", )
115+ e.args += ("Failed to start unity8: %s" % e.output,)
98 raise
116 raise
117+ else:
118+ return _get_unity_proxy_object(pid)
99
119
100
120
101def _get_unity_status():
121def _get_unity_status():
@@ -114,3 +134,10 @@ def _get_unity_pid():
114 if not "start/" in status:
134 if not "start/" in status:
115 raise CannotAccessUnity("Unity is not in the running state.")
135 raise CannotAccessUnity("Unity is not in the running state.")
116 return int(status.split()[-1])
136 return int(status.split()[-1])
137+
138+
139+def _get_unity_proxy_object(pid):
140+ return get_proxy_object_for_existing_process(
141+ pid=pid,
142+ emulator_base=UnityEmulatorBase,
143+ )
tests/autopilot/unity8/shell/tests/__init__.py+8−21
@@ -28,7 +28,6 @@ from autopilot.platform import model
28from autopilot.testcase import AutopilotTestCase
28from autopilot.testcase import AutopilotTestCase
29from autopilot.matchers import Eventually
29from autopilot.matchers import Eventually
30from autopilot.input import Touch
30from autopilot.input import Touch
31−from autopilot.introspection import get_proxy_object_for_existing_process
32from autopilot.display import Display
31from autopilot.display import Display
33import logging
32import logging
34import os.path
33import os.path
@@ -43,7 +42,7 @@ from unity8 import (
43 get_default_extra_mock_libraries,
42 get_default_extra_mock_libraries,
44 get_data_dirs
43 get_data_dirs
45)
44)
46−from unity8.shell.emulators import UnityEmulatorBase
45+from unity8.process_helpers import restart_unity_with_testability
47from unity8.shell.emulators.dash import Dash
46from unity8.shell.emulators.dash import Dash
48from unity8.shell.emulators.main_window import MainWindow
47from unity8.shell.emulators.main_window import MainWindow
49
48
@@ -105,7 +104,7 @@ class UnityTestCase(AutopilotTestCase):
105 ),
104 ),
106 "upstart")
105 "upstart")
107 )
106 )
108− )
107+ )
109 sys.exit(1)
108 sys.exit(1)
110
109
111 if "start/" in output:
110 if "start/" in output:
@@ -303,32 +302,20 @@ class UnityTestCase(AutopilotTestCase):
303
302
304 binary_arg = "BINARY=%s" % binary_path
303 binary_arg = "BINARY=%s" % binary_path
305 extra_args = "ARGS=%s" % " ".join(args)
304 extra_args = "ARGS=%s" % " ".join(args)
306−
307− output = subprocess.check_output(
308− [
309− "/sbin/initctl",
310− "start",
311− "unity8",
312− binary_arg,
313− extra_args,
314− ] + ["%s=%s" % (k, v) for k, v in self._environment.iteritems()],
305+ env_args = ["%s=%s" % (k, v) for k, v in self._environment.iteritems()]
315− stderr=subprocess.STDOUT,
306+ all_args = [binary_arg, extra_args] + env_args
316− )
317
307
318 self.addCleanup(self._cleanup_launching_upstart_unity)
308 self.addCleanup(self._cleanup_launching_upstart_unity)
319
309
320− pid = int(output.split()[-1])
310+ return restart_unity_with_testability(*all_args)
321−
322− return get_proxy_object_for_existing_process(
323− pid=pid,
324− emulator_base=UnityEmulatorBase,
325− )
326
311
327 def _cleanup_launching_upstart_unity(self):
312 def _cleanup_launching_upstart_unity(self):
328 logger.info("Stopping unity")
313 logger.info("Stopping unity")
329 try:
314 try:
330 subprocess.check_output(
315 subprocess.check_output(
316+ ["/sbin/initctl", "stop", "unity8"],
331− ["/sbin/initctl", "stop", "unity8"], stderr=subprocess.STDOUT)
317+ stderr=subprocess.STDOUT
318+ )
332 except subprocess.CalledProcessError:
319 except subprocess.CalledProcessError:
333 logger.warning("Appears unity was already stopped!")
320 logger.warning("Appears unity was already stopped!")
334
321
tests/autopilot/unity8/shell/tests/test_hud.py+11−10
@@ -19,6 +19,7 @@
19
19
20from __future__ import absolute_import
20from __future__ import absolute_import
21
21
22+from unity8.process_helpers import unlock_unity
22from unity8.shell import with_lightdm_mock, DragMixin
23from unity8.shell import with_lightdm_mock, DragMixin
23from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24
25
@@ -38,8 +39,8 @@ class TestHud(UnityTestCase, DragMixin):
38 The button must disappear when touching somewhere on the screen except the button itself.
39 The button must disappear when touching somewhere on the screen except the button itself.
39
40
40 """
41 """
41− self.launch_unity()
42+ unity_proxy = self.launch_unity()
42− self.main_window.get_greeter().swipe()
43+ unlock_unity(unity_proxy)
43 window = self.main_window.get_qml_view()
44 window = self.main_window.get_qml_view()
44 hud_show_button = self.main_window.get_hud_show_button()
45 hud_show_button = self.main_window.get_hud_show_button()
45 edge_drag_area = self.main_window.get_hud_edge_drag_area()
46 edge_drag_area = self.main_window.get_hud_edge_drag_area()
@@ -80,8 +81,8 @@ class TestHud(UnityTestCase, DragMixin):
80 Test that the hud button stays on screen and tapping it opens the hud.
81 Test that the hud button stays on screen and tapping it opens the hud.
81
82
82 """
83 """
83− self.launch_unity()
84+ unity_proxy = self.launch_unity()
84− self.main_window.get_greeter().swipe()
85+ unlock_unity(unity_proxy)
85 window = self.main_window.get_qml_view()
86 window = self.main_window.get_qml_view()
86 hud_show_button = self.main_window.get_hud_show_button()
87 hud_show_button = self.main_window.get_hud_show_button()
87 hud = self.main_window.get_hud()
88 hud = self.main_window.get_hud()
@@ -117,8 +118,8 @@ class TestHud(UnityTestCase, DragMixin):
117
118
118 def test_hide_hud_click(self):
119 def test_hide_hud_click(self):
119 """Tapping the close button of the Hud must dismiss it."""
120 """Tapping the close button of the Hud must dismiss it."""
120− self.launch_unity()
121+ unity_proxy = self.launch_unity()
121− self.main_window.get_greeter().swipe()
122+ unlock_unity(unity_proxy)
122 hud = self.main_window.get_hud()
123 hud = self.main_window.get_hud()
123
124
124 self._launch_test_app_from_app_screen()
125 self._launch_test_app_from_app_screen()
@@ -134,8 +135,8 @@ class TestHud(UnityTestCase, DragMixin):
134 released downward.
135 released downward.
135
136
136 """
137 """
137− self.launch_unity()
138+ unity_proxy = self.launch_unity()
138− self.main_window.get_greeter().swipe()
139+ unlock_unity(unity_proxy)
139 window = self.main_window.get_qml_view()
140 window = self.main_window.get_qml_view()
140 hud = self.main_window.get_hud()
141 hud = self.main_window.get_hud()
141
142
@@ -152,8 +153,8 @@ class TestHud(UnityTestCase, DragMixin):
152
153
153 def test_launcher_hides_hud(self):
154 def test_launcher_hides_hud(self):
154 """Opening the Launcher while the Hud is active must close the Hud."""
155 """Opening the Launcher while the Hud is active must close the Hud."""
155− self.launch_unity()
156+ unity_proxy = self.launch_unity()
156− self.main_window.get_greeter().swipe()
157+ unlock_unity(unity_proxy)
157 hud = self.main_window.get_hud()
158 hud = self.main_window.get_hud()
158 launcher = self.main_window.get_launcher()
159 launcher = self.main_window.get_launcher()
159
160
tests/autopilot/unity8/shell/tests/test_notifications.py+25−30
@@ -21,6 +21,7 @@
21
21
22from __future__ import absolute_import
22from __future__ import absolute_import
23
23
24+from unity8.process_helpers import unlock_unity
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25
26
26from testtools.matchers import Equals, NotEquals
27from testtools.matchers import Equals, NotEquals
@@ -118,9 +119,8 @@ class InteractiveNotificationBase(NotificationsBase):
118
119
119 def test_interactive(self):
120 def test_interactive(self):
120 """Interactive notification must react upon click on itself."""
121 """Interactive notification must react upon click on itself."""
121− self.launch_unity()
122+ unity_proxy = self.launch_unity()
122− greeter = self.main_window.get_greeter()
123+ unlock_unity(unity_proxy)
123− greeter.swipe()
124
124
125 notify_list = self._get_notifications_list()
125 notify_list = self._get_notifications_list()
126
126
@@ -158,9 +158,8 @@ class InteractiveNotificationBase(NotificationsBase):
158 def test_sd_incoming_call(self):
158 def test_sd_incoming_call(self):
159 """Rejecting a call should make notification expand and
159 """Rejecting a call should make notification expand and
160 offer more options."""
160 offer more options."""
161− self.launch_unity()
161+ unity_proxy = self.launch_unity()
162− greeter = self.main_window.get_greeter()
162+ unlock_unity(unity_proxy)
163− greeter.swipe()
164
163
165 notify_list = self._get_notifications_list()
164 notify_list = self._get_notifications_list()
166
165
@@ -336,9 +335,8 @@ class EphemeralNotificationsTests(NotificationsBase):
336
335
337 def test_icon_summary_body(self):
336 def test_icon_summary_body(self):
338 """Notification must display the expected summary and body text."""
337 """Notification must display the expected summary and body text."""
339− self.launch_unity()
338+ unity_proxy = self.launch_unity()
340− greeter = self.main_window.get_greeter()
339+ unlock_unity(unity_proxy)
341− greeter.swipe()
342
340
343 notify_list = self._get_notifications_list()
341 notify_list = self._get_notifications_list()
344
342
@@ -377,9 +375,8 @@ class EphemeralNotificationsTests(NotificationsBase):
377 def test_icon_summary(self):
375 def test_icon_summary(self):
378 """Notification must display the expected summary and secondary
376 """Notification must display the expected summary and secondary
379 icon."""
377 icon."""
380− self.launch_unity()
378+ unity_proxy = self.launch_unity()
381− greeter = self.main_window.get_greeter()
379+ unlock_unity(unity_proxy)
382− greeter.swipe()
383
380
384 notify_list = self._get_notifications_list()
381 notify_list = self._get_notifications_list()
385
382
@@ -416,9 +413,8 @@ class EphemeralNotificationsTests(NotificationsBase):
416 def test_urgency_order(self):
413 def test_urgency_order(self):
417 """Notifications must be displayed in order according to their
414 """Notifications must be displayed in order according to their
418 urgency."""
415 urgency."""
419− self.launch_unity()
416+ unity_proxy = self.launch_unity()
420− greeter = self.main_window.get_greeter()
417+ unlock_unity(unity_proxy)
421− greeter.swipe()
422
418
423 notify_list = self._get_notifications_list()
419 notify_list = self._get_notifications_list()
424
420
@@ -504,9 +500,8 @@ class EphemeralNotificationsTests(NotificationsBase):
504
500
505 def test_summary_and_body(self):
501 def test_summary_and_body(self):
506 """Notification must display the expected summary- and body-text."""
502 """Notification must display the expected summary- and body-text."""
507− self.launch_unity()
503+ unity_proxy = self.launch_unity()
508− greeter = self.main_window.get_greeter()
504+ unlock_unity(unity_proxy)
509− greeter.swipe()
510
505
511 notify_list = self._get_notifications_list()
506 notify_list = self._get_notifications_list()
512
507
@@ -518,6 +513,7 @@ class EphemeralNotificationsTests(NotificationsBase):
518
513
519 notification = notify_list.wait_select_single(
514 notification = notify_list.wait_select_single(
520 'Notification', objectName='notification1')
515 'Notification', objectName='notification1')
516+
521 self._assert_notification(
517 self._assert_notification(
522 notification,
518 notification,
523 summary,
519 summary,
@@ -529,9 +525,8 @@ class EphemeralNotificationsTests(NotificationsBase):
529
525
530 def test_summary_only(self):
526 def test_summary_only(self):
531 """Notification must display only the expected summary-text."""
527 """Notification must display only the expected summary-text."""
532− self.launch_unity()
528+ unity_proxy = self.launch_unity()
533− greeter = self.main_window.get_greeter()
529+ unlock_unity(unity_proxy)
534− greeter.swipe()
535
530
536 notify_list = self._get_notifications_list()
531 notify_list = self._get_notifications_list()
537
532
@@ -548,9 +543,8 @@ class EphemeralNotificationsTests(NotificationsBase):
548 def test_update_notification_same_layout(self):
543 def test_update_notification_same_layout(self):
549 """Notification must allow updating its contents while being
544 """Notification must allow updating its contents while being
550 displayed."""
545 displayed."""
551− self.launch_unity()
546+ unity_proxy = self.launch_unity()
552− greeter = self.main_window.get_greeter()
547+ unlock_unity(unity_proxy)
553− greeter.swipe()
554
548
555 notify_list = self._get_notifications_list()
549 notify_list = self._get_notifications_list()
556
550
@@ -587,9 +581,8 @@ class EphemeralNotificationsTests(NotificationsBase):
587 def test_update_notification_layout_change(self):
581 def test_update_notification_layout_change(self):
588 """Notification must allow updating its contents and layout while
582 """Notification must allow updating its contents and layout while
589 being displayed."""
583 being displayed."""
590− self.launch_unity()
584+ unity_proxy = self.launch_unity()
591− greeter = self.main_window.get_greeter()
585+ unlock_unity(unity_proxy)
592− greeter.swipe()
593
586
594 notify_list = self._get_notifications_list()
587 notify_list = self._get_notifications_list()
595
588
@@ -612,6 +605,7 @@ class EphemeralNotificationsTests(NotificationsBase):
612
605
613 get_notification = lambda: notify_list.wait_select_single(
606 get_notification = lambda: notify_list.wait_select_single(
614 'Notification', objectName='notification1')
607 'Notification', objectName='notification1')
608+
615 self._assert_notification(
609 self._assert_notification(
616 get_notification(),
610 get_notification(),
617 summary,
611 summary,
@@ -633,9 +627,8 @@ class EphemeralNotificationsTests(NotificationsBase):
633
627
634 def test_append_hint(self):
628 def test_append_hint(self):
635 """Notification has to accumulate body-text using append-hint."""
629 """Notification has to accumulate body-text using append-hint."""
636− self.launch_unity()
630+ unity_proxy = self.launch_unity()
637− greeter = self.main_window.get_greeter()
631+ unlock_unity(unity_proxy)
638− greeter.swipe()
639
632
640 notify_list = self._get_notifications_list()
633 notify_list = self._get_notifications_list()
641
634
@@ -654,6 +647,7 @@ class EphemeralNotificationsTests(NotificationsBase):
654
647
655 get_notification = lambda: notify_list.wait_select_single(
648 get_notification = lambda: notify_list.wait_select_single(
656 'Notification', objectName='notification1')
649 'Notification', objectName='notification1')
650+
657 notification = get_notification()
651 notification = get_notification()
658 self._assert_notification(
652 self._assert_notification(
659 notification,
653 notification,
@@ -685,6 +679,7 @@ class EphemeralNotificationsTests(NotificationsBase):
685 hints=[('x-canonical-append', 'true')]
679 hints=[('x-canonical-append', 'true')]
686 )
680 )
687 notification.show()
681 notification.show()
682+
688 get_notification = lambda: notify_list.wait_select_single(
683 get_notification = lambda: notify_list.wait_select_single(
689 'Notification',
684 'Notification',
690 objectName='notification1'
685 objectName='notification1'