summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/subunit/INSTALL2
-rw-r--r--lib/subunit/MANIFEST.in1
-rw-r--r--lib/subunit/Makefile.am3
-rw-r--r--lib/subunit/NEWS13
-rw-r--r--lib/subunit/README13
-rw-r--r--lib/subunit/configure.ac2
-rw-r--r--lib/subunit/python/subunit/__init__.py29
-rwxr-xr-xlib/subunit/python/subunit/run.py15
-rw-r--r--lib/subunit/python/subunit/test_results.py7
-rw-r--r--lib/subunit/python/subunit/tests/test_test_protocol.py15
-rw-r--r--lib/subunit/python/subunit/tests/test_test_results.py6
-rwxr-xr-xlib/subunit/runtests.py2
-rwxr-xr-xlib/subunit/setup.py5
13 files changed, 101 insertions, 12 deletions
diff --git a/lib/subunit/INSTALL b/lib/subunit/INSTALL
index 2a053d8ad6..eeea734f6a 100644
--- a/lib/subunit/INSTALL
+++ b/lib/subunit/INSTALL
@@ -14,7 +14,7 @@ Dependencies
* Python for the filters
* 'testtools' (On Debian and Ubuntu systems the 'python-testtools' package,
the testtools package on pypi, or https://launchpad.net/testtools) for
- the extended test API which permits attachments. Version 0.9.11 or newer is
+ the extended test API which permits attachments. Version 0.9.23 or newer is
required. Of particular note, http://testtools.python-hosting.com/ is not
the testtools you want.
* A C compiler for the C bindings
diff --git a/lib/subunit/MANIFEST.in b/lib/subunit/MANIFEST.in
index 7c449cf7e7..eb98981628 100644
--- a/lib/subunit/MANIFEST.in
+++ b/lib/subunit/MANIFEST.in
@@ -16,6 +16,5 @@ exclude missing
prune perl
exclude py-compile
prune shell
-prune python/iso8601
exclude stamp-h1
include NEWS
diff --git a/lib/subunit/Makefile.am b/lib/subunit/Makefile.am
index 310c0426ae..da1602037e 100644
--- a/lib/subunit/Makefile.am
+++ b/lib/subunit/Makefile.am
@@ -35,6 +35,7 @@ EXTRA_DIST = \
python/subunit/tests/test_test_protocol.py \
python/subunit/tests/test_test_results.py \
runtests.py \
+ setup.py \
shell/README \
shell/share/subunit.sh \
shell/subunit-ui.patch \
@@ -48,8 +49,10 @@ include_subunitdir = $(includedir)/subunit
dist_bin_SCRIPTS = \
filters/subunit-filter \
filters/subunit-ls \
+ filters/subunit-notify \
filters/subunit-stats \
filters/subunit-tags \
+ filters/subunit2csv \
filters/subunit2gtk \
filters/subunit2junitxml \
filters/subunit2pyunit \
diff --git a/lib/subunit/NEWS b/lib/subunit/NEWS
index f28ec5a6df..081dc5dbfc 100644
--- a/lib/subunit/NEWS
+++ b/lib/subunit/NEWS
@@ -5,12 +5,25 @@ subunit release notes
NEXT (In development)
---------------------
+0.0.9
+-----
+
BUG FIXES
~~~~~~~~~
+* All the source files are now included in the distribution tarball.
+ (Arfrever Frehtes Taifersar Arahesis, Robert Collins, #996275)
+
* ``python/subunit/tests/test_run.py`` and ``python/subunit/filters.py`` were
not included in the 0.0.8 tarball. (Robert Collins)
+* Test ids which include non-ascii unicode characters are now supported.
+ (Robert Collins, #1029866)
+
+* The ``failfast`` option to ``subunit.run`` will now work. The dependency on
+ testtools has been raised to 0.9.23 to permit this.
+ (Robert Collins, #1090582)
+
0.0.8
-----
diff --git a/lib/subunit/README b/lib/subunit/README
index 4818a057bf..103a32cdf9 100644
--- a/lib/subunit/README
+++ b/lib/subunit/README
@@ -43,6 +43,7 @@ A number of useful things can be done easily with subunit:
Subunit supplies the following filters:
* tap2subunit - convert perl's TestAnythingProtocol to subunit.
+ * subunit2csv - convert a subunit stream to csv.
* subunit2pyunit - convert a subunit stream to pyunit test results.
* subunit2gtk - show a subunit stream in GTK.
* subunit2junitxml - convert a subunit stream to JUnit's XML format.
@@ -214,3 +215,15 @@ to indicate a test that errored in some expected fashion (also know as "TODO"
tests in some frameworks). uxsuccess is used to indicate and unexpected success
where a test though to be failing actually passes. It is complementary to
xfail.
+
+Hacking on subunit
+------------------
+
+Releases
+========
+
+* Update versions in configure.ac and python/subunit/__init__.py.
+* Make PyPI and regular tarball releases. Upload the regular one to LP, the
+ PyPI one to PyPI.
+* Push a tagged commit.
+
diff --git a/lib/subunit/configure.ac b/lib/subunit/configure.ac
index 223b3c9b49..cf21d55480 100644
--- a/lib/subunit/configure.ac
+++ b/lib/subunit/configure.ac
@@ -1,6 +1,6 @@
m4_define([SUBUNIT_MAJOR_VERSION], [0])
m4_define([SUBUNIT_MINOR_VERSION], [0])
-m4_define([SUBUNIT_MICRO_VERSION], [8])
+m4_define([SUBUNIT_MICRO_VERSION], [9])
m4_define([SUBUNIT_VERSION],
m4_defn([SUBUNIT_MAJOR_VERSION]).m4_defn([SUBUNIT_MINOR_VERSION]).m4_defn([SUBUNIT_MICRO_VERSION]))
AC_PREREQ([2.59])
diff --git a/lib/subunit/python/subunit/__init__.py b/lib/subunit/python/subunit/__init__.py
index 6015c0e68c..42dcf297e4 100644
--- a/lib/subunit/python/subunit/__init__.py
+++ b/lib/subunit/python/subunit/__init__.py
@@ -147,6 +147,19 @@ from testtools import testresult
from subunit import chunked, details, iso8601, test_results
+# same format as sys.version_info: "A tuple containing the five components of
+# the version number: major, minor, micro, releaselevel, and serial. All
+# values except releaselevel are integers; the release level is 'alpha',
+# 'beta', 'candidate', or 'final'. The version_info value corresponding to the
+# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
+# releaselevel of 'dev' for unreleased under-development code.
+#
+# If the releaselevel is 'alpha' then the major/minor/micro components are not
+# established at this point, and setup.py will use a version of next-$(revno).
+# If the releaselevel is 'final', then the tarball will be major.minor.micro.
+# Otherwise it is major.minor.micro~$(revno).
+
+__version__ = (0, 0, 9, 'final', 0)
PROGRESS_SET = 0
PROGRESS_CUR = 1
@@ -636,6 +649,8 @@ class TestProtocolClient(testresult.TestResult):
to subunit.Content objects.
"""
self._addOutcome("error", test, error=error, details=details)
+ if self.failfast:
+ self.stop()
def addExpectedFailure(self, test, error=None, details=None):
"""Report an expected failure in test test.
@@ -666,6 +681,8 @@ class TestProtocolClient(testresult.TestResult):
to subunit.Content objects.
"""
self._addOutcome("failure", test, error=error, details=details)
+ if self.failfast:
+ self.stop()
def _addOutcome(self, outcome, test, error=None, details=None,
error_permitted=True):
@@ -685,7 +702,7 @@ class TestProtocolClient(testresult.TestResult):
:param error_permitted: If True then one and only one of error or
details must be supplied. If False then error must not be supplied
and details is still optional. """
- self._stream.write(_b("%s: %s" % (outcome, test.id())))
+ self._stream.write(_b("%s: " % outcome) + self._test_id(test))
if error_permitted:
if error is None and details is None:
raise ValueError
@@ -730,11 +747,19 @@ class TestProtocolClient(testresult.TestResult):
"""
self._addOutcome("uxsuccess", test, details=details,
error_permitted=False)
+ if self.failfast:
+ self.stop()
+
+ def _test_id(self, test):
+ result = test.id()
+ if type(result) is not bytes:
+ result = result.encode('utf8')
+ return result
def startTest(self, test):
"""Mark a test as starting its test run."""
super(TestProtocolClient, self).startTest(test)
- self._stream.write(_b("test: %s\n" % test.id()))
+ self._stream.write(_b("test: ") + self._test_id(test) + _b("\n"))
self._stream.flush()
def stopTest(self, test):
diff --git a/lib/subunit/python/subunit/run.py b/lib/subunit/python/subunit/run.py
index ca5fe5c17e..b5ccea449d 100755
--- a/lib/subunit/python/subunit/run.py
+++ b/lib/subunit/python/subunit/run.py
@@ -34,13 +34,22 @@ from testtools.run import (
class SubunitTestRunner(object):
- def __init__(self, stream=sys.stdout):
- self.stream = stream
+ def __init__(self, verbosity=None, failfast=None, buffer=None, stream=None):
+ """Create a TestToolsTestRunner.
+
+ :param verbosity: Ignored.
+ :param failfast: Stop running tests at the first failure.
+ :param buffer: Ignored.
+ """
+ self.failfast = failfast
+ self.stream = stream or sys.stdout
def run(self, test):
"Run the given test case or test suite."
result = TestProtocolClient(self.stream)
result = AutoTimingTestResultDecorator(result)
+ if self.failfast is not None:
+ result.failfast = self.failfast
test(result)
return result
@@ -70,6 +79,6 @@ class SubunitTestProgram(TestProgram):
if __name__ == '__main__':
stream = get_default_formatter()
- runner = SubunitTestRunner(stream)
+ runner = SubunitTestRunner
SubunitTestProgram(module=None, argv=sys.argv, testRunner=runner,
stdout=sys.stdout)
diff --git a/lib/subunit/python/subunit/test_results.py b/lib/subunit/python/subunit/test_results.py
index c00a2d3e97..91c9bbdc1e 100644
--- a/lib/subunit/python/subunit/test_results.py
+++ b/lib/subunit/python/subunit/test_results.py
@@ -78,6 +78,13 @@ class TestResultDecorator(object):
def addUnexpectedSuccess(self, test, details=None):
return self.decorated.addUnexpectedSuccess(test, details=details)
+ def _get_failfast(self):
+ return getattr(self.decorated, 'failfast', False)
+
+ def _set_failfast(self, value):
+ self.decorated.failfast = value
+ failfast = property(_get_failfast, _set_failfast)
+
def progress(self, offset, whence):
return self.decorated.progress(offset, whence)
diff --git a/lib/subunit/python/subunit/tests/test_test_protocol.py b/lib/subunit/python/subunit/tests/test_test_protocol.py
index ec6830d03b..7831ba16cd 100644
--- a/lib/subunit/python/subunit/tests/test_test_protocol.py
+++ b/lib/subunit/python/subunit/tests/test_test_protocol.py
@@ -18,7 +18,7 @@ import datetime
import unittest
import os
-from testtools import skipIf, TestCase, TestResult
+from testtools import PlaceHolder, skipIf, TestCase, TestResult
from testtools.compat import _b, _u, BytesIO
from testtools.content import Content, TracebackContent, text_content
from testtools.content_type import ContentType
@@ -1133,6 +1133,7 @@ class TestTestProtocolClient(unittest.TestCase):
def setUp(self):
self.io = BytesIO()
self.protocol = subunit.TestProtocolClient(self.io)
+ self.unicode_test = PlaceHolder(_u('\u2603'))
self.test = TestTestProtocolClient("test_start_test")
self.sample_details = {'something':Content(
ContentType('text', 'plain'), lambda:[_b('serialised\nform')])}
@@ -1145,6 +1146,12 @@ class TestTestProtocolClient(unittest.TestCase):
self.protocol.startTest(self.test)
self.assertEqual(self.io.getvalue(), _b("test: %s\n" % self.test.id()))
+ def test_start_test_unicode_id(self):
+ """Test startTest on a TestProtocolClient."""
+ self.protocol.startTest(self.unicode_test)
+ expected = _b("test: ") + _u('\u2603').encode('utf8') + _b("\n")
+ self.assertEqual(expected, self.io.getvalue())
+
def test_stop_test(self):
# stopTest doesn't output anything.
self.protocol.stopTest(self.test)
@@ -1156,6 +1163,12 @@ class TestTestProtocolClient(unittest.TestCase):
self.assertEqual(
self.io.getvalue(), _b("successful: %s\n" % self.test.id()))
+ def test_add_outcome_unicode_id(self):
+ """Test addSuccess on a TestProtocolClient."""
+ self.protocol.addSuccess(self.unicode_test)
+ expected = _b("successful: ") + _u('\u2603').encode('utf8') + _b("\n")
+ self.assertEqual(expected, self.io.getvalue())
+
def test_add_success_details(self):
"""Test addSuccess on a TestProtocolClient with details."""
self.protocol.addSuccess(self.test, details=self.sample_details)
diff --git a/lib/subunit/python/subunit/tests/test_test_results.py b/lib/subunit/python/subunit/tests/test_test_results.py
index 236dfa22e5..ff74b9a818 100644
--- a/lib/subunit/python/subunit/tests/test_test_results.py
+++ b/lib/subunit/python/subunit/tests/test_test_results.py
@@ -61,6 +61,7 @@ class TimeCapturingResult(unittest.TestResult):
def __init__(self):
super(TimeCapturingResult, self).__init__()
self._calls = []
+ self.failfast = False
def time(self, a_datetime):
self._calls.append(a_datetime)
@@ -198,6 +199,11 @@ class TestAutoTimingTestResultDecorator(unittest.TestCase):
self.assertEqual(3, len(self.decorated._calls))
self.assertNotEqual(None, self.decorated._calls[2])
+ def test_set_failfast_True(self):
+ self.assertFalse(self.decorated.failfast)
+ self.result.failfast = True
+ self.assertTrue(self.decorated.failfast)
+
class TestTagCollapsingDecorator(TestCase):
diff --git a/lib/subunit/runtests.py b/lib/subunit/runtests.py
index 691e3b34da..8ecc6cd3fb 100755
--- a/lib/subunit/runtests.py
+++ b/lib/subunit/runtests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
# -*- Mode: python -*-
#
# Copyright (C) 2004 Canonical.com
diff --git a/lib/subunit/setup.py b/lib/subunit/setup.py
index a78eb999d7..1a0b192b1b 100755
--- a/lib/subunit/setup.py
+++ b/lib/subunit/setup.py
@@ -9,7 +9,7 @@ except ImportError:
else:
extra = {
'install_requires': [
- 'testtools>=0.9.11',
+ 'testtools>=0.9.23',
]
}
@@ -38,6 +38,7 @@ setup(
long_description=open('README').read(),
classifiers=[
'Intended Audience :: Developers',
+ 'Programming Language :: Python :: 3',
'Programming Language :: Python',
'Topic :: Software Development :: Testing',
],
@@ -45,7 +46,7 @@ setup(
author='Robert Collins',
author_email='subunit-dev@lists.launchpad.net',
url='http://launchpad.net/subunit',
- packages=['subunit'],
+ packages=['subunit', 'subunit.tests'],
package_dir={'subunit': 'python/subunit'},
scripts = [
'filters/subunit2gtk',