Merge lp:autopilot into lp:autopilot/1.6

Proposed by dobey
Status: Merged
Approved by: Santiago Baldassin
Approved revision: 592
Merged at revision: 584
Proposed branch: lp:autopilot
Merge into: lp:autopilot/1.6
Diff against target: 745 lines (+125/-263)
17 files modified
README (+6/-0)
autopilot/application/_launcher.py (+20/-14)
autopilot/display/__init__.py (+6/-45)
autopilot/display/_upa.py (+45/-27)
autopilot/input/__init__.py (+7/-13)
autopilot/introspection/types.py (+1/-0)
autopilot/introspection/utilities.py (+1/-0)
autopilot/platform.py (+2/-21)
autopilot/process/__init__.py (+0/-4)
autopilot/run.py (+1/-0)
autopilot/testcase.py (+8/-7)
autopilot/tests/unit/introspection_base.py (+1/-0)
autopilot/tests/unit/test_application_launcher.py (+18/-21)
autopilot/tests/unit/test_platform.py (+0/-22)
autopilot/tests/unit/test_query_resolution.py (+0/-82)
autopilot/utilities.py (+2/-0)
debian/control (+7/-7)
To merge this branch: bzr merge lp:autopilot
Reviewer Review Type Date Requested Status
Autopilot Hackers Pending
Review via email: mp+318824@code.launchpad.net

Commit message

New upstream release.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2016-08-04 05:32:39 +0000
3+++ README 2017-03-02 18:46:50 +0000
4@@ -72,6 +72,12 @@
5 If you are in the root of the autopilot source tree this will run/list the tests from
6 within that local module. Otherwise autopilot will look in the system python path.
7
8+Release Autopilot
9+=================
10+1. Open a new request on bileto: https://bileto.ubuntu.com/ with the lp:autopilot -> lp:autopilot/1.5 merge proposal
11+2. Add the relevant details (i.e. bug fix details in the landing description and a link to the testplan: https://wiki.ubuntu.com/Process/Merges/TestPlan/autopilot)
12+3. Build the silo and run the tests
13+4. Once happy with all tests approve and publish the result
14
15 Release Manual Tests
16 ====================
17
18=== modified file 'autopilot/application/_launcher.py'
19--- autopilot/application/_launcher.py 2015-12-08 21:42:14 +0000
20+++ autopilot/application/_launcher.py 2017-03-02 18:46:50 +0000
21@@ -1,7 +1,7 @@
22 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
23 #
24 # Autopilot Functional Test Tool
25-# Copyright (C) 2013 Canonical
26+# Copyright (C) 2013,2017 Canonical
27 #
28 # This program is free software: you can redistribute it and/or modify
29 # it under the terms of the GNU General Public License as published by
30@@ -20,21 +20,20 @@
31 """Base module for application launchers."""
32
33 import fixtures
34-from gi.repository import GLib
35+from gi import require_version
36 try:
37- from gi import require_version
38+ require_version('UbuntuAppLaunch', '3')
39+except ValueError:
40 require_version('UbuntuAppLaunch', '2')
41- from gi.repository import UbuntuAppLaunch
42-except ImportError:
43- # Note: the renamed package is not in Trusty.
44- from gi.repository import UpstartAppLaunch as UbuntuAppLaunch
45+from gi.repository import GLib, UbuntuAppLaunch
46+
47 import json
48 import logging
49 import os
50 import psutil
51 import subprocess
52 import signal
53-from testtools.content import content_from_file
54+from systemd import journal
55 from autopilot.utilities import safe_text_content
56
57 from autopilot._timeout import Timeout
58@@ -186,13 +185,20 @@
59 self.addCleanup(self._stop_application, app_id)
60 self.addCleanup(self._attach_application_log, app_id)
61
62+ @staticmethod
63+ def _get_user_unit_match(app_id):
64+ return 'ubuntu-app-launch-*-%s-*.service' % app_id
65+
66 def _attach_application_log(self, app_id):
67- log_path = UbuntuAppLaunch.application_log_path(app_id)
68- if log_path and os.path.exists(log_path):
69- self.caseAddDetail(
70- "Application Log (%s)" % app_id,
71- content_from_file(log_path)
72- )
73+ j = journal.Reader()
74+ j.log_level(journal.LOG_INFO)
75+ j.add_match(_SYSTEMD_USER_UNIT=self._get_user_unit_match(app_id))
76+ log_data = ''
77+ for i in j:
78+ log_data += str(i) + '\n'
79+ if len(log_data) > 0:
80+ self.caseAddDetail('Application Log (%s)' % app_id,
81+ safe_text_content(log_data))
82
83 def _stop_application(self, app_id):
84 state = {}
85
86=== modified file 'autopilot/display/__init__.py'
87--- autopilot/display/__init__.py 2014-07-09 00:21:04 +0000
88+++ autopilot/display/__init__.py 2017-03-02 18:46:50 +0000
89@@ -40,9 +40,9 @@
90 def is_rect_on_screen(screen_number, rect):
91 """Return True if *rect* is **entirely** on the specified screen, with no
92 overlap."""
93- (x, y, w, h) = rect
94- (mx, my, mw, mh) = Display.create().get_screen_geometry(screen_number)
95- return (x >= mx and x + w <= mx + mw and y >= my and y + h <= my + mh)
96+ x, y, w, h = rect
97+ mx, my, mw, mh = Display.create().get_screen_geometry(screen_number)
98+ return x >= mx and x + w <= mx + mw and y >= my and y + h <= my + mh
99
100
101 def is_point_on_screen(screen_number, point):
102@@ -52,8 +52,8 @@
103
104 """
105 x, y = point
106- (mx, my, mw, mh) = Display.create().get_screen_geometry(screen_number)
107- return (x >= mx and x < mx + mw and y >= my and y < my + mh)
108+ mx, my, mw, mh = Display.create().get_screen_geometry(screen_number)
109+ return mx <= x < mx + mw and my <= y < my + mh
110
111
112 def is_point_on_any_screen(point):
113@@ -71,45 +71,6 @@
114 Mouse.create().move(x, y, False)
115
116
117-# veebers TODO: Write this so it's usable.
118-# def drag_window_to_screen(self, window, screen):
119-# """Drags *window* to *screen*
120-
121-# :param BamfWindow window: The window to drag
122-# :param integer screen: The screen to drag the *window* to
123-# :raises: **TypeError** if *window* is not a BamfWindow
124-
125-# """
126-# if not isinstance(window, BamfWindow):
127-# raise TypeError("Window must be a BamfWindow")
128-
129-# if window.monitor == screen:
130-# logger.debug(
131-# "Window %r is already on screen %d." % (window.x_id, screen))
132-# return
133-
134-# assert(not window.is_maximized)
135-# (win_x, win_y, win_w, win_h) = window.geometry
136-# (mx, my, mw, mh) = self.get_screen_geometry(screen)
137-
138-# logger.debug("Dragging window %r to screen %d." % (window.x_id, screen))
139-
140-# mouse = Mouse()
141-# keyboard = Keyboard()
142-# mouse.move(win_x + win_w/2, win_y + win_h/2)
143-# keyboard.press("Alt")
144-# mouse.press()
145-# keyboard.release("Alt")
146-
147-# # We do the movements in two steps, to reduce the risk of being
148-# # blocked by the pointer barrier
149-# target_x = mx + mw/2
150-# target_y = my + mh/2
151-# mouse.move(win_x, target_y, rate=20, time_between_events=0.005)
152-# mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
153-# mouse.release()
154-
155-
156 class Display(object):
157
158 """The base class/inteface for the display devices."""
159@@ -146,8 +107,8 @@
160 return Display()
161
162 backends = OrderedDict()
163+ backends['UPA'] = get_upa_display
164 backends['X11'] = get_x11_display
165- backends['UPA'] = get_upa_display
166 return _pick_backend(backends, preferred_backend)
167
168 class BlacklistedDriverError(RuntimeError):
169
170=== modified file 'autopilot/display/_upa.py'
171--- autopilot/display/_upa.py 2014-03-25 14:42:25 +0000
172+++ autopilot/display/_upa.py 2017-03-02 18:46:50 +0000
173@@ -17,44 +17,33 @@
174 # along with this program. If not, see <http://www.gnu.org/licenses/>.
175 #
176
177+import os
178+import subprocess
179
180 from autopilot.display import Display as DisplayBase
181-from autopilot.platform import image_codename
182-import subprocess
183+from autopilot.platform import get_display_server, image_codename
184+
185+DISPLAY_SERVER_X11 = 'X11'
186+DISPLAY_SERVER_MIR = 'MIR'
187+ENV_MIR_SOCKET = 'MIR_SERVER_HOST_SOCKET'
188
189
190 def query_resolution():
191- try:
192- return _get_fbset_resolution()
193- except Exception:
194+ display_server = get_display_server()
195+ if display_server == DISPLAY_SERVER_X11:
196+ return _get_resolution_from_xrandr()
197+ elif display_server == DISPLAY_SERVER_MIR:
198+ return _get_resolution_from_mirout()
199+ else:
200 return _get_hardcoded_resolution()
201
202
203-def _get_fbset_resolution():
204- """Return the resolution, as determined by fbset, or None."""
205- fbset_output = _get_fbset_output()
206- for line in fbset_output.split('\n'):
207- line = line.strip()
208- if line.startswith('Mode'):
209- quoted_resolution = line.split()[1]
210- resolution_string = quoted_resolution.strip('"')
211- return tuple(int(piece) for piece in resolution_string.split('x'))
212- raise RuntimeError("No modes found from fbset output")
213-
214-
215-def _get_fbset_output():
216- return subprocess.check_output(["fbset", "-s", "-x"]).decode().strip()
217-
218-
219 def _get_hardcoded_resolution():
220 name = image_codename()
221
222 resolutions = {
223- "generic": (480, 800),
224- "mako": (768, 1280),
225- "maguro": (720, 1280),
226- "manta": (2560, 1600),
227- "grouper": (800, 1280),
228+ "Aquaris_M10_HD": (800, 1280),
229+ "Desktop": (1920, 1080)
230 }
231
232 if name not in resolutions:
233@@ -64,6 +53,35 @@
234 return resolutions[name]
235
236
237+def _get_stdout_for_command(command, *args):
238+ full_command = [command]
239+ full_command.extend(args)
240+ return subprocess.check_output(
241+ full_command,
242+ universal_newlines=True,
243+ stderr=subprocess.DEVNULL,
244+ ).split('\n')
245+
246+
247+def _get_resolution(server_output):
248+ relevant_line = list(filter(lambda line: '*' in line, server_output))[0]
249+ if relevant_line:
250+ return tuple([int(i) for i in relevant_line.split()[0].split('x')])
251+ raise ValueError(
252+ 'Failed to get display resolution, is a display connected?'
253+ )
254+
255+
256+def _get_resolution_from_xrandr():
257+ return _get_resolution(_get_stdout_for_command('xrandr', '--current'))
258+
259+
260+def _get_resolution_from_mirout():
261+ return _get_resolution(
262+ _get_stdout_for_command('mirout', os.environ.get(ENV_MIR_SOCKET))
263+ )
264+
265+
266 class Display(DisplayBase):
267 """The base class/inteface for the display devices"""
268
269@@ -91,4 +109,4 @@
270 :return: Tuple containing (x, y, width, height).
271
272 """
273- return (0, 0, self._X, self._Y)
274+ return 0, 0, self._X, self._Y
275
276=== modified file 'autopilot/input/__init__.py'
277--- autopilot/input/__init__.py 2016-01-08 09:35:07 +0000
278+++ autopilot/input/__init__.py 2017-03-02 18:46:50 +0000
279@@ -126,9 +126,9 @@
280 raise
281
282 backends = OrderedDict()
283- backends['X11'] = get_x11_kb
284 backends['UInput'] = get_uinput_kb
285 backends['OSK'] = get_osk_kb
286+ backends['X11'] = get_x11_kb
287 return _pick_backend(backends, preferred_backend)
288
289 @contextmanager
290@@ -283,21 +283,15 @@
291 from autopilot.input._X11 import Mouse
292 return Mouse()
293
294- from autopilot.platform import model
295- if model() != 'Desktop':
296- _logger.info(
297- "You cannot create a Mouse on the devices where X11 is not "
298- "available. consider using a Touch or Pointer device. "
299- "For more information, see: "
300- "http://unity.ubuntu.com/autopilot/api/input.html"
301- "#autopilot-unified-input-system"
302- )
303- raise RuntimeError(
304- "Cannot create a Mouse on devices where X11 is not available."
305- )
306+ def get_uinput_mouse():
307+ # Return the Touch device for now as Mouse under a Mir desktop
308+ # is a challenge for now.
309+ from autopilot.input._uinput import Touch
310+ return Touch()
311
312 backends = OrderedDict()
313 backends['X11'] = get_x11_mouse
314+ backends['UInput'] = get_uinput_mouse
315 return _pick_backend(backends, preferred_backend)
316
317 @property
318
319=== modified file 'autopilot/introspection/types.py'
320--- autopilot/introspection/types.py 2015-12-08 01:07:10 +0000
321+++ autopilot/introspection/types.py 2017-03-02 18:46:50 +0000
322@@ -255,6 +255,7 @@
323 def _create_generic_repr(target_type):
324 return compatible_repr(lambda self: repr(target_type(self)))
325
326+
327 _bytes_repr = _create_generic_repr(bytes)
328 _text_repr = _create_generic_repr(str)
329 _dict_repr = _create_generic_repr(dict)
330
331=== modified file 'autopilot/introspection/utilities.py'
332--- autopilot/introspection/utilities.py 2016-07-14 08:18:20 +0000
333+++ autopilot/introspection/utilities.py 2017-03-02 18:46:50 +0000
334@@ -138,4 +138,5 @@
335 """
336 return self._query_pids_for_process(process_name)
337
338+
339 process_util = ProcessUtil()
340
341=== modified file 'autopilot/platform.py'
342--- autopilot/platform.py 2014-07-23 01:59:47 +0000
343+++ autopilot/platform.py 2017-03-02 18:46:50 +0000
344@@ -19,8 +19,6 @@
345
346
347 import os
348-import psutil
349-from functools import lru_cache
350
351 """
352 Platform identification utilities for Autopilot.
353@@ -143,27 +141,10 @@
354 def get_display_server():
355 """Returns display server type.
356
357- :returns: string indicating display server type. Either "X11", "MIR" or
358- "UNKNOWN"
359+ :returns: string indicating display server type.
360
361 """
362- if _display_is_x11():
363- return "X11"
364- elif _display_is_mir():
365- return "MIR"
366- else:
367- return "UNKNOWN"
368-
369-
370-def _display_is_x11():
371- return 'DISPLAY' in os.environ
372-
373-
374-@lru_cache()
375-def _display_is_mir():
376- return "unity-system-compositor" in [
377- _get_process_name(p.name) for p in psutil.process_iter()
378- ]
379+ return os.environ.get('XDG_SESSION_TYPE', 'UNKNOWN').upper()
380
381
382 # Different vers. of psutil across Trusty and Utopic have name as either a
383
384=== modified file 'autopilot/process/__init__.py'
385--- autopilot/process/__init__.py 2015-05-04 06:28:37 +0000
386+++ autopilot/process/__init__.py 2017-03-02 18:46:50 +0000
387@@ -89,10 +89,6 @@
388 from autopilot.process._bamf import ProcessManager
389 return ProcessManager()
390
391- def get_upa_pm():
392- from autopilot.process._upa import ProcessManager
393- return ProcessManager()
394-
395 backends = OrderedDict()
396 backends['BAMF'] = get_bamf_pm
397 return _pick_backend(backends, preferred_backend)
398
399=== modified file 'autopilot/run.py'
400--- autopilot/run.py 2015-08-19 00:25:00 +0000
401+++ autopilot/run.py 2017-03-02 18:46:50 +0000
402@@ -749,5 +749,6 @@
403 print(e)
404 exit(1)
405
406+
407 if __name__ == "__main__":
408 main()
409
410=== modified file 'autopilot/testcase.py'
411--- autopilot/testcase.py 2015-09-02 03:25:43 +0000
412+++ autopilot/testcase.py 2017-03-02 18:46:50 +0000
413@@ -173,13 +173,14 @@
414 # Work around for bug lp:1297592.
415 _ensure_uinput_device_created()
416
417- try:
418- self._app_snapshot = _get_process_snapshot()
419- self.addCleanup(self._compare_system_with_app_snapshot)
420- except RuntimeError:
421- _logger.warning(
422- "Process manager backend unavailable, application snapshot "
423- "support disabled.")
424+ if get_display_server() == 'X11':
425+ try:
426+ self._app_snapshot = _get_process_snapshot()
427+ self.addCleanup(self._compare_system_with_app_snapshot)
428+ except RuntimeError:
429+ _logger.warning(
430+ "Process manager backend unavailable, application "
431+ "snapshot support disabled.")
432
433 self.addOnException(self._take_screenshot_on_failure)
434
435
436=== modified file 'autopilot/tests/unit/introspection_base.py'
437--- autopilot/tests/unit/introspection_base.py 2016-07-19 14:24:10 +0000
438+++ autopilot/tests/unit/introspection_base.py 2017-03-02 18:46:50 +0000
439@@ -38,6 +38,7 @@
440 def get_properties(self):
441 return self.__dict__
442
443+
444 get_mock_object = MockObject
445
446
447
448=== modified file 'autopilot/tests/unit/test_application_launcher.py'
449--- autopilot/tests/unit/test_application_launcher.py 2014-07-22 02:30:19 +0000
450+++ autopilot/tests/unit/test_application_launcher.py 2017-03-02 18:46:50 +0000
451@@ -1,7 +1,7 @@
452 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
453 #
454 # Autopilot Functional Test Tool
455-# Copyright (C) 2013 Canonical
456+# Copyright (C) 2013,2017 Canonical
457 #
458 # This program is free software: you can redistribute it and/or modify
459 # it under the terms of the GNU General Public License as published by
460@@ -33,8 +33,7 @@
461 raises,
462 )
463 from testtools.content import text_content
464-import tempfile
465-from unittest.mock import Mock, patch
466+from unittest.mock import MagicMock, Mock, patch
467
468 from autopilot.application import (
469 ClickApplicationLauncher,
470@@ -782,32 +781,30 @@
471 app_id = self.getUniqueString()
472 case_addDetail = Mock()
473 launcher = UpstartApplicationLauncher(case_addDetail)
474- with patch.object(_l.UbuntuAppLaunch, 'application_log_path') as p:
475- p.return_value = None
476+ j = MagicMock(spec=_l.journal.Reader)
477+ with patch.object(_l.journal, 'Reader', return_value=j):
478 launcher._attach_application_log(app_id)
479-
480- p.assert_called_once_with(app_id)
481+ expected = launcher._get_user_unit_match(app_id)
482+ j.add_match.assert_called_once_with(_SYSTEMD_USER_UNIT=expected)
483 self.assertEqual(0, case_addDetail.call_count)
484
485- def test_attach_application_log_attaches_log_file(self):
486+ def test_attach_application_log_attaches_log(self):
487 token = self.getUniqueString()
488 case_addDetail = Mock()
489 launcher = UpstartApplicationLauncher(case_addDetail)
490 app_id = self.getUniqueString()
491- with tempfile.NamedTemporaryFile(mode='w') as f:
492- f.write(token)
493- f.flush()
494- with patch.object(_l.UbuntuAppLaunch, 'application_log_path',
495- return_value=f.name):
496- launcher._attach_application_log(app_id)
497+ j = MagicMock(spec=_l.journal.Reader)
498+ j.__iter__ = lambda x: iter([token])
499+ with patch.object(_l.journal, 'Reader', return_value=j):
500+ launcher._attach_application_log(app_id)
501
502- self.assertEqual(1, case_addDetail.call_count)
503- content_name, content_obj = case_addDetail.call_args[0]
504- self.assertEqual(
505- "Application Log (%s)" % app_id,
506- content_name
507- )
508- self.assertThat(content_obj.as_text(), Contains(token))
509+ self.assertEqual(1, case_addDetail.call_count)
510+ content_name, content_obj = case_addDetail.call_args[0]
511+ self.assertEqual(
512+ "Application Log (%s)" % app_id,
513+ content_name
514+ )
515+ self.assertThat(content_obj.as_text(), Contains(token))
516
517 def test_stop_adds_app_stopped_observer(self):
518 mock_add_detail = Mock()
519
520=== modified file 'autopilot/tests/unit/test_platform.py'
521--- autopilot/tests/unit/test_platform.py 2015-12-08 00:48:04 +0000
522+++ autopilot/tests/unit/test_platform.py 2017-03-02 18:46:50 +0000
523@@ -20,7 +20,6 @@
524 """Tests for the autopilot platform code."""
525
526
527-from contextlib import contextmanager
528 from io import StringIO
529 from testtools import TestCase
530 from testtools.matchers import Equals
531@@ -34,7 +33,6 @@
532
533 def setUp(self):
534 super().setUp()
535- platform._display_is_mir.cache_clear()
536
537 @patch('autopilot.platform._PlatformDetector')
538 def test_model_creates_platform_detector(self, mock_detector):
539@@ -56,14 +54,6 @@
540 mock_detector.image_codename = "test123"
541 self.assertThat(platform.image_codename(), Equals('test123'))
542
543- def test_is_x11_returns_False_on_failure(self):
544- with _simulate_not_X11():
545- self.assertFalse(platform._display_is_x11())
546-
547- def test_is_x11_returns_True_on_success(self):
548- with _simulate_X11():
549- self.assertTrue(platform._display_is_x11())
550-
551
552 class PlatformGetProcessNameTests(TestCase):
553
554@@ -247,15 +237,3 @@
555 prop_file = StringIO("ro.product.model=maguro")
556 properties = platform._parse_build_properties_file(prop_file)
557 self.assertThat(properties, Equals({'ro.product.model': 'maguro'}))
558-
559-
560-@contextmanager
561-def _simulate_not_X11():
562- with patch.dict(platform.os.environ, dict(), clear=True):
563- yield
564-
565-
566-@contextmanager
567-def _simulate_X11():
568- with patch.dict(platform.os.environ, dict(DISPLAY=':0'), clear=True):
569- yield
570
571=== modified file 'autopilot/tests/unit/test_query_resolution.py'
572--- autopilot/tests/unit/test_query_resolution.py 2014-05-20 08:53:21 +0000
573+++ autopilot/tests/unit/test_query_resolution.py 2017-03-02 18:46:50 +0000
574@@ -16,85 +16,3 @@
575 # You should have received a copy of the GNU General Public License
576 # along with this program. If not, see <http://www.gnu.org/licenses/>.
577 #
578-
579-from testtools import TestCase
580-from testtools.matchers import raises
581-from testscenarios import WithScenarios
582-from textwrap import dedent
583-from unittest.mock import patch
584-
585-from autopilot.display import _upa as upa
586-
587-
588-class QueryResolutionFunctionTests(TestCase):
589-
590- @patch('subprocess.check_output', return_value=b'')
591- def test_fbset_output_calls_subprocess(self, patched_check_output):
592- upa._get_fbset_output()
593- patched_check_output.assert_called_once_with(
594- ["fbset", "-s", "-x"]
595- )
596-
597- def test_get_fbset_resolution(self):
598- patched_fbset_resolution = dedent(
599- '''
600- Mode "768x1280"
601- # D: 0.002 MHz, H: 0.002 kHz, V: 0.002 Hz
602- DotClock 0.003
603- HTimings 768 776 780 960
604- VTimings 1280 1288 1290 1312
605- Flags "-HSync" "-VSync"
606- EndMode
607- '''
608- )
609- with patch.object(upa, '_get_fbset_output') as patched_gfo:
610- patched_gfo.return_value = patched_fbset_resolution
611- observed = upa._get_fbset_resolution()
612- self.assertEqual((768, 1280), observed)
613-
614- def test_get_fbset_resolution_raises_runtimeError(self):
615- patched_fbset_resolution = 'something went wrong!'
616- with patch.object(upa, '_get_fbset_output') as patched_gfo:
617- patched_gfo.return_value = patched_fbset_resolution
618- self.assertThat(
619- upa._get_fbset_resolution,
620- raises(RuntimeError),
621- )
622-
623- def test_hardcoded_raises_error_on_unknown_model(self):
624- with patch.object(upa, 'image_codename', return_value="unknown"):
625- self.assertThat(
626- upa._get_hardcoded_resolution,
627- raises(
628- NotImplementedError(
629- 'Device "unknown" is not supported by Autopilot.'
630- )
631- )
632- )
633-
634- def test_query_resolution_uses_fbset_first(self):
635- with patch.object(upa, '_get_fbset_resolution', return_value=(1, 2)):
636- self.assertEqual((1, 2), upa.query_resolution())
637-
638- def test_query_resolution_uses_hardcoded_second(self):
639- with patch.object(upa, '_get_fbset_resolution', side_effect=Exception):
640- with patch.object(
641- upa, '_get_hardcoded_resolution', return_value=(2, 3)
642- ):
643- self.assertEqual((2, 3), upa.query_resolution())
644-
645-
646-class HardCodedResolutionTests(WithScenarios, TestCase):
647-
648- scenarios = [
649- ("generic", dict(name="generic", expected=(480, 800))),
650- ("mako", dict(name="mako", expected=(768, 1280))),
651- ("maguro", dict(name="maguro", expected=(720, 1280))),
652- ("manta", dict(name="manta", expected=(2560, 1600))),
653- ("grouper", dict(name="grouper", expected=(800, 1280))),
654- ]
655-
656- def test_hardcoded_resolutions_works_for_known_codenames(self):
657- with patch.object(upa, 'image_codename', return_value=self.name):
658- observed = upa._get_hardcoded_resolution()
659- self.assertEqual(self.expected, observed)
660
661=== modified file 'autopilot/utilities.py'
662--- autopilot/utilities.py 2016-05-18 07:06:16 +0000
663+++ autopilot/utilities.py 2017-03-02 18:46:50 +0000
664@@ -430,6 +430,7 @@
665 def total_time_slept(self):
666 return self._mock_count
667
668+
669 sleep = MockableSleep()
670
671
672@@ -665,4 +666,5 @@
673 process.get('pid')
674 )
675
676+
677 process_iter = MockableProcessIter()
678
679=== modified file 'debian/control'
680--- debian/control 2016-08-10 16:36:11 +0000
681+++ debian/control 2017-03-02 18:46:50 +0000
682@@ -6,10 +6,9 @@
683 Build-Depends: debhelper (>= 9.0.0),
684 dh-python,
685 dvipng,
686- gir1.2-gconf-2.0,
687 gir1.2-gtk-3.0,
688 gir1.2-ibus-1.0,
689- gir1.2-ubuntu-app-launch-2 | gir1.2-upstart-app-launch-2,
690+ gir1.2-ubuntu-app-launch-3 | gir1.2-ubuntu-app-launch-2,
691 graphviz,
692 libjs-jquery,
693 libjs-underscore,
694@@ -28,6 +27,7 @@
695 python3-setuptools,
696 python3-sphinx,
697 python3-subunit,
698+ python3-systemd,
699 python3-testscenarios,
700 python3-testtools,
701 python3-tz,
702@@ -38,15 +38,16 @@
703 upstart,
704 Standards-Version: 3.9.5
705 Homepage: https://launchpad.net/autopilot
706-Vcs-bzr: https://code.launchpad.net/+branch/ubuntu/autopilot
707+Vcs-Bzr: https://code.launchpad.net/~autopilot/autopilot/trunk
708 X-Python-Version: >= 2.7
709 X-Python3-Version: >= 3.3
710
711 Package: python3-autopilot
712 Architecture: all
713-Depends: gir1.2-ubuntu-app-launch-2 | gir1.2-upstart-app-launch-2,
714+Depends: gir1.2-ubuntu-app-launch-3 | gir1.2-ubuntu-app-launch-2,
715 libjs-jquery,
716 libjs-underscore,
717+ mir-utils,
718 python3-dateutil,
719 python3-dbus,
720 python3-decorator,
721@@ -57,14 +58,14 @@
722 python3-pil,
723 python3-psutil,
724 python3-subunit,
725+ python3-systemd,
726 python3-testscenarios,
727 python3-testtools,
728 python3-tz,
729 udev,
730 ${misc:Depends},
731 ${python3:Depends},
732-Recommends: gir1.2-gconf-2.0,
733- gir1.2-glib-2.0,
734+Recommends: gir1.2-glib-2.0,
735 gir1.2-gtk-3.0,
736 gir1.2-ibus-1.0,
737 libautopilot-gtk (>= 1.4),
738@@ -109,7 +110,6 @@
739 Section: metapackages
740 Depends: at-spi2-core,
741 bamfdaemon,
742- gir1.2-gconf-2.0,
743 gir1.2-glib-2.0,
744 gir1.2-gtk-3.0,
745 python3-autopilot,

Subscribers

People subscribed via source and target branches