on xenial help sign in
Initial rough-cast
2ced3adChristopher Lee
tests/autopilot/unity8/shell/tests/__init__.py+103−10
@@ -28,9 +28,11 @@ 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
31from autopilot.display import Display
32from autopilot.display import Display
32import logging
33import logging
33import os.path
34import os.path
35+import subprocess
34from testtools.matchers import Equals, NotEquals
36from testtools.matchers import Equals, NotEquals
35
37
36from unity8 import (
38from unity8 import (
@@ -90,6 +92,10 @@ class UnityTestCase(AutopilotTestCase):
90 self.touch = Touch.create()
92 self.touch = Touch.create()
91 self._setup_display_details()
93 self._setup_display_details()
92
94
95+ self._using_upstart = False
96+ if model() != "Desktop": # or check env
97+ self._using_upstart = True
98+
93 def _reset_launcher(self):
99 def _reset_launcher(self):
94 """Reset Unity launcher hide mode"""
100 """Reset Unity launcher hide mode"""
95 self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, self._launcher_hide_mode)
101 self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, self._launcher_hide_mode)
@@ -129,7 +135,7 @@ class UnityTestCase(AutopilotTestCase):
129 self.grid_size = int(os.getenv('GRID_UNIT_PX'))
135 self.grid_size = int(os.getenv('GRID_UNIT_PX'))
130 else:
136 else:
131 self.grid_size = int(self.grid_unit_px / scale_divisor)
137 self.grid_size = int(self.grid_unit_px / scale_divisor)
132− self.patch_environment("GRID_UNIT_PX", str(self.grid_size))
138+ self._patch_environment("GRID_UNIT_PX", str(self.grid_size))
133
139
134 def _geo_larger_than_display(self, width, height):
140 def _geo_larger_than_display(self, width, height):
135 should_scale = getattr(self, 'scale_geo', True)
141 should_scale = getattr(self, 'scale_geo', True)
@@ -147,6 +153,41 @@ class UnityTestCase(AutopilotTestCase):
147 divisor = divisor * 2
153 divisor = divisor * 2
148 return divisor
154 return divisor
149
155
156+ def _patch_environment(self, key, value):
157+ """Wrapper for patching env for either upstart or non-upstart
158+ environments.
159+
160+ """
161+ if self._using_upstart:
162+ try:
163+ current_value = subprocess.check_output([
164+ "/sbin/initctl",
165+ "get-env",
166+ key
167+ ])
168+ except subprocess.CalledProcessError:
169+ current_value = None
170+
171+ subprocess.call([
172+ "/sbin/initctl",
173+ "set-env",
174+ "%s=%s" % (key, value)
175+ ])
176+ self.addCleanup(self._upstart_reset_env, key, current_value)
177+ else:
178+ self.patch_environment(key, value)
179+
180+ def _upstart_reset_env(self, key, value):
181+ logger.info("Resetting upstart env %s to %s", key, value)
182+ if value is None:
183+ subprocess.call(["/sbin/initctl", "unset-env", key])
184+ else:
185+ subprocess.call([
186+ "/sbin/initctl",
187+ "set-env",
188+ "%s=%s" % (key, value)
189+ ])
190+
150 def launch_unity(self, **kwargs):
191 def launch_unity(self, **kwargs):
151 """Launch the unity shell, return a proxy object for it."""
192 """Launch the unity shell, return a proxy object for it."""
152 binary_path = get_binary_path()
193 binary_path = get_binary_path()
@@ -175,13 +216,17 @@ class UnityTestCase(AutopilotTestCase):
175 except OSError:
216 except OSError:
176 pass
217 pass
177
218
219+ if self._using_upstart:
220+ app_proxy = self._launch_unity_with_upstart()
221+ else:
178− app_proxy = self.launch_test_application(
222+ app_proxy = self.launch_test_application(
179− binary_path,
223+ binary_path,
180− *self.unity_geometry_args,
224+ *self.unity_geometry_args,
181− app_type='qt',
225+ app_type='qt',
182− emulator_base=UnityEmulatorBase,
226+ emulator_base=UnityEmulatorBase,
183− **kwargs
227+ **kwargs
184− )
228+ )
229+
185 self._set_proxy(app_proxy)
230 self._set_proxy(app_proxy)
186
231
187 # Ensure that the dash is visible before we return:
232 # Ensure that the dash is visible before we return:
@@ -191,6 +236,54 @@ class UnityTestCase(AutopilotTestCase):
191
236
192 return app_proxy
237 return app_proxy
193
238
239+ def _launch_unity_with_upstart(self):
240+ subprocess.call(["/sbin/initctl", "set-env", "QT_LOAD_TESTABILITY=1"])
241+
242+ output = subprocess.check_output([
243+ "/sbin/initctl",
244+ "status",
245+ "unity8"
246+ ])
247+
248+ unity_already_started = False
249+ if "start/" in output:
250+ unity_already_started = True
251+ try:
252+ subprocess.check_call(["/sbin/initctl", "stop", "unity8"])
253+ except subprocess.CalledProcessError as e:
254+ logger.warning("Unable to stop unity8")
255+ e.args += ("Failed to stop existing unity8 process", )
256+ raise
257+
258+ output = subprocess.check_output(["/sbin/initctl", "start", "unity8"])
259+
260+ self.addCleanup(
261+ self._cleanup_launching_upstart_unity,
262+ unity_already_started
263+ )
264+
265+ pid = int(output.split()[-1])
266+
267+ return get_proxy_object_for_existing_process(
268+ pid=pid,
269+ emulator_base=UnityEmulatorBase,
270+ )
271+
272+ def _cleanup_launching_upstart_unity(self, restart_unity):
273+ logger.info("Cleaning up launching unity, unsetting env")
274+ subprocess.call(["/sbin/initctl", "unset-env", "QT_LOAD_TESTABILITY"])
275+
276+ try:
277+ logger.info("Stopping existing unity")
278+ subprocess.check_call(["/sbin/initctl", "stop", "unity8"])
279+ except subprocess.CalledProcessError:
280+ logger.warning("Appears unity was already stopped")
281+
282+ # Actually, the previous env stuff will be still here right?
283+ if restart_unity:
284+ logger.info("Starting unity again with original env")
285+ subprocess.check_call(["/sbin/initctl", "start", "unity8"])
286+
194 def patch_lightdm_mock(self, mock_type='single'):
287 def patch_lightdm_mock(self, mock_type='single'):
195 self._lightdm_mock_type = mock_type
288 self._lightdm_mock_type = mock_type
196 logger.info("Setting up LightDM mock type '%s'", mock_type)
289 logger.info("Setting up LightDM mock type '%s'", mock_type)
@@ -204,7 +297,7 @@ class UnityTestCase(AutopilotTestCase):
204 new_ld_library_path = ':'.join(new_ld_library_path)
297 new_ld_library_path = ':'.join(new_ld_library_path)
205 logger.info("New library path: %s", new_ld_library_path)
298 logger.info("New library path: %s", new_ld_library_path)
206
299
207− self.patch_environment('LD_LIBRARY_PATH', new_ld_library_path)
300+ self._patch_environment('LD_LIBRARY_PATH', new_ld_library_path)
208
301
209 def _get_lightdm_mock_path(self, mock_type):
302 def _get_lightdm_mock_path(self, mock_type):
210 lib_path = get_mocks_library_path()
303 lib_path = get_mocks_library_path()
@@ -226,7 +319,7 @@ class UnityTestCase(AutopilotTestCase):
226
319
227 qml_import_path = ':'.join(qml_import_path)
320 qml_import_path = ':'.join(qml_import_path)
228 logger.info("New QML2 import path: %s", qml_import_path)
321 logger.info("New QML2 import path: %s", qml_import_path)
229− self.patch_environment('QML2_IMPORT_PATH', qml_import_path)
322+ self._patch_environment('QML2_IMPORT_PATH', qml_import_path)
230
323
231 def _set_proxy(self, proxy):
324 def _set_proxy(self, proxy):
232 """Keep a copy of the proxy object, so we can use it to get common
325 """Keep a copy of the proxy object, so we can use it to get common