def test_re_blocks_ops_from_queue(self, stage, mocker):
        first_connect = pipeline_ops_base.ConnectOperation(
            callback=mocker.MagicMock())
        first_fake_op = FakeOperation(callback=mocker.MagicMock())
        second_connect = pipeline_ops_base.ReconnectOperation(
            callback=mocker.MagicMock())
        second_fake_op = FakeOperation(callback=mocker.MagicMock())

        stage.run_op(first_connect)
        stage.run_op(first_fake_op)
        stage.run_op(second_connect)
        stage.run_op(second_fake_op)

        # at this point, ops are pended waiting for the first connect to complete.  Verify this and complete the connect.
        assert stage.next.run_op.call_count == 1
        assert stage.next.run_op.call_args[0][0] == first_connect
        operation_flow.complete_op(stage=stage.next, op=first_connect)

        # The connect is complete.  This passes down first_fake_op and second_connect and second_fake_op gets pended waiting i
        # for second_connect to complete.
        # Note: this isn't ideal.  In a perfect world, second_connect wouldn't start until first_fake_op is complete, but we
        # dont have this logic in place yet.
        assert stage.next.run_op.call_count == 3
        assert stage.next.run_op.call_args_list[1][0][0] == first_fake_op
        assert stage.next.run_op.call_args_list[2][0][0] == second_connect

        # now, complete second_connect to give second_fake_op a chance to get passed down
        operation_flow.complete_op(stage=stage.next, op=second_connect)
        assert stage.next.run_op.call_count == 4
        assert stage.next.run_op.call_args_list[3][0][0] == second_fake_op
 def on_twin_response(twin_op):
     logger.info("{}({}): Got response for GetTwinOperation".format(
         self.name, op.name))
     map_twin_error(original_op=op, twin_op=twin_op)
     if not twin_op.error:
         op.twin = json.loads(twin_op.response_body.decode("utf-8"))
     operation_flow.complete_op(self, op)
Ejemplo n.º 3
0
 def test_op_callback_raises_exception(self, stage, op, fake_exception,
                                       mocker, unhandled_error_handler):
     op.callback = mocker.Mock(side_effect=fake_exception)
     complete_op(stage, op)
     assert op.callback.call_count == 1
     assert op.callback.call_args == mocker.call(op)
     assert unhandled_error_handler.call_count == 1
     assert unhandled_error_handler.call_args == mocker.call(fake_exception)
Ejemplo n.º 4
0
 def on_twin_response(twin_op):
     logger.info(
         "{}({}): Got response for PatchTwinReportedPropertiesOperation operation".format(
             self.name, op.name
         )
     )
     map_twin_error(original_op=op, twin_op=twin_op)
     operation_flow.complete_op(self, op)
Ejemplo n.º 5
0
 def test_runs_second_op(self, mocker, stage, op, op2, op3, finally_op, callback):
     op.action = "pend"
     op2.action = "pend"
     run_ops_in_serial(stage, op, op2, op3, callback=callback, finally_op=finally_op)
     assert stage.next._run_op.call_count == 1
     assert stage.next._run_op.call_args == mocker.call(op)
     complete_op(stage.next, op)
     assert stage.next._run_op.call_args_list[1] == mocker.call(op2)
Ejemplo n.º 6
0
 def test_runs_second_op_after_first_op_succceeds(self, mocker, stage, op, op2, op3, callback):
     op.action = "pend"
     op2.action = "pend"
     run_ops_in_serial(stage, op, op2, op3, callback=callback)
     assert stage.next._run_op.call_count == 1
     assert stage.next._run_op.call_args == mocker.call(op)
     complete_op(stage.next, op)
     assert stage.next._run_op.call_count == 2
     assert stage.next._run_op.call_args_list[1] == mocker.call(op2)
    def test_operation_complete(self, params, op, stage):
        stage.pipeline_root.connected = False

        stage.run_op(op)
        connect_op = stage.next.run_op.call_args[0][0]
        operation_flow.complete_op(stage=stage.next, op=connect_op)

        operation_flow.complete_op(stage=stage.next, op=op)
        assert_callback_succeeded(op=op)
    def test_connect_failure(self, params, op, stage, fake_exception):
        stage.pipeline_root.connected = False

        stage.run_op(op)
        connect_op = stage.next.run_op.call_args[0][0]
        connect_op.error = fake_exception
        operation_flow.complete_op(stage=stage.next, op=connect_op)

        assert_callback_failed(op=op, error=fake_exception)
Ejemplo n.º 9
0
    def test_completes_original_op_after_new_op_completes(self, stage, op, new_op, callback):
        op.callback = callback
        new_op.action = "pend"

        delegate_to_different_op(stage, original_op=op, new_op=new_op)
        assert callback.call_count == 0  # because new_op is pending

        complete_op(stage.next, new_op)
        assert_callback_succeeded(op=op)
Ejemplo n.º 10
0
 def test_calls_third_op_after_second_op_succeeds(self, mocker, stage, op, op2, op3, callback):
     op2.action = "pend"
     run_ops_in_serial(stage, op, op2, op3, callback=callback)
     assert stage.next._run_op.call_count == 2
     assert stage.next._run_op.call_args_list[0] == mocker.call(op)
     assert stage.next._run_op.call_args_list[1] == mocker.call(op2)
     complete_op(stage.next, op2)
     assert stage.next._run_op.call_count == 3
     assert stage.next._run_op.call_args_list[2] == mocker.call(op3)
 def test_fails_blocked_op_if_serialized_op_fails(self, params, stage,
                                                  connection_op, fake_op,
                                                  fake_exception):
     stage.pipeline_root.connected = params[
         "connected_flag_required_to_run"]
     stage.run_op(connection_op)
     stage.run_op(fake_op)
     connection_op.error = fake_exception
     operation_flow.complete_op(stage=stage.next, op=connection_op)
     assert_callback_failed(op=fake_op, error=fake_exception)
    def test_waits_for_serialized_op_to_complete_before_passing_blocked_op(
            self, params, stage, connection_op, fake_op):
        stage.pipeline_root.connected = params[
            "connected_flag_required_to_run"]
        stage.run_op(connection_op)
        stage.run_op(fake_op)
        operation_flow.complete_op(stage=stage.next, op=connection_op)

        assert stage.next.run_op.call_count == 2
        assert stage.next.run_op.call_args[0][0] == fake_op
    def test_connect_success(self, params, op, stage):
        stage.pipeline_root.connected = False

        stage.run_op(op)
        assert stage.next.run_op.call_count == 1
        connect_op = stage.next.run_op.call_args[0][0]
        operation_flow.complete_op(stage=stage.next, op=connect_op)

        assert stage.next.run_op.call_count == 2
        assert stage.next.run_op.call_args[0][0] == op
 def stage_run_op(self, op):
     if getattr(op, "action", None) is None or op.action == "pass":
         operation_flow.complete_op(self, op)
     elif op.action == "fail" or op.action == "exception":
         raise Exception()
     elif op.action == "base_exception":
         raise UnhandledException()
     elif op.action == "pend":
         pass
     else:
         assert False
Ejemplo n.º 15
0
 def on_reconnect_complete(reconnect_op):
     if reconnect_op.error:
         op.error = reconnect_op.error
         logger.error(
             "{}({}) reconnection failed.  returning error {}".
             format(self.name, op.name, op.error))
         operation_flow.complete_op(stage=self, op=op)
     else:
         logger.debug(
             "{}({}) reconnection succeeded.  returning success.".
             format(self.name, op.name))
         operation_flow.complete_op(stage=self, op=op)
    def test_fails_multiple_ops(self, params, stage, connection_op, fake_ops,
                                fake_exception):
        stage.pipeline_root.connected = params[
            "connected_flag_required_to_run"]
        stage.run_op(connection_op)
        for op in fake_ops:
            stage.run_op(op)

        connection_op.error = fake_exception
        operation_flow.complete_op(stage=stage.next, op=connection_op)

        for op in fake_ops:
            assert_callback_failed(op=op, error=fake_exception)
    def test_unblocks_multiple_ops(self, params, stage, connection_op,
                                   fake_ops):
        stage.pipeline_root.connected = params[
            "connected_flag_required_to_run"]
        stage.run_op(connection_op)
        for op in fake_ops:
            stage.run_op(op)

        operation_flow.complete_op(stage=stage.next, op=connection_op)

        assert stage.next.run_op.call_count == 1 + len(fake_ops)

        # zip our ops and our calls together and make sure they match
        run_ops = zip(fake_ops, stage.next.run_op.call_args_list[1:])
        for run_op in run_ops:
            op = run_op[0]
            call_args = run_op[1]
            assert op == call_args[0][0]
    def test_immediately_completes_second_op(self, stage, params, mocker):
        first_connection_op = params["first_connection_op"](mocker.MagicMock())
        second_connection_op = params["second_connection_op"](
            mocker.MagicMock())
        stage.pipeline_root.connected = params["pre_connected_flag"]

        stage.run_op(first_connection_op)
        stage.run_op(second_connection_op)

        # first_connection_op has been passed down.  second_connection_op is waiting for first disconnect to complete.
        assert stage.next.run_op.call_count == 1
        assert stage.next.run_op.call_args[0][0] == first_connection_op

        # complete first_connection_op
        stage.pipeline_root.connected = params["mid_connect_flag"]
        operation_flow.complete_op(stage=stage.next, op=first_connection_op)

        # second connect_op should be completed without having been passed down.
        assert stage.next.run_op.call_count == 1
        assert_callback_succeeded(op=second_connection_op)
Ejemplo n.º 19
0
            def on_token_update_complete(op):
                op.callback = old_callback
                if op.error:
                    logger.error(
                        "{}({}) token update failed.  returning failure {}".
                        format(self.name, op.name, op.error))
                    operation_flow.complete_op(stage=self, op=op)
                else:
                    logger.debug(
                        "{}({}) token update succeeded.  reconnecting".format(
                            self.name, op.name))

                    operation_flow.pass_op_to_next_stage(
                        stage=self,
                        op=pipeline_ops_base.ReconnectOperation(
                            callback=on_reconnect_complete),
                    )

                logger.debug(
                    "{}({}): passing to next stage with updated callback.".
                    format(self.name, op.name))
 def fail_set_auth_provider(self, op):
     if isinstance(op, params_security_clients["set_args_op_class"]):
         op.error = fake_exception
         operation_flow.complete_op(stage=self, op=op)
     else:
         old_execute_op(self, op)
Ejemplo n.º 21
0
 def test_op_callback_raises_base_exception(self, stage, op,
                                            fake_base_exception, mocker):
     op.callback = mocker.Mock(side_effect=fake_base_exception)
     with pytest.raises(UnhandledException):
         complete_op(stage, op)
Ejemplo n.º 22
0
 def test_calls_callback_on_error(self, stage, op, callback,
                                  fake_exception):
     op.error = fake_exception
     op.callback = callback
     complete_op(stage, op)
     assert_callback_failed(op=op, error=fake_exception)
Ejemplo n.º 23
0
 def test_calls_callback_on_success(self, stage, op, callback):
     op.callback = callback
     complete_op(stage, op)
     assert_callback_succeeded(op)
 def fail_set_auth_provider(self, op):
     if isinstance(op, pipeline_stages_base.SetX509AuthProviderOperation):
         op.error = fake_exception
         operation_flow.complete_op(stage=self, op=op)
     else:
         old_execute_op(self, op)