def test_numbers(self): result = subunit.StreamResultToBytes(BytesIO()) packet = [] self.assertRaises(Exception, result._write_number, -1, packet) self.assertEqual([], packet) result._write_number(0, packet) self.assertEqual([b'\x00'], packet) del packet[:] result._write_number(63, packet) self.assertEqual([b'\x3f'], packet) del packet[:] result._write_number(64, packet) self.assertEqual([b'\x40\x40'], packet) del packet[:] result._write_number(16383, packet) self.assertEqual([b'\x7f\xff'], packet) del packet[:] result._write_number(16384, packet) self.assertEqual([b'\x80\x40', b'\x00'], packet) del packet[:] result._write_number(4194303, packet) self.assertEqual([b'\xbf\xff', b'\xff'], packet) del packet[:] result._write_number(4194304, packet) self.assertEqual([b'\xc0\x40\x00\x00'], packet) del packet[:] result._write_number(1073741823, packet) self.assertEqual([b'\xff\xff\xff\xff'], packet) del packet[:] self.assertRaises(Exception, result._write_number, 1073741824, packet) self.assertEqual([], packet)
def test_add_tag(self): # Literal values to avoid set sort-order dependencies. Python code show # derivation. # reference = BytesIO() # stream = subunit.StreamResultToBytes(reference) # stream.status( # test_id='test', test_status='inprogress', test_tags=set(['quux', 'foo'])) # stream.status( # test_id='test', test_status='success', test_tags=set(['bar', 'quux', 'foo'])) reference = [ b'\xb3)\x82\x17\x04test\x02\x04quux\x03foo\x05\x97n\x86\xb3)' b'\x83\x1b\x04test\x03\x03bar\x04quux\x03fooqn\xab)', b'\xb3)\x82\x17\x04test\x02\x04quux\x03foo\x05\x97n\x86\xb3)' b'\x83\x1b\x04test\x03\x04quux\x03foo\x03bar\xaf\xbd\x9d\xd6', b'\xb3)\x82\x17\x04test\x02\x04quux\x03foo\x05\x97n\x86\xb3)' b'\x83\x1b\x04test\x03\x04quux\x03bar\x03foo\x03\x04b\r', b'\xb3)\x82\x17\x04test\x02\x04quux\x03foo\x05\x97n\x86\xb3)' b'\x83\x1b\x04test\x03\x03bar\x03foo\x04quux\xd2\x18\x1bC', b'\xb3)\x82\x17\x04test\x02\x03foo\x04quux\xa6\xe1\xde\xec\xb3)' b'\x83\x1b\x04test\x03\x03foo\x04quux\x03bar\x08\xc2X\x83', b'\xb3)\x82\x17\x04test\x02\x03foo\x04quux\xa6\xe1\xde\xec\xb3)' b'\x83\x1b\x04test\x03\x03bar\x03foo\x04quux\xd2\x18\x1bC', b'\xb3)\x82\x17\x04test\x02\x03foo\x04quux\xa6\xe1\xde\xec\xb3)' b'\x83\x1b\x04test\x03\x03foo\x03bar\x04quux:\x05e\x80', ] stream = subunit.StreamResultToBytes(self.original) stream.status( test_id='test', test_status='inprogress', test_tags=set(['foo'])) stream.status( test_id='test', test_status='success', test_tags=set(['foo', 'bar'])) self.original.seek(0) self.assertEqual( 0, subunit.tag_stream(self.original, self.filtered, ["quux"])) self.assertThat(reference, Contains(self.filtered.getvalue()))
def test_process_exit_code_nonzero_causes_synthetic_error_test(self): if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='success') subunit_bytes = buffer.getvalue() else: subunit_bytes = b'test: foo\nsuccess: foo\n' ui, cmd = self.get_test_ui_and_cmd(options=[ ('quiet', True), ], proc_outputs=[subunit_bytes], proc_results=[2]) # 2 is non-zero, and non-zero triggers the behaviour of exiting # with 1 - but we want to see that it doesn't pass-through the # value literally. cmd.repository_factory = memory.RepositoryFactory() self.setup_repo(cmd, ui) self.set_config('[DEFAULT]\ntest_command=foo\n') result = cmd.execute() self.assertEqual(1, result) run = cmd.repository_factory.repos[ui.here].get_test_run(1) self.assertEqual([Wildcard, 'fail'], [test['status'] for test in run._tests])
def test_load_timed_run(self): if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) time = datetime(2011, 1, 1, 0, 0, 1, tzinfo=iso8601.Utc()) stream.status(test_id='foo', test_status='inprogress', timestamp=time) stream.status(test_id='foo', test_status='success', timestamp=time + timedelta(seconds=2)) timed_bytes = buffer.getvalue() else: timed_bytes = _b('time: 2011-01-01 00:00:01.000000Z\n' 'test: foo\n' 'time: 2011-01-01 00:00:03.000000Z\n' 'success: foo\n' 'time: 2011-01-01 00:00:06.000000Z\n') ui = UI([('subunit', timed_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() cmd.repository_factory.initialise(ui.here) self.assertEqual(0, cmd.execute()) # Note that the time here is 2.0, the difference between first and # second time: directives. That's because 'load' uses a # ThreadsafeForwardingResult (via ConcurrentTestSuite) that suppresses # time information not involved in the start or stop of a test. self.assertEqual( [('summary', True, 1, None, 2.0, None, [('id', 0, None)])], ui.outputs[1:])
def _append_return_code_as_test(self): if self.done is True: return self.source = BytesIO() returncode = self.proc.wait() if returncode != 0: if self.lastoutput != LINEFEED: # Subunit V1 is line orientated, it has to start on a fresh # line. V2 needs to start on any fresh utf8 character border # - which is not guaranteed in an arbitrary stream endpoint, so # injecting a \n gives us such a guarantee. self.source.write(_b('\n')) if v2_avail: stream = subunit.StreamResultToBytes(self.source) stream.status(test_id='process-returncode', test_status='fail', file_name='traceback', mime_type='text/plain;charset=utf8', file_bytes=('returncode %d' % returncode).encode('utf8')) else: self.source.write( _b('test: process-returncode\n' 'failure: process-returncode [\n' ' returncode %d\n' ']\n' % returncode)) self.source.seek(0) self.done = True
def test_calls_list_tests(self): ui, cmd = self.get_test_ui_and_cmd(args=('--', 'bar', 'quux')) cmd.repository_factory = memory.RepositoryFactory() if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='returned', test_status='exists') stream.status(test_id='values', test_status='exists') subunit_bytes = buffer.getvalue() else: subunit_bytes = _b('returned\n\nvalues\n') ui.proc_outputs = [subunit_bytes] self.setup_repo(cmd, ui) self.set_config('[DEFAULT]\ntest_command=foo $LISTOPT $IDOPTION\n' 'test_id_option=--load-list $IDFILE\n' 'test_list_option=--list\n') self.assertEqual(0, cmd.execute()) expected_cmd = 'foo --list bar quux' self.assertEqual([ ('values', [('running', expected_cmd)]), ('popen', (expected_cmd, ), { 'shell': True, 'stdout': PIPE, 'stdin': PIPE }), ('communicate', ), ('stream', _b('returned\nvalues\n')), ], ui.outputs)
def __init__(self, failure=True): # Generate a subunit stream stream_buf = io.BytesIO() stream = subunit.StreamResultToBytes(stream_buf) stream.status(test_id='test_a', test_status='inprogress', test_tags=['worker-0']) stream.status(test_id='test_a', test_status='success', test_tags=['worker-0']) stream.status(test_id='test_b', test_status='inprogress', test_tags=['worker-1']) stream.status(test_id='test_b', test_status='success', test_tags=['worker-1']) stream.status(test_id='test_c', test_status='inprogress', test_tags=['worker-0']) stream.status(test_id='test_c', test_status='fail', test_tags=['worker-0']) stream_buf.seek(0) self._content = stream_buf.getvalue() self.id = 2
def test_remove_tag(self): reference = BytesIO() stream = subunit.StreamResultToBytes(reference) stream.status( test_id='test', test_status='inprogress', test_tags=set(['foo'])) stream.status( test_id='test', test_status='success', test_tags=set(['foo'])) stream = subunit.StreamResultToBytes(self.original) stream.status( test_id='test', test_status='inprogress', test_tags=set(['foo'])) stream.status( test_id='test', test_status='success', test_tags=set(['foo', 'bar'])) self.original.seek(0) self.assertEqual( 0, subunit.tag_stream(self.original, self.filtered, ["-bar"])) self.assertEqual(reference.getvalue(), self.filtered.getvalue())
def test_load_new_shows_test_failure_details(self): if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='fail', file_name="traceback", mime_type='text/plain;charset=utf8', file_bytes=b'arg\n') subunit_bytes = buffer.getvalue() else: subunit_bytes = b'test: foo\nfailure: foo [\narg\n]\n' ui = UI([('subunit', subunit_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() cmd.repository_factory.initialise(ui.here) self.assertEqual(1, cmd.execute()) suite = ui.outputs[0][1] self.assertEqual([('results', Wildcard), ('summary', False, 1, None, Wildcard, None, [ ('id', 0, None), ('failures', 1, None) ])], ui.outputs) result = testtools.StreamSummary() result.startTestRun() try: suite.run(result) finally: result.stopTestRun() self.assertEqual(1, result.testsRun) self.assertEqual(1, len(result.errors))
def _subunit_factory(cls, stream): """Return a TestResult attached to the given stream.""" stream_result = _RunnableDecorator(subunit.StreamResultToBytes(stream)) result = testtools.ExtendedToStreamDecorator(stream_result) # Lift our decorating method up so that we can get at it easily. result.setRunnable = stream_result.setRunnable result.startTestRun() return result
def make_result(get_id, output=sys.stdout): serializer = subunit.StreamResultToBytes(output) # By pass user transforms - just forward it all, result = serializer # and interpret everything as success. summary = testtools.StreamSummary() summary.startTestRun() summary.stopTestRun() return result, summary
def test_load_second_run(self): # If there's a previous run in the database, then show information # about the high level differences in the test run: how many more # tests, how many more failures, how much longer it takes. buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) time = datetime(2011, 1, 2, 0, 0, 1, tzinfo=iso8601.Utc()) stream.status(test_id='foo', test_status='inprogress', timestamp=time) stream.status(test_id='foo', test_status='fail', timestamp=time + timedelta(seconds=2)) stream.status(test_id='bar', test_status='inprogress', timestamp=time + timedelta(seconds=4)) stream.status(test_id='bar', test_status='fail', timestamp=time + timedelta(seconds=6)) timed_bytes = buffer.getvalue() ui = UI([('subunit', timed_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() repo = cmd.repository_factory.initialise(ui.here) # XXX: Circumvent the AutoTimingTestResultDecorator so we can get # predictable times, rather than ones based on the system # clock. (Would normally expect to use repo.get_inserter()) inserter = repo._get_inserter(False) # Insert a run with different results. inserter.startTestRun() inserter.status(test_id=self.id(), test_status='inprogress', timestamp=datetime(2011, 1, 1, 0, 0, 1, tzinfo=iso8601.Utc())) inserter.status(test_id=self.id(), test_status='fail', timestamp=datetime(2011, 1, 1, 0, 0, 10, tzinfo=iso8601.Utc())) inserter.stopTestRun() self.assertEqual(1, cmd.execute()) self.assertEqual( [('summary', False, 2, 1, 6.0, -3.0, [('id', 1, None), ('failures', 2, 1)])], ui.outputs[1:])
def test_load_returns_1_on_failed_stream(self): buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='fail') subunit_bytes = buffer.getvalue() ui = UI([('subunit', subunit_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() cmd.repository_factory.initialise(ui.here) self.assertEqual(1, cmd.execute())
def test_route_code_and_file_content(self): content = BytesIO() subunit.StreamResultToBytes(content).status(route_code='0', mime_type='text/plain', file_name='bar', file_bytes=b'foo') self.check_event(content.getvalue(), test_id=None, file_name='bar', route_code='0', mime_type='text/plain', file_bytes=b'foo')
def test_list_tests_parsing(self): buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='returned', test_status='exists') stream.status(test_id='ids', test_status='exists') subunit_bytes = buffer.getvalue() ui, command = self.get_test_ui_and_cmd() ui.proc_outputs = [subunit_bytes] self.set_config( '[DEFAULT]\ntest_command=foo $LISTOPT $IDLIST\ntest_id_list_default=whoo yea\n' 'test_list_option=--list\n') fixture = self.useFixture(command.get_run_command()) self.assertEqual(set(['returned', 'ids']), set(fixture.list_tests()))
def test_load_new_shows_test_failures(self): buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='fail') subunit_bytes = buffer.getvalue() ui = UI([('subunit', subunit_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() cmd.repository_factory.initialise(ui.here) self.assertEqual(1, cmd.execute()) self.assertEqual([('summary', False, 1, None, Wildcard, None, [ ('id', 0, None), ('failures', 1, None) ])], ui.outputs[1:])
def test_load_failure_exposed(self): buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='fail') subunit_bytes = buffer.getvalue() ui, cmd = self.get_test_ui_and_cmd(options=[ ('quiet', True), ], proc_outputs=[subunit_bytes]) cmd.repository_factory = memory.RepositoryFactory() self.setup_repo(cmd, ui) self.set_config('[DEFAULT]\ntest_command=foo\n') result = cmd.execute() cmd.repository_factory.repos[ui.here].get_test_run(1) self.assertEqual(1, result)
def test_returncode_nonzero_fail_appended_to_content(self): proc = ProcessModel(None) proc.stdout.write(self.stdout) proc.stdout.seek(0) proc.returncode = 1 stream = run.ReturnCodeToSubunit(proc) content = accumulate(stream, self.reader) buffer = BytesIO() buffer.write(b'foo\nbar\n') stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='process-returncode', test_status='fail', file_name='traceback', mime_type='text/plain;charset=utf8', file_bytes=b'returncode 1') expected_content = buffer.getvalue() self.assertEqual(expected_content, content)
def test_until_failure(self): ui, cmd = self.get_test_ui_and_cmd(options=[('until_failure', True)]) if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='success') subunit_bytes1 = buffer.getvalue() buffer.seek(0) buffer.truncate() stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='fail') subunit_bytes2 = buffer.getvalue() else: subunit_bytes1 = b'test: foo\nsuccess: foo\n' subunit_bytes2 = b'test: foo\nfailure: foo\n' ui.proc_outputs = [ subunit_bytes1, # stream one, works subunit_bytes2, # stream two, fails ] ui.require_proc_stdout = True cmd.repository_factory = memory.RepositoryFactory() self.setup_repo(cmd, ui) self.set_config('[DEFAULT]\ntest_command=foo $IDLIST $LISTOPT\n' 'test_id_option=--load-list $IDFILE\n' 'test_list_option=--list\n') cmd_result = cmd.execute() expected_cmd = 'foo ' self.assertEqual([ ('values', [('running', expected_cmd)]), ('popen', (expected_cmd, ), { 'shell': True, 'stdin': PIPE, 'stdout': PIPE }), ('results', Wildcard), ('summary', True, 1, -2, Wildcard, Wildcard, [('id', 1, None)]), ('values', [('running', expected_cmd)]), ('popen', (expected_cmd, ), { 'shell': True, 'stdin': PIPE, 'stdout': PIPE }), ('results', Wildcard), ('summary', False, 1, 0, Wildcard, Wildcard, [('id', 2, None), ('failures', 1, 1)]) ], ui.outputs) self.assertEqual(1, cmd_result)
def test_filter_tests_by_regex_only(self): if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='returned', test_status='exists') stream.status(test_id='ids', test_status='exists') subunit_bytes = buffer.getvalue() else: subunit_bytes = _b('returned\nids\n') ui, command = self.get_test_ui_and_cmd() ui.proc_outputs = [subunit_bytes] self.set_config( '[DEFAULT]\ntest_command=foo $LISTOPT $IDLIST\ntest_id_list_default=whoo yea\n' 'test_list_option=--list\n') filters = ['return'] fixture = self.useFixture( command.get_run_command(test_filters=filters)) self.assertEqual(['returned'], fixture.test_ids)
def test_get_run_command_default_and_list_expands(self): ui, command = self.get_test_ui_and_cmd() buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='returned', test_status='exists') stream.status(test_id='ids', test_status='exists') subunit_bytes = buffer.getvalue() ui.proc_outputs = [subunit_bytes] ui.options = optparse.Values() ui.options.parallel = True ui.options.concurrency = 2 self.set_config( '[DEFAULT]\ntest_command=foo $IDLIST $LISTOPT\n' 'test_id_list_default=whoo yea\n' 'test_list_option=--list\n') fixture = self.useFixture(command.get_run_command()) expected_cmd = 'foo returned ids ' self.assertEqual(expected_cmd, fixture.cmd)
def test_not_subunit_no_subunit_name_set(self): stream_buf = io.BytesIO() stream = subunit_lib.StreamResultToBytes(stream_buf) stream.status(test_id='test_a', test_status='inprogress') stream.status(test_id='test_a', test_status='success') stream_buf.write(b'I AM NOT SUBUNIT') stream_buf.seek(0) result = subunit.ReadSubunit(stream_buf) exc_found = False try: result.get_results() # NOTE(mtreinish): Subunit raises the generic Exception class # so manually inspect the Exception object to check the error # message except Exception as e: self.assertIsInstance(e, Exception) self.assertEqual(e.args, ('Non subunit content', b'I')) exc_found = True self.assertTrue(exc_found, 'subunit exception not raised on invalid content')
def make_result(self, get_id, test_command, previous_run=None): if getattr(self.options, 'subunit', False): serializer = subunit.StreamResultToBytes(self._stdout) # By pass user transforms - just forward it all, result = serializer # and interpret everything as success. summary = testtools.StreamSummary() summary.startTestRun() summary.stopTestRun() return result, summary else: # Apply user defined transforms. filter_tags = test_command.get_filter_tags() output = CLITestResult(self, get_id, self._stdout, previous_run, filter_tags=filter_tags) summary = output._summary return output, summary
def test_load_new_shows_test_skips(self): if v2_avail: buffer = BytesIO() stream = subunit.StreamResultToBytes(buffer) stream.status(test_id='foo', test_status='inprogress') stream.status(test_id='foo', test_status='skip') subunit_bytes = buffer.getvalue() else: subunit_bytes = b'test: foo\nskip: foo\n' ui = UI([('subunit', subunit_bytes)]) cmd = load.load(ui) ui.set_command(cmd) cmd.repository_factory = memory.RepositoryFactory() cmd.repository_factory.initialise(ui.here) self.assertEqual(0, cmd.execute()) self.assertEqual( [('results', Wildcard), ('summary', True, 1, None, Wildcard, None, [('id', 0, None), ('skips', 1, None)])], ui.outputs)
def _make_result(self): output = BytesIO() return subunit.StreamResultToBytes(output), output
def _make_result(self): return subunit.StreamResultToBytes(BytesIO())