def test_handle_timer_fired(decider, mock_decision_context: DecisionContext): event = HistoryEvent() event.timer_fired_event_attributes = TimerFiredEventAttributes() decider.handle_timer_fired(event) mock_decision_context.handle_timer_fired.assert_called_once() args, kwargs = mock_decision_context.handle_timer_fired.call_args_list[0] assert args[0] is event.timer_fired_event_attributes
def test_handle_timer_started(decider, mock_decision: DecisionStateMachine): event = HistoryEvent() event.event_id = DECISION_EVENT_ID decider.handle_timer_started(event) mock_decision.handle_initiated_event.assert_called_once() args, kwargs = mock_decision.handle_initiated_event.call_args_list[0] assert args[0] is event
def test_handle_timer_canceled(decider, mock_decision: DecisionStateMachine): event = HistoryEvent() event.timer_canceled_event_attributes = TimerCanceledEventAttributes() event.timer_canceled_event_attributes.started_event_id = DECISION_EVENT_ID ret = decider.handle_timer_canceled(event) assert ret is True mock_decision.handle_cancellation_event.assert_called_once()
def test_handle_cancel_timer_failed(decider, mock_decision: DecisionStateMachine): event = HistoryEvent() event.event_id = DECISION_EVENT_ID ret = decider.handle_cancel_timer_failed(event) assert ret is True mock_decision.handle_cancellation_failure_event.assert_called_once() args, kwargs = mock_decision.handle_cancellation_failure_event.call_args_list[0] assert args[0] is event
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 marker_recorded_event(marker_header_json): event = HistoryEvent() event.event_id = 20 event.event_type = EventType.MarkerRecorded event.marker_recorded_event_attributes = MarkerRecordedEventAttributes() event.marker_recorded_event_attributes.marker_name = "the-marker-name" event.marker_recorded_event_attributes.header = Header() event.marker_recorded_event_attributes.header.fields[MUTABLE_MARKER_HEADER_KEY] = bytes(marker_header_json, "utf-8") event.marker_recorded_event_attributes.details = b'blah-blah' return event
def test_handle_activity_task_started(self): state_machine: DecisionStateMachine = Mock() self.decider.decisions[DecisionId(DecisionTarget.ACTIVITY, 10)] = state_machine event = HistoryEvent(event_id=15) event.activity_task_started_event_attributes = ActivityTaskStartedEventAttributes() event.activity_task_started_event_attributes.scheduled_event_id = 10 self.decider.handle_activity_task_started(event) state_machine.handle_started_event.assert_called() args, kwargs = state_machine.handle_started_event.call_args_list[0] self.assertIn(event, args)
def version_marker_recorded_event(marker_header_json): marker_header_json = MarkerHeader(id="abc", event_id=55, access_count=0).to_json() event = HistoryEvent() event.event_id = 20 event.event_type = EventType.MarkerRecorded event.marker_recorded_event_attributes = MarkerRecordedEventAttributes() event.marker_recorded_event_attributes.marker_name = VERSION_MARKER_NAME event.marker_recorded_event_attributes.header = Header() event.marker_recorded_event_attributes.header.fields[MUTABLE_MARKER_HEADER_KEY] = bytes(marker_header_json, "utf-8") event.marker_recorded_event_attributes.details = b'4' return event
def test_handle_timer_canceled(clock_decision_context, decider, request_info): event = HistoryEvent() event.timer_canceled_event_attributes = TimerCanceledEventAttributes() event.timer_canceled_event_attributes.started_event_id = START_TIMER_ID clock_decision_context.handle_timer_canceled(event) assert len(clock_decision_context.scheduled_timers) == 0 decider.handle_timer_canceled.assert_called_once() request_info.completion_handle.assert_called_once() args, kwargs = request_info.completion_handle.call_args_list[0] assert args[0] is None assert isinstance(args[1], Exception)
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_handle_decision_task_failed(self): event = HistoryEvent(event_id=15) event.event_type = EventType.DecisionTaskFailed event.decision_task_failed_event_attributes = DecisionTaskFailedEventAttributes( ) event.decision_task_failed_event_attributes.cause = DecisionTaskFailedCause.RESET_WORKFLOW event.decision_task_failed_event_attributes.new_run_id = "the-new-run-id" self.decider.decision_context = decision_context = MagicMock() self.decider.handle_decision_task_failed(event) decision_context.set_current_run_id.assert_called() args, kwargs = decision_context.set_current_run_id.call_args_list[0] assert args[0] == "the-new-run-id"
def test_process_decision_events_notifies_when_replay(self): self.decider.event_loop = Mock() events = [ HistoryEvent(event_type=EventType.WorkflowExecutionStarted, workflow_execution_started_event_attributes=WorkflowExecutionStartedEventAttributes()), HistoryEvent(event_type=EventType.DecisionTaskScheduled) ] decision_events = DecisionEvents(events, [], replay=True, replay_current_time_milliseconds=0, next_decision_event_id=5) self.decider.notify_decision_sent = MagicMock() self.decider.process_decision_events(decision_events) self.decider.notify_decision_sent.assert_called_once()
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" attr.details = bytes("details", "utf-8") self.context.handle_activity_task_failed(event) self.assertTrue(self.future.done()) exception = self.future.exception() self.assertIsInstance(exception, ActivityTaskFailedException) self.assertEqual(attr.reason, exception.reason) self.assertEqual(attr.details, exception.details) self.assertEqual(0, len(self.context.scheduled_activities))
def test_markers(): marker = HistoryEvent(event_type=EventType.MarkerRecorded) events = [ HistoryEvent(event_type=EventType.WorkflowExecutionStarted), HistoryEvent(event_type=EventType.ActivityTaskScheduled), HistoryEvent(event_type=EventType.ActivityTaskCanceled), marker ] decision_events = DecisionEvents(events=[], decision_events=events, replay=True, replay_current_time_milliseconds=0, next_decision_event_id=10) assert len(decision_events.markers) == 1 assert id(decision_events.markers[0]) == id(marker)
def test_handle_workflow_execution_signaled(decider, workflow_task): assert isinstance(MagicMock, object) event = HistoryEvent() event.workflow_execution_signaled_event_attributes = WorkflowExecutionSignaledEventAttributes() event.workflow_execution_signaled_event_attributes.signal_name = "DummyWorkflow::the_signal_method" event.workflow_execution_signaled_event_attributes.input = json.dumps(["bob", 28]); decider.handle_workflow_execution_signaled(event) assert decider.tasks task = decider.tasks[0] assert task.signal_name == "DummyWorkflow::the_signal_method" assert task.signal_input == ["bob", 28] assert task.decider == decider assert task.task_id == "run-id" assert task.status == Status.CREATED
def test_list(self): history = History() history_event = HistoryEvent() history.events.append(history_event) thrift_object = copy_py_to_thrift(history) self.assertIsInstance(thrift_object, cadence_thrift.shared.History) self.assertEqual(1, len(thrift_object.events))
def test_handle_cancellation_failure_event( timer_dsm: TimerDecisionStateMachine): timer_dsm.state = DecisionState.CANCELLATION_DECISION_SENT timer_dsm.handle_cancellation_failure_event(HistoryEvent()) assert "handle_cancellation_failure_event" in timer_dsm.state_history assert timer_dsm.state == DecisionState.INITIATED assert str(timer_dsm.state) in timer_dsm.state_history
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 make_history(event_types: List[EventType]) -> List[HistoryEvent]: history = [] for offset, event_type in enumerate(event_types): history.append( HistoryEvent(event_id=offset + 1, event_type=event_type, timestamp=0)) return history
def test_copy_with_enum(self): event: HistoryEvent = HistoryEvent() event.event_type = EventType.ActivityTaskFailed thrift_object = copy_py_to_thrift(event) self.assertIsInstance(thrift_object, cadence_thrift.shared.HistoryEvent) self.assertEqual(EventType.ActivityTaskFailed, thrift_object.eventType) self.assertIsInstance(thrift_object.eventType, int) self.assertEqual(int(EventType.ActivityTaskFailed), thrift_object.eventType)
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_handle_marker_recorded_version(clock_decision_context): event = HistoryEvent(event_type=EventType.MarkerRecorded) event.marker_recorded_event_attributes = MarkerRecordedEventAttributes() event.marker_recorded_event_attributes.details = "Blahh" event.marker_recorded_event_attributes.marker_name = VERSION_MARKER_NAME event.marker_recorded_event_attributes.header = Header() event.marker_recorded_event_attributes.header.fields[ MUTABLE_MARKER_HEADER_KEY] = bytes( json.dumps({ "id": "the-id", "eventId": 20, "accessCount": 0 }), "utf-8") clock_decision_context.handle_marker_recorded(event) assert "the-id" in clock_decision_context.version_handler.mutable_marker_results assert clock_decision_context.version_handler.mutable_marker_results[ "the-id"].data == "Blahh"
def test_process_decision_events_markers_first(self): self.decider.event_loop = Mock() marker_event = HistoryEvent(event_type=EventType.MarkerRecorded) marker_event.marker_recorded_event_attributes = MarkerRecordedEventAttributes( ) marker_event.marker_recorded_event_attributes.marker_name = VERSION_MARKER_NAME events = [ HistoryEvent(event_type=EventType.WorkflowExecutionStarted, workflow_execution_started_event_attributes= WorkflowExecutionStartedEventAttributes()), HistoryEvent(event_type=EventType.DecisionTaskScheduled), marker_event ] decision_events = DecisionEvents([], events, replay=True, replay_current_time_milliseconds=0, next_decision_event_id=5) self.decider.process_event = Mock() self.decider.process_decision_events(decision_events) self.decider.process_event.assert_called() assert len(self.decider.process_event.call_args_list) == 4 args, kwargs = self.decider.process_event.call_args_list[0] assert id(args[0]) == id(marker_event)
def test_false(self): event = HistoryEvent(event_type=EventType.WorkflowExecutionStarted) self.assertFalse(is_decision_event(event))
def test_true(self): event = HistoryEvent(event_type=EventType.ActivityTaskScheduled) self.assertTrue(is_decision_event(event))
def test_handle_initiated_event_canceled_before_initiated(self): self.state_machine.state = DecisionState.CANCELED_BEFORE_INITIATED self.state_machine.handle_initiated_event(HistoryEvent()) self.assertEqual(DecisionState.CANCELED_AFTER_INITIATED, self.state_machine.state)
def test_handle_initiation_failed_event(self): for state in (DecisionState.INITIATED, DecisionState.DECISION_SENT, DecisionState.CANCELED_BEFORE_INITIATED): self.state_machine.state = state self.state_machine.handle_initiation_failed_event(HistoryEvent()) self.assertEqual(DecisionState.COMPLETED, self.state_machine.state)
def test_handled_started_event(self): self.state_machine.handle_started_event(HistoryEvent())
def test_handle_cancellation_failure_event(self): self.state_machine.state = DecisionState.COMPLETED_AFTER_CANCELLATION_DECISION_SENT self.state_machine.handle_cancellation_failure_event(HistoryEvent()) self.assertEqual(DecisionState.COMPLETED, self.state_machine.state)
def event_object(): return HistoryEvent()