Ejemplo n.º 1
0
    def with_context(
        cls, setup_nodes: Optional[phase_collections.SequenceInitializerT],
        teardown_nodes: Optional[phase_collections.SequenceInitializerT]
    ) -> Callable[..., 'PhaseGroup']:
        """Create PhaseGroup creator function with setup and teardown phases.

    Args:
      setup_nodes: phases to run during the setup for the PhaseGroup returned
        from the created function.
      teardown_nodes: phases to run during the teardown for the PhaseGroup
        returned from the created function.

    Returns:
      Function that takes *phases and returns a PhaseGroup with the predefined
      setup and teardown phases, with *phases as the main phases.
    """
        setup = phase_collections.PhaseSequence(
            setup_nodes) if setup_nodes else None
        teardown = phase_collections.PhaseSequence(
            teardown_nodes) if teardown_nodes else None

        def _context_wrapper(
                *phases: phase_descriptor.PhaseCallableOrNodeT
        ) -> 'PhaseGroup':
            return cls(setup=data.attr_copy(setup) if setup else None,
                       main=phase_collections.PhaseSequence(phases),
                       teardown=data.attr_copy(teardown) if teardown else None)

        return _context_wrapper
Ejemplo n.º 2
0
  def test_nested(self):
    seq = phase_collections.PhaseSequence(
        phase_collections.PhaseSequence(phase, empty_phase))

    test_rec = yield htf.Test(seq)

    self.assertTestPass(test_rec)

    self.assertPhasesOutcomeByName(test_record.PhaseOutcome.PASS, test_rec,
                                   'phase', 'empty_phase')
Ejemplo n.º 3
0
 def testConstruct(self):
     setup = _fake_phases('1')
     main = _fake_phases('2')
     teardown = _fake_phases('3')
     name = 'name'
     pg = htf.PhaseGroup(setup=setup,
                         main=main,
                         teardown=teardown,
                         name=name)
     self.assertEqual(phase_collections.PhaseSequence(tuple(setup)),
                      pg.setup)
     self.assertEqual(phase_collections.PhaseSequence(tuple(main)), pg.main)
     self.assertEqual(phase_collections.PhaseSequence(tuple(teardown)),
                      pg.teardown)
     self.assertEqual(name, pg.name)
Ejemplo n.º 4
0
 def testExecuteAbortable_AbortedPrior(self):
     self.test_exec.abort()
     sequence = phase_collections.PhaseSequence(_fake_phases('not-run'))
     self.assertEqual(
         test_executor._ExecutorReturn.TERMINAL,
         self.test_exec._execute_sequence(sequence, None, False))
     self.mock_execute_node.assert_not_called()
Ejemplo n.º 5
0
 def setUp(self):
     super(TestExecutorExecuteBranchTest, self).setUp()
     self.diag_store = diagnoses_lib.DiagnosesStore()
     self.mock_test_record = mock.create_autospec(test_record.TestRecord)
     self.mock_logger = mock.create_autospec(logging.Logger)
     self.test_state = mock.MagicMock(
         spec=test_state.TestState,
         plug_manager=plugs.PlugManager(),
         diagnoses_manager=mock.MagicMock(
             spec=diagnoses_lib.DiagnosesManager, store=self.diag_store),
         execution_uid='01234567890',
         test_record=self.mock_test_record,
         state_logger=self.mock_logger)
     td = test_descriptor.TestDescriptor(
         phase_sequence=phase_collections.PhaseSequence(
             phase_group.PhaseGroup()),
         code_info=test_record.CodeInfo.uncaptured(),
         metadata={})
     self.test_exec = test_executor.TestExecutor(
         td,
         td.uid,
         None,
         test_descriptor.TestOptions(),
         run_with_profiling=False)
     self.test_exec.test_state = self.test_state
     patcher = mock.patch.object(self.test_exec, '_execute_sequence')
     self.mock_execute_sequence = patcher.start()
Ejemplo n.º 6
0
    def __init__(self, *nodes: phase_descriptor.PhaseCallableOrNodeT,
                 **metadata: Any):
        # Some sanity checks on special metadata keys we automatically fill in.
        if 'config' in metadata:
            raise KeyError(
                'Invalid metadata key "config", it will be automatically populated.'
            )

        self.created_time_millis = util.time_millis()
        self.last_run_time_millis = None
        self._test_options = TestOptions()
        self._lock = threading.Lock()
        self._executor = None
        # TODO(arsharma): Drop _flatten at some point.
        sequence = phase_collections.PhaseSequence(nodes)
        self._test_desc = TestDescriptor(sequence,
                                         htf_test_record.CodeInfo.uncaptured(),
                                         metadata)

        if CONF.capture_source:
            # Copy the phases with the real CodeInfo for them.
            self._test_desc.phase_sequence = (
                self._test_desc.phase_sequence.load_code_info())
            self._test_desc.code_info = (
                htf_test_record.CodeInfo.for_module_from_stack(levels_up=2))

        # Make sure configure() gets called at least once before Execute().  The
        # user might call configure() again to override options, but we don't want
        # to force them to if they want to use defaults.  For default values, see
        # the class definition of TestOptions.
        if 'test_name' in metadata:
            # Allow legacy metadata key for specifying test name.
            self.configure(name=metadata['test_name'])
        else:
            self.configure()
Ejemplo n.º 7
0
def _initialize_group_sequence(
    seq: Optional[phase_collections.SequenceInitializerT]
) -> Optional[phase_collections.PhaseSequence]:
    if not seq:
        return None
    if isinstance(seq, phase_collections.PhaseSequence):
        return seq
    return phase_collections.PhaseSequence(seq)
Ejemplo n.º 8
0
 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())
Ejemplo n.º 9
0
 def testExecuteTeardown_Empty(self):
     self.assertEqual(
         test_executor._ExecutorReturn.CONTINUE,
         self.test_exec._execute_sequence(phase_collections.PhaseSequence(
             tuple()),
                                          None,
                                          True,
                                          override_message='group'))
     self.mock_execute_node.assert_not_called()
Ejemplo n.º 10
0
 def testExecuteAbortable_NoPhases(self):
     self.assertEqual(
         test_executor._ExecutorReturn.CONTINUE,
         self.test_exec._execute_sequence(phase_collections.PhaseSequence(
             tuple()),
                                          None,
                                          False,
                                          override_message='main group'))
     self.mock_execute_node.assert_not_called()
Ejemplo n.º 11
0
    def setUp(self):
        super(TestExecutorExecutePhaseGroupTest, self).setUp()
        self.test_state = mock.MagicMock(spec=test_state.TestState,
                                         plug_manager=plugs.PlugManager(),
                                         execution_uid='01234567890',
                                         state_logger=mock.MagicMock())
        td = test_descriptor.TestDescriptor(
            phase_sequence=phase_collections.PhaseSequence(
                phase_group.PhaseGroup()),
            code_info=test_record.CodeInfo.uncaptured(),
            metadata={})
        self.test_exec = test_executor.TestExecutor(
            td,
            td.uid,
            None,
            test_descriptor.TestOptions(),
            run_with_profiling=False)
        self.test_exec.test_state = self.test_state
        patcher = mock.patch.object(self.test_exec, '_execute_sequence')
        self.mock_execute_sequence = patcher.start()

        @phase_descriptor.PhaseOptions()
        def setup():
            pass

        self._setup = phase_collections.PhaseSequence((setup, ))

        @phase_descriptor.PhaseOptions()
        def main():
            pass

        self._main = phase_collections.PhaseSequence((main, ))

        @openhtf.PhaseOptions(timeout_s=30)
        def teardown():
            pass

        self._teardown = phase_collections.PhaseSequence((teardown, ))

        self.group = phase_group.PhaseGroup(setup=self._setup,
                                            main=self._main,
                                            teardown=self._teardown,
                                            name='group')
Ejemplo n.º 12
0
  def test_with_args(self):
    mock_node = mock.create_autospec(phase_nodes.PhaseNode)
    seq = phase_collections.PhaseSequence(
        nodes=(empty_phase, phase_with_args, mock_node), name='seq')

    updated = seq.with_args(arg1=1, ignored_arg=2)
    self.assertEqual(seq.name, updated.name)
    self.assertEqual(empty_phase, updated.nodes[0])
    self.assertEqual(phase_with_args.with_args(arg1=1), updated.nodes[1])
    self.assertEqual(mock_node.with_args.return_value, updated.nodes[2])
    mock_node.with_args.assert_called_once_with(arg1=1, ignored_arg=2)
Ejemplo n.º 13
0
 def testExecuteTeardown_Normal(self):
     self.mock_execute_node.side_effect = [
         test_executor._ExecutorReturn.CONTINUE
     ]
     sequence = phase_collections.PhaseSequence(_fake_phases('normal'))
     all_phases = list(sequence.all_phases())
     self.assertEqual(
         test_executor._ExecutorReturn.CONTINUE,
         self.test_exec._execute_sequence(sequence, None, True))
     self.mock_execute_node.assert_called_once_with(all_phases[0], None,
                                                    True)
Ejemplo n.º 14
0
  def test_with_plugs(self):
    mock_node = mock.create_autospec(phase_nodes.PhaseNode)
    seq = phase_collections.PhaseSequence(
        nodes=(empty_phase, plug_phase, mock_node), name='seq')

    updated = seq.with_plugs(my_plug=ChildPlug, ignored_plug=ParentPlug)
    self.assertEqual(seq.name, updated.name)
    self.assertEqual(empty_phase, updated.nodes[0])
    self.assertEqual(plug_phase.with_plugs(my_plug=ChildPlug), updated.nodes[1])
    self.assertEqual(mock_node.with_plugs.return_value, updated.nodes[2])
    mock_node.with_plugs.assert_called_once_with(
        my_plug=ChildPlug, ignored_plug=ParentPlug)
Ejemplo n.º 15
0
  def test_apply_to_all_phases(self):
    mock_node = mock.create_autospec(phase_nodes.PhaseNode)
    seq = phase_collections.PhaseSequence(
        nodes=(empty_phase, plug_phase, mock_node), name='seq')

    updated = seq.apply_to_all_phases(_prefix_name)
    self.assertEqual(seq.name, updated.name)
    self.assertEqual(_prefix_name(empty_phase), updated.nodes[0])
    self.assertEqual(_prefix_name(plug_phase), updated.nodes[1])
    self.assertEqual(mock_node.apply_to_all_phases.return_value,
                     updated.nodes[2])
    mock_node.apply_to_all_phases.assert_called_once_with(_prefix_name)
Ejemplo n.º 16
0
  def test_asdict(self):
    expected = {
        'name': 'sequence_name',
        'nodes': [{
            'name': '1'
        }, {
            'name': '2'
        }],
    }
    seq = phase_collections.PhaseSequence(
        _create_nodes('1', '2'), name='sequence_name')

    self.assertEqual(expected, seq._asdict())
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
  def test_load_code_info(self):
    mock_node = mock.create_autospec(phase_nodes.PhaseNode)
    seq = phase_collections.PhaseSequence(
        nodes=(empty_phase, plug_phase, mock_node), name='seq')

    updated = seq.load_code_info()
    self.assertEqual(seq.name, updated.name)
    phases = list(updated.all_phases())
    self.assertEqual(
        test_record.CodeInfo.for_function(empty_phase.func),
        phases[0].code_info)
    self.assertEqual(
        test_record.CodeInfo.for_function(plug_phase.func), phases[1].code_info)
    self.assertEqual(mock_node.load_code_info.return_value, updated.nodes[2])
    mock_node.load_code_info.assert_called_once_with()
Ejemplo n.º 19
0
 def testExecuteAbortable_Terminal(self):
     self.mock_execute_node.side_effect = [
         test_executor._ExecutorReturn.CONTINUE,
         test_executor._ExecutorReturn.TERMINAL
     ]
     sequence = phase_collections.PhaseSequence(
         _fake_phases('normal', 'abort', 'not_run'))
     all_phases = list(sequence.all_phases())
     self.assertEqual(
         test_executor._ExecutorReturn.TERMINAL,
         self.test_exec._execute_sequence(sequence, None, False))
     self.assertEqual([
         mock.call(all_phases[0], None, False),
         mock.call(all_phases[1], None, False)
     ], self.mock_execute_node.call_args_list)
Ejemplo n.º 20
0
 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
Ejemplo n.º 21
0
    def testExecuteAbortable_AbortedDuring(self):
        def execute_node(node, subtest_rec, in_teardown):
            del node  # Unused.
            del subtest_rec  # Unused.
            del in_teardown  # Unused.
            self.test_exec.abort()
            return test_executor._ExecutorReturn.TERMINAL

        self.mock_execute_node.side_effect = execute_node
        sequence = phase_collections.PhaseSequence(
            _fake_phases('abort', 'not-run'))
        all_phases = list(sequence.all_phases())
        self.assertEqual(
            test_executor._ExecutorReturn.TERMINAL,
            self.test_exec._execute_sequence(sequence, None, False))
        self.mock_execute_node.assert_called_once_with(all_phases[0], None,
                                                       False)
Ejemplo n.º 22
0
    def testExecuteTeardown_Terminal(self):
        def execute_node(node, subtest_rec, in_teardown):
            del subtest_rec  # Unused.
            del in_teardown  # Unused.
            if node.name == 'error':
                return test_executor._ExecutorReturn.TERMINAL
            return test_executor._ExecutorReturn.CONTINUE

        self.mock_execute_node.side_effect = execute_node
        sequence = phase_collections.PhaseSequence(
            _fake_phases('error', 'still-run'))
        all_phases = list(sequence.all_phases())
        self.assertEqual(
            test_executor._ExecutorReturn.TERMINAL,
            self.test_exec._execute_sequence(sequence, None, True))
        self.assertEqual([
            mock.call(all_phases[0], None, True),
            mock.call(all_phases[1], None, True)
        ], self.mock_execute_node.call_args_list)
Ejemplo n.º 23
0
 def setUp(self):
     super(TestExecutorExecuteSequencesTest, self).setUp()
     self.test_state = mock.MagicMock(spec=test_state.TestState,
                                      plug_manager=plugs.PlugManager(),
                                      execution_uid='01234567890',
                                      state_logger=mock.MagicMock())
     td = test_descriptor.TestDescriptor(
         phase_sequence=phase_collections.PhaseSequence(
             phase_group.PhaseGroup()),
         code_info=test_record.CodeInfo.uncaptured(),
         metadata={})
     self.test_exec = test_executor.TestExecutor(
         td,
         td.uid,
         None,
         test_descriptor.TestOptions(),
         run_with_profiling=False)
     self.test_exec.test_state = self.test_state
     patcher = mock.patch.object(self.test_exec, '_execute_node')
     self.mock_execute_node = patcher.start()
Ejemplo n.º 24
0
 def _context_wrapper(
         *phases: phase_descriptor.PhaseCallableOrNodeT
 ) -> 'PhaseGroup':
     return cls(setup=data.attr_copy(setup) if setup else None,
                main=phase_collections.PhaseSequence(phases),
                teardown=data.attr_copy(teardown) if teardown else None)
Ejemplo n.º 25
0
 def test_check_duplicates__nested_dupes(self):
   seq = phase_collections.PhaseSequence(
       nodes=(phase_collections.Subtest(
           'dupe', nodes=(phase_collections.Subtest('dupe'),)),))
   with self.assertRaises(phase_collections.DuplicateSubtestNamesError):
     phase_collections.check_for_duplicate_subtest_names(seq)
Ejemplo n.º 26
0
 def test_all_phases(self):
   mock_node = mock.create_autospec(phase_nodes.PhaseNode)
   seq = phase_collections.PhaseSequence(
       nodes=(empty_phase, plug_phase, mock_node), name='seq')
   self.assertEqual([empty_phase, plug_phase], list(seq.all_phases()))
Ejemplo n.º 27
0
 def test_init__nodes_and_args(self):
   with self.assertRaises(ValueError):
     phase_collections.PhaseSequence(phase, nodes=tuple(_create_nodes('1')))
Ejemplo n.º 28
0
  def test_init__single_callable(self):
    expected = phase_collections.PhaseSequence(
        nodes=tuple((phase_descriptor.PhaseDescriptor.wrap_or_copy(phase),)))

    self.assertEqual(expected, phase_collections.PhaseSequence(phase))
Ejemplo n.º 29
0
 def test_init__extra_kwargs(self):
   with self.assertRaises(ValueError):
     phase_collections.PhaseSequence(other=1)