Merge lp:autopilot into lp:autopilot/1.5

Proposed by Christopher Lee
Status: Merged
Approved by: Selene ToyKeeper
Approved revision: 572
Merged at revision: 524
Proposed branch: lp:autopilot
Merge into: lp:autopilot/1.5
Diff against target: 328 lines (+74/-49)
10 files modified
autopilot/_logging.py (+5/-4)
autopilot/_video.py (+2/-2)
autopilot/application/_launcher.py (+7/-4)
autopilot/content.py (+11/-2)
autopilot/introspection/types.py (+7/-30)
autopilot/tests/unit/test_platform.py (+2/-2)
autopilot/tests/unit/test_utilities.py (+16/-0)
autopilot/utilities.py (+20/-0)
debian/control (+2/-0)
docs/otto.py (+2/-5)
To merge this branch: bzr merge lp:autopilot
Reviewer Review Type Date Requested Status
Martin Pitt (community) packaging Approve
Selene ToyKeeper (community) Approve
Max Brustkern (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: [email protected]

Commit message

Stops attempts to access NoneType instead of bytes''. Considered a workaround, fixed in newer testtools.

Description of the change

Provide a workaround due to older versions of testtools on vivid. Stops attempts to access NoneType instead of bytes''

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Max Brustkern (nuclearbob) wrote :

This looks good to me, but I haven't run tests yet.

review: Approve
Revision history for this message
Selene ToyKeeper (toykeeper) wrote :

Approving since it's the same as the other already-approved MP.

review: Approve
Revision history for this message
Max Brustkern (nuclearbob) wrote :

There are sphinx build problems in xenial with docs/api/autopilot.emulators.rst and docs/tutorial/getting_started.rst

I'll look into a resolution for that.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

The ".. otto::" lines are creating problems. I suspect maybe something we're using there work differently in the current version of sphinx, so I'll look for API changes.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

This line in otto.py is the problem:
image_container.children.append(nodes.image(uri='/images/otto-64.png'))

Revision history for this message
Max Brustkern (nuclearbob) wrote :

If I remove that line, sphinx builds fine, but I get 8 test failures around datetime stuff that don't appear on wily. I'll look into that more.

Revision history for this message
Max Brustkern (nuclearbob) wrote :
Download full text (18.1 KiB)

I get these failures running tests under python3.5 on xenial, while they pass if run under 3.4:
/usr/lib/python3/dist-packages/unittest2/loader.py:367: PyGIWarning: UbuntuAppLaunch was imported without specifying a version first. Use gi.require_version('UbuntuAppLaunch', '2') before import to ensure that the right version gets loaded.
  tests = list(self._find_tests(start_dir, pattern))

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1

** (process:27668): WARNING **: Unable to connect to Upstart bus: Error spawning command line 'dbus-launch --autolaunch=435350870788ae3025aa21ed00000538 --binary-syntax --close-stderr': Child process exited with code 1
Followed stream is empty.
Could not add content object 'autopilot.tests.unit.test_content.FileFollowerTests.test_follow_file_does_not_raise_on_IOError-1' due to IO Error: [Errno 13] Permission denied: '/tmp/tmpm6ggk9mx'
Could not add content object 'autopilot.tests.unit.test_content.FileFollowerTests.test_follow_file_returns_empty_content_object_on_error-1' due to IO Error: [Errno 13] Permission denied: '/tmp/tmpgqe4twb0'
Followed stream is empty.
Followed stream is empty.
INFO:root:************************************************************
INFO:root:Starting test Test.id
INFO:autopilot.tests.unit.test_logging:autopilot.tests.unit.test_logging.TestCaseLoggingFixtureTests.test_test_log_is_added-1
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
INFO:root:Autopilot Source Version: 1.5.0
WARNING:autopil...

Revision history for this message
Max Brustkern (nuclearbob) wrote :

The same problems (sphinx and test failures) appear when building lp:autopilot/1.5 under xenial. I think this is an issue with the transition to python3.5

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Changing debian/rules to force python3.4 for the testing portion allows that to work, but I can't get sphinx to finish building yet.

lp:autopilot updated
573. By Christopher Lee

Fix build issues on Xenial. Incl. simplifying DateTime. Fixes: https://bugs.launchpad.net/bugs/1524000.

Approved by Max Brustkern, PS Jenkins bot.

574. By Christopher Lee

Fix missing dep packaging.

Approved by PS Jenkins bot.

Revision history for this message
Martin Pitt (pitti) wrote :

(Trivial) packaging change ack, python3-tz is in main and no other changes in the packaging. Thanks!

review: Approve (packaging)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'autopilot/_logging.py'
2--- autopilot/_logging.py 2014-07-14 04:07:05 +0000
3+++ autopilot/_logging.py 2015-12-09 05:28:20 +0000
4@@ -22,10 +22,11 @@
5 import logging
6 from io import StringIO
7
8-from testtools.content import text_content
9-
10 from autopilot._fixtures import FixtureWithDirectAddDetail
11-from autopilot.utilities import LogFormatter
12+from autopilot.utilities import (
13+ LogFormatter,
14+ safe_text_content,
15+)
16
17
18 class TestCaseLoggingFixture(FixtureWithDirectAddDetail):
19@@ -54,7 +55,7 @@
20 self._log_buffer.seek(0)
21 self.caseAddDetail(
22 'test-log',
23- text_content(self._log_buffer.getvalue())
24+ safe_text_content(self._log_buffer.getvalue())
25 )
26 root_logger.removeHandler(self._log_handler)
27 self._log_buffer = None
28
29=== modified file 'autopilot/_video.py'
30--- autopilot/_video.py 2014-09-05 04:03:57 +0000
31+++ autopilot/_video.py 2015-12-09 05:28:20 +0000
32@@ -26,10 +26,10 @@
33 import signal
34 import subprocess
35
36-from testtools.content import text_content
37 from testtools.matchers import NotEquals
38
39 from autopilot.matchers import Eventually
40+from autopilot.utilities import safe_text_content
41
42
43 logger = logging.getLogger(__name__)
44@@ -103,7 +103,7 @@
45 if self._capture_process.returncode != 0:
46 test_instance.addDetail(
47 'video capture log',
48- text_content(self._capture_process.stdout.read()))
49+ safe_text_content(self._capture_process.stdout.read()))
50 self._capture_process = None
51 self._currently_recording_description = None
52
53
54=== modified file 'autopilot/application/_launcher.py'
55--- autopilot/application/_launcher.py 2015-09-07 21:59:05 +0000
56+++ autopilot/application/_launcher.py 2015-12-09 05:28:20 +0000
57@@ -22,6 +22,8 @@
58 import fixtures
59 from gi.repository import GLib
60 try:
61+ from gi import require_version
62+ require_version('UbuntuAppLaunch', '2')
63 from gi.repository import UbuntuAppLaunch
64 except ImportError:
65 # Note: the renamed package is not in Trusty.
66@@ -32,7 +34,8 @@
67 import psutil
68 import subprocess
69 import signal
70-from testtools.content import content_from_file, text_content
71+from testtools.content import content_from_file
72+from autopilot.utilities import safe_text_content
73
74 from autopilot._timeout import Timeout
75 from autopilot._fixtures import FixtureWithDirectAddDetail
76@@ -428,15 +431,15 @@
77 stdout, stderr, return_code = _kill_process(process)
78 self.caseAddDetail(
79 'process-return-code (%s)' % app_path,
80- text_content(str(return_code))
81+ safe_text_content(str(return_code))
82 )
83 self.caseAddDetail(
84 'process-stdout (%s)' % app_path,
85- text_content(stdout)
86+ safe_text_content(stdout)
87 )
88 self.caseAddDetail(
89 'process-stderr (%s)' % app_path,
90- text_content(stderr)
91+ safe_text_content(stderr)
92 )
93
94
95
96=== modified file 'autopilot/content.py'
97--- autopilot/content.py 2014-05-23 13:22:56 +0000
98+++ autopilot/content.py 2015-12-09 05:28:20 +0000
99@@ -22,7 +22,8 @@
100 import io
101
102 import logging
103-from testtools.content import ContentType, content_from_stream, text_content
104+from testtools.content import ContentType, content_from_stream
105+from autopilot.utilities import safe_text_content
106
107 _logger = logging.getLogger(__name__)
108
109@@ -46,7 +47,7 @@
110 content_name,
111 str(e)
112 )
113- return text_content('')
114+ return safe_text_content('')
115 else:
116 file_obj.seek(0, io.SEEK_END)
117 return follow_stream(
118@@ -74,5 +75,13 @@
119 ContentType('text', 'plain', {'charset': 'iso8859-1'}),
120 buffer_now=True
121 )
122+
123+ # Work around a bug in older testtools where an empty file would result
124+ # in None being decoded and exploding.
125+ # See: https://bugs.launchpad.net/autopilot/+bug/1517289
126+ if list(content_obj.iter_text()) == []:
127+ _logger.warning('Followed stream is empty.')
128+ content_obj = safe_text_content('Unable to read file data.')
129+
130 test_case.addDetail(content_name, content_obj)
131 test_case.addCleanup(make_content)
132
133=== modified file 'autopilot/introspection/types.py'
134--- autopilot/introspection/types.py 2014-10-22 20:43:01 +0000
135+++ autopilot/introspection/types.py 2015-12-09 05:28:20 +0000
136@@ -37,8 +37,9 @@
137
138 """
139
140+import pytz
141 from datetime import datetime, time, timedelta
142-from dateutil.tz import gettz, tzutc
143+from dateutil.tz import gettz
144
145 import dbus
146 import logging
147@@ -650,39 +651,15 @@
148 super(DateTime, self).__init__(*args, **kwargs)
149 # Using timedelta in this manner is a workaround so that we can support
150 # timestamps larger than the 32bit time_t limit on 32bit hardware.
151- # We then apply another workaround where timedelta doesn't apply
152- # daylight savings, so we need to work out the offsets for the
153- # localtime manually and apply them to give us the correct local time.
154+ # We then apply the timezone information to this to get the correct
155+ # datetime.
156 #
157 # Note. self[0] is a UTC timestamp
158- EPOCH = datetime(1970, 1, 1, tzinfo=tzutc())
159+ utc = pytz.timezone('UTC')
160+ EPOCH = datetime(1970, 1, 1, tzinfo=utc)
161 utc_dt = EPOCH + timedelta(seconds=self[0])
162
163- local_tzinfo = gettz()
164-
165- # Get the localtimes timezone offset (known as standard offset) by
166- # subtracting its dst offset (if any) from its utc offset.
167- # We apply this to the utc datetime object to get datetime object in
168- # localtime.
169- # (We will check (once we have a local datetime) if the time is in dst
170- # and make that adjustment then.)
171- utc_offset = local_tzinfo.utcoffset(utc_dt)
172- dst_offset = local_tzinfo.dst(utc_dt)
173- standard_offset = utc_offset - dst_offset
174-
175- # Create a local timezone aware datetime object from the utc_dt
176- # (i.e. attaching a timezone to it) and apply the standard offset to
177- # give us the local time.
178- local_dt = utc_dt.replace(tzinfo=local_tzinfo) + standard_offset
179-
180- # If the new local time is firmly in std time then the standard offset
181- # will be 0 (i.e. timedelta(0)).
182- # If the delta isn't 0 then we need to use the timezone information to
183- # apply the dst delta to the local time.
184- if standard_offset != timedelta(0):
185- local_dt = local_dt + local_tzinfo.dst(local_dt)
186-
187- self._cached_dt = local_dt
188+ self._cached_dt = utc_dt.astimezone(gettz())
189
190 @property
191 def year(self):
192
193=== modified file 'autopilot/tests/unit/test_platform.py'
194--- autopilot/tests/unit/test_platform.py 2014-07-23 03:37:24 +0000
195+++ autopilot/tests/unit/test_platform.py 2015-12-09 05:28:20 +0000
196@@ -39,7 +39,7 @@
197 @patch('autopilot.platform._PlatformDetector')
198 def test_model_creates_platform_detector(self, mock_detector):
199 platform.model()
200- mock_detector.create.assert_called_once()
201+ mock_detector.create.assert_called_once_with()
202
203 @patch('autopilot.platform._PlatformDetector._cached_detector')
204 def test_model_returns_correct_value(self, mock_detector):
205@@ -49,7 +49,7 @@
206 @patch('autopilot.platform._PlatformDetector')
207 def test_image_codename_creates_platform_detector(self, mock_detector):
208 platform.image_codename()
209- mock_detector.create.assert_called_once()
210+ mock_detector.create.assert_called_once_with()
211
212 @patch('autopilot.platform._PlatformDetector._cached_detector')
213 def test_image_codename_returns_correct_value(self, mock_detector):
214
215=== modified file 'autopilot/tests/unit/test_utilities.py'
216--- autopilot/tests/unit/test_utilities.py 2014-11-10 11:00:21 +0000
217+++ autopilot/tests/unit/test_utilities.py 2015-12-09 05:28:20 +0000
218@@ -20,6 +20,7 @@
219 from unittest.mock import Mock, patch
220 import re
221 from testtools import TestCase
222+from testtools.content import Content
223 from testtools.matchers import (
224 Equals,
225 IsInstance,
226@@ -39,6 +40,7 @@
227 compatible_repr,
228 deprecated,
229 EventDelay,
230+ safe_text_content,
231 sleep,
232 )
233
234@@ -357,3 +359,17 @@
235 wrapped.reset_cache()
236 wrapped()
237 self.assertThat(inner.call_count, Equals(2))
238+
239+
240+class SafeTextContentTests(TestCase):
241+
242+ def test_raises_TypeError_on_non_texttype(self):
243+ self.assertThat(
244+ lambda: safe_text_content(None),
245+ raises(TypeError)
246+ )
247+
248+ def test_returns_text_content_object(self):
249+ example_string = self.getUniqueString()
250+ content_obj = safe_text_content(example_string)
251+ self.assertTrue(isinstance(content_obj, Content))
252
253=== modified file 'autopilot/utilities.py'
254--- autopilot/utilities.py 2014-11-10 11:00:21 +0000
255+++ autopilot/utilities.py 2015-12-09 05:28:20 +0000
256@@ -29,6 +29,7 @@
257 import os
258 import time
259 import timeit
260+from testtools.content import text_content
261 from functools import wraps
262
263 from autopilot.exceptions import BackendException
264@@ -37,6 +38,25 @@
265 logger = logging.getLogger(__name__)
266
267
268+def safe_text_content(text):
269+ """Return testtools.content.Content object.
270+
271+ Safe in the sense that it will catch any attempt to attach NoneType
272+ objects.
273+
274+ :raises ValueError: If `text` is not a text-type object.
275+
276+ """
277+ if not isinstance(text, str):
278+ raise TypeError(
279+ 'text argument must be string not {}'.format(
280+ type(text).__name__
281+ )
282+ )
283+
284+ return text_content(text)
285+
286+
287 def _pick_backend(backends, preferred_backend):
288 """Pick a backend and return an instance of it."""
289 possible_backends = list(backends.keys())
290
291=== modified file 'debian/control'
292--- debian/control 2015-07-22 23:29:11 +0000
293+++ debian/control 2015-12-09 05:28:20 +0000
294@@ -30,6 +30,7 @@
295 python3-subunit,
296 python3-testscenarios,
297 python3-testtools,
298+ python3-tz,
299 python3-xlib (>=0.14+20091101-1ubuntu3),
300 sphinx-common,
301 texlive-latex-extra,
302@@ -55,6 +56,7 @@
303 python3-subunit,
304 python3-testscenarios,
305 python3-testtools,
306+ python3-tz,
307 udev,
308 ${misc:Depends},
309 ${python3:Depends},
310
311=== modified file 'docs/otto.py'
312--- docs/otto.py 2013-07-25 05:47:36 +0000
313+++ docs/otto.py 2015-12-09 05:28:20 +0000
314@@ -56,12 +56,9 @@
315 self.content, self.lineno, self.content_offset,
316 self.block_text, self.state, self.state_machine)
317 image_container = nodes.container()
318- image_container.children.append(nodes.image(uri='/images/otto-64.png'))
319+ image_container.append(nodes.image(uri='/images/otto-64.png'))
320 image_container['classes'] = ['otto-image-container']
321 outer_container = nodes.container()
322- outer_container.children.extend(
323- [image_container]
324- + ad
325- )
326+ outer_container.extend([image_container] + ad)
327 outer_container['classes'] = ['otto-says-container']
328 return [outer_container]

Subscribers

People subscribed via source and target branches