subunit/Fix-tests-with-testtools-2.5.0.patch

470 lines
18 KiB
Diff
Raw Normal View History

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