def test_trace_with_stuck_inprogress(self): output = io.BytesIO() stream = StreamResultToBytes(output) stream.startTestRun() stream.status(test_id='test_passes', test_status='inprogress', timestamp=dt.now(UTC)) stream.status(test_id='test_segfault', test_status='inprogress', timestamp=dt.now(UTC)) stream.status(test_id='test_passes', test_status='success', timestamp=dt.now(UTC)) stream.stopTestRun() output.seek(0) # capture stderr for test stderr = io.StringIO() sys_err = sys.stderr sys.stderr = stderr def restore_stderr(): sys.stderr = sys_err self.addCleanup(restore_stderr) stdin = io.TextIOWrapper(io.BufferedReader(output)) returncode = subunit_trace.trace(stdin, sys.stdout) self.assertEqual(1, returncode) stderr.seek(0) expected = """ The following tests exited without returning a status and likely segfaulted or crashed Python: \t* test_segfault """ self.assertEqual(stderr.read(), expected)
class SubunitContext(): """Context manager for writing subunit results.""" def __init__(self, output_path): self.output_path = output_path def __enter__(self): self.output_stream = open(self.output_path, "wb+") self.output = StreamResultToBytes(self.output_stream) self.output.startTestRun() return self.output def __exit__(self, *args, **kwargs): self.output.stopTestRun() self.output_stream.close()
def test_smoke(self): output = os.path.join(self.useFixture(TempDir()).path, 'output') stdin = io.BytesIO() stdout = io.StringIO() writer = StreamResultToBytes(stdin) writer.startTestRun() writer.status( 'foo', 'success', set(['tag']), file_name='fred', file_bytes=b'abcdefg', eof=True, mime_type='text/plain') writer.stopTestRun() stdin.seek(0) _to_disk.to_disk(['-d', output], stdin=stdin, stdout=stdout) self.expectThat( os.path.join(output, 'foo/test.json'), FileContains( '{"details": ["fred"], "id": "foo", "start": null, ' '"status": "success", "stop": null, "tags": ["tag"]}')) self.expectThat( os.path.join(output, 'foo/fred'), FileContains('abcdefg'))
def test_smoke(self): output = os.path.join(self.useFixture(TempDir()).path, 'output') stdin = io.BytesIO() stdout = io.StringIO() writer = StreamResultToBytes(stdin) writer.startTestRun() writer.status('foo', 'success', set(['tag']), file_name='fred', file_bytes=b'abcdefg', eof=True, mime_type='text/plain') writer.stopTestRun() stdin.seek(0) _to_disk.to_disk(['-d', output], stdin=stdin, stdout=stdout) self.expectThat( os.path.join(output, 'foo/test.json'), FileContains( '{"details": ["fred"], "id": "foo", "start": null, ' '"status": "success", "stop": null, "tags": ["tag"]}')) self.expectThat(os.path.join(output, 'foo/fred'), FileContains('abcdefg'))
else: tests = [] if not args.subunit: # Human readable test output import testtools, unittest #output = testtools.StreamToExtendedDecorator( # unittest.TextTestResult( # unittest.runner._WritelnDecorator(sys.stdout), True, 2)) output = testtools.StreamToExtendedDecorator( testtools.TextTestResult(sys.stdout)) else: from subunit.v2 import StreamResultToBytes output = StreamResultToBytes(sys.stdout) output.startTestRun() # Start up a local HTTP server which serves the files to the browser and # collects the test results. # ----------------------------------------------------------------------------- import SimpleHTTPServer import SocketServer import threading import cgi import simplejson class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): STATUS = {0:'success', 1:'fail', 2:'fail', 3:'skip'} # Make the HTTP requests be quiet def log_message(self, format, *args):
def enable(filename=None): file_ = open_file(filename) streamresult = StreamResultToBytes(file_) streamresult.startTestRun() real_stdout = sys.stdout real_stderr = sys.stderr @before.each_scenario def before_scenario(scenario): # create redirects for stdout and stderr scenario.stdout = StringIO() scenario.stderr = StringIO() try: test_tags = scenario.tags except AttributeError: test_tags = () streamresult.status(test_id=get_test_id(scenario), test_status='inprogress', test_tags=test_tags, timestamp=now()) @before.step_output def capture_output(step): # only consider steps for background if not step.scenario: return sys.stdout = step.scenario.stdout sys.stderr = step.scenario.stderr @after.step_output def uncapture_output(step): sys.stdout = real_stdout sys.stderr = real_stderr @after.each_scenario def after_scenario(scenario): streamresult.status( test_id=get_test_id(scenario), file_name='stdout', file_bytes=scenario.stdout.getvalue().encode('utf-8'), mime_type='text/plain; charset=utf8', eof=True) streamresult.status( test_id=get_test_id(scenario), file_name='stderr', file_bytes=scenario.stderr.getvalue().encode('utf-8'), mime_type='text/plain; charset=utf8', eof=True) if scenario.passed: streamresult.status(test_id=get_test_id(scenario), test_status='success', timestamp=now()) else: streamresult.status(test_id=get_test_id(scenario), test_status='fail', timestamp=now()) @after.each_step def after_step(step): # only consider steps for background if not step.scenario: return test_id = get_test_id(step.scenario) if step.passed: marker = u'✔' elif not step.defined_at: marker = u'?' elif step.failed: marker = u'❌' try: streamresult.status( test_id=test_id, file_name='traceback', file_bytes=step.why.traceback.encode('utf-8'), mime_type='text/plain; charset=utf8') except AttributeError: pass elif not step.ran: marker = u' ' else: raise AssertionError("Internal error") steps = u'{marker} {sentence}\n'.format(marker=marker, sentence=step.sentence) streamresult.status(test_id=test_id, file_name='steps', file_bytes=steps.encode('utf-8'), mime_type='text/plain; charset=utf8') @after.all def after_all(total): streamresult.stopTestRun() close_file(file_)
def take_action(self, args): # Setup where the output stream must go if args.output_file == '-': output_stream = sys.stdout else: output_stream = open(args.output_file, 'wb') # Create the output stream output = StreamResultToBytes(output_stream) # Create the test run output.startTestRun() if args.playbook is not None: playbooks = args.playbook results = (models.TaskResult().query.join(models.Task).filter( models.TaskResult.task_id == models.Task.id).filter( models.Task.playbook_id.in_(playbooks))) else: results = models.TaskResult().query.all() for result in results: # Generate a fixed length identifier for the task test_id = utils.generate_identifier(result) # Assign the test_status value if result.status in ('failed', 'unreachable'): if result.ignore_errors is False: test_status = 'xfail' else: test_status = 'fail' elif result.status == 'skipped': test_status = 'skip' else: test_status = 'success' # Determine the play file path if result.task.playbook and result.task.playbook.path: playbook_path = result.task.playbook.path else: playbook_path = '' # Determine the task file path if result.task.file and result.task.file.path: task_path = result.task.file.path else: task_path = '' # Assign the file_bytes value test_data = { 'host': result.host.name, 'playbook_id': result.task.playbook.id, 'playbook_path': playbook_path, 'play_name': result.task.play.name, 'task_action': result.task.action, 'task_action_lineno': result.task.lineno, 'task_id': result.task.id, 'task_name': result.task.name, 'task_path': task_path } file_bytes = encodeutils.safe_encode(jsonutils.dumps(test_data)) # Assign the start_time and stop_time value # The timestamp needs to be an epoch, so we need # to convert it. start_time = datetime.datetime.fromtimestamp( float(result.time_start.strftime('%s'))).replace( tzinfo=iso8601.UTC) end_time = datetime.datetime.fromtimestamp( float(result.time_end.strftime('%s'))).replace( tzinfo=iso8601.UTC) # Output the start of the event output.status(test_id=test_id, timestamp=start_time) # Output the end of the event output.status(test_id=test_id, test_status=test_status, test_tags=None, runnable=False, file_name=test_id, file_bytes=file_bytes, timestamp=end_time, eof=True, mime_type='text/plain; charset=UTF8') output.stopTestRun()
def enable(filename=None): file_ = open_file(filename) streamresult = StreamResultToBytes(file_) streamresult.startTestRun() real_stdout = sys.stdout real_stderr = sys.stderr @before.each_scenario def before_scenario(scenario): # create redirects for stdout and stderr scenario.stdout = StringIO() scenario.stderr = StringIO() try: test_tags = scenario.tags except AttributeError: test_tags = () streamresult.status(test_id=get_test_id(scenario), test_status='inprogress', test_tags=test_tags, timestamp=now()) @before.step_output def capture_output(step): # only consider steps for background if not step.scenario: return sys.stdout = step.scenario.stdout sys.stderr = step.scenario.stderr @after.step_output def uncapture_output(step): sys.stdout = real_stdout sys.stderr = real_stderr @after.each_scenario def after_scenario(scenario): streamresult.status(test_id=get_test_id(scenario), file_name='stdout', file_bytes=scenario.stdout.getvalue().encode('utf-8'), mime_type='text/plain; charset=utf8', eof=True) streamresult.status(test_id=get_test_id(scenario), file_name='stderr', file_bytes=scenario.stderr.getvalue().encode('utf-8'), mime_type='text/plain; charset=utf8', eof=True) if scenario.passed: streamresult.status(test_id=get_test_id(scenario), test_status='success', timestamp=now()) else: streamresult.status(test_id=get_test_id(scenario), test_status='fail', timestamp=now()) @after.each_step def after_step(step): # only consider steps for background if not step.scenario: return test_id = get_test_id(step.scenario) if step.passed: marker = u'✔' elif not step.defined_at: marker = u'?' elif step.failed: marker = u'❌' try: streamresult.status(test_id=test_id, file_name='traceback', file_bytes=step.why.traceback.encode('utf-8'), mime_type='text/plain; charset=utf8') except AttributeError: pass elif not step.ran: marker = u' ' else: raise AssertionError("Internal error") steps = u'{marker} {sentence}\n'.format( marker=marker, sentence=step.sentence) streamresult.status(test_id=test_id, file_name='steps', file_bytes=steps.encode('utf-8'), mime_type='text/plain; charset=utf8') @after.all def after_all(total): streamresult.stopTestRun() close_file(file_)
def take_action(self, args): # Setup where the output stream must go if args.output_file == '-': output_stream = sys.stdout else: output_stream = open(args.output_file, 'wb') # Create the output stream output = StreamResultToBytes(output_stream) # Create the test run output.startTestRun() if args.playbook is not None: playbooks = args.playbook results = (models.TaskResult().query .join(models.Task) .filter(models.TaskResult.task_id == models.Task.id) .filter(models.Task.playbook_id.in_(playbooks))) else: results = models.TaskResult().query.all() for result in results: # Generate a fixed length identifier for the task test_id = utils.generate_identifier(result) # Assign the test_status value if result.status in ('failed', 'unreachable'): if result.ignore_errors is False: test_status = 'xfail' else: test_status = 'fail' elif result.status == 'skipped': test_status = 'skip' else: test_status = 'success' # Determine the play file path if result.task.playbook and result.task.playbook.path: playbook_path = result.task.playbook.path else: playbook_path = '' # Determine the task file path if result.task.file and result.task.file.path: task_path = result.task.file.path else: task_path = '' # Assign the file_bytes value test_data = { 'host': result.host.name, 'playbook_id': result.task.playbook.id, 'playbook_path': playbook_path, 'play_name': result.task.play.name, 'task_action': result.task.action, 'task_action_lineno': result.task.lineno, 'task_id': result.task.id, 'task_name': result.task.name, 'task_path': task_path } file_bytes = encodeutils.safe_encode(jsonutils.dumps(test_data)) # Assign the start_time and stop_time value # The timestamp needs to be an epoch, so we need # to convert it. start_time = datetime.datetime.fromtimestamp( float(result.time_start.strftime('%s')) ).replace(tzinfo=iso8601.UTC) end_time = datetime.datetime.fromtimestamp( float(result.time_end.strftime('%s')) ).replace(tzinfo=iso8601.UTC) # Output the start of the event output.status( test_id=test_id, timestamp=start_time ) # Output the end of the event output.status( test_id=test_id, test_status=test_status, test_tags=None, runnable=False, file_name=test_id, file_bytes=file_bytes, timestamp=end_time, eof=True, mime_type='text/plain; charset=UTF8' ) output.stopTestRun()