diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index ff31ea939..e7a94ff40 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -4,6 +4,7 @@ __all__ = [ "SyncTestCase", "AsyncTestCase", "AsyncBrokenTestCase", + "TrialTestCase", "flush_logged_errors", "skip", @@ -11,6 +12,7 @@ __all__ = [ ] import os, random, struct +import six import tempfile from tempfile import mktemp from functools import partial @@ -57,6 +59,7 @@ from twisted.internet.interfaces import ( IReactorSocket, ) from twisted.internet.endpoints import AdoptedStreamServerEndpoint +from twisted.trial.unittest import TestCase as _TrialTestCase from allmydata import uri from allmydata.interfaces import IMutableFileNode, IImmutableFileNode,\ @@ -1242,3 +1245,29 @@ class AsyncBrokenTestCase(_TestCaseMixin, TestCase): run_tests_with = EliotLoggedRunTest.make_factory( AsynchronousDeferredRunTestForBrokenTwisted.make_factory(timeout=60.0), ) + + +class TrialTestCase(_TrialTestCase): + """ + A twisted.trial.unittest.TestCaes with Tahoe required fixes + applied. Currently these are: + + - ensure that .fail() passes a bytes msg on Python2 + """ + + def fail(self, msg): + """ + Ensure our msg is a native string on Python2. If it was Unicode, + we encode it as utf8 and hope for the best. On Python3 we take + no action. + + This is necessary because Twisted passes the 'msg' argument + along to the constructor of an exception; on Python2, + Exception will accept a `unicode` instance but will fail if + you try to turn that Exception instance into a string. + """ + + if six.PY2: + if isinstance(msg, six.text_type): + return super(self, TrialTestCase).fail(msg.encode("utf8")) + return super(self, TrialTestCase).fail(msg) diff --git a/src/allmydata/test/web/common.py b/src/allmydata/test/web/common.py index 15743bb92..871cdeb26 100644 --- a/src/allmydata/test/web/common.py +++ b/src/allmydata/test/web/common.py @@ -28,9 +28,8 @@ def assert_soup_has_tag_with_attributes(testcase, soup, tag_name, attrs): for tag in tags: if all(v in tag.attrs.get(k, []) for k, v in attrs.items()): return # we found every attr in this tag; done - # seems like exceptions can't support unicode text in python2?? testcase.fail( - "No <{}> tags contain attributes: {}".format(tag_name, attrs) + u"No <{}> tags contain attributes: {}".format(tag_name, attrs) ) @@ -72,9 +71,8 @@ def assert_soup_has_tag_with_content(testcase, soup, tag_name, content): if content in _normalized_contents(tag): return - # seems like exceptions can't support unicode text in python2?? testcase.fail( - "No <{}> tag contains the text '{}'".format(tag_name, content).encode('utf8') + u"No <{}> tag contains the text '{}'".format(tag_name, content) ) diff --git a/src/allmydata/test/web/test_web.py b/src/allmydata/test/web/test_web.py index 1e36b6a21..191ffbdef 100644 --- a/src/allmydata/test/web/test_web.py +++ b/src/allmydata/test/web/test_web.py @@ -8,7 +8,6 @@ import mock from bs4 import BeautifulSoup from twisted.application import service -from twisted.trial import unittest from twisted.internet import defer from twisted.internet.defer import inlineCallbacks, returnValue, maybeDeferred from twisted.internet.task import Clock @@ -50,6 +49,7 @@ from ..common import ( WebErrorMixin, make_mutable_file_uri, create_mutable_filenode, + TrialTestCase, ) from .common import ( assert_soup_has_favicon, @@ -681,7 +681,7 @@ class WebMixin(testutil.TimezoneMixin): -class MultiFormatPageTests(unittest.TestCase): +class MultiFormatPageTests(TrialTestCase): """ Tests for ``MultiFormatPage``. """ @@ -790,7 +790,7 @@ class MultiFormatPageTests(unittest.TestCase): -class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixin, unittest.TestCase): +class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixin, TrialTestCase): maxDiff = None def test_create(self):