Merge ~xnox/autopilot:master into autopilot:master

Proposed by Dimitri John Ledkov
Status: Needs review
Proposed branch: ~xnox/autopilot:master
Merge into: autopilot:master
Diff against target: 1211 lines (+15/-1051)
8 files modified
autopilot/application/__init__.py (+0/-4)
autopilot/application/_launcher.py (+1/-262)
autopilot/testcase.py (+0/-74)
autopilot/tests/functional/test_ap_apps.py (+0/-7)
autopilot/tests/functional/test_application_launcher.py (+0/-50)
autopilot/tests/unit/test_application_launcher.py (+0/-651)
debian/changelog (+13/-0)
debian/control (+1/-3)
Reviewer Review Type Date Requested Status
Paride Legovini Approve
Review via email: mp+385115@code.launchpad.net

Commit message

Drop ual support, blocking groovy transitions.

To post a comment you must log in.
Revision history for this message
Paride Legovini (paride) wrote :

The proposed change looks reasonable to me, however I do not use autopilot so I'm probably not the best person to review this. I will approve but won't merge.

review: Approve

Unmerged commits

20f75d0... by Dimitri John Ledkov

Drop upstart, click, ubuntu-app-launch support. All of those things are removed from the Ubuntu Archive.

* Drop upstart, click, ubuntu-app-launch support. All of those things
  are removed from the Ubuntu Archive.
* No-change rebuild to drop python3.7.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/autopilot/application/__init__.py b/autopilot/application/__init__.py
2index 8ebda84..efaac1e 100644
3--- a/autopilot/application/__init__.py
4+++ b/autopilot/application/__init__.py
5@@ -20,15 +20,11 @@
6 """Base package for application launching and environment management."""
7
8 from autopilot.application._launcher import (
9- ClickApplicationLauncher,
10 get_application_launcher_wrapper,
11 NormalApplicationLauncher,
12- UpstartApplicationLauncher,
13 )
14
15 __all__ = [
16- 'ClickApplicationLauncher',
17 'NormalApplicationLauncher',
18- 'UpstartApplicationLauncher',
19 'get_application_launcher_wrapper',
20 ]
21diff --git a/autopilot/application/_launcher.py b/autopilot/application/_launcher.py
22index 8ec391f..72fef39 100644
23--- a/autopilot/application/_launcher.py
24+++ b/autopilot/application/_launcher.py
25@@ -20,12 +20,7 @@
26 """Base module for application launchers."""
27
28 import fixtures
29-from gi import require_version
30-try:
31- require_version('UbuntuAppLaunch', '3')
32-except ValueError:
33- require_version('UbuntuAppLaunch', '2')
34-from gi.repository import GLib, UbuntuAppLaunch
35+from gi.repository import GLib
36
37 import json
38 import logging
39@@ -81,233 +76,6 @@ class ApplicationLauncher(FixtureWithDirectAddDetail):
40 raise NotImplementedError("Sub-classes must implement this method.")
41
42
43-class UpstartApplicationLauncher(ApplicationLauncher):
44-
45- """A launcher class that launches applications with UpstartAppLaunch."""
46- __doc__ += ApplicationLauncher.__doc__
47-
48- Timeout = object()
49- Failed = object()
50- Started = object()
51- Stopped = object()
52-
53- def launch(self, app_id, app_uris=[]):
54- """Launch an application with upstart.
55-
56- This method launches an application via the ``upstart-app-launch``
57- library, on platforms that support it.
58-
59- Usage is similar to NormalApplicationLauncher::
60-
61- from autopilot.application import UpstartApplicationLauncher
62- launcher = UpstartApplicationLauncher()
63- launcher.setUp()
64- app_proxy = launcher.launch('gallery-app')
65-
66- :param app_id: name of the application to launch
67- :param app_uris: list of separate application uris to launch
68- :raises RuntimeError: If the specified application cannot be launched.
69-
70- :returns: proxy object for the launched package application
71-
72- """
73- if isinstance(app_uris, str):
74- app_uris = [app_uris]
75- if isinstance(app_uris, bytes):
76- app_uris = [app_uris.decode()]
77- _logger.info(
78- "Attempting to launch application '%s' with URIs '%s' via "
79- "upstart-app-launch",
80- app_id,
81- ','.join(app_uris)
82- )
83- state = {}
84- state['loop'] = self._get_glib_loop()
85- state['expected_app_id'] = app_id
86- state['message'] = ''
87-
88- UbuntuAppLaunch.observer_add_app_failed(self._on_failed, state)
89- UbuntuAppLaunch.observer_add_app_started(self._on_started, state)
90- UbuntuAppLaunch.observer_add_app_focus(self._on_started, state)
91- GLib.timeout_add_seconds(10.0, self._on_timeout, state)
92-
93- self._launch_app(app_id, app_uris)
94- state['loop'].run()
95- UbuntuAppLaunch.observer_delete_app_failed(self._on_failed)
96- UbuntuAppLaunch.observer_delete_app_started(self._on_started)
97- UbuntuAppLaunch.observer_delete_app_focus(self._on_started)
98- self._maybe_add_application_cleanups(state)
99- self._check_status_error(
100- state.get('status', None),
101- state.get('message', '')
102- )
103- pid = self._get_pid_for_launched_app(app_id)
104-
105- return self._get_proxy_object(pid)
106-
107- def _get_proxy_object(self, pid):
108- return get_proxy_object_for_existing_process(
109- dbus_bus=self.dbus_bus,
110- emulator_base=self.proxy_base,
111- pid=pid
112- )
113-
114- @staticmethod
115- def _on_failed(launched_app_id, failure_type, state):
116- if launched_app_id == state['expected_app_id']:
117- if failure_type == UbuntuAppLaunch.AppFailed.CRASH:
118- state['message'] = 'Application crashed.'
119- elif failure_type == UbuntuAppLaunch.AppFailed.START_FAILURE:
120- state['message'] = 'Application failed to start.'
121- state['status'] = UpstartApplicationLauncher.Failed
122- state['loop'].quit()
123-
124- @staticmethod
125- def _on_started(launched_app_id, state):
126- if launched_app_id == state['expected_app_id']:
127- state['status'] = UpstartApplicationLauncher.Started
128- state['loop'].quit()
129-
130- @staticmethod
131- def _on_stopped(stopped_app_id, state):
132- if stopped_app_id == state['expected_app_id']:
133- state['status'] = UpstartApplicationLauncher.Stopped
134- state['loop'].quit()
135-
136- @staticmethod
137- def _on_timeout(state):
138- state['status'] = UpstartApplicationLauncher.Timeout
139- state['loop'].quit()
140-
141- def _maybe_add_application_cleanups(self, state):
142- if state.get('status', None) == UpstartApplicationLauncher.Started:
143- app_id = state['expected_app_id']
144- self.addCleanup(self._stop_application, app_id)
145- self.addCleanup(self._attach_application_log, app_id)
146-
147- @staticmethod
148- def _get_user_unit_match(app_id):
149- return 'ubuntu-app-launch-*-%s-*.service' % app_id
150-
151- def _attach_application_log(self, app_id):
152- j = journal.Reader()
153- j.log_level(journal.LOG_INFO)
154- j.add_match(_SYSTEMD_USER_UNIT=self._get_user_unit_match(app_id))
155- log_data = ''
156- for i in j:
157- log_data += str(i) + '\n'
158- if len(log_data) > 0:
159- self.caseAddDetail('Application Log (%s)' % app_id,
160- safe_text_content(log_data))
161-
162- def _stop_application(self, app_id):
163- state = {}
164- state['loop'] = self._get_glib_loop()
165- state['expected_app_id'] = app_id
166-
167- UbuntuAppLaunch.observer_add_app_stop(self._on_stopped, state)
168- GLib.timeout_add_seconds(10.0, self._on_timeout, state)
169-
170- UbuntuAppLaunch.stop_application(app_id)
171- state['loop'].run()
172- UbuntuAppLaunch.observer_delete_app_stop(self._on_stopped)
173-
174- if state.get('status', None) == UpstartApplicationLauncher.Timeout:
175- _logger.error(
176- "Timed out waiting for Application with app_id '%s' to stop.",
177- app_id
178- )
179-
180- @staticmethod
181- def _get_glib_loop():
182- return GLib.MainLoop()
183-
184- @staticmethod
185- def _get_pid_for_launched_app(app_id):
186- return UbuntuAppLaunch.get_primary_pid(app_id)
187-
188- @staticmethod
189- def _launch_app(app_name, app_uris):
190- UbuntuAppLaunch.start_application_test(app_name, app_uris)
191-
192- @staticmethod
193- def _check_status_error(status, extra_message=''):
194- message_parts = []
195- if status == UpstartApplicationLauncher.Timeout:
196- message_parts.append(
197- "Timed out while waiting for application to launch"
198- )
199- elif status == UpstartApplicationLauncher.Failed:
200- message_parts.append("Application Launch Failed")
201- if message_parts and extra_message:
202- message_parts.append(extra_message)
203- if message_parts:
204- raise RuntimeError(': '.join(message_parts))
205-
206-
207-class AlreadyLaunchedUpstartLauncher(UpstartApplicationLauncher):
208- """Launcher that doesn't wait for a proxy object.
209-
210- This is useful when you are 're-launching' an already running application
211- and it's state has changed to suspended.
212-
213- """
214-
215- def _get_proxy_object(self, pid):
216- # Don't wait for a proxy object
217- return None
218-
219-
220-class ClickApplicationLauncher(UpstartApplicationLauncher):
221-
222- """Fixture to manage launching a Click application."""
223- __doc__ += ApplicationLauncher.__doc__
224-
225- def launch(self, package_id, app_name=None, app_uris=[]):
226- """Launch a click package application with introspection enabled.
227-
228- This method takes care of launching a click package with introspection
229- exabled. You probably want to use this method if your application is
230- packaged in a click application, or is started via upstart.
231-
232- Usage is similar to NormalApplicationLauncher.launch::
233-
234- from autopilot.application import ClickApplicationLauncher
235- launcher = ClickApplicationLauncher()
236- launcher.setUp()
237- app_proxy = launcher.launch('com.ubuntu.dropping-letters')
238-
239- :param package_id: The Click package name you want to launch. For
240- example: ``com.ubuntu.dropping-letters``
241- :param app_name: Currently, only one application can be packaged in a
242- click package, and this parameter can be left at None. If
243- specified, it should be the application name you wish to launch.
244- :param app_uris: Parameters used to launch the click package. This
245- parameter will be left empty if not used.
246-
247- :raises RuntimeError: If the specified package_id cannot be found in
248- the click package manifest.
249- :raises RuntimeError: If the specified app_name cannot be found within
250- the specified click package.
251-
252- :returns: proxy object for the launched package application
253-
254- """
255- if isinstance(app_uris, str):
256- app_uris = [app_uris]
257- if isinstance(app_uris, bytes):
258- app_uris = [app_uris.decode()]
259- _logger.info(
260- "Attempting to launch click application '%s' from click package "
261- " '%s' and URIs '%s'",
262- app_name if app_name is not None else "(default)",
263- package_id,
264- ','.join(app_uris)
265- )
266- app_id = _get_click_app_id(package_id, app_name)
267- return super().launch(app_id, app_uris)
268-
269-
270 class NormalApplicationLauncher(ApplicationLauncher):
271
272 """Fixture to manage launching an application."""
273@@ -470,35 +238,6 @@ def launch_process(application, args, capture_output=False, **kwargs):
274 return process
275
276
277-def _get_click_app_id(package_id, app_name=None):
278- for pkg in _get_click_manifest():
279- if pkg['name'] == package_id:
280- if app_name is None:
281- # py3 dict.keys isn't indexable.
282- app_name = list(pkg['hooks'].keys())[0]
283- elif app_name not in pkg['hooks']:
284- raise RuntimeError(
285- "Application '{}' is not present within the click "
286- "package '{}'.".format(app_name, package_id))
287-
288- return "{0}_{1}_{2}".format(package_id, app_name, pkg['version'])
289- raise RuntimeError(
290- "Unable to find package '{}' in the click manifest."
291- .format(package_id)
292- )
293-
294-
295-def _get_click_manifest():
296- """Return the click package manifest as a python list."""
297- # get the whole click package manifest every time - it seems fast enough
298- # but this is a potential optimisation point for the future:
299- click_manifest_str = subprocess.check_output(
300- ["click", "list", "--manifest"],
301- universal_newlines=True
302- )
303- return json.loads(click_manifest_str)
304-
305-
306 def _get_application_environment(app_type=None, app_path=None):
307 if app_type is None and app_path is None:
308 raise ValueError("Must specify either app_type or app_path.")
309diff --git a/autopilot/testcase.py b/autopilot/testcase.py
310index af8c2d4..8360eea 100644
311--- a/autopilot/testcase.py
312+++ b/autopilot/testcase.py
313@@ -57,9 +57,7 @@ from testtools.testcase import _ExpectedFailure
314 from unittest.case import SkipTest
315
316 from autopilot.application import (
317- ClickApplicationLauncher,
318 NormalApplicationLauncher,
319- UpstartApplicationLauncher,
320 )
321 from autopilot.display import Display, get_screenshot_data
322 from autopilot.globals import get_debug_profile_fixture, get_test_timeout
323@@ -285,78 +283,6 @@ class AutopilotTestCase(TestWithScenarios, TestCase, KeybindingsHelper):
324 )
325 return launcher.launch(application, arguments, **launch_args)
326
327- def launch_click_package(self, package_id, app_name=None, app_uris=[],
328- **kwargs):
329- """Launch a click package application with introspection enabled.
330-
331- This method takes care of launching a click package with introspection
332- exabled. You probably want to use this method if your application is
333- packaged in a click application, or is started via upstart.
334-
335- Usage is similar to the
336- :py:meth:`AutopilotTestCase.launch_test_application`::
337-
338- app_proxy = self.launch_click_package(
339- "com.ubuntu.dropping-letters"
340- )
341-
342- :param package_id: The Click package name you want to launch. For
343- example: ``com.ubuntu.dropping-letters``
344- :param app_name: Currently, only one application can be packaged in a
345- click package, and this parameter can be left at None. If
346- specified, it should be the application name you wish to launch.
347- :param app_uris: Parameters used to launch the click package. This
348- parameter will be left empty if not used.
349-
350- :keyword emulator_base: If set, specifies the base class to be used for
351- all emulators for this loaded application.
352-
353- :raises RuntimeError: If the specified package_id cannot be found in
354- the click package manifest.
355- :raises RuntimeError: If the specified app_name cannot be found within
356- the specified click package.
357-
358- :returns: proxy object for the launched package application
359-
360- """
361- launcher = self.useFixture(
362- ClickApplicationLauncher(
363- case_addDetail=self.addDetailUniqueName,
364- **kwargs
365- )
366- )
367- return launcher.launch(package_id, app_name, app_uris)
368-
369- def launch_upstart_application(self, application_name, uris=[],
370- launcher_class=UpstartApplicationLauncher,
371- **kwargs):
372- """Launch an application with upstart.
373-
374- This method launched an application via the ``ubuntu-app-launch``
375- library, on platforms that support it.
376-
377- Usage is similar to the
378- :py:meth:`AutopilotTestCase.launch_test_application`::
379-
380- app_proxy = self.launch_upstart_application("gallery-app")
381-
382- :param application_name: The name of the application to launch.
383- :param launcher_class: The application launcher class to use. Useful if
384- you need to overwrite the default to do something custom (i.e. using
385- AlreadyLaunchedUpstartLauncher)
386- :keyword emulator_base: If set, specifies the base class to be used for
387- all emulators for this loaded application.
388-
389- :raises RuntimeError: If the specified application cannot be launched.
390- """
391- launcher = self.useFixture(
392- launcher_class(
393- case_addDetail=self.addDetailUniqueName,
394- **kwargs
395- )
396- )
397- return launcher.launch(application_name, uris)
398-
399 def _compare_system_with_app_snapshot(self):
400 """Compare the currently running application with the last snapshot.
401
402diff --git a/autopilot/tests/functional/test_ap_apps.py b/autopilot/tests/functional/test_ap_apps.py
403index 71d5928..de66fa0 100644
404--- a/autopilot/tests/functional/test_ap_apps.py
405+++ b/autopilot/tests/functional/test_ap_apps.py
406@@ -37,7 +37,6 @@ from fixtures import EnvironmentVariable
407
408 from autopilot.application import (
409 NormalApplicationLauncher,
410- UpstartApplicationLauncher,
411 )
412 from autopilot.exceptions import ProcessSearchError
413 from autopilot.process import ProcessManager
414@@ -296,12 +295,6 @@ class QtTests(ApplicationTests, QmlTestMixin):
415 )
416 self.assertTrue(app_proxy is not None)
417
418- def test_can_launch_upstart_app(self):
419- path = self.get_qml_viewer_app_path()
420- fixture = self.useFixture(TempDesktopFile(exec_=path,))
421- launcher = self.useFixture(UpstartApplicationLauncher())
422- launcher.launch(fixture.get_desktop_file_id())
423-
424 @skipIf(model() != "Desktop", "Only suitable on Desktop (Qt4)")
425 def test_can_launch_normal_qt_script(self):
426 path = self.write_script(dedent("""\
427diff --git a/autopilot/tests/functional/test_application_launcher.py b/autopilot/tests/functional/test_application_launcher.py
428index f9c1e48..7e16a0c 100644
429--- a/autopilot/tests/functional/test_application_launcher.py
430+++ b/autopilot/tests/functional/test_application_launcher.py
431@@ -44,53 +44,3 @@ class AutopilotTestCaseClassTests(TestCase):
432 uf.return_value.launch.assert_called_once_with('a', ('b', 'c'))
433 self.assertEqual(result, uf.return_value.launch.return_value)
434
435- @patch('autopilot.testcase.ClickApplicationLauncher')
436- def test_launch_click_package(self, cal):
437- class LauncherTest(AutopilotTestCase):
438-
439- """Test launchers."""
440-
441- def test_anything(self):
442- pass
443-
444- test_case = LauncherTest('test_anything')
445- with patch.object(test_case, 'useFixture') as uf:
446- result = test_case.launch_click_package('a', 'b', ['c', 'd'])
447- uf.assert_called_once_with(cal.return_value)
448- uf.return_value.launch.assert_called_once_with(
449- 'a', 'b', ['c', 'd']
450- )
451- self.assertEqual(result, uf.return_value.launch.return_value)
452-
453- @patch('autopilot.testcase.UpstartApplicationLauncher')
454- def test_launch_upstart_application_defaults(self, ual):
455- class LauncherTest(AutopilotTestCase):
456-
457- """Test launchers."""
458-
459- def test_anything(self):
460- pass
461-
462- test_case = LauncherTest('test_anything')
463- with patch.object(test_case, 'useFixture') as uf:
464- result = test_case.launch_upstart_application(
465- 'a', ['b'], launcher_class=ual
466- )
467- uf.assert_called_once_with(ual.return_value)
468- uf.return_value.launch.assert_called_once_with('a', ['b'])
469- self.assertEqual(result, uf.return_value.launch.return_value)
470-
471- def test_launch_upstart_application_custom_launcher(self):
472- class LauncherTest(AutopilotTestCase):
473-
474- """Test launchers."""
475-
476- def test_anything(self):
477- pass
478-
479- test_case = LauncherTest('test_anything')
480- self.assertRaises(
481- NotImplementedError,
482- test_case.launch_upstart_application,
483- 'a', ['b'], launcher_class=_launcher.ApplicationLauncher
484- )
485diff --git a/autopilot/tests/unit/test_application_launcher.py b/autopilot/tests/unit/test_application_launcher.py
486index 3de7819..af92c42 100644
487--- a/autopilot/tests/unit/test_application_launcher.py
488+++ b/autopilot/tests/unit/test_application_launcher.py
489@@ -36,9 +36,7 @@ from testtools.content import text_content
490 from unittest.mock import MagicMock, Mock, patch
491
492 from autopilot.application import (
493- ClickApplicationLauncher,
494 NormalApplicationLauncher,
495- UpstartApplicationLauncher,
496 )
497 from autopilot.application._environment import (
498 GtkApplicationEnvironment,
499@@ -53,8 +51,6 @@ from autopilot.application._launcher import (
500 _get_app_env_from_string_hint,
501 _get_application_environment,
502 _get_application_path,
503- _get_click_app_id,
504- _get_click_manifest,
505 _is_process_running,
506 _kill_process,
507 )
508@@ -261,635 +257,6 @@ class NormalApplicationLauncherTests(TestCase):
509 )
510
511
512-class ClickApplicationLauncherTests(TestCase):
513-
514- def test_raises_exception_on_unknown_kwargs(self):
515- self.assertThat(
516- lambda: ClickApplicationLauncher(self.addDetail, unknown=True),
517- raises(TypeError("__init__() got an unexpected keyword argument "
518- "'unknown'"))
519- )
520-
521- @patch('autopilot.application._launcher._get_click_app_id')
522- def test_handle_string(self, gcai):
523- class FakeUpstartBase(_l.ApplicationLauncher):
524- launch_call_args = []
525-
526- def launch(self, *args):
527- FakeUpstartBase.launch_call_args = list(args)
528-
529- patcher = patch.object(
530- _l.ClickApplicationLauncher,
531- '__bases__',
532- (FakeUpstartBase,)
533- )
534- token = self.getUniqueString()
535- with patcher:
536- # Prevent mock from trying to delete __bases__
537- patcher.is_local = True
538- launcher = self.useFixture(
539- _l.ClickApplicationLauncher())
540- launcher.launch('', '', token)
541- self.assertEqual(
542- FakeUpstartBase.launch_call_args,
543- [gcai.return_value, [token]])
544-
545- @patch('autopilot.application._launcher._get_click_app_id')
546- def test_handle_bytes(self, gcai):
547- class FakeUpstartBase(_l.ApplicationLauncher):
548- launch_call_args = []
549-
550- def launch(self, *args):
551- FakeUpstartBase.launch_call_args = list(args)
552-
553- patcher = patch.object(
554- _l.ClickApplicationLauncher,
555- '__bases__',
556- (FakeUpstartBase,)
557- )
558- token = self.getUniqueString()
559- with patcher:
560- # Prevent mock from trying to delete __bases__
561- patcher.is_local = True
562- launcher = self.useFixture(
563- _l.ClickApplicationLauncher())
564- launcher.launch('', '', token.encode())
565- self.assertEqual(
566- FakeUpstartBase.launch_call_args,
567- [gcai.return_value, [token]])
568-
569- @patch('autopilot.application._launcher._get_click_app_id')
570- def test_handle_list(self, gcai):
571- class FakeUpstartBase(_l.ApplicationLauncher):
572- launch_call_args = []
573-
574- def launch(self, *args):
575- FakeUpstartBase.launch_call_args = list(args)
576-
577- patcher = patch.object(
578- _l.ClickApplicationLauncher,
579- '__bases__',
580- (FakeUpstartBase,)
581- )
582- token = self.getUniqueString()
583- with patcher:
584- # Prevent mock from trying to delete __bases__
585- patcher.is_local = True
586- launcher = self.useFixture(
587- _l.ClickApplicationLauncher())
588- launcher.launch('', '', [token])
589- self.assertEqual(
590- FakeUpstartBase.launch_call_args,
591- [gcai.return_value, [token]])
592-
593- @patch('autopilot.application._launcher._get_click_app_id')
594- def test_call_get_click_app_id(self, gcai):
595- class FakeUpstartBase(_l.ApplicationLauncher):
596- launch_call_args = []
597-
598- def launch(self, *args):
599- FakeUpstartBase.launch_call_args = list(args)
600-
601- patcher = patch.object(
602- _l.ClickApplicationLauncher,
603- '__bases__',
604- (FakeUpstartBase,)
605- )
606- token_a = self.getUniqueString()
607- token_b = self.getUniqueString()
608- with patcher:
609- # Prevent mock from trying to delete __bases__
610- patcher.is_local = True
611- launcher = self.useFixture(
612- _l.ClickApplicationLauncher())
613- launcher.launch(token_a, token_b)
614- gcai.assert_called_once_with(token_a, token_b)
615-
616- @patch('autopilot.application._launcher._get_click_app_id')
617- def test_call_upstart_launch(self, gcai):
618- class FakeUpstartBase(_l.ApplicationLauncher):
619- launch_call_args = []
620-
621- def launch(self, *args):
622- FakeUpstartBase.launch_call_args = list(args)
623-
624- patcher = patch.object(
625- _l.ClickApplicationLauncher,
626- '__bases__',
627- (FakeUpstartBase,)
628- )
629- with patcher:
630- # Prevent mock from trying to delete __bases__
631- patcher.is_local = True
632- launcher = self.useFixture(
633- _l.ClickApplicationLauncher())
634- launcher.launch('', '')
635- self.assertEqual(launcher.launch_call_args,
636- [gcai.return_value, []])
637-
638-
639-class ClickFunctionTests(TestCase):
640-
641- def test_get_click_app_id_raises_runtimeerror_on_empty_manifest(self):
642- """_get_click_app_id must raise a RuntimeError if the requested
643- package id is not found in the click manifest.
644-
645- """
646- with patch.object(_l, '_get_click_manifest', return_value=[]):
647- self.assertThat(
648- lambda: _get_click_app_id("com.autopilot.testing"),
649- raises(
650- RuntimeError(
651- "Unable to find package 'com.autopilot.testing' in "
652- "the click manifest."
653- )
654- )
655- )
656-
657- def test_get_click_app_id_raises_runtimeerror_on_missing_package(self):
658- with patch.object(_l, '_get_click_manifest') as cm:
659- cm.return_value = [
660- {
661- 'name': 'com.not.expected.name',
662- 'hooks': {'bar': {}}, 'version': '1.0'
663- }
664- ]
665-
666- self.assertThat(
667- lambda: _get_click_app_id("com.autopilot.testing"),
668- raises(
669- RuntimeError(
670- "Unable to find package 'com.autopilot.testing' in "
671- "the click manifest."
672- )
673- )
674- )
675-
676- def test_get_click_app_id_raises_runtimeerror_on_wrong_app(self):
677- """get_click_app_id must raise a RuntimeError if the requested
678- application is not found within the click package.
679-
680- """
681- with patch.object(_l, '_get_click_manifest') as cm:
682- cm.return_value = [{'name': 'com.autopilot.testing', 'hooks': {}}]
683-
684- self.assertThat(
685- lambda: _get_click_app_id("com.autopilot.testing", "bar"),
686- raises(
687- RuntimeError(
688- "Application 'bar' is not present within the click "
689- "package 'com.autopilot.testing'."
690- )
691- )
692- )
693-
694- def test_get_click_app_id_returns_id(self):
695- with patch.object(_l, '_get_click_manifest') as cm:
696- cm.return_value = [
697- {
698- 'name': 'com.autopilot.testing',
699- 'hooks': {'bar': {}}, 'version': '1.0'
700- }
701- ]
702-
703- self.assertThat(
704- _get_click_app_id("com.autopilot.testing", "bar"),
705- Equals("com.autopilot.testing_bar_1.0")
706- )
707-
708- def test_get_click_app_id_returns_id_without_appid_passed(self):
709- with patch.object(_l, '_get_click_manifest') as cm:
710- cm.return_value = [
711- {
712- 'name': 'com.autopilot.testing',
713- 'hooks': {'bar': {}}, 'version': '1.0'
714- }
715- ]
716-
717- self.assertThat(
718- _get_click_app_id("com.autopilot.testing"),
719- Equals("com.autopilot.testing_bar_1.0")
720- )
721-
722-
723-class UpstartApplicationLauncherTests(TestCase):
724-
725- def test_can_construct_UpstartApplicationLauncher(self):
726- UpstartApplicationLauncher(self.addDetail)
727-
728- def test_raises_exception_on_unknown_kwargs(self):
729- self.assertThat(
730- lambda: UpstartApplicationLauncher(self.addDetail, unknown=True),
731- raises(TypeError("__init__() got an unexpected keyword argument "
732- "'unknown'"))
733- )
734-
735- def test_on_failed_only_sets_status_on_correct_app_id(self):
736- state = {
737- 'expected_app_id': 'gedit',
738- }
739-
740- UpstartApplicationLauncher._on_failed('some_game', None, state)
741-
742- self.assertThat(state, Not(Contains('status')))
743-
744- def assertFunctionSetsCorrectStateAndQuits(self, observer, expected_state):
745- """Assert that the observer observer sets the correct state id.
746-
747- :param observer: The observer callable you want to test.
748- :param expected_state: The state id the observer callable must set.
749-
750- """
751- expected_app_id = self.getUniqueString()
752- state = {
753- 'expected_app_id': expected_app_id,
754- 'loop': Mock()
755- }
756-
757- if observer == UpstartApplicationLauncher._on_failed:
758- observer(expected_app_id, None, state)
759- elif observer == UpstartApplicationLauncher._on_started or \
760- observer == UpstartApplicationLauncher._on_stopped:
761- observer(expected_app_id, state)
762- else:
763- observer(state)
764-
765- self.assertThat(
766- state['status'],
767- Equals(expected_state)
768- )
769- state['loop'].quit.assert_called_once_with()
770-
771- def test_on_failed_sets_status_with_correct_app_id(self):
772- self.assertFunctionSetsCorrectStateAndQuits(
773- UpstartApplicationLauncher._on_failed,
774- UpstartApplicationLauncher.Failed
775- )
776-
777- def test_on_started_sets_status_with_correct_app_id(self):
778- self.assertFunctionSetsCorrectStateAndQuits(
779- UpstartApplicationLauncher._on_started,
780- UpstartApplicationLauncher.Started
781- )
782-
783- def test_on_timeout_sets_status_and_exits_loop(self):
784- self.assertFunctionSetsCorrectStateAndQuits(
785- UpstartApplicationLauncher._on_timeout,
786- UpstartApplicationLauncher.Timeout
787- )
788-
789- def test_on_started_only_sets_status_on_correct_app_id(self):
790- state = {
791- 'expected_app_id': 'gedit',
792- }
793-
794- UpstartApplicationLauncher._on_started('some_game', state)
795-
796- self.assertThat(state, Not(Contains('status')))
797-
798- def test_on_stopped_only_sets_status_on_correct_app_id(self):
799- state = {
800- 'expected_app_id': 'gedit',
801- }
802-
803- UpstartApplicationLauncher._on_stopped('some_game', state)
804- self.assertThat(state, Not(Contains('status')))
805-
806- def test_on_stopped_sets_status_and_exits_loop(self):
807- self.assertFunctionSetsCorrectStateAndQuits(
808- UpstartApplicationLauncher._on_stopped,
809- UpstartApplicationLauncher.Stopped
810- )
811-
812- def test_get_pid_calls_upstart_module(self):
813- expected_return = self.getUniqueInteger()
814- with patch.object(_l, 'UbuntuAppLaunch') as mock_ual:
815- mock_ual.get_primary_pid.return_value = expected_return
816- observed = UpstartApplicationLauncher._get_pid_for_launched_app(
817- 'gedit'
818- )
819-
820- mock_ual.get_primary_pid.assert_called_once_with('gedit')
821- self.assertThat(expected_return, Equals(observed))
822-
823- def test_launch_app_calls_upstart_module(self):
824- with patch.object(_l, 'UbuntuAppLaunch') as mock_ual:
825- UpstartApplicationLauncher._launch_app(
826- 'gedit',
827- ['some', 'uris']
828- )
829-
830- mock_ual.start_application_test.assert_called_once_with(
831- 'gedit',
832- ['some', 'uris']
833- )
834-
835- def test_check_error_raises_RuntimeError_on_timeout(self):
836- fn = lambda: UpstartApplicationLauncher._check_status_error(
837- UpstartApplicationLauncher.Timeout
838- )
839- self.assertThat(
840- fn,
841- raises(
842- RuntimeError(
843- "Timed out while waiting for application to launch"
844- )
845- )
846- )
847-
848- def test_check_error_raises_RuntimeError_on_failure(self):
849- fn = lambda: UpstartApplicationLauncher._check_status_error(
850- UpstartApplicationLauncher.Failed
851- )
852- self.assertThat(
853- fn,
854- raises(
855- RuntimeError(
856- "Application Launch Failed"
857- )
858- )
859- )
860-
861- def test_check_error_raises_RuntimeError_with_extra_message(self):
862- fn = lambda: UpstartApplicationLauncher._check_status_error(
863- UpstartApplicationLauncher.Failed,
864- "extra message"
865- )
866- self.assertThat(
867- fn,
868- raises(
869- RuntimeError(
870- "Application Launch Failed: extra message"
871- )
872- )
873- )
874-
875- def test_check_error_does_nothing_on_None(self):
876- UpstartApplicationLauncher._check_status_error(None)
877-
878- def test_get_loop_returns_glib_mainloop_instance(self):
879- loop = UpstartApplicationLauncher._get_glib_loop()
880- self.assertThat(loop, IsInstance(GLib.MainLoop))
881-
882- @patch('autopilot.application._launcher.UbuntuAppLaunch')
883- @patch('autopilot.application._launcher.'
884- 'get_proxy_object_for_existing_process')
885- def test_handle_string(self, gpofep, ual):
886- launcher = UpstartApplicationLauncher()
887- token_a = self.getUniqueString()
888- token_b = self.getUniqueString()
889- with patch.object(launcher, '_launch_app') as la:
890- with patch.object(launcher, '_get_pid_for_launched_app'):
891- with patch.object(launcher, '_get_glib_loop'):
892- launcher.launch(token_a, token_b)
893- la.assert_called_once_with(token_a, [token_b])
894-
895- @patch('autopilot.application._launcher.UbuntuAppLaunch')
896- @patch('autopilot.application._launcher.'
897- 'get_proxy_object_for_existing_process')
898- def test_handle_bytes(self, gpofep, ual):
899- launcher = UpstartApplicationLauncher()
900- token_a = self.getUniqueString()
901- token_b = self.getUniqueString()
902- with patch.object(launcher, '_launch_app') as la:
903- with patch.object(launcher, '_get_pid_for_launched_app'):
904- with patch.object(launcher, '_get_glib_loop'):
905- launcher.launch(token_a, token_b.encode())
906- la.assert_called_once_with(token_a, [token_b])
907-
908- @patch('autopilot.application._launcher.UbuntuAppLaunch')
909- @patch('autopilot.application._launcher.'
910- 'get_proxy_object_for_existing_process')
911- def test_handle_list(self, gpofep, ual):
912- launcher = UpstartApplicationLauncher()
913- token_a = self.getUniqueString()
914- token_b = self.getUniqueString()
915- with patch.object(launcher, '_launch_app') as la:
916- with patch.object(launcher, '_get_pid_for_launched_app'):
917- with patch.object(launcher, '_get_glib_loop'):
918- launcher.launch(token_a, [token_b])
919- la.assert_called_once_with(token_a, [token_b])
920-
921- @patch('autopilot.application._launcher.UbuntuAppLaunch')
922- @patch('autopilot.application._launcher.'
923- 'get_proxy_object_for_existing_process')
924- def test_calls_get_pid(self, gpofep, ual):
925- launcher = UpstartApplicationLauncher()
926- token = self.getUniqueString()
927- with patch.object(launcher, '_launch_app'):
928- with patch.object(launcher, '_get_pid_for_launched_app') as gp:
929- with patch.object(launcher, '_get_glib_loop'):
930- launcher.launch(token)
931- gp.assert_called_once_with(token)
932-
933- @patch('autopilot.application._launcher.UbuntuAppLaunch')
934- @patch('autopilot.application._launcher.'
935- 'get_proxy_object_for_existing_process')
936- def test_gets_correct_proxy_object(self, gpofep, ual):
937- launcher = UpstartApplicationLauncher()
938- with patch.object(launcher, '_launch_app'):
939- with patch.object(launcher, '_get_pid_for_launched_app') as gp:
940- with patch.object(launcher, '_get_glib_loop'):
941- launcher.launch('')
942- gpofep.assert_called_once_with(pid=gp.return_value,
943- emulator_base=None,
944- dbus_bus='session')
945-
946- @patch('autopilot.application._launcher.UbuntuAppLaunch')
947- @patch('autopilot.application._launcher.'
948- 'get_proxy_object_for_existing_process')
949- def test_returns_proxy_object(self, gpofep, ual):
950- launcher = UpstartApplicationLauncher()
951- with patch.object(launcher, '_launch_app'):
952- with patch.object(launcher, '_get_pid_for_launched_app'):
953- with patch.object(launcher, '_get_glib_loop'):
954- result = launcher.launch('')
955- self.assertEqual(result, gpofep.return_value)
956-
957- @patch('autopilot.application._launcher.UbuntuAppLaunch')
958- @patch('autopilot.application._launcher.'
959- 'get_proxy_object_for_existing_process')
960- def test_calls_get_glib_loop(self, gpofep, ual):
961- launcher = UpstartApplicationLauncher()
962- with patch.object(launcher, '_launch_app'):
963- with patch.object(launcher, '_get_pid_for_launched_app'):
964- with patch.object(launcher, '_get_glib_loop') as ggl:
965- launcher.launch('')
966- ggl.assert_called_once_with()
967-
968- def assertFailedObserverSetsExtraMessage(self, fail_type, expected_msg):
969- """Assert that the on_failed observer must set the expected message
970- for a particular failure_type."""
971- expected_app_id = self.getUniqueString()
972- state = {
973- 'expected_app_id': expected_app_id,
974- 'loop': Mock()
975- }
976- UpstartApplicationLauncher._on_failed(
977- expected_app_id,
978- fail_type,
979- state
980- )
981- self.assertEqual(expected_msg, state['message'])
982-
983- def test_on_failed_sets_message_for_app_crash(self):
984- self.assertFailedObserverSetsExtraMessage(
985- _l.UbuntuAppLaunch.AppFailed.CRASH,
986- 'Application crashed.'
987- )
988-
989- def test_on_failed_sets_message_for_app_start_failure(self):
990- self.assertFailedObserverSetsExtraMessage(
991- _l.UbuntuAppLaunch.AppFailed.START_FAILURE,
992- 'Application failed to start.'
993- )
994-
995- def test_add_application_cleanups_adds_both_cleanup_actions(self):
996- token = self.getUniqueString()
997- state = {
998- 'status': UpstartApplicationLauncher.Started,
999- 'expected_app_id': token,
1000- }
1001- launcher = UpstartApplicationLauncher(Mock())
1002- launcher.setUp()
1003- launcher._maybe_add_application_cleanups(state)
1004- self.assertThat(
1005- launcher._cleanups._cleanups,
1006- Contains(
1007- (launcher._attach_application_log, (token,), {})
1008- )
1009- )
1010- self.assertThat(
1011- launcher._cleanups._cleanups,
1012- Contains(
1013- (launcher._stop_application, (token,), {})
1014- )
1015- )
1016-
1017- def test_add_application_cleanups_does_nothing_when_app_timedout(self):
1018- state = {
1019- 'status': UpstartApplicationLauncher.Timeout,
1020- }
1021- launcher = UpstartApplicationLauncher(Mock())
1022- launcher.setUp()
1023- launcher._maybe_add_application_cleanups(state)
1024- self.assertThat(launcher._cleanups._cleanups, HasLength(0))
1025-
1026- def test_add_application_cleanups_does_nothing_when_app_failed(self):
1027- state = {
1028- 'status': UpstartApplicationLauncher.Failed,
1029- }
1030- launcher = UpstartApplicationLauncher(Mock())
1031- launcher.setUp()
1032- launcher._maybe_add_application_cleanups(state)
1033- self.assertThat(launcher._cleanups._cleanups, HasLength(0))
1034-
1035- def test_attach_application_log_does_nothing_wth_no_log_specified(self):
1036- app_id = self.getUniqueString()
1037- case_addDetail = Mock()
1038- launcher = UpstartApplicationLauncher(case_addDetail)
1039- j = MagicMock(spec=_l.journal.Reader)
1040- with patch.object(_l.journal, 'Reader', return_value=j):
1041- launcher._attach_application_log(app_id)
1042- expected = launcher._get_user_unit_match(app_id)
1043- j.add_match.assert_called_once_with(_SYSTEMD_USER_UNIT=expected)
1044- self.assertEqual(0, case_addDetail.call_count)
1045-
1046- def test_attach_application_log_attaches_log(self):
1047- token = self.getUniqueString()
1048- case_addDetail = Mock()
1049- launcher = UpstartApplicationLauncher(case_addDetail)
1050- app_id = self.getUniqueString()
1051- j = MagicMock(spec=_l.journal.Reader)
1052- j.__iter__ = lambda x: iter([token])
1053- with patch.object(_l.journal, 'Reader', return_value=j):
1054- launcher._attach_application_log(app_id)
1055-
1056- self.assertEqual(1, case_addDetail.call_count)
1057- content_name, content_obj = case_addDetail.call_args[0]
1058- self.assertEqual(
1059- "Application Log (%s)" % app_id,
1060- content_name
1061- )
1062- self.assertThat(content_obj.as_text(), Contains(token))
1063-
1064- def test_stop_adds_app_stopped_observer(self):
1065- mock_add_detail = Mock()
1066- mock_glib_loop = Mock()
1067- patch_get_loop = patch.object(
1068- UpstartApplicationLauncher,
1069- '_get_glib_loop',
1070- new=mock_glib_loop,
1071- )
1072- mock_UAL = Mock()
1073- patch_UAL = patch.object(_l, 'UbuntuAppLaunch', new=mock_UAL)
1074- launcher = UpstartApplicationLauncher(mock_add_detail)
1075- app_id = self.getUniqueString()
1076- with ExitStack() as patches:
1077- patches.enter_context(patch_get_loop)
1078- patches.enter_context(patch_UAL)
1079-
1080- launcher._stop_application(app_id)
1081- call_args = mock_UAL.observer_add_app_stop.call_args[0]
1082- self.assertThat(
1083- call_args[0],
1084- Equals(UpstartApplicationLauncher._on_stopped)
1085- )
1086- self.assertThat(call_args[1]['expected_app_id'], Equals(app_id))
1087-
1088- def test_stop_calls_libUAL_stop_function(self):
1089- mock_add_detail = Mock()
1090- mock_glib_loop = Mock()
1091- patch_get_loop = patch.object(
1092- UpstartApplicationLauncher,
1093- '_get_glib_loop',
1094- new=mock_glib_loop,
1095- )
1096- mock_UAL = Mock()
1097- patch_UAL = patch.object(_l, 'UbuntuAppLaunch', new=mock_UAL)
1098- launcher = UpstartApplicationLauncher(mock_add_detail)
1099- app_id = self.getUniqueString()
1100- with ExitStack() as patches:
1101- patches.enter_context(patch_get_loop)
1102- patches.enter_context(patch_UAL)
1103-
1104- launcher._stop_application(app_id)
1105- mock_UAL.stop_application.assert_called_once_with(app_id)
1106-
1107- def test_stop_logs_error_on_timeout(self):
1108- mock_add_detail = Mock()
1109- mock_glib_loop = Mock()
1110- patch_get_loop = patch.object(
1111- UpstartApplicationLauncher,
1112- '_get_glib_loop',
1113- new=mock_glib_loop,
1114- )
1115- mock_UAL = Mock()
1116-
1117- # we replace the add_observer function with one that can set the
1118- # tiemout state, so we can ibject the timeout condition within the
1119- # glib loop. This is ugly, but necessary.
1120- def fake_add_observer(fn, state):
1121- state['status'] = UpstartApplicationLauncher.Timeout
1122- mock_UAL.observer_add_app_stop = fake_add_observer
1123- patch_UAL = patch.object(_l, 'UbuntuAppLaunch', new=mock_UAL)
1124- launcher = UpstartApplicationLauncher(mock_add_detail)
1125- app_id = self.getUniqueString()
1126- mock_logger = Mock()
1127- patch_logger = patch.object(_l, '_logger', new=mock_logger)
1128- with ExitStack() as patches:
1129- patches.enter_context(patch_get_loop)
1130- patches.enter_context(patch_UAL)
1131- patches.enter_context(patch_logger)
1132-
1133- launcher._stop_application(app_id)
1134-
1135- mock_logger.error.assert_called_once_with(
1136- "Timed out waiting for Application with app_id '%s' to stop.",
1137- app_id
1138- )
1139-
1140-
1141 class ApplicationLauncherInternalTests(TestCase):
1142
1143 def test_get_app_env_from_string_hint_returns_qt_env(self):
1144@@ -1098,24 +465,6 @@ class ApplicationLauncherInternalTests(TestCase):
1145 get_application_launcher_wrapper(""), Equals(None)
1146 )
1147
1148- def test_get_click_manifest_returns_python_object(self):
1149- example_manifest = """
1150- [{
1151- "description": "Calculator application",
1152- "framework": "ubuntu-sdk-13.10",
1153- "hooks": {
1154- "calculator": {
1155- "apparmor": "apparmor/calculator.json",
1156- "desktop": "ubuntu-calculator-app.desktop"
1157- }
1158- },
1159- "icon": "calculator64.png"
1160- }]
1161- """
1162- with patch.object(_l.subprocess, 'check_output') as check_output:
1163- check_output.return_value = example_manifest
1164- self.assertThat(_get_click_manifest(), IsInstance(list))
1165-
1166 @patch.object(_l.psutil, 'pid_exists')
1167 def test_is_process_running_checks_with_pid(self, pid_exists):
1168 pid_exists.return_value = True
1169diff --git a/debian/changelog b/debian/changelog
1170index b1b6624..a951fae 100644
1171--- a/debian/changelog
1172+++ b/debian/changelog
1173@@ -1,3 +1,16 @@
1174+autopilot (1.6.0+17.04.20170313-0ubuntu9) groovy; urgency=medium
1175+
1176+ * Drop upstart, click, ubuntu-app-launch support. All of those things
1177+ are removed from the Ubuntu Archive.
1178+
1179+ -- Dimitri John Ledkov <xnox@ubuntu.com> Thu, 04 Jun 2020 14:10:05 +0100
1180+
1181+autopilot (1.6.0+17.04.20170313-0ubuntu8) focal; urgency=medium
1182+
1183+ * No-change rebuild to drop python3.7.
1184+
1185+ -- Matthias Klose <doko@ubuntu.com> Tue, 18 Feb 2020 09:16:48 +0100
1186+
1187 autopilot (1.6.0+17.04.20170313-0ubuntu7) focal; urgency=medium
1188
1189 * autopilot-vis has been removed, so removed test_vis_main which depends on
1190diff --git a/debian/control b/debian/control
1191index 30f73e8..27699b6 100644
1192--- a/debian/control
1193+++ b/debian/control
1194@@ -7,7 +7,6 @@ Build-Depends: debhelper (>= 9.0.0),
1195 dh-python,
1196 gir1.2-gtk-3.0,
1197 gir1.2-ibus-1.0,
1198- gir1.2-ubuntu-app-launch-3 | gir1.2-ubuntu-app-launch-2,
1199 graphviz,
1200 libjs-jquery,
1201 libjs-underscore,
1202@@ -39,8 +38,7 @@ X-Python3-Version: >= 3.3
1203
1204 Package: python3-autopilot
1205 Architecture: all
1206-Depends: gir1.2-ubuntu-app-launch-3 | gir1.2-ubuntu-app-launch-2,
1207- libjs-jquery,
1208+Depends: libjs-jquery,
1209 libjs-underscore,
1210 mir-utils,
1211 python3-dateutil,

Subscribers

People subscribed via source and target branches