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()