Automatically handle subunit v1 or v2 streams.

Change-Id: Ib1ef05a6aa66606d03eca81d50ba84f6e6f41c1b
Reviewed-on: https://review.openstack.org/26688
Reviewed-by: Clark Boylan <clark.boylan@gmail.com>
Approved: Jeremy Stanley <fungi@yuggoth.org>
Reviewed-by: Jeremy Stanley <fungi@yuggoth.org>
Tested-by: Jenkins
This commit is contained in:
Robert Collins 2013-04-11 11:32:07 +12:00 committed by Jenkins
parent 4fcc68924c
commit c8962dea27

View File

@ -40,7 +40,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
""" """
import argparse import argparse
import collections
import datetime import datetime
import io
import traceback import traceback
import unittest import unittest
from xml.sax import saxutils from xml.sax import saxutils
@ -689,32 +691,53 @@ class HtmlOutput(unittest.TestResult):
super(HtmlOutput, self).startTestRun() super(HtmlOutput, self).startTestRun()
class FileAccumulator(testtools.StreamResult):
def __init__(self):
super(FileAccumulator, self).__init__()
self.route_codes = collections.defaultdict(io.BytesIO)
def status(self, **kwargs):
if kwargs.get('file_name') != 'stdout':
return
file_bytes = kwargs.get('file_bytes')
if not file_bytes:
return
route_code = kwargs.get('route_code')
stream = self.route_codes[route_code]
stream.write(file_bytes)
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("subunit_file", parser.add_argument("subunit_file",
help="Path to input subunit file.") help="Path to input subunit file.")
parser.add_argument("html_file", parser.add_argument("html_file",
help="Path to output html file.") help="Path to output html file.")
parser.add_argument("-2", "--subunitv2", action="store_true",
help="Input log file is in subunit version 2 format.")
args = parser.parse_args() args = parser.parse_args()
result = HtmlOutput(args.html_file) html_result = HtmlOutput(args.html_file)
stream = open(args.subunit_file, 'rb') stream = open(args.subunit_file, 'rb')
if args.subunitv2:
try: # Feed the subunit stream through both a V1 and V2 parser.
# Use subunit v2 if the library supports it. # Depends on having the v2 capable libraries installed.
# NB: This trivial config will not passthrough non-test output # First V2.
# - a difference to subunit v1's default. # Non-v2 content and captured non-test output will be presented as file
suite = subunit.ByteStreamToStreamResult( # segments called stdout.
stream, non_subunit_name='stdout') suite = subunit.ByteStreamToStreamResult(stream, non_subunit_name='stdout')
result = testtools.StreamToExtendedDecorator(result) # The HTML output code is in legacy mode.
except AttributeError: result = testtools.StreamToExtendedDecorator(html_result)
suite = subunit.ProtocolTestCase(stream) # Divert non-test output
else: accumulator = FileAccumulator()
suite = subunit.ProtocolTestCase(stream) result = testtools.StreamResultRouter(result)
result.add_rule(accumulator, 'test_id', test_id=None)
result.startTestRun() result.startTestRun()
suite.run(result) suite.run(result)
# Now reprocess any found stdout content as V1 subunit
for bytes_io in accumulator.route_codes.values():
bytes_io.seek(0)
suite = subunit.ProtocolTestCase(bytes_io)
suite.run(html_result)
result.stopTestRun() result.stopTestRun()