azure-functions-durable 1.2.8__py3-none-any.whl → 1.2.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. azure/durable_functions/__init__.py +81 -81
  2. azure/durable_functions/constants.py +9 -9
  3. azure/durable_functions/decorators/__init__.py +3 -3
  4. azure/durable_functions/decorators/durable_app.py +249 -249
  5. azure/durable_functions/decorators/metadata.py +109 -109
  6. azure/durable_functions/entity.py +125 -125
  7. azure/durable_functions/models/DurableEntityContext.py +201 -201
  8. azure/durable_functions/models/DurableHttpRequest.py +58 -58
  9. azure/durable_functions/models/DurableOrchestrationBindings.py +66 -66
  10. azure/durable_functions/models/DurableOrchestrationClient.py +781 -711
  11. azure/durable_functions/models/DurableOrchestrationContext.py +722 -707
  12. azure/durable_functions/models/DurableOrchestrationStatus.py +156 -156
  13. azure/durable_functions/models/EntityStateResponse.py +23 -23
  14. azure/durable_functions/models/FunctionContext.py +7 -7
  15. azure/durable_functions/models/OrchestrationRuntimeStatus.py +32 -29
  16. azure/durable_functions/models/OrchestratorState.py +117 -116
  17. azure/durable_functions/models/PurgeHistoryResult.py +33 -33
  18. azure/durable_functions/models/ReplaySchema.py +8 -8
  19. azure/durable_functions/models/RetryOptions.py +69 -69
  20. azure/durable_functions/models/RpcManagementOptions.py +86 -86
  21. azure/durable_functions/models/Task.py +426 -426
  22. azure/durable_functions/models/TaskOrchestrationExecutor.py +346 -333
  23. azure/durable_functions/models/TokenSource.py +56 -56
  24. azure/durable_functions/models/__init__.py +24 -24
  25. azure/durable_functions/models/actions/Action.py +23 -23
  26. azure/durable_functions/models/actions/ActionType.py +18 -18
  27. azure/durable_functions/models/actions/CallActivityAction.py +41 -41
  28. azure/durable_functions/models/actions/CallActivityWithRetryAction.py +45 -45
  29. azure/durable_functions/models/actions/CallEntityAction.py +46 -46
  30. azure/durable_functions/models/actions/CallHttpAction.py +35 -35
  31. azure/durable_functions/models/actions/CallSubOrchestratorAction.py +40 -40
  32. azure/durable_functions/models/actions/CallSubOrchestratorWithRetryAction.py +44 -44
  33. azure/durable_functions/models/actions/CompoundAction.py +35 -35
  34. azure/durable_functions/models/actions/ContinueAsNewAction.py +36 -36
  35. azure/durable_functions/models/actions/CreateTimerAction.py +48 -48
  36. azure/durable_functions/models/actions/NoOpAction.py +35 -35
  37. azure/durable_functions/models/actions/SignalEntityAction.py +47 -47
  38. azure/durable_functions/models/actions/WaitForExternalEventAction.py +63 -63
  39. azure/durable_functions/models/actions/WhenAllAction.py +14 -14
  40. azure/durable_functions/models/actions/WhenAnyAction.py +14 -14
  41. azure/durable_functions/models/actions/__init__.py +24 -24
  42. azure/durable_functions/models/entities/EntityState.py +74 -74
  43. azure/durable_functions/models/entities/OperationResult.py +76 -76
  44. azure/durable_functions/models/entities/RequestMessage.py +53 -53
  45. azure/durable_functions/models/entities/ResponseMessage.py +48 -48
  46. azure/durable_functions/models/entities/Signal.py +62 -62
  47. azure/durable_functions/models/entities/__init__.py +17 -17
  48. azure/durable_functions/models/history/HistoryEvent.py +92 -92
  49. azure/durable_functions/models/history/HistoryEventType.py +27 -25
  50. azure/durable_functions/models/history/__init__.py +8 -8
  51. azure/durable_functions/models/utils/__init__.py +7 -7
  52. azure/durable_functions/models/utils/entity_utils.py +103 -91
  53. azure/durable_functions/models/utils/http_utils.py +69 -69
  54. azure/durable_functions/models/utils/json_utils.py +56 -56
  55. azure/durable_functions/orchestrator.py +71 -71
  56. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/LICENSE +21 -21
  57. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/METADATA +58 -58
  58. azure_functions_durable-1.2.10.dist-info/RECORD +100 -0
  59. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/WHEEL +1 -1
  60. tests/models/test_DecoratorMetadata.py +135 -135
  61. tests/models/test_Decorators.py +107 -107
  62. tests/models/test_DurableOrchestrationBindings.py +68 -56
  63. tests/models/test_DurableOrchestrationClient.py +730 -612
  64. tests/models/test_DurableOrchestrationContext.py +102 -102
  65. tests/models/test_DurableOrchestrationStatus.py +59 -59
  66. tests/models/test_OrchestrationState.py +28 -28
  67. tests/models/test_RpcManagementOptions.py +79 -79
  68. tests/models/test_TokenSource.py +10 -10
  69. tests/orchestrator/models/OrchestrationInstance.py +18 -18
  70. tests/orchestrator/orchestrator_test_utils.py +130 -130
  71. tests/orchestrator/schemas/OrchetrationStateSchema.py +66 -66
  72. tests/orchestrator/test_call_http.py +235 -176
  73. tests/orchestrator/test_continue_as_new.py +67 -67
  74. tests/orchestrator/test_create_timer.py +126 -126
  75. tests/orchestrator/test_entity.py +395 -395
  76. tests/orchestrator/test_external_event.py +53 -53
  77. tests/orchestrator/test_fan_out_fan_in.py +175 -175
  78. tests/orchestrator/test_is_replaying_flag.py +101 -101
  79. tests/orchestrator/test_retries.py +308 -308
  80. tests/orchestrator/test_sequential_orchestrator.py +841 -801
  81. tests/orchestrator/test_sequential_orchestrator_custom_status.py +119 -119
  82. tests/orchestrator/test_sequential_orchestrator_with_retry.py +465 -465
  83. tests/orchestrator/test_serialization.py +30 -30
  84. tests/orchestrator/test_sub_orchestrator.py +95 -95
  85. tests/orchestrator/test_sub_orchestrator_with_retry.py +129 -129
  86. tests/orchestrator/test_task_any.py +60 -60
  87. tests/tasks/tasks_test_utils.py +17 -17
  88. tests/tasks/test_new_uuid.py +34 -34
  89. tests/test_utils/ContextBuilder.py +174 -174
  90. tests/test_utils/EntityContextBuilder.py +56 -56
  91. tests/test_utils/constants.py +1 -1
  92. tests/test_utils/json_utils.py +30 -30
  93. tests/test_utils/testClasses.py +56 -56
  94. tests/utils/__init__.py +1 -0
  95. tests/utils/test_entity_utils.py +24 -0
  96. azure_functions_durable-1.2.8.data/data/_manifest/bsi.json +0 -1
  97. azure_functions_durable-1.2.8.data/data/_manifest/manifest.cat +0 -0
  98. azure_functions_durable-1.2.8.data/data/_manifest/manifest.spdx.json +0 -12845
  99. azure_functions_durable-1.2.8.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  100. azure_functions_durable-1.2.8.dist-info/RECORD +0 -102
  101. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/top_level.txt +0 -0
@@ -1,31 +1,31 @@
1
- from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
- from tests.test_utils.ContextBuilder import ContextBuilder
3
- from .orchestrator_test_utils \
4
- import get_orchestration_state_result, assert_orchestration_state_equals, assert_valid_schema
5
- from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
-
7
- def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
8
- return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
9
-
10
- def generator_function(context):
11
- return False
12
-
13
- def test_serialization_of_False():
14
- """Test that an orchestrator can return False."""
15
-
16
- context_builder = ContextBuilder("serialize False")
17
-
18
- result = get_orchestration_state_result(
19
- context_builder, generator_function)
20
-
21
- expected_state = base_expected_state(output=False)
22
-
23
- expected_state._is_done = True
24
- expected = expected_state.to_json()
25
-
26
- # Since we're essentially testing the `to_json` functionality,
27
- # we explicitely ensure that the output is set
28
- expected["output"] = False
29
-
30
- assert_valid_schema(result)
1
+ from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
+ from tests.test_utils.ContextBuilder import ContextBuilder
3
+ from .orchestrator_test_utils \
4
+ import get_orchestration_state_result, assert_orchestration_state_equals, assert_valid_schema
5
+ from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
+
7
+ def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
8
+ return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
9
+
10
+ def generator_function(context):
11
+ return False
12
+
13
+ def test_serialization_of_False():
14
+ """Test that an orchestrator can return False."""
15
+
16
+ context_builder = ContextBuilder("serialize False")
17
+
18
+ result = get_orchestration_state_result(
19
+ context_builder, generator_function)
20
+
21
+ expected_state = base_expected_state(output=False)
22
+
23
+ expected_state._is_done = True
24
+ expected = expected_state.to_json()
25
+
26
+ # Since we're essentially testing the `to_json` functionality,
27
+ # we explicitely ensure that the output is set
28
+ expected["output"] = False
29
+
30
+ assert_valid_schema(result)
31
31
  assert_orchestration_state_equals(expected, result)
@@ -1,95 +1,95 @@
1
- from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
- from .orchestrator_test_utils \
3
- import assert_orchestration_state_equals, get_orchestration_state_result, assert_valid_schema
4
- from tests.test_utils.ContextBuilder import ContextBuilder
5
- from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
- from azure.durable_functions.models.actions.CallSubOrchestratorAction \
7
- import CallSubOrchestratorAction
8
- import azure.durable_functions as df
9
- import azure.functions as func
10
-
11
- app = df.DFApp(http_auth_level=func.AuthLevel.ANONYMOUS)
12
-
13
- def generator_function(context):
14
- outputs = []
15
- task1 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "Tokyo")
16
- task2 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "Seattle")
17
- task3 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "London")
18
-
19
- outputs.append(task1)
20
- outputs.append(task2)
21
- outputs.append(task3)
22
-
23
- return outputs
24
-
25
- def generator_function_call_by_function_name(context):
26
- outputs = []
27
- task1 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "Tokyo")
28
- task2 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "Seattle")
29
- task3 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "London")
30
-
31
- outputs.append(task1)
32
- outputs.append(task2)
33
- outputs.append(task3)
34
-
35
- return outputs
36
-
37
- @app.orchestration_trigger(context_name="context")
38
- def HelloSubOrchestrator(context):
39
- return "Hello" + context
40
-
41
- def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
42
- return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
43
-
44
-
45
- def add_hello_suborch_action(state: OrchestratorState, input_: str):
46
- action = CallSubOrchestratorAction(function_name='HelloSubOrchestrator', _input=input_)
47
- state.actions.append([action])
48
-
49
-
50
- def add_hello_suborch_completed_events(
51
- context_builder: ContextBuilder, id_: int, result: str):
52
- context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
53
- context_builder.add_orchestrator_completed_event()
54
- context_builder.add_orchestrator_started_event()
55
- context_builder.add_sub_orchestrator_completed_event(result=result, id_=id_)
56
-
57
- def test_tokyo_and_seattle_and_london_state():
58
- context_builder = ContextBuilder('test_simple_function')
59
- add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
60
- add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
61
- add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
62
-
63
- result = get_orchestration_state_result(
64
- context_builder, generator_function)
65
-
66
- expected_state = base_expected_state(
67
- ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
68
- add_hello_suborch_action(expected_state, 'Tokyo')
69
- add_hello_suborch_action(expected_state, 'Seattle')
70
- add_hello_suborch_action(expected_state, 'London')
71
- expected_state._is_done = True
72
- expected = expected_state.to_json()
73
-
74
- #assert_valid_schema(result)
75
- assert_orchestration_state_equals(expected, result)
76
-
77
- def test_call_suborchestrator_by_name():
78
- context_builder = ContextBuilder('test_call_suborchestrator_by_name')
79
- add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
80
- add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
81
- add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
82
-
83
- result = get_orchestration_state_result(
84
- context_builder, generator_function_call_by_function_name)
85
-
86
- expected_state = base_expected_state(
87
- ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
88
- add_hello_suborch_action(expected_state, 'Tokyo')
89
- add_hello_suborch_action(expected_state, 'Seattle')
90
- add_hello_suborch_action(expected_state, 'London')
91
- expected_state._is_done = True
92
- expected = expected_state.to_json()
93
-
94
- #assert_valid_schema(result)
95
- assert_orchestration_state_equals(expected, result)
1
+ from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
+ from .orchestrator_test_utils \
3
+ import assert_orchestration_state_equals, get_orchestration_state_result, assert_valid_schema
4
+ from tests.test_utils.ContextBuilder import ContextBuilder
5
+ from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
+ from azure.durable_functions.models.actions.CallSubOrchestratorAction \
7
+ import CallSubOrchestratorAction
8
+ import azure.durable_functions as df
9
+ import azure.functions as func
10
+
11
+ app = df.DFApp(http_auth_level=func.AuthLevel.ANONYMOUS)
12
+
13
+ def generator_function(context):
14
+ outputs = []
15
+ task1 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "Tokyo")
16
+ task2 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "Seattle")
17
+ task3 = yield context.call_sub_orchestrator("HelloSubOrchestrator", "London")
18
+
19
+ outputs.append(task1)
20
+ outputs.append(task2)
21
+ outputs.append(task3)
22
+
23
+ return outputs
24
+
25
+ def generator_function_call_by_function_name(context):
26
+ outputs = []
27
+ task1 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "Tokyo")
28
+ task2 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "Seattle")
29
+ task3 = yield context.call_sub_orchestrator(HelloSubOrchestrator, "London")
30
+
31
+ outputs.append(task1)
32
+ outputs.append(task2)
33
+ outputs.append(task3)
34
+
35
+ return outputs
36
+
37
+ @app.orchestration_trigger(context_name="context")
38
+ def HelloSubOrchestrator(context):
39
+ return "Hello" + context
40
+
41
+ def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
42
+ return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
43
+
44
+
45
+ def add_hello_suborch_action(state: OrchestratorState, input_: str):
46
+ action = CallSubOrchestratorAction(function_name='HelloSubOrchestrator', _input=input_)
47
+ state.actions.append([action])
48
+
49
+
50
+ def add_hello_suborch_completed_events(
51
+ context_builder: ContextBuilder, id_: int, result: str):
52
+ context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
53
+ context_builder.add_orchestrator_completed_event()
54
+ context_builder.add_orchestrator_started_event()
55
+ context_builder.add_sub_orchestrator_completed_event(result=result, id_=id_)
56
+
57
+ def test_tokyo_and_seattle_and_london_state():
58
+ context_builder = ContextBuilder('test_simple_function')
59
+ add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
60
+ add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
61
+ add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
62
+
63
+ result = get_orchestration_state_result(
64
+ context_builder, generator_function)
65
+
66
+ expected_state = base_expected_state(
67
+ ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
68
+ add_hello_suborch_action(expected_state, 'Tokyo')
69
+ add_hello_suborch_action(expected_state, 'Seattle')
70
+ add_hello_suborch_action(expected_state, 'London')
71
+ expected_state._is_done = True
72
+ expected = expected_state.to_json()
73
+
74
+ #assert_valid_schema(result)
75
+ assert_orchestration_state_equals(expected, result)
76
+
77
+ def test_call_suborchestrator_by_name():
78
+ context_builder = ContextBuilder('test_call_suborchestrator_by_name')
79
+ add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
80
+ add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
81
+ add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
82
+
83
+ result = get_orchestration_state_result(
84
+ context_builder, generator_function_call_by_function_name)
85
+
86
+ expected_state = base_expected_state(
87
+ ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
88
+ add_hello_suborch_action(expected_state, 'Tokyo')
89
+ add_hello_suborch_action(expected_state, 'Seattle')
90
+ add_hello_suborch_action(expected_state, 'London')
91
+ expected_state._is_done = True
92
+ expected = expected_state.to_json()
93
+
94
+ #assert_valid_schema(result)
95
+ assert_orchestration_state_equals(expected, result)
@@ -1,130 +1,130 @@
1
- from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
- from .orchestrator_test_utils \
3
- import assert_orchestration_state_equals, get_orchestration_state_result, assert_valid_schema
4
- from tests.test_utils.ContextBuilder import ContextBuilder
5
- from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
- from azure.durable_functions.models.RetryOptions import RetryOptions
7
- from azure.durable_functions.models.actions.CallSubOrchestratorWithRetryAction \
8
- import CallSubOrchestratorWithRetryAction
9
-
10
- RETRY_OPTIONS = RetryOptions(5000, 3)
11
-
12
- def generator_function(context):
13
- outputs = []
14
- retry_options = RETRY_OPTIONS
15
-
16
- task1 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "Tokyo")
17
- task2 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "Seattle")
18
- task3 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "London")
19
-
20
- outputs.append(task1)
21
- outputs.append(task2)
22
- outputs.append(task3)
23
-
24
- return outputs
25
-
26
- def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
27
- return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
28
-
29
-
30
- def add_hello_suborch_action(state: OrchestratorState, input_: str):
31
- retry_options = RETRY_OPTIONS
32
- action = CallSubOrchestratorWithRetryAction(function_name='HelloSubOrchestrator',
33
- retry_options=retry_options,_input=input_)
34
- state.actions.append([action])
35
-
36
-
37
- def add_hello_suborch_completed_events(
38
- context_builder: ContextBuilder, id_: int, result: str):
39
- context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
40
- context_builder.add_orchestrator_completed_event()
41
- context_builder.add_orchestrator_started_event()
42
- context_builder.add_sub_orchestrator_completed_event(result=result, id_=id_)
43
-
44
- def add_hello_suborch_failed_events(
45
- context_builder: ContextBuilder, id_: int, reason: str, details: str):
46
- context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
47
- context_builder.add_orchestrator_completed_event()
48
- context_builder.add_orchestrator_started_event()
49
- context_builder.add_sub_orchestrator_failed_event(id_=id_, reason=reason, details=details)
50
-
51
- def add_retry_timer_events(context_builder: ContextBuilder, id_: int):
52
- fire_at = context_builder.add_timer_created_event(id_)
53
- context_builder.add_orchestrator_completed_event()
54
- context_builder.add_orchestrator_started_event()
55
- context_builder.add_timer_fired_event(id_=id_, fire_at=fire_at)
56
-
57
- def test_tokyo_and_seattle_and_london_state():
58
- context_builder = ContextBuilder('test_simple_function')
59
- add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
60
- add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
61
- add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
62
-
63
- result = get_orchestration_state_result(
64
- context_builder, generator_function)
65
-
66
- expected_state = base_expected_state(
67
- ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
68
- add_hello_suborch_action(expected_state, 'Tokyo')
69
- add_hello_suborch_action(expected_state, 'Seattle')
70
- add_hello_suborch_action(expected_state, 'London')
71
- expected_state._is_done = True
72
- expected = expected_state.to_json()
73
-
74
- #assert_valid_schema(result)
75
- assert_orchestration_state_equals(expected, result)
76
-
77
-
78
- def test_tokyo_and_seattle_and_london_state_partial_failure():
79
- failed_reason = 'Reasons'
80
- failed_details = 'Stuff and Things'
81
- context_builder = ContextBuilder('test_simple_function')
82
- add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
83
- add_hello_suborch_failed_events(context_builder, 1, failed_reason, failed_details)
84
- add_retry_timer_events(context_builder, 2)
85
- add_hello_suborch_completed_events(context_builder, 3, "\"Hello Seattle!\"")
86
- add_hello_suborch_completed_events(context_builder, 4, "\"Hello London!\"")
87
-
88
- result = get_orchestration_state_result(
89
- context_builder, generator_function)
90
-
91
- expected_state = base_expected_state(
92
- ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
93
- add_hello_suborch_action(expected_state, 'Tokyo')
94
- add_hello_suborch_action(expected_state, 'Seattle')
95
- add_hello_suborch_action(expected_state, 'London')
96
- expected_state._is_done = True
97
- expected = expected_state.to_json()
98
-
99
- #assert_valid_schema(result)
100
- assert_orchestration_state_equals(expected, result)
101
-
102
- def test_tokyo_and_seattle_and_london_state_all_failed():
103
- failed_reason = 'Reasons'
104
- failed_details = 'Stuff and Things'
105
- context_builder = ContextBuilder('test_simple_function')
106
- add_hello_suborch_failed_events(context_builder, 0, failed_reason, failed_details)
107
- add_retry_timer_events(context_builder, 1)
108
- add_hello_suborch_failed_events(context_builder, 2, failed_reason, failed_details)
109
- add_retry_timer_events(context_builder, 3)
110
- add_hello_suborch_failed_events(context_builder, 4, failed_reason, failed_details)
111
- add_retry_timer_events(context_builder, 5)
112
-
113
- try:
114
- result = get_orchestration_state_result(
115
- context_builder, generator_function)
116
- # Should have error'ed out
117
- assert False
118
- except Exception as e:
119
- error_label = "\n\n$OutOfProcData$:"
120
- error_str = str(e)
121
-
122
- expected_state = base_expected_state()
123
- add_hello_suborch_action(expected_state, 'Tokyo')
124
-
125
- error_msg = f'{failed_reason} \n {failed_details}'
126
- expected_state._error = error_msg
127
- state_str = expected_state.to_json_string()
128
-
129
- expected_error_str = f"{error_msg}{error_label}{state_str}"
1
+ from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
+ from .orchestrator_test_utils \
3
+ import assert_orchestration_state_equals, get_orchestration_state_result, assert_valid_schema
4
+ from tests.test_utils.ContextBuilder import ContextBuilder
5
+ from azure.durable_functions.models.OrchestratorState import OrchestratorState
6
+ from azure.durable_functions.models.RetryOptions import RetryOptions
7
+ from azure.durable_functions.models.actions.CallSubOrchestratorWithRetryAction \
8
+ import CallSubOrchestratorWithRetryAction
9
+
10
+ RETRY_OPTIONS = RetryOptions(5000, 3)
11
+
12
+ def generator_function(context):
13
+ outputs = []
14
+ retry_options = RETRY_OPTIONS
15
+
16
+ task1 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "Tokyo")
17
+ task2 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "Seattle")
18
+ task3 = yield context.call_sub_orchestrator_with_retry("HelloSubOrchestrator", retry_options, "London")
19
+
20
+ outputs.append(task1)
21
+ outputs.append(task2)
22
+ outputs.append(task3)
23
+
24
+ return outputs
25
+
26
+ def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
27
+ return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema.value)
28
+
29
+
30
+ def add_hello_suborch_action(state: OrchestratorState, input_: str):
31
+ retry_options = RETRY_OPTIONS
32
+ action = CallSubOrchestratorWithRetryAction(function_name='HelloSubOrchestrator',
33
+ retry_options=retry_options,_input=input_)
34
+ state.actions.append([action])
35
+
36
+
37
+ def add_hello_suborch_completed_events(
38
+ context_builder: ContextBuilder, id_: int, result: str):
39
+ context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
40
+ context_builder.add_orchestrator_completed_event()
41
+ context_builder.add_orchestrator_started_event()
42
+ context_builder.add_sub_orchestrator_completed_event(result=result, id_=id_)
43
+
44
+ def add_hello_suborch_failed_events(
45
+ context_builder: ContextBuilder, id_: int, reason: str, details: str):
46
+ context_builder.add_sub_orchestrator_started_event(name="HelloSubOrchestrator", id_=id_,input_="")
47
+ context_builder.add_orchestrator_completed_event()
48
+ context_builder.add_orchestrator_started_event()
49
+ context_builder.add_sub_orchestrator_failed_event(id_=id_, reason=reason, details=details)
50
+
51
+ def add_retry_timer_events(context_builder: ContextBuilder, id_: int):
52
+ fire_at = context_builder.add_timer_created_event(id_)
53
+ context_builder.add_orchestrator_completed_event()
54
+ context_builder.add_orchestrator_started_event()
55
+ context_builder.add_timer_fired_event(id_=id_, fire_at=fire_at)
56
+
57
+ def test_tokyo_and_seattle_and_london_state():
58
+ context_builder = ContextBuilder('test_simple_function')
59
+ add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
60
+ add_hello_suborch_completed_events(context_builder, 1, "\"Hello Seattle!\"")
61
+ add_hello_suborch_completed_events(context_builder, 2, "\"Hello London!\"")
62
+
63
+ result = get_orchestration_state_result(
64
+ context_builder, generator_function)
65
+
66
+ expected_state = base_expected_state(
67
+ ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
68
+ add_hello_suborch_action(expected_state, 'Tokyo')
69
+ add_hello_suborch_action(expected_state, 'Seattle')
70
+ add_hello_suborch_action(expected_state, 'London')
71
+ expected_state._is_done = True
72
+ expected = expected_state.to_json()
73
+
74
+ #assert_valid_schema(result)
75
+ assert_orchestration_state_equals(expected, result)
76
+
77
+
78
+ def test_tokyo_and_seattle_and_london_state_partial_failure():
79
+ failed_reason = 'Reasons'
80
+ failed_details = 'Stuff and Things'
81
+ context_builder = ContextBuilder('test_simple_function')
82
+ add_hello_suborch_completed_events(context_builder, 0, "\"Hello Tokyo!\"")
83
+ add_hello_suborch_failed_events(context_builder, 1, failed_reason, failed_details)
84
+ add_retry_timer_events(context_builder, 2)
85
+ add_hello_suborch_completed_events(context_builder, 3, "\"Hello Seattle!\"")
86
+ add_hello_suborch_completed_events(context_builder, 4, "\"Hello London!\"")
87
+
88
+ result = get_orchestration_state_result(
89
+ context_builder, generator_function)
90
+
91
+ expected_state = base_expected_state(
92
+ ['Hello Tokyo!', 'Hello Seattle!', 'Hello London!'])
93
+ add_hello_suborch_action(expected_state, 'Tokyo')
94
+ add_hello_suborch_action(expected_state, 'Seattle')
95
+ add_hello_suborch_action(expected_state, 'London')
96
+ expected_state._is_done = True
97
+ expected = expected_state.to_json()
98
+
99
+ #assert_valid_schema(result)
100
+ assert_orchestration_state_equals(expected, result)
101
+
102
+ def test_tokyo_and_seattle_and_london_state_all_failed():
103
+ failed_reason = 'Reasons'
104
+ failed_details = 'Stuff and Things'
105
+ context_builder = ContextBuilder('test_simple_function')
106
+ add_hello_suborch_failed_events(context_builder, 0, failed_reason, failed_details)
107
+ add_retry_timer_events(context_builder, 1)
108
+ add_hello_suborch_failed_events(context_builder, 2, failed_reason, failed_details)
109
+ add_retry_timer_events(context_builder, 3)
110
+ add_hello_suborch_failed_events(context_builder, 4, failed_reason, failed_details)
111
+ add_retry_timer_events(context_builder, 5)
112
+
113
+ try:
114
+ result = get_orchestration_state_result(
115
+ context_builder, generator_function)
116
+ # Should have error'ed out
117
+ assert False
118
+ except Exception as e:
119
+ error_label = "\n\n$OutOfProcData$:"
120
+ error_str = str(e)
121
+
122
+ expected_state = base_expected_state()
123
+ add_hello_suborch_action(expected_state, 'Tokyo')
124
+
125
+ error_msg = f'{failed_reason} \n {failed_details}'
126
+ expected_state._error = error_msg
127
+ state_str = expected_state.to_json_string()
128
+
129
+ expected_error_str = f"{error_msg}{error_label}{state_str}"
130
130
  assert expected_error_str == error_str
@@ -1,61 +1,61 @@
1
- from tests.orchestrator.test_fan_out_fan_in import add_completed_event, add_failed_event, base_expected_state, add_multi_actions
2
- from tests.orchestrator.orchestrator_test_utils import assert_orchestration_state_equals, get_orchestration_state_result
3
- from tests.test_utils.ContextBuilder import ContextBuilder
4
-
5
- def generator_function(context):
6
- task1 = context.call_activity("Hello", "0")
7
- task2 = context.call_activity("Hello", "1")
8
- task3 = context.call_activity("Hello", "2")
9
- task4 = context.task_any([task1, task2, task3])
10
- first_completed_task = yield task4
11
- try:
12
- result = yield first_completed_task
13
- return result
14
- except:
15
- return "exception"
16
-
17
- def generator_function_no_activity(context):
18
- yield context.task_any([])
19
- return "Done!"
20
-
21
- def test_continues_on_zero_inner_tasks():
22
- context_builder = ContextBuilder()
23
- result = get_orchestration_state_result(
24
- context_builder, generator_function_no_activity)
25
- expected_state = base_expected_state("Done!")
26
- expected_state._is_done = True
27
- expected = expected_state.to_json()
28
- assert_orchestration_state_equals(expected, result)
29
-
30
- def test_continues_on_zero_results():
31
- context_builder = ContextBuilder()
32
- result = get_orchestration_state_result(
33
- context_builder, generator_function)
34
- expected_state = base_expected_state()
35
- add_multi_actions(expected_state, function_name='Hello', volume=3)
36
- expected = expected_state.to_json()
37
- assert_orchestration_state_equals(expected, result)
38
-
39
- def test_continues_on_one_failure():
40
- context_builder = ContextBuilder()
41
- add_failed_event(context_builder, 0, "Hello", reason="", details="")
42
- result = get_orchestration_state_result(
43
- context_builder, generator_function)
44
- add_failed_event(context_builder, 0, "Hello", reason="", details="")
45
- expected_state = base_expected_state("exception")
46
- add_multi_actions(expected_state, function_name='Hello', volume=3)
47
- expected_state._is_done = True
48
- expected = expected_state.to_json()
49
- assert_orchestration_state_equals(expected, result)
50
-
51
- def test_succeeds_on_one_result():
52
- context_builder = ContextBuilder()
53
- add_completed_event(context_builder, 0, "Hello", result="1")
54
- result = get_orchestration_state_result(
55
- context_builder, generator_function)
56
- add_completed_event(context_builder, 2, "Hello", "3")
57
- expected_state = base_expected_state("1")
58
- add_multi_actions(expected_state, function_name='Hello', volume=3)
59
- expected_state._is_done = True
60
- expected = expected_state.to_json()
1
+ from tests.orchestrator.test_fan_out_fan_in import add_completed_event, add_failed_event, base_expected_state, add_multi_actions
2
+ from tests.orchestrator.orchestrator_test_utils import assert_orchestration_state_equals, get_orchestration_state_result
3
+ from tests.test_utils.ContextBuilder import ContextBuilder
4
+
5
+ def generator_function(context):
6
+ task1 = context.call_activity("Hello", "0")
7
+ task2 = context.call_activity("Hello", "1")
8
+ task3 = context.call_activity("Hello", "2")
9
+ task4 = context.task_any([task1, task2, task3])
10
+ first_completed_task = yield task4
11
+ try:
12
+ result = yield first_completed_task
13
+ return result
14
+ except:
15
+ return "exception"
16
+
17
+ def generator_function_no_activity(context):
18
+ yield context.task_any([])
19
+ return "Done!"
20
+
21
+ def test_continues_on_zero_inner_tasks():
22
+ context_builder = ContextBuilder()
23
+ result = get_orchestration_state_result(
24
+ context_builder, generator_function_no_activity)
25
+ expected_state = base_expected_state("Done!")
26
+ expected_state._is_done = True
27
+ expected = expected_state.to_json()
28
+ assert_orchestration_state_equals(expected, result)
29
+
30
+ def test_continues_on_zero_results():
31
+ context_builder = ContextBuilder()
32
+ result = get_orchestration_state_result(
33
+ context_builder, generator_function)
34
+ expected_state = base_expected_state()
35
+ add_multi_actions(expected_state, function_name='Hello', volume=3)
36
+ expected = expected_state.to_json()
37
+ assert_orchestration_state_equals(expected, result)
38
+
39
+ def test_continues_on_one_failure():
40
+ context_builder = ContextBuilder()
41
+ add_failed_event(context_builder, 0, "Hello", reason="", details="")
42
+ result = get_orchestration_state_result(
43
+ context_builder, generator_function)
44
+ add_failed_event(context_builder, 0, "Hello", reason="", details="")
45
+ expected_state = base_expected_state("exception")
46
+ add_multi_actions(expected_state, function_name='Hello', volume=3)
47
+ expected_state._is_done = True
48
+ expected = expected_state.to_json()
49
+ assert_orchestration_state_equals(expected, result)
50
+
51
+ def test_succeeds_on_one_result():
52
+ context_builder = ContextBuilder()
53
+ add_completed_event(context_builder, 0, "Hello", result="1")
54
+ result = get_orchestration_state_result(
55
+ context_builder, generator_function)
56
+ add_completed_event(context_builder, 2, "Hello", "3")
57
+ expected_state = base_expected_state("1")
58
+ add_multi_actions(expected_state, function_name='Hello', volume=3)
59
+ expected_state._is_done = True
60
+ expected = expected_state.to_json()
61
61
  assert_orchestration_state_equals(expected, result)