def _handle_phase(self, phase_desc): """Handle execution of a single test phase.""" logs.configure_logging() self._initialize_plugs(phase_plug.cls for phase_plug in phase_desc.plugs) # Cobble together a fake TestState to pass to the test phase. test_options = test_descriptor.TestOptions() with mock.patch('openhtf.plugs.PlugManager', new=lambda _, __: self.plug_manager): test_state_ = test_state.TestState( openhtf.TestDescriptor((phase_desc, ), phase_desc.code_info, {}), 'Unittest:StubTest:UID', test_options) test_state_.mark_test_started() # Actually execute the phase, saving the result in our return value. executor = phase_executor.PhaseExecutor(test_state_) # Log an exception stack when a Phase errors out. with mock.patch.object(phase_executor.PhaseExecutorThread, '_log_exception', side_effect=logging.exception): # Use _execute_phase_once because we want to expose all possible outcomes. executor._execute_phase_once(phase_desc, is_last_repeat=False, run_with_profiling=False) return test_state_.test_record.phases[-1]
def _thread_proc(self): """Handles one whole test from start to finish.""" try: # Top level steps required to run a single iteration of the Test. self.test_state = test_state.TestState(self._test_descriptor, self.uid, self._test_options) phase_exec = phase_executor.PhaseExecutor(self.test_state) # Any access to self._exit_stacks must be done while holding this lock. with self._lock: self._phase_exec = phase_exec if self._test_start is not None and self._execute_test_start(): # Exit early if test_start returned a terminal outcome of any kind. return self.test_state.mark_test_started() # Full plug initialization happens _after_ the start trigger, as close to # test execution as possible, for the best chance of test equipment being # in a known-good state at the start of test execution. if self._initialize_plugs(): return # Everything is set, set status and begin test execution. self.test_state.set_status_running() self._execute_phase_group(self._test_descriptor.phase_group) finally: self._execute_test_teardown()
def _thread_proc(self) -> None: """Handles one whole test from start to finish.""" try: # Top level steps required to run a single iteration of the Test. self.test_state = test_state.TestState(self._test_descriptor, self.uid, self._test_options) phase_exec = phase_executor.PhaseExecutor(self.test_state) # Any access to self._exit_stacks must be done while holding this lock. with self._lock: self._phase_exec = phase_exec if self._test_start is not None and self._execute_test_start(): # Exit early if test_start returned a terminal outcome of any kind. return self.test_state.mark_test_started() # Full plug initialization happens _after_ the start trigger, as close to # test execution as possible, for the best chance of test equipment being # in a known-good state at the start of test execution. if self._initialize_plugs(): return # Everything is set, set status and begin test execution. self.test_state.set_status_running() self._execute_node(self._test_descriptor.phase_sequence, None, False) self._execute_test_diagnosers() except: # pylint: disable=bare-except stacktrace = traceback.format_exc() _LOG.error('Error in TestExecutor: \n%s', stacktrace) raise finally: self._execute_test_teardown()
def _thread_proc(self): """Handles one whole test from start to finish.""" with contextlib.ExitStack() as exit_stack: # Top level steps required to run a single iteration of the Test. self.test_state = test_state.TestState(self._test_descriptor, self.uid) phase_exec = phase_executor.PhaseExecutor(self.test_state) # Any access to self._exit_stacks must be done while holding this lock. with self._lock: self._exit_stack = exit_stack # Ensure that we tear everything down when exiting. exit_stack.callback(self._execute_test_teardown, phase_exec) # We don't want to run the 'teardown function' unless the test has # actually started. self._do_teardown_function = False if self._test_start is not None and self._execute_test_start( phase_exec): # Exit early if test_start returned a terminal outcome of any kind. return # The trigger has run and the test has started, so from now on we want the # teardown function to execute at the end, no matter what. with self._lock: self._do_teardown_function = True self.test_state.mark_test_started() # Full plug initialization happens _after_ the start trigger, as close to # test execution as possible, for the best chance of test equipment being # in a known-good state at the start of test execution. self.test_state.plug_manager.initialize_plugs() # Everything is set, set status and begin test execution. self._execute_test_phases(phase_exec)
def setUp(self): test_descriptor = mock.MagicMock() self.test_state = test_state.TestState(test_descriptor, 'testing-123') self.running_phase_state = test_state.PhaseState.from_descriptor( test_phase, lambda *args: None) self.test_state.running_phase_state = self.running_phase_state self.test_api = self.test_state.test_api
def _handle_phase(self, phase_desc): """Handle execution of a single test phase.""" self._initialize_plugs(phase_plug.cls for phase_plug in phase_desc.plugs) # Cobble together a fake TestState to pass to the test phase. with mock.patch('openhtf.plugs.PlugManager', new=lambda _, __: self.plug_manager): test_state_ = test_state.TestState( openhtf.TestDescriptor((phase_desc, ), phase_desc.code_info, {}), 'Unittest:StubTest:UID') test_state_.mark_test_started() # Actually execute the phase, saving the result in our return value. with test_state_.running_phase_context(phase_desc) as phase_state: try: phase_state.result = phase_executor.PhaseExecutionOutcome( phase_desc(test_state_)) except Exception: # pylint:disable=broad-except logging.exception('Exception executing phase %s', phase_desc.name) phase_state.result = phase_executor.PhaseExecutionOutcome( phase_executor.ExceptionInfo(*sys.exc_info())) return phase_state.phase_record
def setUp(self): super(TestPhaseDescriptor, self).setUp() self._test_state = test_state.TestState( test_descriptor.TestDescriptor( phase_sequence=phase_collections.PhaseSequence(), code_info=test_record.CodeInfo.uncaptured(), metadata={}), execution_uid='', test_options=test_descriptor.TestOptions())
def setUp(self): self.test_descriptor = test_descriptor.TestDescriptor( phase_group.PhaseGroup(main=[test_phase]), None, {'config': {}}) self.test_state = test_state.TestState(self.test_descriptor, 'testing-123', test_descriptor.TestOptions()) self.test_record = self.test_state.test_record self.running_phase_state = test_state.PhaseState.from_descriptor( test_phase, lambda *args: None) self.test_state.running_phase_state = self.running_phase_state self.test_api = self.test_state.test_api
def _handle_phase(self, phase_desc): """Handle execution of a single test phase.""" phase_descriptor.check_for_duplicate_results(iter([phase_desc]), []) logs.configure_logging() self._initialize_plugs(phase_plug.cls for phase_plug in phase_desc.plugs) # Cobble together a fake TestState to pass to the test phase. test_options = test_descriptor.TestOptions() with mock.patch.object(plugs, 'PlugManager', new=lambda _, __: self.plug_manager): test_state_ = test_state.TestState( test_descriptor.TestDescriptor( phase_collections.PhaseSequence((phase_desc, )), phase_desc.code_info, {}), 'Unittest:StubTest:UID', test_options) test_state_.mark_test_started() test_state_.user_defined_state.update(self.phase_user_defined_state) for diag in self.phase_diagnoses: test_state_.diagnoses_manager._add_diagnosis(diag) # pylint: disable=protected-access test_state_.test_record.add_diagnosis(diag) # Save the test_state to the last_test_case attribute to give it access to # the underlying state. self.test_case.last_test_state = test_state_ # Actually execute the phase, saving the result in our return value. executor = phase_executor.PhaseExecutor(test_state_) profile_filepath = self.test_case.get_profile_filepath() # Log an exception stack when a Phase errors out. with mock.patch.object(phase_executor.PhaseExecutorThread, '_log_exception', side_effect=logging.exception): # Use _execute_phase_once because we want to expose all possible outcomes. phase_result, profile_stats = executor._execute_phase_once( phase_desc, is_last_repeat=False, run_with_profiling=profile_filepath, subtest_rec=None) if profile_filepath is not None: _merge_stats(profile_stats, profile_filepath) if phase_result.raised_exception: failure_message = phase_result.phase_result.get_traceback_string() else: failure_message = None return test_state_.test_record.phases[-1], failure_message
def setUp(self): super(TestTestApi, self).setUp() patcher = mock.patch.object(test_record.PhaseRecord, 'record_start_time', return_value=11235) self.mock_record_start_time = patcher.start() self.addCleanup(patcher.stop) self.test_descriptor = test_descriptor.TestDescriptor( phase_group.PhaseGroup(main=[test_phase]), None, {'config': {}}) self.test_state = test_state.TestState(self.test_descriptor, 'testing-123', test_descriptor.TestOptions()) self.test_record = self.test_state.test_record self.running_phase_state = test_state.PhaseState.from_descriptor( test_phase, self.test_state, logging.getLogger()) self.test_state.running_phase_state = self.running_phase_state self.test_api = self.test_state.test_api
def setUp(self): super(TestTestApi, self).setUp() patcher = mock.patch.object( test_record.PhaseRecord, 'record_start_time', return_value=11235) self.mock_record_start_time = patcher.start() self.addCleanup(patcher.stop) self.test_descriptor = test_descriptor.TestDescriptor( phase_collections.PhaseSequence((test_phase,)), test_record.CodeInfo.uncaptured(), {'config': {}}) self.test_state = test_state.TestState(self.test_descriptor, 'testing-123', test_descriptor.TestOptions()) self.test_record = self.test_state.test_record self.running_phase_state = test_state.PhaseState.from_descriptor( test_phase, self.test_state, logging.getLogger()) self.test_state.running_phase_state = self.running_phase_state self.test_api = self.test_state.test_api
def _handle_phase(self, phase_desc): """Handle execution of a single test phase.""" self._initialize_plugs(phase_plug.cls for phase_plug in phase_desc.plugs) # Cobble together a fake TestState to pass to the test phase. with mock.patch('openhtf.plugs.PlugManager', new=lambda _, __: self.plug_manager): test_state_ = test_state.TestState( openhtf.TestDescriptor((phase_desc, ), phase_desc.code_info, {}), 'Unittest:StubTest:UID') test_state_.mark_test_started() # Actually execute the phase, saving the result in our return value. executor = phase_executor.PhaseExecutor(test_state_) # Use _execute_phase_once because we want to expose all possible outcomes. executor._execute_phase_once(phase_desc, is_last_repeat=False) return test_state_.test_record.phases[-1]
def _thread_proc(self): """Handles one whole test from start to finish.""" with contextlib.ExitStack() as exit_stack: # Top level steps required to run a single iteration of the Test. self.test_state = test_state.TestState(self._test_descriptor, self.uid) phase_exec = phase_executor.PhaseExecutor(self.test_state) # Any access to self._exit_stack must be done while holding this lock. with self._lock: self._exit_stack = exit_stack # We need to exit the PhaseExecutor before we tear down the plugs # that a phase may be executing, so we add them in reverse order. exit_stack.callback( self.test_state.plug_manager.tear_down_plugs) exit_stack.callback(phase_exec.stop) # Have the phase executor run the start trigger phase. Do partial plug # initialization for just the plugs needed by the start trigger phase. if self._test_start is not None: self.test_state.plug_manager.initialize_plugs( (phase_plug.cls for phase_plug in self._test_start.plugs)) phase_exec.execute_start_trigger(self._test_start) self.test_state.mark_test_started() # Full plug initialization happens _after_ the start trigger, as close to # test execution as possible, for the best chance of test equipment being # in a known-good state at the start of test execution. self.test_state.plug_manager.initialize_plugs() # Everything is set, set status and begin test execution. Note we don't # protect this with a try: block because the PhaseExecutor handles any # exceptions from test code. Any exceptions here are caused by the # framework, and we probably want them to interrupt framework state # changes (like the transition to FINISHING). self._execute_test_phases(phase_exec)