def test_runner_wrapper(suite, keep_alive_pipe, result_pipe, stdouterr_queue,
- logger):
+ partial_result_queue, logger):
sys.stdout = stdouterr_queue
sys.stderr = stdouterr_queue
VppTestCase.logger = logger
result = VppTestRunner(keep_alive_pipe=keep_alive_pipe,
descriptions=descriptions,
verbosity=verbose,
+ results_pipe=partial_result_queue,
failfast=failfast).run(suite)
result_pipe.send(result)
result_pipe.close()
self.keep_alive_parent_end, self.keep_alive_child_end = Pipe(
duplex=False)
self.result_parent_end, self.result_child_end = Pipe(duplex=False)
+ self.partial_result_parent_end, self.partial_result_child_end = Pipe(
+ duplex=False)
self.testcase_suite = testcase_suite
self.stdouterr_queue = manager.Queue()
self.logger = get_parallel_logger(self.stdouterr_queue)
self.child = Process(target=test_runner_wrapper,
args=(testcase_suite, self.keep_alive_child_end,
self.result_child_end, self.stdouterr_queue,
- self.logger)
+ self.partial_result_child_end, self.logger)
)
self.child.start()
self.pid = self.child.pid
self.last_test_vpp_binary = None
self.last_test = None
self.result = None
+ self.vpp_pid = None
self.last_heard = time.time()
self.core_detected_at = None
self.failed_tests = []
+ self.partial_result = None
def close_pipes(self):
self.keep_alive_child_end.close()
self.result_child_end.close()
+ self.partial_result_child_end.close()
self.keep_alive_parent_end.close()
self.result_parent_end.close()
+ self.partial_result_parent_end.close()
def stdouterr_reader_wrapper(unread_testcases, finished_unread_testcases,
read_testcase = None
-def run_forked(testcases):
+def run_forked(testcase_suites):
wrapped_testcase_suites = set()
# suites are unhashable, need to use list
manager = StreamQueueManager()
manager.start()
for i in range(concurrent_tests):
- if len(testcases) > 0:
- wrapped_testcase_suite = TestCaseWrapper(testcases.pop(0), manager)
+ if len(testcase_suites) > 0:
+ wrapped_testcase_suite = TestCaseWrapper(testcase_suites.pop(0),
+ manager)
wrapped_testcase_suites.add(wrapped_testcase_suite)
unread_testcases.add(wrapped_testcase_suite)
# time.sleep(1)
for wrapped_testcase_suite in wrapped_testcase_suites:
readable = select.select(
[wrapped_testcase_suite.keep_alive_parent_end.fileno(),
- wrapped_testcase_suite.result_parent_end.fileno()],
+ wrapped_testcase_suite.result_parent_end.fileno(),
+ wrapped_testcase_suite.partial_result_parent_end.fileno()],
[], [], 1)[0]
if wrapped_testcase_suite.result_parent_end.fileno() in readable:
results.append(
finished_testcase_suites.add(wrapped_testcase_suite)
continue
+ if wrapped_testcase_suite.partial_result_parent_end.fileno() \
+ in readable:
+ while wrapped_testcase_suite.partial_result_parent_end.poll():
+ wrapped_testcase_suite.partial_result = \
+ wrapped_testcase_suite.partial_result_parent_end.recv()
+ wrapped_testcase_suite.last_heard = time.time()
+
if wrapped_testcase_suite.keep_alive_parent_end.fileno() \
in readable:
while wrapped_testcase_suite.keep_alive_parent_end.poll():
if fail:
failed_dir = os.getenv('VPP_TEST_FAILED_DIR')
- lttd = os.path.basename(
- wrapped_testcase_suite.last_test_temp_dir)
+ if wrapped_testcase_suite.last_test_temp_dir:
+ lttd = os.path.basename(
+ wrapped_testcase_suite.last_test_temp_dir)
+ else:
+ lttd = None
link_path = '%s%s-FAILED' % (failed_dir, lttd)
wrapped_testcase_suite.logger.error(
"Creating a link to the failed test: %s -> %s" %
(link_path, lttd))
- if not os.path.exists(link_path):
+ if not os.path.exists(link_path) \
+ and wrapped_testcase_suite.last_test_temp_dir:
os.symlink(wrapped_testcase_suite.last_test_temp_dir,
link_path)
api_post_mortem_path = "/tmp/api_post_mortem.%d" % \
except OSError:
# already dead
pass
- results.append((wrapped_testcase_suite.testcase_suite, None))
+ results.append((wrapped_testcase_suite.testcase_suite,
+ wrapped_testcase_suite.partial_result))
finished_testcase_suites.add(wrapped_testcase_suite)
for finished_testcase in finished_testcase_suites:
wrapped_testcase_suites.remove(finished_testcase)
finished_unread_testcases.add(finished_testcase)
finished_testcase.stdouterr_queue.put(None)
- if len(testcases) > 0:
- new_testcase = TestCaseWrapper(testcases.pop(0), manager)
+ if len(testcase_suites) > 0:
+ new_testcase = TestCaseWrapper(testcase_suites.pop(0), manager)
wrapped_testcase_suites.add(new_testcase)
unread_testcases.add(new_testcase)
class FilterByClassList:
- def __init__(self, class_list):
- self.class_list = class_list
+ def __init__(self, classes_with_filenames):
+ self.classes_with_filenames = classes_with_filenames
def __call__(self, file_name, class_name, func_name):
- return class_name in self.class_list
+ return '.'.join([file_name, class_name]) in self.classes_with_filenames
def suite_from_failed(suite, failed):
+ failed = {x.rsplit('.', 1)[0] for x in failed}
filter_cb = FilterByClassList(failed)
suite = filter_tests(suite, filter_cb)
return suite
self.expectedFailures_id = 'expectedFailures'
self.unexpectedSuccesses_id = 'unexpectedSuccesses'
self.rerun = []
+ self.passed = 0
self[self.failures_id] = 0
self[self.errors_id] = 0
- self[self.crashes_id] = 0
self[self.skipped_id] = 0
self[self.expectedFailures_id] = 0
self[self.unexpectedSuccesses_id] = 0
self.results_per_suite[tc_class] = \
{self.failures_id: [],
self.errors_id: [],
- self.crashes_id: [],
self.skipped_id: [],
self.expectedFailures_id: [],
self.unexpectedSuccesses_id: []}
return True
return False
- def add_results(self, testcases, testcase_result,
- duplicates=None):
+ def add_results(self, testcases, testcase_result_id):
for failed_testcase, _ in testcases:
- if self._add_result(failed_testcase, testcase_result):
- if duplicates:
- if failed_testcase not in duplicates:
- self[testcase_result] += 1
- else:
- self[testcase_result] += 1
+ if self._add_result(failed_testcase, testcase_result_id):
+ self[testcase_result_id] += 1
def add_result(self, testcase_suite, result):
retval = 0
- self.all_testcases += testcase_suite.countTestCases()
if result:
- # suite finished properly
- if not result.wasSuccessful():
+ self.all_testcases += result.testsRun
+ self.passed += len(result.passed)
+ if not len(result.passed) + len(result.skipped) \
+ == testcase_suite.countTestCases():
retval = 1
self.add_results(result.failures, self.failures_id)
- self.add_results(result.errors, self.errors_id,
- result.failures + result.errors)
+ self.add_results(result.errors, self.errors_id)
self.add_results(result.skipped, self.skipped_id)
self.add_results(result.expectedFailures,
self.expectedFailures_id)
self.add_results(result.unexpectedSuccesses,
self.unexpectedSuccesses_id)
-
else:
- # suite crashed
retval = -1
- self.add_results([(x, None) for x in testcase_suite],
- self.crashes_id)
if retval != 0:
if concurrent_tests == 1:
if result:
- rerun_classes = {x[0].__class__.__name__ for
- x in result.errors}
- rerun_classes.update({x[0].__class__.__name__ for
- x in result.failures})
- self.rerun.append(suite_from_failed(testcase_suite,
- rerun_classes))
+ rerun_ids = set([])
+ skipped = [x.id() for (x, _) in result.skipped]
+ for testcase in testcase_suite:
+ tc_id = testcase.id()
+ if tc_id not in result.passed and \
+ tc_id not in skipped:
+ rerun_ids.add(tc_id)
+ if len(rerun_ids) > 0:
+ self.rerun.append(suite_from_failed(testcase_suite,
+ rerun_ids))
else:
self.rerun.append(testcase_suite)
else:
print('TEST RESULTS:')
print(' Executed tests: {}'.format(self.all_testcases))
print(' Passed tests: {}'.format(
- colorize(str(self.all_testcases -
- self.all_nonpassed), GREEN)))
+ colorize(str(self.passed), GREEN)))
if self[self.failures_id] > 0:
- print(' Failed tests: {}'.format(
+ print(' Failures: {}'.format(
colorize(str(self[self.failures_id]), RED)))
if self[self.errors_id] > 0:
- print(' Errored tests: {}'.format(
+ print(' Errors: {}'.format(
colorize(str(self[self.errors_id]), RED)))
- if self[self.crashes_id] > 0:
- print(' Crashed tests: {}'.format(
- colorize(str(self[self.crashes_id]), RED)))
if self[self.skipped_id] > 0:
print(' Skipped tests: {}'.format(
colorize(str(self[self.skipped_id]), YELLOW)))
self.failures_id]
errored_testcases = suite_results[
self.errors_id]
- crashed_testcases = suite_results[
- self.crashes_id]
- if len(failed_testcases) or len(errored_testcases) \
- or len(crashed_testcases):
+ if len(failed_testcases) or len(errored_testcases):
print(' Testcase name: {}'.format(
colorize(testcase_class, RED)))
for failed_test in failed_testcases:
print(' ERRORED: {}'.format(
colorize(get_test_description(
descriptions, failed_test), RED)))
- for failed_test in crashed_testcases:
- print(' CRASHED: {}'.format(
- colorize(get_test_description(
- descriptions, failed_test), RED)))
print(double_line_delim)
print('')
- @property
- def all_nonpassed(self):
- return self[self.failures_id] + self[self.errors_id] + \
- self[self.crashes_id] + self[self.skipped_id] + \
- self[self.expectedFailures_id] + \
- self[self.unexpectedSuccesses_id]
-
@property
def all_failed(self):
- return self[self.failures_id] + self[self.errors_id] + \
- self[self.crashes_id]
+ return self[self.failures_id] + self[self.errors_id]
def parse_results(results):
if concurrent_tests == 1:
new_suite = unittest.TestSuite()
for suite in suites:
- new_suite.addTest(suite)
+ new_suite.addTests(suite)
suites = [new_suite]