예제 #1
0
def test_record_marker(decider, header):
    decision_context = DecisionContext(decider=decider)
    decision_context.record_marker("marker-name", header, bytes())
    assert len(decider.decisions) == 1
    decision_id: DecisionId
    state_machine: MarkerDecisionStateMachine
    decision_id, state_machine = list(decider.decisions.items())[0]
    assert decision_id.decision_event_id == DECISION_EVENT_ID
    assert decision_id.decision_target == DecisionTarget.MARKER
    assert state_machine.decision.decision_type == DecisionType.RecordMarker
    attr = state_machine.decision.record_marker_decision_attributes
    assert attr.marker_name == "marker-name"
    assert attr.header == header
    assert attr.details == bytes()
예제 #2
0
def decision_context(event_loop):
    decider: ReplayDecider = Mock()
    decider.get_and_increment_next_id = MagicMock(return_value="0")
    decider.event_loop = event_loop
    decision_context = DecisionContext(decider=decider)
    decider.decision_context = decision_context
    return decision_context
예제 #3
0
 def setUp(self) -> None:
     self.event_loop: AbstractEventLoop = asyncio.get_event_loop()
     self.decider: ReplayDecider = Mock()
     self.decider.get_and_increment_next_id = MagicMock(return_value="0")
     self.decider.event_loop = Mock()
     self.future = self.event_loop.create_future()
     self.decider.event_loop.create_future = MagicMock(
         return_value=self.future)
     self.context = DecisionContext(decider=self.decider)
     self.params = ExecuteActivityParameters()
     self.params.input = bytes(json.dumps([1, 2, 3]), "utf-8")
     self.params.heartbeat_timeout_seconds = 10
     self.params.schedule_to_close_timeout_seconds = 20
     self.params.schedule_to_start_timeout_seconds = 30
     self.params.start_to_close_timeout_seconds = 40
     self.params.activity_type = ActivityType()
     self.params.activity_type.name = "Activity::activity"
     self.params.task_list = "the-task-list"
예제 #4
0
def version_decision_context(version_marker_recorded_event):
    decider = ReplayDecider(execution_id=Mock(), workflow_type=Mock(), worker=Mock())
    decision_context = DecisionContext(decider=decider)
    decider.decision_context = decision_context
    decider.decision_context.workflow_clock.version_handler.decision_context = decision_context
    decision_context.decider.decision_events = DecisionEvents(events=[],
                                                              decision_events=[version_marker_recorded_event],
                                                              replay=True,
                                                              replay_current_time_milliseconds=0,
                                                              next_decision_event_id=20)
    decision_context.decider.next_decision_event_id = 20
    return decision_context
예제 #5
0
class TestScheduleActivity(TestCase):
    def setUp(self) -> None:
        self.event_loop: AbstractEventLoop = asyncio.get_event_loop()
        self.decider: ReplayDecider = Mock()
        self.decider.get_and_increment_next_id = MagicMock(return_value="0")
        self.decider.event_loop = Mock()
        self.future = self.event_loop.create_future()
        self.decider.event_loop.create_future = MagicMock(
            return_value=self.future)
        self.context = DecisionContext(decider=self.decider)
        self.params = ExecuteActivityParameters()
        self.params.input = bytes(json.dumps([1, 2, 3]), "utf-8")
        self.params.heartbeat_timeout_seconds = 10
        self.params.schedule_to_close_timeout_seconds = 20
        self.params.schedule_to_start_timeout_seconds = 30
        self.params.start_to_close_timeout_seconds = 40
        self.params.activity_type = ActivityType()
        self.params.activity_type.name = "Activity::activity"
        self.params.task_list = "the-task-list"

    def test_schedule(self):
        self.task = self.event_loop.create_task(
            self.context.schedule_activity_task(self.params))
        run_once(self.event_loop)
        self.assertEqual(1, len(self.context.scheduled_activities))
        self.decider.schedule_activity_task.assert_called_once()
        args, kwargs = self.decider.schedule_activity_task.call_args_list[0]
        attr: ScheduleActivityTaskDecisionAttributes = kwargs["schedule"]
        self.assertEqual("Activity::activity", attr.activity_type.name)
        self.assertEqual("the-task-list", attr.task_list.name)
        self.assertEqual(b"[1, 2, 3]", attr.input)
        self.assertEqual(10, attr.heartbeat_timeout_seconds)
        self.assertEqual(20, attr.schedule_to_close_timeout_seconds)
        self.assertEqual(30, attr.schedule_to_start_timeout_seconds)
        self.assertEqual(40, attr.start_to_close_timeout_seconds)
        self.assertEqual("0", attr.activity_id)

    def test_custom_activity_id(self):
        self.params.activity_id = "20"
        self.task = self.event_loop.create_task(
            self.context.schedule_activity_task(self.params))
        run_once(self.event_loop)
        args, kwargs = self.decider.schedule_activity_task.call_args_list[0]
        attr: ScheduleActivityTaskDecisionAttributes = kwargs["schedule"]
        self.assertEqual("20", attr.activity_id)

    def test_return_value(self):
        self.decider.schedule_activity_task = MagicMock(return_value=20)
        self.task = self.event_loop.create_task(
            self.context.schedule_activity_task(self.params))

        run_once(self.event_loop)
        self.assertFalse(self.task.done())
        future = self.context.scheduled_activities[20]
        self.assertIs(self.future, future)

        activity_ret_value = {"name": "this-is-python"}
        future.set_result(bytes(json.dumps(activity_ret_value), "utf-8"))
        run_once(self.event_loop)
        self.assertTrue(self.task.done())
        result = self.task.result()
        self.assertEqual(result, activity_ret_value)

    def test_raise_exception(self):
        self.decider.schedule_activity_task = MagicMock(return_value=20)
        self.task = self.event_loop.create_task(
            self.context.schedule_activity_task(self.params))

        run_once(self.event_loop)
        self.assertFalse(self.task.done())

        future = self.context.scheduled_activities[20]
        exception = DummyUserLevelException("thrown by activity")
        future.set_exception(exception)
        run_once(self.event_loop)
        self.assertTrue(self.task.done())

        raised_exception = self.task.exception()
        self.assertIsInstance(raised_exception, ActivityFailureException)
        self.assertEqual(repr(exception), repr(raised_exception.get_cause()))

    def tearDown(self) -> None:
        self.task.cancel()
예제 #6
0
 def setUp(self) -> None:
     self.decider: ReplayDecider = Mock()
     self.decider.handle_activity_task_closed = MagicMock(return_value=True)
     self.context = DecisionContext(decider=self.decider)
     self.future: Future = Future()
     self.context.scheduled_activities[20] = self.future
예제 #7
0
class TestHandleActivityTaskEvents(TestCase):
    def setUp(self) -> None:
        self.decider: ReplayDecider = Mock()
        self.decider.handle_activity_task_closed = MagicMock(return_value=True)
        self.context = DecisionContext(decider=self.decider)
        self.future: Future = Future()
        self.context.scheduled_activities[20] = self.future

    def test_handle_activity_task_completed(self):
        event = HistoryEvent(event_type=EventType.ActivityTaskCompleted)
        attr = ActivityTaskCompletedEventAttributes()
        self.payload = {"name": "bob"}
        attr.scheduled_event_id = 20
        attr.result = bytes(json.dumps(self.payload), "utf-8")
        event.activity_task_completed_event_attributes = attr
        self.context.handle_activity_task_completed(event)
        self.assertTrue(self.future.done())
        result = self.future.result()
        self.assertIs(attr.result, result)
        self.assertEqual(0, len(self.context.scheduled_activities))

    def test_non_deterministic(self):
        event = HistoryEvent(event_type=EventType.ActivityTaskCompleted)
        attr = ActivityTaskCompletedEventAttributes()
        attr.scheduled_event_id = 9999
        event.activity_task_completed_event_attributes = attr
        with self.assertRaises(NonDeterministicWorkflowException):
            self.context.handle_activity_task_completed(event)
        self.assertFalse(self.future.done())

    def test_activity_task_failed(self):
        event = HistoryEvent(event_type=EventType.ActivityTaskFailed)
        attr = ActivityTaskFailedEventAttributes()
        attr.scheduled_event_id = 20
        event.activity_task_failed_event_attributes = attr
        attr.reason = "the-reason"
        ex = None
        try:
            raise DummyUserLevelException("abc")
        except Exception as e:
            ex = e
        attr.details = serialize_exception(ex)
        self.context.handle_activity_task_failed(event)
        self.assertTrue(self.future.done())
        exception = self.future.exception()
        self.assertIsInstance(exception, DummyUserLevelException)
        self.assertEqual(0, len(self.context.scheduled_activities))

    def test_activity_task_timed_out(self):
        event = HistoryEvent(event_type=EventType.ActivityTaskTimedOut)
        event.event_id = 25
        attr = ActivityTaskTimedOutEventAttributes()
        attr.scheduled_event_id = 20
        attr.details = bytes("details", "utf-8")
        attr.timeout_type = TimeoutType.HEARTBEAT
        event.activity_task_timed_out_event_attributes = attr
        self.context.handle_activity_task_timed_out(event)
        self.assertTrue(self.future.done())
        exception = self.future.exception()
        self.assertIsInstance(exception, ActivityTaskTimeoutException)
        self.assertEqual(event.event_id, exception.event_id)
        self.assertEqual(attr.timeout_type, exception.timeout_type)
        self.assertEqual(attr.details, exception.details)
        self.assertEqual(0, len(self.context.scheduled_activities))
def test_set_replaying(decision_context: DecisionContext,
                       workflow_clock: ClockDecisionContext):
    decision_context.set_replaying(False)
    workflow_clock.set_replaying.assert_called_once()
    args, kwargs = workflow_clock.set_replaying.call_args_list[0]
    assert args[0] is False
def test_current_time_millis(decision_context: DecisionContext):
    assert decision_context.current_time_millis() == CURRENT_TIME_MILLISECONDS
def decision_context(workflow_clock: ClockDecisionContext):
    decider = MagicMock()
    context = DecisionContext(decider, workflow_clock=workflow_clock)
    return context