11
22import os
33import sys
4+ import datetime
45import time
56import traceback
67import six
1617# http://stackoverflow.com/questions/1707890/fast-way-to-filter-illegal-xml-unicode-chars-in-python
1718
1819_illegal_unichrs = [
19- (0x00 , 0x08 ), (0x0B , 0x0C ), (0x0E , 0x1F ),
20- (0x7F , 0x84 ), (0x86 , 0x9F ),
20+ (0x00 , 0x08 ), (0x0B , 0x0C ), (0x0E , 0x1F ),
21+ (0x7F , 0x84 ), (0x86 , 0x9F ),
2122 (0xFDD0 , 0xFDDF ), (0xFFFE , 0xFFFF ),
22- ]
23- if sys .maxunicode >= 0x10000 : # not narrow build
23+ ]
24+ if sys .maxunicode >= 0x10000 : # not narrow build
2425 _illegal_unichrs .extend ([
25- (0x1FFFE , 0x1FFFF ), (0x2FFFE , 0x2FFFF ),
26- (0x3FFFE , 0x3FFFF ), (0x4FFFE , 0x4FFFF ),
27- (0x5FFFE , 0x5FFFF ), (0x6FFFE , 0x6FFFF ),
28- (0x7FFFE , 0x7FFFF ), (0x8FFFE , 0x8FFFF ),
29- (0x9FFFE , 0x9FFFF ), (0xAFFFE , 0xAFFFF ),
30- (0xBFFFE , 0xBFFFF ), (0xCFFFE , 0xCFFFF ),
31- (0xDFFFE , 0xDFFFF ), (0xEFFFE , 0xEFFFF ),
26+ (0x1FFFE , 0x1FFFF ), (0x2FFFE , 0x2FFFF ),
27+ (0x3FFFE , 0x3FFFF ), (0x4FFFE , 0x4FFFF ),
28+ (0x5FFFE , 0x5FFFF ), (0x6FFFE , 0x6FFFF ),
29+ (0x7FFFE , 0x7FFFF ), (0x8FFFE , 0x8FFFF ),
30+ (0x9FFFE , 0x9FFFF ), (0xAFFFE , 0xAFFFF ),
31+ (0xBFFFE , 0xBFFFF ), (0xCFFFE , 0xCFFFF ),
32+ (0xDFFFE , 0xDFFFF ), (0xEFFFE , 0xEFFFF ),
3233 (0xFFFFE , 0xFFFFF ), (0x10FFFE , 0x10FFFF ),
33- ])
34+ ])
3435
3536_illegal_ranges = [
3637 "%s-%s" % (six .unichr (low ), six .unichr (high ))
3738 for (low , high ) in _illegal_unichrs
3839]
3940
40- INVALID_XML_1_0_UNICODE_RE = re .compile (u'[%s]' % u'' .join (_illegal_ranges ))
41+ INVALID_XML_1_0_UNICODE_RE = re .compile (u'[%s]' % u'' .join (_illegal_ranges ))
4142
4243
4344STDOUT_LINE = '\n Stdout:\n %s'
@@ -94,6 +95,7 @@ def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=
9495 self .test_result = test_result
9596 self .outcome = outcome
9697 self .elapsed_time = 0
98+ self .timestamp = datetime .datetime .min .replace (microsecond = 0 ).isoformat ()
9799 if err :
98100 if self .outcome != _TestInfo .SKIP :
99101 self .test_exception_name = safe_unicode (err [0 ].__name__ )
@@ -124,6 +126,8 @@ def test_finished(self):
124126 """
125127 self .elapsed_time = \
126128 self .test_result .stop_time - self .test_result .start_time
129+ timestamp = datetime .datetime .fromtimestamp (self .test_result .stop_time )
130+ self .timestamp = timestamp .replace (microsecond = 0 ).isoformat ()
127131
128132 def get_description (self ):
129133 """
@@ -343,6 +347,10 @@ def _report_testsuite(suite_name, tests, xml_document, parentElement,
343347 testsuite .setAttribute (
344348 'time' , '%.3f' % sum (map (lambda e : e .elapsed_time , tests ))
345349 )
350+ if tests :
351+ testsuite .setAttribute (
352+ 'timestamp' , max (map (lambda e : e .timestamp , tests ))
353+ )
346354 failures = filter (lambda e : e .outcome == e .FAILURE , tests )
347355 testsuite .setAttribute ('failures' , str (len (list (failures ))))
348356
@@ -351,7 +359,7 @@ def _report_testsuite(suite_name, tests, xml_document, parentElement,
351359
352360 skips = filter (lambda e : e .outcome == _TestInfo .SKIP , tests )
353361 testsuite .setAttribute ('skipped' , str (len (list (skips ))))
354-
362+
355363 _XMLTestResult ._report_testsuite_properties (
356364 testsuite , xml_document , properties )
357365
@@ -420,6 +428,7 @@ def _report_testcase(test_result, xml_testsuite, xml_document):
420428 'name' , _XMLTestResult ._test_method_name (test_result .test_id )
421429 )
422430 testcase .setAttribute ('time' , '%.3f' % test_result .elapsed_time )
431+ testcase .setAttribute ('timestamp' , test_result .timestamp )
423432
424433 if (test_result .outcome != test_result .SUCCESS ):
425434 elem_name = ('failure' , 'error' , 'skipped' )[test_result .outcome - 1 ]
0 commit comments