azure-functions-durable 1.2.9__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 -781
  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 -32
  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 -336
  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 -27
  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.9.dist-info → azure_functions_durable-1.2.10.dist-info}/LICENSE +21 -21
  57. {azure_functions_durable-1.2.9.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. tests/models/test_DecoratorMetadata.py +135 -135
  60. tests/models/test_Decorators.py +107 -107
  61. tests/models/test_DurableOrchestrationBindings.py +68 -68
  62. tests/models/test_DurableOrchestrationClient.py +730 -730
  63. tests/models/test_DurableOrchestrationContext.py +102 -102
  64. tests/models/test_DurableOrchestrationStatus.py +59 -59
  65. tests/models/test_OrchestrationState.py +28 -28
  66. tests/models/test_RpcManagementOptions.py +79 -79
  67. tests/models/test_TokenSource.py +10 -10
  68. tests/orchestrator/models/OrchestrationInstance.py +18 -18
  69. tests/orchestrator/orchestrator_test_utils.py +130 -130
  70. tests/orchestrator/schemas/OrchetrationStateSchema.py +66 -66
  71. tests/orchestrator/test_call_http.py +235 -176
  72. tests/orchestrator/test_continue_as_new.py +67 -67
  73. tests/orchestrator/test_create_timer.py +126 -126
  74. tests/orchestrator/test_entity.py +395 -395
  75. tests/orchestrator/test_external_event.py +53 -53
  76. tests/orchestrator/test_fan_out_fan_in.py +175 -175
  77. tests/orchestrator/test_is_replaying_flag.py +101 -101
  78. tests/orchestrator/test_retries.py +308 -308
  79. tests/orchestrator/test_sequential_orchestrator.py +841 -841
  80. tests/orchestrator/test_sequential_orchestrator_custom_status.py +119 -119
  81. tests/orchestrator/test_sequential_orchestrator_with_retry.py +465 -465
  82. tests/orchestrator/test_serialization.py +30 -30
  83. tests/orchestrator/test_sub_orchestrator.py +95 -95
  84. tests/orchestrator/test_sub_orchestrator_with_retry.py +129 -129
  85. tests/orchestrator/test_task_any.py +60 -60
  86. tests/tasks/tasks_test_utils.py +17 -17
  87. tests/tasks/test_new_uuid.py +34 -34
  88. tests/test_utils/ContextBuilder.py +174 -174
  89. tests/test_utils/EntityContextBuilder.py +56 -56
  90. tests/test_utils/constants.py +1 -1
  91. tests/test_utils/json_utils.py +30 -30
  92. tests/test_utils/testClasses.py +56 -56
  93. tests/utils/__init__.py +1 -0
  94. tests/utils/test_entity_utils.py +24 -0
  95. azure_functions_durable-1.2.9.data/data/_manifest/bsi.json +0 -1
  96. azure_functions_durable-1.2.9.data/data/_manifest/manifest.cat +0 -0
  97. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json +0 -11985
  98. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  99. azure_functions_durable-1.2.9.dist-info/RECORD +0 -102
  100. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.2.10.dist-info}/WHEEL +0 -0
  101. {azure_functions_durable-1.2.9.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)