diff --git a/os_testr/subunit2html.py b/os_testr/subunit2html.py
index 6711025..e151dca 100755
--- a/os_testr/subunit2html.py
+++ b/os_testr/subunit2html.py
@@ -53,6 +53,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
+import codecs
import collections
import datetime
import io
@@ -680,9 +681,16 @@ class HtmlOutput(testtools.TestResult):
tmpl = (has_output and TemplateData.REPORT_TEST_WITH_OUTPUT_TMPL or
TemplateData.REPORT_TEST_NO_OUTPUT_TMPL)
+ try:
+ output = saxutils.escape(o + e)
+ # We expect to get this exception in python2.
+ except UnicodeDecodeError:
+ e = codecs.decode(e, 'utf-8')
+ output = saxutils.escape(o + e)
+
script = TemplateData.REPORT_TEST_OUTPUT_TMPL % dict(
id=tid,
- output=saxutils.escape(o + e),
+ output=output,
)
row = tmpl % dict(
diff --git a/os_testr/tests/test_subunit2html.py b/os_testr/tests/test_subunit2html.py
index 57e92bb..8bd6b8f 100644
--- a/os_testr/tests/test_subunit2html.py
+++ b/os_testr/tests/test_subunit2html.py
@@ -76,3 +76,17 @@ class TestSubunit2html(base.TestCase):
'example.path.to.test8']
for i, r in enumerate(sorted_result):
self.assertEqual(expected_class_order[i], str(r[0]))
+
+ @data(RemotedTestCase, PlaceHolder)
+ def test_generate_report_with_no_ascii_characters(self, test_cls):
+ # The test examines a case where an error containing no ascii
+ # characters is received.
+ test = test_cls(u'example.path.to.test1.method')
+ try:
+ raise Exception('\xe2\x82\xa5')
+ except Exception:
+ err = sys.exc_info()
+ obj = subunit2html.HtmlOutput()
+ # Add failure that contains no ascii characters
+ obj.addFailure(test, err)
+ obj._generate_report()