def _add_unknown_events_tests(cls, module, all_events, handled_events): """ Add tests for properly handling of "unknown events," which are events that aren't handled by a particular stage. These operations should be passed up by any stage into the stages that proceed it.. """ unknown_events = all_except(all_items=all_events, items_to_exclude=handled_events) if not unknown_events: return @pytest.mark.describe( "{} - .handle_pipeline_event() -- unknown and unhandled events".format( cls.__name__)) class LocalTestObject(StageHandlePipelineEventTestBase): @pytest.fixture(params=unknown_events) def event(self, request): return make_mock_op_or_event(request.param) @pytest.fixture def stage(self): return cls() @pytest.mark.it("Passes unknown event to previous stage") def test_passes_event_to_previous_stage(self, stage, event, mocker): mocker.spy(stage, "send_event_up") stage.handle_pipeline_event(event) assert stage.send_event_up.call_count == 1 assert stage.send_event_up.call_args == mocker.call(event) setattr(module, "Test{}UnknownEvents".format(cls.__name__), LocalTestObject)
def _add_unknown_ops_tests(cls, module, all_ops, handled_ops): """ Add tests for properly handling of "unknown operations," which are operations that aren't handled by a particular stage. These operations should be passed down by any stage into the stages that follow. """ unknown_ops = all_except(all_items=all_ops, items_to_exclude=handled_ops) @pytest.mark.describe( "{} - .run_op() -- unknown and unhandled operations".format( cls.__name__)) class LocalTestObject(StageRunOpTestBase): @pytest.fixture(params=unknown_ops) def op(self, request, mocker): op = make_mock_op_or_event(request.param) op.callback_stack.append(mocker.MagicMock()) return op @pytest.fixture def stage(self): if cls == PipelineRootStage: return cls(None) else: return cls() @pytest.mark.it("Passes unknown operation down to the next stage") def test_passes_op_to_next_stage(self, mocker, op, stage): mocker.spy(stage, "send_op_down") stage.run_op(op) assert stage.send_op_down.call_count == 1 assert stage.send_op_down.call_args == mocker.call(op) setattr(module, "Test{}UnknownOps".format(cls.__name__), LocalTestObject)
def add_unknown_ops_tests(cls, module, all_ops, handled_ops): """ Add tests for properly handling of "unknown operations," which are operations that aren't handled by a particular stage. These operations should be passed down by any stage into the stages that follow. """ unknown_ops = all_except(all_items=all_ops, items_to_exclude=handled_ops) @pytest.mark.describe("{} - .run_op() -- unknown and unhandled operations".format(cls.__name__)) class LocalTestObject(object): @pytest.fixture def op(self, op_cls, callback): op = make_mock_op_or_event(op_cls) op.callback = callback op.action = "pend" add_mock_method_waiter(op, "callback") return op @pytest.fixture def stage(self, mocker): return make_mock_stage(mocker=mocker, stage_to_make=cls) @pytest.mark.it("Passes unknown operation to next stage") @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage(self, op_cls, op, stage): stage.run_op(op) assert stage.next.run_op.call_count == 1 assert stage.next.run_op.call_args[0][0] == op @pytest.mark.it("Fails unknown operation if there is no next stage") @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_with_no_next_stage(self, op_cls, op, stage): stage.next = None stage.run_op(op) op.wait_for_callback_to_be_called() assert_callback_failed(op=op) @pytest.mark.it("Catches Exceptions raised when passing unknown operation to next stage") @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage_which_throws_exception(self, op_cls, op, stage): op.action = "exception" stage.run_op(op) op.wait_for_callback_to_be_called() assert_callback_failed(op=op) @pytest.mark.it( "Allows BaseExceptions raised when passing unknown operation to next start to propogate" ) @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage_which_throws_base_exception(self, op_cls, op, stage): op.action = "base_exception" with pytest.raises(UnhandledException): stage.run_op(op) setattr(module, "Test{}UnknownOps".format(cls.__name__), LocalTestObject)
def add_unknown_events_tests(cls, module, all_events, handled_events): """ Add tests for properly handling of "unknown events," which are events that aren't handled by a particular stage. These operations should be passed up by any stage into the stages that proceed it.. """ unknown_events = all_except(all_items=all_events, items_to_exclude=handled_events) if not unknown_events: return @pytest.mark.describe( "{} - .handle_pipeline_event() -- unknown and unhandled events".format( cls.__name__)) @pytest.mark.parametrize("event_cls", unknown_events) class LocalTestObject(object): @pytest.fixture def event(self, event_cls): return make_mock_op_or_event(event_cls) @pytest.fixture def stage(self, mocker): return make_mock_stage(mocker=mocker, stage_to_make=cls) @pytest.fixture def previous(self, stage, mocker): class PreviousStage(PipelineStage): def __init__(self): super(PreviousStage, self).__init__() self.handle_pipeline_event = mocker.MagicMock() def _run_op(self, op): pass previous = PreviousStage() stage.previous = previous return previous @pytest.mark.it("Passes unknown event to previous stage") def test_passes_event_to_previous_stage(self, event_cls, stage, event, previous): stage.handle_pipeline_event(event) assert previous.handle_pipeline_event.call_count == 1 assert previous.handle_pipeline_event.call_args[0][0] == event @pytest.mark.it( "Calls unhandled exception handler if there is no previous stage") def test_passes_event_with_no_previous_stage(self, event_cls, stage, event, unhandled_error_handler): stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 1 @pytest.mark.it( "Catches Exceptions raised when passing unknown event to previous stage" ) def test_passes_event_to_previous_stage_which_throws_exception( self, event_cls, stage, event, previous, unhandled_error_handler): e = Exception() previous.handle_pipeline_event.side_effect = e stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 1 assert unhandled_error_handler.call_args[0][0] == e @pytest.mark.it( "Allows BaseExceptions raised when passing unknown operation to next start to propogate" ) def test_passes_event_to_previous_stage_which_throws_base_exception( self, event_cls, stage, event, previous, unhandled_error_handler): e = UnhandledException() previous.handle_pipeline_event.side_effect = e with pytest.raises(UnhandledException): stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 0 setattr(module, "Test{}UnknownEvents".format(cls.__name__), LocalTestObject)
stage.next.send_event_up(iot_response) assert op.callback.call_count == 0 assert unhandled_error_handler.call_count == 0 """ A note on terms in the TimeoutStage tests: No-timeout ops are ops that don't need a timeout check Yes-timeout ops are ops that do need a timeout check """ timeout_intervals = { pipeline_ops_mqtt.MQTTSubscribeOperation: 10, pipeline_ops_mqtt.MQTTUnsubscribeOperation: 10, } yes_timeout_ops = list(timeout_intervals.keys()) no_timeout_ops = all_except(all_common_ops, yes_timeout_ops) pipeline_stage_test.add_base_pipeline_stage_tests( cls=pipeline_stages_base.TimeoutStage, module=this_module, all_ops=all_common_ops, handled_ops=yes_timeout_ops, all_events=all_common_events, handled_events=[], extra_initializer_defaults={"timeout_intervals": timeout_intervals}, ) @pytest.fixture() def mock_timer(mocker): return mocker.patch(
def add_unknown_ops_tests(cls, module, all_ops, handled_ops): """ Add tests for properly handling of "unknown operations," which are operations that aren't handled by a particular stage. These operations should be passed down by any stage into the stages that follow. """ unknown_ops = all_except(all_items=all_ops, items_to_exclude=handled_ops) @pytest.mark.describe( "{} - .run_op() -- unknown and unhandled operations".format( cls.__name__)) class LocalTestObject(StageTestBase): @pytest.fixture def op(self, op_cls, mocker): op = make_mock_op_or_event(op_cls) op.callback = mocker.MagicMock() add_mock_method_waiter(op, "callback") return op @pytest.fixture def stage(self): if cls == PipelineRootStage: return cls(None) else: return cls() @pytest.mark.it("Passes unknown operation to next stage") @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage(self, op_cls, op, stage): stage.run_op(op) assert stage.next.run_op.call_count == 1 assert stage.next.run_op.call_args[0][0] == op @pytest.mark.it("Fails unknown operation if there is no next stage") @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_with_no_next_stage(self, op_cls, op, stage): stage.next = None stage.run_op(op) op.wait_for_callback_to_be_called() assert_callback_failed(op=op) @pytest.mark.it( "Catches Exceptions raised when passing unknown operation to next stage" ) @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage_which_throws_exception( self, op_cls, op, stage, next_stage_raises_arbitrary_exception, arbitrary_exception): stage.run_op(op) op.wait_for_callback_to_be_called() assert_callback_failed(op=op, error=arbitrary_exception) @pytest.mark.it( "Allows BaseExceptions raised when passing unknown operation to next start to propogate" ) @pytest.mark.parametrize("op_cls", unknown_ops) def test_passes_op_to_next_stage_which_throws_base_exception( self, op_cls, op, stage, next_stage_raises_arbitrary_base_exception, arbitrary_base_exception, ): with pytest.raises(arbitrary_base_exception.__class__) as e_info: stage.run_op(op) assert e_info.value is arbitrary_base_exception setattr(module, "Test{}UnknownOps".format(cls.__name__), LocalTestObject)
def add_unknown_events_tests(cls, module, all_events, handled_events): """ Add tests for properly handling of "unknown events," which are events that aren't handled by a particular stage. These operations should be passed up by any stage into the stages that proceed it.. """ unknown_events = all_except(all_items=all_events, items_to_exclude=handled_events) if not unknown_events: return @pytest.mark.describe( "{} - .handle_pipeline_event() -- unknown and unhandled events".format( cls.__name__)) @pytest.mark.parametrize("event_cls", unknown_events) class LocalTestObject(StageTestBase): @pytest.fixture def event(self, event_cls): return make_mock_op_or_event(event_cls) @pytest.fixture def stage(self): return cls() @pytest.fixture def previous(self, stage, stage_base_configuration): return stage.previous @pytest.mark.it("Passes unknown event to previous stage") def test_passes_event_to_previous_stage(self, event_cls, stage, event, previous, mocker): mocker.spy(previous, "handle_pipeline_event") stage.handle_pipeline_event(event) assert previous.handle_pipeline_event.call_count == 1 assert previous.handle_pipeline_event.call_args[0][0] == event @pytest.mark.it( "Calls unhandled exception handler if there is no previous stage") def test_passes_event_with_no_previous_stage(self, event_cls, stage, event, unhandled_error_handler): stage.previous = None stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 1 @pytest.mark.it( "Catches Exceptions raised when passing unknown event to previous stage" ) def test_passes_event_to_previous_stage_which_throws_exception( self, event_cls, stage, event, previous, unhandled_error_handler, arbitrary_exception, mocker, ): previous.handle_pipeline_event = mocker.MagicMock( side_effect=arbitrary_exception) stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 1 assert unhandled_error_handler.call_args[0][ 0] == arbitrary_exception @pytest.mark.it( "Allows BaseExceptions raised when passing unknown operation to next start to propogate" ) def test_passes_event_to_previous_stage_which_throws_base_exception( self, event_cls, stage, event, previous, unhandled_error_handler, arbitrary_base_exception, mocker, ): previous.handle_pipeline_event = mocker.MagicMock( side_effect=arbitrary_base_exception) with pytest.raises(arbitrary_base_exception.__class__) as e_info: stage.handle_pipeline_event(event) assert unhandled_error_handler.call_count == 0 assert e_info.value is arbitrary_base_exception setattr(module, "Test{}UnknownEvents".format(cls.__name__), LocalTestObject)