@@ -74,6 +74,7 @@ def __init__(self, test_descriptor, execution_uid, test_start,
7474 self ._exit_stack = None
7575 self .uid = execution_uid
7676 self .failure_exceptions = failure_exceptions
77+ self ._latest_outcome = None
7778
7879 def stop (self ):
7980 """Stop this test."""
@@ -150,21 +151,29 @@ def _thread_proc(self):
150151 # Full plug initialization happens _after_ the start trigger, as close to
151152 # test execution as possible, for the best chance of test equipment being
152153 # in a known-good state at the start of test execution.
153- if not self ._initialize_plugs ():
154+ if self ._initialize_plugs ():
154155 return
155156
156157 # Everything is set, set status and begin test execution.
157158 self ._execute_test_phases (phase_exec )
158159
159160 def _initialize_plugs (self , plug_types = None ):
161+ """Initialize plugs.
162+
163+ Args:
164+ plug_types: optional list of plug classes to initialize.
165+
166+ Returns:
167+ True if there was an error initializing the plugs.
168+ """
160169 try :
161170 self .test_state .plug_manager .initialize_plugs (plug_types = plug_types )
162- return True
171+ return False
163172 except Exception : # pylint: disable=broad-except
164- # Exit early if plug initializaion failed .
165- self .test_state . finalize_on_failed_plug_initialization (
173+ # Record the equivalent failure outcome and exit early .
174+ self ._latest_outcome = phase_executor . PhaseExecutionOutcome (
166175 phase_executor .ExceptionInfo (* sys .exc_info ()))
167- return False
176+ return True
168177
169178 def _execute_test_start (self , phase_exec ):
170179 """Run the start trigger phase, and check that the DUT ID is set after.
@@ -181,24 +190,35 @@ def _execute_test_start(self, phase_exec):
181190 """
182191 # Have the phase executor run the start trigger phase. Do partial plug
183192 # initialization for just the plugs needed by the start trigger phase.
184- if not self ._initialize_plugs (
185- plug_types = [ phase_plug .cls for phase_plug in self ._test_start .plugs ]):
193+ if self ._initialize_plugs (plug_types = [
194+ phase_plug .cls for phase_plug in self ._test_start .plugs ]):
186195 return True
187196
188- outcome = phase_exec .execute_phase (self ._test_start )
189- if outcome .is_terminal :
190- self . test_state . finalize_from_phase_outcome ( outcome )
197+ self . _latest_outcome = phase_exec .execute_phase (self ._test_start )
198+ if self . _latest_outcome .is_terminal :
199+ return True
191200
192201 if self .test_state .test_record .dut_id is None :
193202 _LOG .warning ('Start trigger did not set DUT ID. A later phase will need'
194203 ' to do so to prevent a BlankDutIdError when the test ends.' )
195- return outcome . is_terminal
204+ return False
196205
197206 def _execute_test_teardown (self , phase_exec ):
198207 phase_exec .stop (timeout_s = conf .cancel_timeout_s )
199208 if self ._do_teardown_function and self ._teardown_function :
200- phase_exec .execute_phase (self ._teardown_function )
209+ outcome = phase_exec .execute_phase (self ._teardown_function )
210+ # Ignore teardown phase outcome if there is already a terminal error.
211+ if not self ._latest_outcome or not self ._latest_outcome .is_terminal :
212+ self ._latest_outcome = outcome
213+ # Plug teardown does not affect the test outcome.
201214 self .test_state .plug_manager .tear_down_plugs ()
215+
216+ # Now finalize the test state.
217+ if self ._latest_outcome and self ._latest_outcome .is_terminal :
218+ self .test_state .finalize_from_phase_outcome (self ._latest_outcome )
219+ else :
220+ self .test_state .finalize_normally ()
221+
202222 # Make sure if there was an error during test execution that the error
203223 # message is printed last and in a noticeable color so it doesn't get
204224 # scrolled off the screen or missed.
@@ -212,12 +232,9 @@ def _execute_test_phases(self, phase_exec):
212232
213233 try :
214234 for phase in self ._test_descriptor .phases :
215- outcome = phase_exec .execute_phase (phase )
216- if outcome .is_terminal :
217- self .test_state .finalize_from_phase_outcome (outcome )
235+ self ._latest_outcome = phase_exec .execute_phase (phase )
236+ if self ._latest_outcome .is_terminal :
218237 break
219- else :
220- self .test_state .finalize_normally ()
221238 except KeyboardInterrupt :
222239 self .test_state .logger .info ('KeyboardInterrupt caught, aborting test.' )
223240 raise
0 commit comments