Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package subunit for openSUSE:Factory checked in at 2021-10-20 20:23:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/subunit (Old) and /work/SRC/openSUSE:Factory/.subunit.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "subunit" Wed Oct 20 20:23:34 2021 rev:9 rq:925759 version:1.4.0+git.1627548288.c87ffbd Changes: -------- --- /work/SRC/openSUSE:Factory/subunit/subunit.changes 2021-06-01 10:32:56.436351202 +0200 +++ /work/SRC/openSUSE:Factory/.subunit.new.1890/subunit.changes 2021-10-20 20:24:20.533380221 +0200 @@ -1,0 +2,24 @@ +Sat Oct 16 21:33:15 UTC 2021 - mc...@cepl.eu + +- Update to version 1.4.0+git.1627548288.c87ffbd: + * Update NEWS + * Handle different SyntaxError output in testtools 2.5.0 + * Sort Content-Type parameters when writing details + * Import six from the right place + * Pivot CI to github actions + * Revert "Merge pull request #17 from mtreinish/timestamp-output" + * fix trailing comma + * Fix imports from testtools.compat + * python: Mark rawstrings as such + * run everything on focal, except pypy3.5 which only runs on xenial + * add missing reference + * add current pythons + * drop Python 3.4 support + * Unittest from testtools doesn't work, use the one from stdlib. + * Acommodate review requests. + * Fix timestamp test copy paste error + * Add options to output filter to set timestamps + * Remove dependency on unittest2 +- remove remove_unittest2.patch (upstream) + +------------------------------------------------------------------- Old: ---- remove_unittest2.patch subunit-1.4.0+git.1584197985.0e9f67b.tar.xz New: ---- subunit-1.4.0+git.1627548288.c87ffbd.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ subunit.spec ++++++ --- /var/tmp/diff_new_pack.pL2gvr/_old 2021-10-20 20:24:21.069380551 +0200 +++ /var/tmp/diff_new_pack.pL2gvr/_new 2021-10-20 20:24:21.069380551 +0200 @@ -22,7 +22,7 @@ %global majver 1.4 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: subunit -Version: 1.4.0+git.1584197985.0e9f67b +Version: 1.4.0+git.1627548288.c87ffbd Release: 0 Summary: C library for the subunit testing protocol License: Apache-2.0 OR BSD-3-Clause @@ -33,9 +33,6 @@ # PATCH-FIX-UPSTREAM python38-failing-tests.patch mc...@suse.com # skip tests failing with Python 3.8+ Patch0: python38-failing-tests.patch -# patch-feature-upstream remove_unittest2.patch gh#testing-cabal/subunit#32 mc...@suse.com -# Remove dependency on unittest2 -Patch1: remove_unittest2.patch BuildRequires: %{python_module docutils} BuildRequires: %{python_module extras} BuildRequires: %{python_module fixtures} ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.pL2gvr/_old 2021-10-20 20:24:21.117380581 +0200 +++ /var/tmp/diff_new_pack.pL2gvr/_new 2021-10-20 20:24:21.117380581 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/testing-cabal/subunit.git</param> - <param name="changesrevision">0e9f67b9683bf2c8c82edb4e511d9b2c7708d900</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">faaca9b50f59d63a21663a1dc8ed21f22ffb6223</param></service></servicedata> \ No newline at end of file ++++++ python38-failing-tests.patch ++++++ --- /var/tmp/diff_new_pack.pL2gvr/_old 2021-10-20 20:24:21.125380586 +0200 +++ /var/tmp/diff_new_pack.pL2gvr/_new 2021-10-20 20:24:21.125380586 +0200 @@ -1,15 +1,8 @@ ---- a/python/subunit/tests/test_test_protocol.py -+++ b/python/subunit/tests/test_test_protocol.py -@@ -48,7 +48,7 @@ from subunit.tests import ( - import subunit.iso8601 as iso8601 - - --tb_prelude = "Traceback (most recent call last):\n" -+tb_prelude = "Traceback (most recent call last):\n" - - - def details_to_str(details): -@@ -1055,12 +1055,14 @@ class TestExecTestCase(unittest.TestCase +Index: subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_protocol.py +=================================================================== +--- subunit-1.4.0+git.1627548288.c87ffbd.orig/python/subunit/tests/test_test_protocol.py ++++ subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_protocol.py +@@ -1072,12 +1072,14 @@ class TestExecTestCase(unittest.TestCase self.assertEqual(test.script, subunit.join_dir(__file__, 'sample-script.py')) ++++++ subunit-1.4.0+git.1584197985.0e9f67b.tar.xz -> subunit-1.4.0+git.1627548288.c87ffbd.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/.travis.yml new/subunit-1.4.0+git.1627548288.c87ffbd/.travis.yml --- old/subunit-1.4.0+git.1584197985.0e9f67b/.travis.yml 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,32 +0,0 @@ -sudo: false -addons: - apt: - packages: - - check - - libcppunit-dev -language: python -python: - - "2.7" - - "3.4" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - pypy - - pypy3.5 -matrix: - include: -# Travis nightly look to be 3.5.0a4, b3 is out and the error we see -# doesn't happen in trunk. -# - python: "nightly" -install: - - pip install -U pip - - pip install -U wheel setuptools - - pip install -U .[test,docs] - - pip list - - python --version - - autoreconf -fi && ./configure && make -script: - - make check - - make distcheck - - rst2html.py README.rst README.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/NEWS new/subunit-1.4.0+git.1627548288.c87ffbd/NEWS --- old/subunit-1.4.0+git.1584197985.0e9f67b/NEWS 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/NEWS 2021-07-29 10:44:48.000000000 +0200 @@ -5,6 +5,12 @@ NEXT (In development) --------------------- +BUGFIXES +~~~~~~~~ + +* Fix tests with testtools >= 2.5.0. + (Colin Watson) + 1.4.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/__init__.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/__init__.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/__init__.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/__init__.py 2021-07-29 10:44:48.000000000 +0200 @@ -129,7 +129,11 @@ from extras import safe_hasattr from testtools import content, content_type, ExtendedToOriginalDecorator from testtools.content import TracebackContent -from testtools.compat import _b, _u, BytesIO, StringIO +from testtools.compat import _b, _u +try: + from testtools.compat import BytesIO, StringIO +except ImportError: + from io import BytesIO, StringIO try: from testtools.testresult.real import _StringException RemoteException = _StringException @@ -817,7 +821,7 @@ if parameters: self._stream.write(_b(";")) param_strs = [] - for param, value in parameters.items(): + for param, value in sorted(parameters.items()): param_strs.append("%s=%s" % (param, value)) self._stream.write(_b(",".join(param_strs))) self._stream.write(_b("\n%s\n" % name)) @@ -1033,7 +1037,7 @@ file_name=file_name, runnable=False) for line in tap: if state == BEFORE_PLAN: - match = re.match("(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?\n", line) + match = re.match(r"(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?\n", line) if match: state = AFTER_PLAN _, plan_stop, comment = match.groups() @@ -1046,7 +1050,7 @@ file_name='tap comment') continue # not a plan line, or have seen one before - match = re.match("(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?\n", line) + match = re.match(r"(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?\n", line) if match: # new test, emit current one. _emit_test() @@ -1074,7 +1078,7 @@ test_name = "test %d%s" % (plan_start, description) plan_start += 1 continue - match = re.match("Bail out\!(?:\s*(.*))?\n", line) + match = re.match(r"Bail out\!(?:\s*(.*))?\n", line) if match: reason, = match.groups() if reason is None: @@ -1086,7 +1090,7 @@ result = "fail" state = SKIP_STREAM continue - match = re.match("\#.*\n", line) + match = re.match(r"\#.*\n", line) if match: log.append(line[:-1]) continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/details.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/details.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/details.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/details.py 2021-07-29 10:44:48.000000000 +0200 @@ -17,7 +17,11 @@ """Handlers for outcome details.""" from testtools import content, content_type -from testtools.compat import _b, BytesIO +from testtools.compat import _b +try: + from testtools.compat import BytesIO, StringIO +except ImportError: + from io import BytesIO, StringIO from subunit import chunked diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/__init__.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/__init__.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/__init__.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/__init__.py 2021-07-29 10:44:48.000000000 +0200 @@ -23,6 +23,7 @@ # Before the test module imports to avoid circularity. # For testing: different pythons have different str() implementations. _remote_exception_repr = "testtools.testresult.real._StringException" +_remote_exception_repr_chunked = "34\r\n" + _remote_exception_repr + ": boo qux\n0\r\n" _remote_exception_str = "Traceback (most recent call last):\ntesttools.testresult.real._StringException" _remote_exception_str_chunked = "57\r\n" + _remote_exception_str + ": boo qux\n0\r\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_chunked.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_chunked.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_chunked.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_chunked.py 2021-07-29 10:44:48.000000000 +0200 @@ -17,7 +17,11 @@ import unittest -from testtools.compat import _b, BytesIO +from testtools.compat import _b +try: + from testtools.compat import BytesIO +except ImportError: + from io import BytesIO import subunit.chunked diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_details.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_details.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_details.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_details.py 2021-07-29 10:44:48.000000000 +0200 @@ -16,7 +16,11 @@ import unittest -from testtools.compat import _b, StringIO +from testtools.compat import _b +try: + from testtools.compat import StringIO +except ImportError: + from io import StringIO import subunit.tests from subunit import content, content_type, details diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_filter.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_filter.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_filter.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_filter.py 2021-07-29 10:44:48.000000000 +0200 @@ -24,7 +24,11 @@ import unittest from testtools import TestCase -from testtools.compat import _b, BytesIO +from testtools.compat import _b +try: + from testtools.compat import BytesIO +except ImportError: + from io import BytesIO from testtools.testresult.doubles import ExtendedTestResult, StreamResult import subunit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_stats.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_stats.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_stats.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_stats.py 2021-07-29 10:44:48.000000000 +0200 @@ -18,7 +18,11 @@ import unittest -from testtools.compat import _b, BytesIO, StringIO +from testtools.compat import _b +try: + from testtools.compat import BytesIO, StringIO +except ImportError: + from io import BytesIO, StringIO import subunit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_tags.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_tags.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_subunit_tags.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_subunit_tags.py 2021-07-29 10:44:48.000000000 +0200 @@ -56,6 +56,8 @@ b'\x83\x1b\x04test\x03\x03bar\x03foo\x04quux\xd2\x18\x1bC', b'\xb3)\x82\x17\x04test\x02\x03foo\x04quux\xa6\xe1\xde\xec\xb3)' b'\x83\x1b\x04test\x03\x03foo\x03bar\x04quux:\x05e\x80', + b'\xb3)\x82\x17\x04test\x02\x03foo\x04quux\xa6\xe1\xde\xec\xb3)' + b'\x83\x1b\x04test\x03\x04quux\x03foo\x03bar\xaf\xbd\x9d\xd6', ] stream = subunit.StreamResultToBytes(self.original) stream.status( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_test_protocol.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_protocol.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_test_protocol.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_protocol.py 2021-07-29 10:44:48.000000000 +0200 @@ -16,13 +16,17 @@ import datetime import io -import unittest2 as unittest import os -import sys import tempfile +import unittest +import six from testtools import PlaceHolder, skipIf, TestCase, TestResult -from testtools.compat import _b, _u, BytesIO +from testtools.compat import _b, _u +try: + from testtools.compat import BytesIO, StringIO +except ImportError: + from io import BytesIO, StringIO from testtools.content import Content, TracebackContent, text_content from testtools.content_type import ContentType try: @@ -37,18 +41,19 @@ Python27TestResult, ExtendedTestResult, ) -from testtools.matchers import Contains +from testtools.matchers import Contains, Equals, MatchesAny import subunit from subunit.tests import ( _remote_exception_repr, + _remote_exception_repr_chunked, _remote_exception_str, _remote_exception_str_chunked, ) import subunit.iso8601 as iso8601 -tb_prelude = "Traceback (most recent call last):\n" +tb_prelude = "Traceback (most recent call last):\n" def details_to_str(details): @@ -60,7 +65,7 @@ fd, file_path = tempfile.mkstemp() self.addCleanup(os.remove, file_path) fake_file = os.fdopen(fd, 'r') - if sys.version_info > (3, 0): + if six.PY3: self.assertEqual(fake_file.buffer, subunit._unwrap_text(fake_file)) else: @@ -70,7 +75,7 @@ fd, file_path = tempfile.mkstemp() self.addCleanup(os.remove, file_path) fake_file = os.fdopen(fd, 'w') - if sys.version_info > (3, 0): + if six.PY3: self.assertEqual(fake_file.buffer, subunit._unwrap_text(fake_file)) else: @@ -152,13 +157,20 @@ protocol.readFrom(pipe) bing = subunit.RemotedTestCase("bing crosby") an_error = subunit.RemotedTestCase("an error") - self.assertEqual( - client.errors, - [(an_error, tb_prelude + _remote_exception_repr + '\n')]) - self.assertEqual( - client.failures, - [(bing, tb_prelude + _remote_exception_repr + ": " - + details_to_str({'traceback': text_content(traceback)}) + "\n")]) + if six.PY3: + self.assertEqual(client.errors, + [(an_error, _remote_exception_repr + '\n')]) + self.assertEqual( + client.failures, + [(bing, _remote_exception_repr + ": " + + details_to_str({'traceback': text_content(traceback)}) + "\n")]) + else: + self.assertEqual(client.errors, + [(an_error, '_StringException\n')]) + self.assertEqual( + client.failures, + [(bing, "_StringException: " + + details_to_str({'traceback': text_content(traceback)}) + "\n")]) self.assertEqual(client.testsRun, 3) def test_non_test_characters_forwarded_immediately(self): @@ -1012,9 +1024,14 @@ "'A test description'>", "%r" % test) result = unittest.TestResult() test.run(result) - self.assertEqual([(test, tb_prelude + _remote_exception_repr + ": " - "Cannot run RemotedTestCases.\n\n")], - result.errors) + if six.PY3: + self.assertEqual([(test, _remote_exception_repr + ': ' + + "Cannot run RemotedTestCases.\n\n")], + result.errors) + else: + self.assertEqual([(test, "_StringException: " + + "Cannot run RemotedTestCases.\n\n")], + result.errors) self.assertEqual(1, result.testsRun) another_test = subunit.RemotedTestCase("A test description") self.assertEqual(test, another_test) @@ -1178,6 +1195,11 @@ self.assertEqual(self.SampleTestToIsolate.TEST, False) +# A number of these tests produce different output depending on the +# testtools version. testtools < 2.5.0 used traceback2, which incorrectly +# included the traceback header even for an exception with no traceback. +# testtools 2.5.0 switched to the Python 3 standard library's traceback +# module, which fixes this bug. See https://bugs.python.org/issue24695. class TestTestProtocolClient(TestCase): def setUp(self): @@ -1233,96 +1255,121 @@ """Test addFailure on a TestProtocolClient.""" self.protocol.addFailure( self.test, subunit.RemoteError(_u("boo qux"))) - self.assertEqual( - self.io.getvalue(), - _b(('failure: %s [\n' + _remote_exception_str + ': boo qux\n]\n') - % self.test.id())) + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + 'failure: %s [\n' + + _remote_exception_str + ': boo qux\n' + + ']\n') % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + 'failure: %s [\n' + + _remote_exception_repr + ': boo qux\n' + + ']\n') % self.test.id())))) def test_add_failure_details(self): """Test addFailure on a TestProtocolClient with details.""" self.protocol.addFailure( self.test, details=self.sample_tb_details) - self.assertThat([ - _b(("failure: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - _b(("failure: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - ], - Contains(self.io.getvalue())), + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + "failure: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_str_chunked + + "]\n") % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + "failure: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_repr_chunked + + "]\n") % self.test.id())))) def test_add_error(self): """Test stopTest on a TestProtocolClient.""" self.protocol.addError( self.test, subunit.RemoteError(_u("phwoar crikey"))) - self.assertEqual( - self.io.getvalue(), - _b(('error: %s [\n' + - _remote_exception_str + ": phwoar crikey\n" - "]\n") % self.test.id())) + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + 'error: %s [\n' + + _remote_exception_str + ": phwoar crikey\n" + "]\n") % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + 'error: %s [\n' + + _remote_exception_repr + ": phwoar crikey\n" + "]\n") % self.test.id())))) def test_add_error_details(self): """Test stopTest on a TestProtocolClient with details.""" self.protocol.addError( self.test, details=self.sample_tb_details) - self.assertThat([ - _b(("error: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - _b(("error: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - ], - Contains(self.io.getvalue())), + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + "error: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_str_chunked + + "]\n") % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + "error: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_repr_chunked + + "]\n") % self.test.id())))) def test_add_expected_failure(self): """Test addExpectedFailure on a TestProtocolClient.""" self.protocol.addExpectedFailure( self.test, subunit.RemoteError(_u("phwoar crikey"))) - self.assertEqual( - self.io.getvalue(), - _b(('xfail: %s [\n' + - _remote_exception_str + ": phwoar crikey\n" - "]\n") % self.test.id())) + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + 'xfail: %s [\n' + + _remote_exception_str + ": phwoar crikey\n" + "]\n") % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + 'xfail: %s [\n' + + _remote_exception_repr + ": phwoar crikey\n" + "]\n") % self.test.id())))) def test_add_expected_failure_details(self): """Test addExpectedFailure on a TestProtocolClient with details.""" self.protocol.addExpectedFailure( self.test, details=self.sample_tb_details) - self.assertThat([ - _b(("xfail: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - _b(("xfail: %s [ multipart\n" - "Content-Type: text/plain\n" - "something\n" - "F\r\nserialised\nform0\r\n" - "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + - "]\n") % self.test.id()), - ], - Contains(self.io.getvalue())), + self.assertThat(self.io.getvalue(), MatchesAny( + # testtools < 2.5.0 + Equals(_b(( + "xfail: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_str_chunked + + "]\n") % self.test.id())), + # testtools >= 2.5.0 + Equals(_b(( + "xfail: %s [ multipart\n" + "Content-Type: text/plain\n" + "something\n" + "F\r\nserialised\nform0\r\n" + "Content-Type: text/x-traceback;charset=utf8,language=python\n" + "traceback\n" + _remote_exception_repr_chunked + + "]\n") % self.test.id())))) def test_add_skip(self): """Test addSkip on a TestProtocolClient.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_test_results.py new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_results.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/python/subunit/tests/test_test_results.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/python/subunit/tests/test_test_results.py 2021-07-29 10:44:48.000000000 +0200 @@ -20,7 +20,10 @@ import unittest from testtools import TestCase -from testtools.compat import StringIO +try: + from testtools.compat import StringIO +except ImportError: + from io import StringIO from testtools.content import ( text_content, TracebackContent, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/subunit-1.4.0+git.1584197985.0e9f67b/setup.py new/subunit-1.4.0+git.1627548288.c87ffbd/setup.py --- old/subunit-1.4.0+git.1584197985.0e9f67b/setup.py 2020-03-14 15:59:45.000000000 +0100 +++ new/subunit-1.4.0+git.1627548288.c87ffbd/setup.py 2021-07-29 10:44:48.000000000 +0200 @@ -61,6 +61,7 @@ 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Topic :: Software Development :: Testing', ], keywords='python test streaming', @@ -90,5 +91,6 @@ 'filters/subunit2pyunit', 'filters/tap2subunit', ], + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", **extra )