def run(self, suite): """See setuptools' test_runner setup argument for information.""" # only run test cases with id starting with given prefix testcase_filter = os.getenv('GRPC_PYTHON_TESTRUNNER_FILTER') filtered_cases = [] for case in _loader.iterate_suite_cases(suite): if not testcase_filter or case.id().startswith(testcase_filter): filtered_cases.append(case) # Ensure that every test case has no collision with any other test case in # the augmented results. augmented_cases = [ AugmentedCase(case, uuid.uuid4()) for case in filtered_cases ] case_id_by_case = dict((augmented_case.case, augmented_case.id) for augmented_case in augmented_cases) result_out = moves.cStringIO() result = _result.TerminalResult( result_out, id_map=lambda case: case_id_by_case[case]) stdout_pipe = CaptureFile(sys.stdout.fileno()) stderr_pipe = CaptureFile(sys.stderr.fileno()) kill_flag = [False] def sigint_handler(signal_number, frame): if signal_number == signal.SIGINT: kill_flag[0] = True # Python 2.7 not having 'local'... :-( signal.signal(signal_number, signal.SIG_DFL) def fault_handler(signal_number, frame): stdout_pipe.write_bypass( 'Received fault signal {}\nstdout:\n{}\n\nstderr:{}\n'.format( signal_number, stdout_pipe.output(), stderr_pipe.output())) os._exit(1) def check_kill_self(): if kill_flag[0]: stdout_pipe.write_bypass('Stopping tests short...') result.stopTestRun() stdout_pipe.write_bypass(result_out.getvalue()) stdout_pipe.write_bypass('\ninterrupted stdout:\n{}\n'.format( stdout_pipe.output().decode())) stderr_pipe.write_bypass('\ninterrupted stderr:\n{}\n'.format( stderr_pipe.output().decode())) os._exit(1) def try_set_handler(name, handler): try: signal.signal(getattr(signal, name), handler) except AttributeError: pass try_set_handler('SIGINT', sigint_handler) try_set_handler('SIGSEGV', fault_handler) try_set_handler('SIGBUS', fault_handler) try_set_handler('SIGABRT', fault_handler) try_set_handler('SIGFPE', fault_handler) try_set_handler('SIGILL', fault_handler) # Sometimes output will lag after a test has successfully finished; we # ignore such writes to our pipes. try_set_handler('SIGPIPE', signal.SIG_IGN) # Run the tests result.startTestRun() for augmented_case in augmented_cases: for skipped_test in self._skipped_tests: if skipped_test in augmented_case.case.id(): break else: sys.stdout.write('Running {}\n'.format( augmented_case.case.id())) sys.stdout.flush() case_thread = threading.Thread( target=augmented_case.case.run, args=(result,)) try: with stdout_pipe, stderr_pipe: case_thread.start() while case_thread.is_alive(): check_kill_self() time.sleep(0) case_thread.join() except: # re-raise the exception after forcing the with-block to end raise result.set_output(augmented_case.case, stdout_pipe.output(), stderr_pipe.output()) sys.stdout.write(result_out.getvalue()) sys.stdout.flush() result_out.truncate(0) check_kill_self() result.stopTestRun() stdout_pipe.close() stderr_pipe.close() # Report results sys.stdout.write(result_out.getvalue()) sys.stdout.flush() signal.signal(signal.SIGINT, signal.SIG_DFL) with open('report.xml', 'wb') as report_xml_file: _result.jenkins_junit_xml(result).write(report_xml_file) return result
# If the thread is exited unexpected, stop testing. while case_thread.is_alive(): check_kill_self() time.sleep(0) case_thread.join() except: # pylint: disable=try-except-raise # re-raise the exception after forcing the with-block to end raise # Records the result of the test case run. result.set_output(augmented_case.case, stdout_pipe.output(), stderr_pipe.output()) sys.stdout.write(result_out.getvalue()) sys.stdout.flush() result_out.truncate(0) check_kill_self() else: # Donates current thread to test case execution. augmented_case.case.run(result) result.stopTestRun() stdout_pipe.close() stderr_pipe.close() # Report results sys.stdout.write(result_out.getvalue()) sys.stdout.flush() signal.signal(signal.SIGINT, signal.SIG_DFL) with open('report.xml', 'wb') as report_xml_file: _result.jenkins_junit_xml(result).write(report_xml_file) return result
def run(self, suite): """See setuptools' test_runner setup argument for information.""" # Ensure that every test case has no collision with any other test case in # the augmented results. augmented_cases = [AugmentedCase(case, uuid.uuid4()) for case in _loader.iterate_suite_cases(suite)] case_id_by_case = dict((augmented_case.case, augmented_case.id) for augmented_case in augmented_cases) result_out = StringIO.StringIO() result = _result.TerminalResult(result_out, id_map=lambda case: case_id_by_case[case]) stdout_pipe = CapturePipe(sys.stdout.fileno()) stderr_pipe = CapturePipe(sys.stderr.fileno()) kill_flag = [False] def sigint_handler(signal_number, frame): if signal_number == signal.SIGINT: kill_flag[0] = True # Python 2.7 not having 'local'... :-( signal.signal(signal_number, signal.SIG_DFL) def fault_handler(signal_number, frame): stdout_pipe.write_bypass( "Received fault signal {}\nstdout:\n{}\n\nstderr:{}\n".format( signal_number, stdout_pipe.output, stderr_pipe.output ) ) os._exit(1) def check_kill_self(): if kill_flag[0]: stdout_pipe.write_bypass("Stopping tests short...") result.stopTestRun() stdout_pipe.write_bypass(result_out.getvalue()) stdout_pipe.write_bypass("\ninterrupted stdout:\n{}\n".format(stdout_pipe.output)) stderr_pipe.write_bypass("\ninterrupted stderr:\n{}\n".format(stderr_pipe.output)) os._exit(1) signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGSEGV, fault_handler) signal.signal(signal.SIGBUS, fault_handler) signal.signal(signal.SIGABRT, fault_handler) signal.signal(signal.SIGFPE, fault_handler) signal.signal(signal.SIGILL, fault_handler) # Sometimes output will lag after a test has successfully finished; we # ignore such writes to our pipes. signal.signal(signal.SIGPIPE, signal.SIG_IGN) # Run the tests result.startTestRun() for augmented_case in augmented_cases: sys.stdout.write("Running {}\n".format(augmented_case.case.id())) sys.stdout.flush() case_thread = threading.Thread(target=augmented_case.case.run, args=(result,)) try: with stdout_pipe, stderr_pipe: case_thread.start() while case_thread.is_alive(): check_kill_self() time.sleep(0) case_thread.join() except: # re-raise the exception after forcing the with-block to end raise result.set_output(augmented_case.case, stdout_pipe.output, stderr_pipe.output) sys.stdout.write(result_out.getvalue()) sys.stdout.flush() result_out.truncate(0) check_kill_self() result.stopTestRun() stdout_pipe.close() stderr_pipe.close() # Report results sys.stdout.write(result_out.getvalue()) sys.stdout.flush() signal.signal(signal.SIGINT, signal.SIG_DFL) with open("report.xml", "w") as report_xml_file: _result.jenkins_junit_xml(result).write(report_xml_file) return result