Merge lp:~vila/autopilot/timestamped-subunit-stream into lp:autopilot

Proposed by Vincent Ladeuil
Status: Work in progress
Proposed branch: lp:~vila/autopilot/timestamped-subunit-stream
Merge into: lp:autopilot
Diff against target: 85 lines (+41/-5)
3 files modified
.bzrignore (+1/-0)
autopilot/testresult.py (+4/-5)
autopilot/tests/unit/test_testresults.py (+36/-0)
To merge this branch: bzr merge lp:~vila/autopilot/timestamped-subunit-stream
Reviewer Review Type Date Requested Status
Christopher Lee (community) Needs Information
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+256210@code.launchpad.net

Commit message

Add timestamps to the subunit stream

Description of the change

This is a first step in fixing https://bugs.launchpad.net/ubuntu-sanity-tests/+bug/1408732.

The issue is that autopilot doesn't timestamp the tests in the stream to start with (so ubuntu-sanity-tests can't preserve them either).

Guidance welcome about where to add tests for that (I found autopilot/tests/unit/test_testresults.py but it doesn't seem to test the subunit stream specifically).

The fix can be checked by using 'subunit-ls --times ' on a subunit stream with and without that fix.

I tried running the autopilot test suite on my laptop but in 5 runs I got logged out 3 times from my session :-/

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Christopher Lee (veebers) wrote :

Hi Vincent,

autopilot/tests/unit/test_testresults.py seems like a decent place to put the tests.

Regarding running the tests, which WM/DM are you running out of interest? It seems there may be an assumption the tests are making that is causing this to happen.

I ran some tests with trunk and this branch and compared the results of using 'subunit-ls --times'.

I saw similar results on both runs (the trunk version has some times) perhaps I'm missing something?

Also, I ran some functional tests (so they take a little longer per test) and found that when using this branch every result was 0.000 seconds (even though I was watching them run and they totally took longer than that) where the trunk run had times for each test. Perhaps I'm doing something wrong?

Commands I used:
  $ python3 -m autopilot.run run -v -o /tmp/subunit-output-vila.subunit -f subunit autopilot.tests.functional.test_input_stack

  $ subunit-ls --times /tmp/subunit-output-vila.subunit

The output along the lines of:
autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test_text_typing(UInput,lower_alpha) 0.000
autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test_text_typing(UInput,upper_alpha) 0.000
autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test_text_typing(UInput,numeric) 0.000
autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test_text_typing(UInput,punctuation) 0.000

review: Needs Information
553. By Vincent Ladeuil

Add a test to ensure we get a non-zero timestamp.

Revision history for this message
Vincent Ladeuil (vila) wrote :

...aaaaand I should have wrote the test first ;-)

> Hi Vincent,
>
> autopilot/tests/unit/test_testresults.py seems like a decent place to put the
> tests.

Ack, I went ahead and add one there indeed.

>
> Regarding running the tests, which WM/DM are you running out of interest?

unity7 on vivid (the default AFAIK).

> It
> seems there may be an assumption the tests are making that is causing this to
> happen.

Yeah, newcomer running into silly setup errors most probably ;)

Let's talk about it outside that MP may be ?

I will setup a kvm and re-run there instead.

>
> I ran some tests with trunk and this branch and compared the results of using
> 'subunit-ls --times'.
>
> I saw similar results on both runs (the trunk version has some times) perhaps
> I'm missing something?

I'm a bit confused myself that the test I added succeeds even without my patch... still digging ;)

>
> Also, I ran some functional tests (so they take a little longer per test) and
> found that when using this branch every result was 0.000 seconds (even though
> I was watching them run and they totally took longer than that) where the
> trunk run had times for each test. Perhaps I'm doing something wrong?

That one is puzzling...

class AutoTimingTestResultDecorator(HookedTestResultDecorator):
    """Decorate a TestResult to add time events to a test run.

    By default this will cause a time event before every test event,
    but if explicit time data is being provided by the test run, then
    this decorator will turn itself off to prevent causing confusion.
    """

I.e. timestamps should be added if none exist, you seem to observe that they are *removed* instead which makes litlle sense at that point ;)

>
> Commands I used:
> $ python3 -m autopilot.run run -v -o /tmp/subunit-output-vila.subunit -f
> subunit autopilot.tests.functional.test_input_stack
>
> $ subunit-ls --times /tmp/subunit-output-vila.subunit
>

Which is basically what my added test does.

> The output along the lines of:
> autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test
> _text_typing(UInput,lower_alpha) 0.000
> autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test
> _text_typing(UInput,upper_alpha) 0.000
> autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test
> _text_typing(UInput,numeric) 0.000
> autopilot.tests.functional.test_input_stack.InputStackKeyboardTypingTests.test
> _text_typing(UInput,punctuation) 0.000

Right, so the '0.000' is the issue.

Unfortunately I can't reproduce what you're seeing, I'm getting the opposite, but with failures, so I don't really trust that either ;-/

So, I'll restart from scratch, it seems I've missed something in my initial diagnosis...

Marking this MP 'in progress' until enlightenment ;)

Unmerged revisions

553. By Vincent Ladeuil

Add a test to ensure we get a non-zero timestamp.

552. By Vincent Ladeuil

Wrap the result object to get timestamps on subunit tests.

551. By Vincent Ladeuil

Ignore python3 caches.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2013-12-10 01:26:22 +0000
3+++ .bzrignore 2015-04-15 14:10:00 +0000
4@@ -4,3 +4,4 @@
5 .tox
6 htmlcov
7 .coverage
8+**/__pycache__/
9
10=== modified file 'autopilot/testresult.py'
11--- autopilot/testresult.py 2015-01-27 00:10:54 +0000
12+++ autopilot/testresult.py 2015-04-15 14:10:00 +0000
13@@ -137,13 +137,12 @@
14
15 def _construct_subunit(**kwargs):
16 from subunit import StreamResultToBytes
17+ from subunit import test_results
18 stream = kwargs.pop('stream')
19 failfast = kwargs.pop('failfast')
20 _raise_on_unknown_kwargs(kwargs)
21- result_object = LoggedTestResultDecorator(
22- ExtendedToStreamDecorator(
23- StreamResultToBytes(stream)
24- )
25- )
26+ result_object = test_results.AutoTimingTestResultDecorator(
27+ LoggedTestResultDecorator(
28+ ExtendedToStreamDecorator(StreamResultToBytes(stream))))
29 result_object.failfast = failfast
30 return result_object
31
32=== modified file 'autopilot/tests/unit/test_testresults.py'
33--- autopilot/tests/unit/test_testresults.py 2015-01-27 00:10:10 +0000
34+++ autopilot/tests/unit/test_testresults.py 2015-04-15 14:10:00 +0000
35@@ -20,7 +20,9 @@
36 import codecs
37 from unittest.mock import Mock, patch
38 import os
39+import subprocess
40 import tempfile
41+import time
42
43 from fixtures import FakeLogger
44 from testtools import TestCase, PlaceHolder
45@@ -333,6 +335,40 @@
46 self.assertEqual(1, test_result.testsRun)
47
48
49+class TestSubunitResult(TestCase):
50+ def setUp(self):
51+ super().setUp()
52+ self.output_path = tempfile.mktemp()
53+ self.addCleanup(remove_if_exists, self.output_path)
54+
55+ def test_timestamp_for_tests(self):
56+ # Ensure that the subunit stream embeds timestamps for each test
57+ class MyTest(TestCase):
58+ def test_pass(self):
59+ # sleep enough to have some duration for the test
60+ time.sleep(0.002)
61+
62+ t = MyTest('test_pass')
63+ stream = run.get_output_stream('subunit', self.output_path)
64+ result = testresult.get_output_formats()['subunit'](
65+ stream=stream, failfast=False)
66+ result.startTestRun()
67+ t.run(result)
68+ result.stopTestRun()
69+ stream.flush()
70+ # We just rely on subunit-ls to extract the test timestamps. If none
71+ # are included we'll get very short duration (0.000) representing the
72+ # time it takes to parse the stream. Since there are is no
73+ # details/artifacts here, making the test sleep should be enough to
74+ # distinguish between a stream with or without timestamps.
75+ ls_output = subprocess.check_output(
76+ ['subunit-ls', '--times', self.output_path],
77+ universal_newlines=True
78+ ).strip()
79+ test_name, duration = ls_output.split()
80+ self.assertNotEqual('0.000', duration)
81+
82+
83 def remove_if_exists(path):
84 if os.path.exists(path):
85 os.remove(path)

Subscribers

People subscribed via source and target branches