From 3878956112b6317d986d536df0b971a24841e115 Mon Sep 17 00:00:00 2001 From: starlet-dx <15929766099@163.com> Date: Thu, 7 Jul 2022 19:28:08 +0800 Subject: [PATCH] Resolve the compilation fails, due to python-testtools update to 2.5.0 --- Fix-tests-with-testtools-2.5.0.patch | 469 +++++++++++++++++++++++++++ subunit.spec | 6 +- 2 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 Fix-tests-with-testtools-2.5.0.patch diff --git a/Fix-tests-with-testtools-2.5.0.patch b/Fix-tests-with-testtools-2.5.0.patch new file mode 100644 index 0000000..86a7688 --- /dev/null +++ b/Fix-tests-with-testtools-2.5.0.patch @@ -0,0 +1,469 @@ +From 64970adcf1a324443d2a3bfa3b152d90561906af Mon Sep 17 00:00:00 2001 +From: starlet-dx <15929766099@163.com> +Date: Thu, 7 Jul 2022 17:27:16 +0800 +Subject: [PATCH 1/1] Fix tests with testtools 2.5.0 + +--- + python/subunit/__init__.py | 8 +- + python/subunit/details.py | 6 +- + python/subunit/tests/__init__.py | 1 + + python/subunit/tests/test_chunked.py | 6 +- + python/subunit/tests/test_details.py | 6 +- + python/subunit/tests/test_subunit_filter.py | 6 +- + python/subunit/tests/test_subunit_stats.py | 6 +- + python/subunit/tests/test_test_protocol.py | 211 ++++++++++++-------- + python/subunit/tests/test_test_results.py | 5 +- + 9 files changed, 165 insertions(+), 90 deletions(-) + +diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py +index 17a970a..f9321e0 100644 +--- a/python/subunit/__init__.py ++++ b/python/subunit/__init__.py +@@ -129,7 +129,11 @@ except ImportError: + 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 @@ class TestProtocolClient(testresult.TestResult): + 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)) +diff --git a/python/subunit/details.py b/python/subunit/details.py +index 9e5e005..5105580 100644 +--- a/python/subunit/details.py ++++ b/python/subunit/details.py +@@ -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 --git a/python/subunit/tests/__init__.py b/python/subunit/tests/__init__.py +index c6599f7..4c8b2ae 100644 +--- a/python/subunit/tests/__init__.py ++++ b/python/subunit/tests/__init__.py +@@ -23,6 +23,7 @@ from testscenarios import generate_scenarios + # 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 --git a/python/subunit/tests/test_chunked.py b/python/subunit/tests/test_chunked.py +index 5100b32..46cf150 100644 +--- a/python/subunit/tests/test_chunked.py ++++ b/python/subunit/tests/test_chunked.py +@@ -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 --git a/python/subunit/tests/test_details.py b/python/subunit/tests/test_details.py +index 8605c5a..f3c70d2 100644 +--- a/python/subunit/tests/test_details.py ++++ b/python/subunit/tests/test_details.py +@@ -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 --git a/python/subunit/tests/test_subunit_filter.py b/python/subunit/tests/test_subunit_filter.py +index 95aea36..baef3f6 100644 +--- a/python/subunit/tests/test_subunit_filter.py ++++ b/python/subunit/tests/test_subunit_filter.py +@@ -24,7 +24,11 @@ from subunit import iso8601 + 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 --git a/python/subunit/tests/test_subunit_stats.py b/python/subunit/tests/test_subunit_stats.py +index 7c5e42d..9faf24d 100644 +--- a/python/subunit/tests/test_subunit_stats.py ++++ b/python/subunit/tests/test_subunit_stats.py +@@ -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 --git a/python/subunit/tests/test_test_protocol.py b/python/subunit/tests/test_test_protocol.py +index 7427b12..70e3564 100644 +--- a/python/subunit/tests/test_test_protocol.py ++++ b/python/subunit/tests/test_test_protocol.py +@@ -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 @@ except ImportError: + 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 @@ class TestHelpers(TestCase): + 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 @@ class TestHelpers(TestCase): + 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 @@ class TestTestProtocolServerPipe(unittest.TestCase): + 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 @@ class TestRemotedTestCase(unittest.TestCase): + "'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 @@ class TestIsolatedTestSuite(TestCase): + 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 @@ class TestTestProtocolClient(TestCase): + """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 --git a/python/subunit/tests/test_test_results.py b/python/subunit/tests/test_test_results.py +index 44f95b3..add30bb 100644 +--- a/python/subunit/tests/test_test_results.py ++++ b/python/subunit/tests/test_test_results.py +@@ -20,7 +20,10 @@ import sys + 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, +-- +2.30.0 + diff --git a/subunit.spec b/subunit.spec index 4ad4151..d677420 100644 --- a/subunit.spec +++ b/subunit.spec @@ -1,6 +1,6 @@ Name: subunit Version: 1.4.0 -Release: 1 +Release: 2 Summary: C bindings for subunit License: ASL 2.0 or BSD URL: https://launchpad.net/subunit @@ -8,6 +8,7 @@ Source0: https://launchpad.net/subunit/trunk/%{version}/+download/%{ Patch0: %{name}-unbundle-iso8601.patch Patch1: %{name}-decode-binary-to-unicode.patch Patch2: 0001-port-to-python-iso8601-0.1.14.patch +Patch3: Fix-tests-with-testtools-2.5.0.patch BuildRequires: check-devel cppunit-devel gcc-c++ libtool perl-generators make BuildRequires: perl(ExtUtils::MakeMaker) pkgconfig BuildRequires: python3-devel python3-docutils python3-extras python3-fixtures python3-iso8601 @@ -242,6 +243,9 @@ popd %exclude %{_bindir}/%{name}-diff %changelog +* Thu Jul 07 2022 yaoxin - 1.4.0-2 +- Resolve the compilation fails, due to python-testtools update to 2.5.0 + * Mon Jul 12 2021 huangtianhua - 1.4.0-1 - Upgrade to 1.4.0 and drop the patches which have been upstreamed