azure-functions-durable 1.2.7__py3-none-any.whl → 1.2.9__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 (18) hide show
  1. azure/durable_functions/decorators/durable_app.py +9 -1
  2. azure/durable_functions/models/DurableOrchestrationClient.py +70 -0
  3. azure/durable_functions/models/OrchestrationRuntimeStatus.py +3 -0
  4. azure/durable_functions/models/TaskOrchestrationExecutor.py +6 -3
  5. azure/durable_functions/models/history/HistoryEventType.py +2 -0
  6. {azure_functions_durable-1.2.7.data → azure_functions_durable-1.2.9.data}/data/_manifest/bsi.json +1 -1
  7. {azure_functions_durable-1.2.7.data → azure_functions_durable-1.2.9.data}/data/_manifest/manifest.cat +0 -0
  8. {azure_functions_durable-1.2.7.data → azure_functions_durable-1.2.9.data}/data/_manifest/manifest.spdx.json +2984 -4704
  9. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json.sha256 +1 -0
  10. {azure_functions_durable-1.2.7.dist-info → azure_functions_durable-1.2.9.dist-info}/METADATA +1 -1
  11. {azure_functions_durable-1.2.7.dist-info → azure_functions_durable-1.2.9.dist-info}/RECORD +17 -17
  12. {azure_functions_durable-1.2.7.dist-info → azure_functions_durable-1.2.9.dist-info}/WHEEL +1 -1
  13. tests/models/test_DurableOrchestrationBindings.py +12 -0
  14. tests/models/test_DurableOrchestrationClient.py +119 -1
  15. tests/orchestrator/test_sequential_orchestrator.py +44 -4
  16. azure_functions_durable-1.2.7.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  17. {azure_functions_durable-1.2.7.dist-info → azure_functions_durable-1.2.9.dist-info}/LICENSE +0 -0
  18. {azure_functions_durable-1.2.7.dist-info → azure_functions_durable-1.2.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+ 6194b3b605744eacb5e28e82794b2ebd150bffa2e6636a9c9ece42bb8d4ba889
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azure-functions-durable
3
- Version: 1.2.7
3
+ Version: 1.2.9
4
4
  Summary: Durable Functions For Python
5
5
  Home-page: https://github.com/Azure/azure-functions-durable-python
6
6
  Author: Azure Functions team at Microsoft Corp.
@@ -3,24 +3,24 @@ azure/durable_functions/constants.py,sha256=ocJtRXUTSnhD69cuseN0_pEg7n5cUa_zG6G_
3
3
  azure/durable_functions/entity.py,sha256=ttoZd3X3XeYY8RPhhVAHY2ID8qFvsjnuDunaCbFVLEs,4372
4
4
  azure/durable_functions/orchestrator.py,sha256=s9R9LKUA01fS41VmBOEhgMiPqLU40a4iOkp6clAaXdE,2438
5
5
  azure/durable_functions/decorators/__init__.py,sha256=252iOqXe_lmKLsetZTXmVJcki6xrlJ20A6GnqqGzflQ,147
6
- azure/durable_functions/decorators/durable_app.py,sha256=5VbyQJZ0qf5rjApMh1lycxRqozxnV2rJwcgqoRYfeLY,8920
6
+ azure/durable_functions/decorators/durable_app.py,sha256=armKcMOX9sP7XaqPapGvgwiJQPGGEmTZ4F_uZkFKtsg,9105
7
7
  azure/durable_functions/decorators/metadata.py,sha256=oGsmkXBcPRTosyBdhHcMYCrFI17rGxOxkKAxvhcmANY,2719
8
8
  azure/durable_functions/models/DurableEntityContext.py,sha256=y8RWmfqEHochsreZIBJILy5agp8umeJ1QQ6qfWHfLuc,5629
9
9
  azure/durable_functions/models/DurableHttpRequest.py,sha256=a--KJqJ8BOaZ1EDjpdOAuGSai-oi7LmtpNkt3DyvIes,1963
10
10
  azure/durable_functions/models/DurableOrchestrationBindings.py,sha256=UUemNrsfJiYLTOcABzfYxuxrndAgHNMTpB-URX5zw48,2342
11
- azure/durable_functions/models/DurableOrchestrationClient.py,sha256=VTICNxi_tYfa97Es9FRlaMP_tY8gp8vL8FbdpnzYWB0,28778
11
+ azure/durable_functions/models/DurableOrchestrationClient.py,sha256=br8fC0Esh31ZwHVy7ThXvW3iWqs6tKOqba_NUODTO5E,31214
12
12
  azure/durable_functions/models/DurableOrchestrationContext.py,sha256=7utu8L_RtAmdM_uwHeDjI8MI2P4zpX8S8rKzc8UFTyU,27850
13
13
  azure/durable_functions/models/DurableOrchestrationStatus.py,sha256=OTar8vhzuMNQ2Ib4JrIy9JSxeoiNLujgLHfWysdri9M,5893
14
14
  azure/durable_functions/models/EntityStateResponse.py,sha256=PAT4pNjx3ce0JScPIrqyZnJr9q0r-yZqTi2VmcbYhuA,651
15
15
  azure/durable_functions/models/FunctionContext.py,sha256=xsW6KeBi-_OkzoCg6aHVPuD3ecL8MkWtS6XkIEJu55A,267
16
- azure/durable_functions/models/OrchestrationRuntimeStatus.py,sha256=IXbB5ZaupdQjt2jmid_FYt1PF--S1S94vo1WF6CljhE,808
16
+ azure/durable_functions/models/OrchestrationRuntimeStatus.py,sha256=e7Io1IxkRyBbLc4CdC9xRFnYk-MnjDLBagw2f_Ov74w,937
17
17
  azure/durable_functions/models/OrchestratorState.py,sha256=ZZPR1KuIBcqQgah5txLs6lkR8q39-qlTNWrfegzLSRE,3881
18
18
  azure/durable_functions/models/PurgeHistoryResult.py,sha256=_8JScnOP9tx8xBhcaKb_CqRvpwAQUZwFjfxMOb9Ajg0,1059
19
19
  azure/durable_functions/models/ReplaySchema.py,sha256=F6diOY4Fj-9-eaO1uwhUXzhAk86sQbV6ErC918vXuNg,150
20
20
  azure/durable_functions/models/RetryOptions.py,sha256=MliAqGDRsW-FZD8V3PYXlKE_idtf7LieSy-L_XGl90M,1919
21
21
  azure/durable_functions/models/RpcManagementOptions.py,sha256=UQihOaIJsn411KCVHFwhIDdGnU8ufoWo_7pOI-qNrvg,3396
22
22
  azure/durable_functions/models/Task.py,sha256=h3dk58_gs1gxMcMMcrde21_lXTodSdp-PKJy1_Cu7OI,14773
23
- azure/durable_functions/models/TaskOrchestrationExecutor.py,sha256=-uCDTBGikgF-k53xoUrTGhnhpDYCEp2czUAC5iijinI,14943
23
+ azure/durable_functions/models/TaskOrchestrationExecutor.py,sha256=INB10M5mAz_tebgvbTyMzlKoyLdfXX2i5w58paPTDIA,15128
24
24
  azure/durable_functions/models/TokenSource.py,sha256=JsZNFCvVmz-c7sXjsFEaEcwI-txmQaYKBDzwGsbbpys,1766
25
25
  azure/durable_functions/models/__init__.py,sha256=D7rbLYJRk0Ifz0p5ZW6ahnTPI7I5dtb8Bv_-iykVqO0,930
26
26
  azure/durable_functions/models/actions/Action.py,sha256=tyH3kf8K-r3CUBbPRLPmmldPiYKC2frGmc96wxDhcTI,575
@@ -47,21 +47,21 @@ azure/durable_functions/models/entities/ResponseMessage.py,sha256=AlUBLiiyNmI4Ds
47
47
  azure/durable_functions/models/entities/Signal.py,sha256=aLzGpBucK4rMHq83sf0Thmd-LDdsqW_IZGihEt-upM0,1251
48
48
  azure/durable_functions/models/entities/__init__.py,sha256=-HNH7BIPVpU6-k6Aigc_MdztKv-0CmZDo7I4y6918Bk,357
49
49
  azure/durable_functions/models/history/HistoryEvent.py,sha256=wL7RTL7YgB7sSRZ15I9r0lEkGkNi2AFvDBWaN1l_7Lk,2471
50
- azure/durable_functions/models/history/HistoryEventType.py,sha256=hZj05mf6Y5csBOMCbaPXEykSyNKN2iXsmstdHYX5TuM,660
50
+ azure/durable_functions/models/history/HistoryEventType.py,sha256=Vk2CwXRmUQ0ght2foErXhttbAwiCCgAlL4R4czDbD0A,716
51
51
  azure/durable_functions/models/history/__init__.py,sha256=caew8L8N0bAYjhBjfaNx_1zCbzPZFcrRdQGjs4V2bT4,229
52
52
  azure/durable_functions/models/utils/__init__.py,sha256=GneVHb4zC2G1gMaNGwxAy-kmbsME2l43WwwllC2n390,214
53
53
  azure/durable_functions/models/utils/entity_utils.py,sha256=aWsg9OzBG-pUb9JqruswDmI0GO1r5dYGY-0Nl1XUYlI,2472
54
54
  azure/durable_functions/models/utils/http_utils.py,sha256=jwkGIxDdRMkPh0Qab0ZsjPhpOJuoVnDAoW4_GYQxUJs,2034
55
55
  azure/durable_functions/models/utils/json_utils.py,sha256=IK3lZChsHDMGFTNsKl5mc_AhZT1qzdtmZkPIHibbVgY,2267
56
- azure_functions_durable-1.2.7.data/data/_manifest/bsi.json,sha256=GClfXrZ7HO3Y2-XpzBkrhBwZ_PIxF28JOMfVu9pMVVg,687
57
- azure_functions_durable-1.2.7.data/data/_manifest/manifest.cat,sha256=rzeunIwL_jkKrSN8vfsAY80v7W2BhFdKDcRg4FsqZNw,11260
58
- azure_functions_durable-1.2.7.data/data/_manifest/manifest.spdx.json,sha256=REy6DPCylxoZz8g83PHPoR_Rd8G1KPmaPVghIL61OO4,513545
59
- azure_functions_durable-1.2.7.data/data/_manifest/manifest.spdx.json.sha256,sha256=Xwncub5OorFRaYnCJfWDMHl7LB0ivtecfi9p0DQEVKk,64
56
+ azure_functions_durable-1.2.9.data/data/_manifest/bsi.json,sha256=JQvi8hLQ8aceRLYn6_377A4X2-VdbaOTiYbHTr6B7jk,687
57
+ azure_functions_durable-1.2.9.data/data/_manifest/manifest.cat,sha256=Yw4LQV47Hx0EXyj_k0ix1gRCIGdOd_WyU6axVmkC5wc,11150
58
+ azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json,sha256=YZSztgV0Tqy14o6CeUsuvRUL_6LmY2qcns5Cu41LqIk,453677
59
+ azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json.sha256,sha256=7GKL1I8nCPfWpDoiXTz3dpA4MGaixwgT1ot1JgFEdCY,64
60
60
  tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  tests/models/test_DecoratorMetadata.py,sha256=qVHApPjW_xEHx6wqzpZq0moUuWrGuRM1C5yOh-WyY7Y,3783
62
62
  tests/models/test_Decorators.py,sha256=dKmK9HDTg-HpYZPAHnWeHDeRnlBcx2mV8aOucJhPpps,2818
63
- tests/models/test_DurableOrchestrationBindings.py,sha256=6v8fwwvAvotANdgwj2Na7X9o6bk5DT13SAt2ZJCmY3w,2302
64
- tests/models/test_DurableOrchestrationClient.py,sha256=kvm3-XuNF8glVzZgxSVJTfZnvAOf7BvEj6voH4cw49A,26514
63
+ tests/models/test_DurableOrchestrationBindings.py,sha256=QYas1ZjATJ-6b6f2f1Bl6uMLA-EAJNkf7CiaZS4BWcI,2893
64
+ tests/models/test_DurableOrchestrationClient.py,sha256=FVYDrHrXqwcTzDnrqLzaeH_QQpwTObolKKsEkd8rxow,31010
65
65
  tests/models/test_DurableOrchestrationContext.py,sha256=dsmURdSXdoN_8DLC6KL0NIFRw7QFs6r2N06y82VxhI4,3828
66
66
  tests/models/test_DurableOrchestrationStatus.py,sha256=4wuqbiKWTgtHdvkGeup23H3T5OrKff-C-IHOws2gy54,2426
67
67
  tests/models/test_OrchestrationState.py,sha256=s9_dyHDSTESv27Qoe6hwbXc9o0I4WdYwNT1KvfLrlec,1244
@@ -77,7 +77,7 @@ tests/orchestrator/test_external_event.py,sha256=Qz-_hhqZmegRdlyYy_UA48rj95fBkPU
77
77
  tests/orchestrator/test_fan_out_fan_in.py,sha256=2ZPspECDPQEZa9h249arXeP0vPlCDntc_cKtYrO6618,7043
78
78
  tests/orchestrator/test_is_replaying_flag.py,sha256=LbYcF4j10B_vxDJeIxQ3JPMuXBgt1PdMNdUqO4ruIrs,4285
79
79
  tests/orchestrator/test_retries.py,sha256=cCGKYjKz2nDS3gdaoOPmiGcEiG9_cAceHPBALpRrlb8,10803
80
- tests/orchestrator/test_sequential_orchestrator.py,sha256=n01oCC00Q8unAnkfileuNgIpkI_dU4N8h9vkKdUeAOM,30363
80
+ tests/orchestrator/test_sequential_orchestrator.py,sha256=rqvuux4V1AKUWqD6B2dkcq9eOfmYFiGT5qsu4HAsHiI,32023
81
81
  tests/orchestrator/test_sequential_orchestrator_custom_status.py,sha256=OFE2Yg-tmUgkO3hi__8hQBVayLZOtXKD2mdl_EC5XOs,4552
82
82
  tests/orchestrator/test_sequential_orchestrator_with_retry.py,sha256=dhjR9VqeB56AGcF_0y0-eGttzbDk7vN3eHGdXVYlXhE,18182
83
83
  tests/orchestrator/test_serialization.py,sha256=nwTb56o-A2VWYUhyMrEM7RaGE14s_RtZ6vHOaqv0IM0,1209
@@ -95,8 +95,8 @@ tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
95
95
  tests/test_utils/constants.py,sha256=mI0HZbhK5zzGVuBUuCqPVmXrvVhZ7HF_xf6dTV2z8Rs,53
96
96
  tests/test_utils/json_utils.py,sha256=7jAN_ihI0S9Z8OL9VZM1yMXpSqfEavJMWYpPQtqh7y4,1381
97
97
  tests/test_utils/testClasses.py,sha256=WMwVttxWwB9AarXhdrKYSEF1_P8KRjgo44SAFvN3rUs,1465
98
- azure_functions_durable-1.2.7.dist-info/LICENSE,sha256=2rToBqx9g8pWXq5nv6gA6Am30gqghONA2d7_04p8Nus,1069
99
- azure_functions_durable-1.2.7.dist-info/METADATA,sha256=-S1FZ0w59nr4on5CvvsGQ9835ephcuk8HlfgC4G-lkU,3362
100
- azure_functions_durable-1.2.7.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
101
- azure_functions_durable-1.2.7.dist-info/top_level.txt,sha256=h-L8XDVPJ9YzBbHlPvM7FVo1cqNGToNK9ix99ySGOUY,12
102
- azure_functions_durable-1.2.7.dist-info/RECORD,,
98
+ azure_functions_durable-1.2.9.dist-info/LICENSE,sha256=2rToBqx9g8pWXq5nv6gA6Am30gqghONA2d7_04p8Nus,1069
99
+ azure_functions_durable-1.2.9.dist-info/METADATA,sha256=iG9STDnO1YW_kAkxeJNJ3X5e7Uy1QvgXLIwGx2iO0J4,3362
100
+ azure_functions_durable-1.2.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
101
+ azure_functions_durable-1.2.9.dist-info/top_level.txt,sha256=h-L8XDVPJ9YzBbHlPvM7FVo1cqNGToNK9ix99ySGOUY,12
102
+ azure_functions_durable-1.2.9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.3)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -54,3 +54,15 @@ def test_extracts_purge_history_delete_uri(binding_info):
54
54
  "=Storage&code=AUTH_CODE")
55
55
  assert expected_url == binding_info.management_urls[
56
56
  "purgeHistoryDeleteUri"]
57
+
58
+ def test_extracts_suspend_post_uri(binding_info):
59
+ expected_url = replace_stand_in_bits(
60
+ "BASE_URL/instances/INSTANCEID/suspend?reason={"
61
+ "text}&taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE")
62
+ assert expected_url == binding_info.management_urls["suspendPostUri"]
63
+
64
+ def test_extracts_resume_post_uri(binding_info):
65
+ expected_url = replace_stand_in_bits(
66
+ "BASE_URL/instances/INSTANCEID/resume?reason={"
67
+ "text}&taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE")
68
+ assert expected_url == binding_info.management_urls["resumePostUri"]
@@ -137,7 +137,15 @@ def test_create_check_status_response(binding_string):
137
137
  "purgeHistoryDeleteUri":
138
138
  r"http://test_azure.net/runtime/webhooks/durabletask/instances/"
139
139
  r"2e2568e7-a906-43bd-8364-c81733c5891e"
140
- r"?taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE"
140
+ r"?taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE",
141
+ "suspendPostUri":
142
+ r"http://test_azure.net/runtime/webhooks/durabletask/instances/"
143
+ r"2e2568e7-a906-43bd-8364-c81733c5891e/suspend"
144
+ r"?reason={text}&taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE",
145
+ "resumePostUri":
146
+ r"http://test_azure.net/runtime/webhooks/durabletask/instances/"
147
+ r"2e2568e7-a906-43bd-8364-c81733c5891e/resume"
148
+ r"?reason={text}&taskHub=TASK_HUB_NAME&connection=Storage&code=AUTH_CODE"
141
149
  }
142
150
  for key, _ in http_management_payload.items():
143
151
  http_management_payload[key] = replace_stand_in_bits(http_management_payload[key])
@@ -610,3 +618,113 @@ async def test_rewind_with_no_rpc_endpoint(binding_string):
610
618
  await client.rewind(INSTANCE_ID, REASON)
611
619
  ex_message = str(ex.value)
612
620
  assert ex_message == expected_exception_str
621
+
622
+ @pytest.mark.asyncio
623
+ async def test_post_202_suspend(binding_string):
624
+ raw_reason = 'stuff and things'
625
+ reason = 'stuff%20and%20things'
626
+ mock_request = MockRequest(
627
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/suspend?reason={reason}",
628
+ response=[202, None])
629
+ client = DurableOrchestrationClient(binding_string)
630
+ client._post_async_request = mock_request.post
631
+
632
+ result = await client.suspend(TEST_INSTANCE_ID, raw_reason)
633
+ assert result is None
634
+
635
+
636
+ @pytest.mark.asyncio
637
+ async def test_post_410_suspend(binding_string):
638
+ raw_reason = 'stuff and things'
639
+ reason = 'stuff%20and%20things'
640
+ mock_request = MockRequest(
641
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/suspend?reason={reason}",
642
+ response=[410, None])
643
+ client = DurableOrchestrationClient(binding_string)
644
+ client._post_async_request = mock_request.post
645
+
646
+ result = await client.suspend(TEST_INSTANCE_ID, raw_reason)
647
+ assert result is None
648
+
649
+
650
+ @pytest.mark.asyncio
651
+ async def test_post_404_suspend(binding_string):
652
+ raw_reason = 'stuff and things'
653
+ reason = 'stuff%20and%20things'
654
+ mock_request = MockRequest(
655
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/suspend?reason={reason}",
656
+ response=[404, MESSAGE_404])
657
+ client = DurableOrchestrationClient(binding_string)
658
+ client._post_async_request = mock_request.post
659
+
660
+ with pytest.raises(Exception):
661
+ await client.suspend(TEST_INSTANCE_ID, raw_reason)
662
+
663
+
664
+ @pytest.mark.asyncio
665
+ async def test_post_500_suspend(binding_string):
666
+ raw_reason = 'stuff and things'
667
+ reason = 'stuff%20and%20things'
668
+ mock_request = MockRequest(
669
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/suspend?reason={reason}",
670
+ response=[500, MESSAGE_500])
671
+ client = DurableOrchestrationClient(binding_string)
672
+ client._post_async_request = mock_request.post
673
+
674
+ with pytest.raises(Exception):
675
+ await client.suspend(TEST_INSTANCE_ID, raw_reason)
676
+
677
+ @pytest.mark.asyncio
678
+ async def test_post_202_resume(binding_string):
679
+ raw_reason = 'stuff and things'
680
+ reason = 'stuff%20and%20things'
681
+ mock_request = MockRequest(
682
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/resume?reason={reason}",
683
+ response=[202, None])
684
+ client = DurableOrchestrationClient(binding_string)
685
+ client._post_async_request = mock_request.post
686
+
687
+ result = await client.resume(TEST_INSTANCE_ID, raw_reason)
688
+ assert result is None
689
+
690
+
691
+ @pytest.mark.asyncio
692
+ async def test_post_410_resume(binding_string):
693
+ raw_reason = 'stuff and things'
694
+ reason = 'stuff%20and%20things'
695
+ mock_request = MockRequest(
696
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/resume?reason={reason}",
697
+ response=[410, None])
698
+ client = DurableOrchestrationClient(binding_string)
699
+ client._post_async_request = mock_request.post
700
+
701
+ result = await client.resume(TEST_INSTANCE_ID, raw_reason)
702
+ assert result is None
703
+
704
+
705
+ @pytest.mark.asyncio
706
+ async def test_post_404_resume(binding_string):
707
+ raw_reason = 'stuff and things'
708
+ reason = 'stuff%20and%20things'
709
+ mock_request = MockRequest(
710
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/resume?reason={reason}",
711
+ response=[404, MESSAGE_404])
712
+ client = DurableOrchestrationClient(binding_string)
713
+ client._post_async_request = mock_request.post
714
+
715
+ with pytest.raises(Exception):
716
+ await client.resume(TEST_INSTANCE_ID, raw_reason)
717
+
718
+
719
+ @pytest.mark.asyncio
720
+ async def test_post_500_resume(binding_string):
721
+ raw_reason = 'stuff and things'
722
+ reason = 'stuff%20and%20things'
723
+ mock_request = MockRequest(
724
+ expected_url=f"{RPC_BASE_URL}instances/{TEST_INSTANCE_ID}/resume?reason={reason}",
725
+ response=[500, MESSAGE_500])
726
+ client = DurableOrchestrationClient(binding_string)
727
+ client._post_async_request = mock_request.post
728
+
729
+ with pytest.raises(Exception):
730
+ await client.resume(TEST_INSTANCE_ID, raw_reason)
@@ -257,10 +257,31 @@ def generator_function_call_activity_with_orchestrator(context):
257
257
 
258
258
  return outputs
259
259
 
260
+ def generator_function_call_activity_with_none_return(context):
261
+ """Simple orchestrator that call activity function which can return None"""
262
+ outputs = []
263
+
264
+ task1 = yield context.call_activity(hello_return_none, "Tokyo")
265
+ task2 = yield context.call_activity(hello_return_none, "Seattle")
266
+ task3 = yield context.call_activity(hello_return_none, "London")
267
+
268
+ outputs.append(task1)
269
+ outputs.append(task2)
270
+ outputs.append(task3)
271
+
272
+ return outputs
273
+
260
274
  @app.activity_trigger(input_name = "myArg")
261
275
  def Hello(myArg: str):
262
276
  return "Hello" + myArg
263
277
 
278
+ @app.activity_trigger(input_name = "myArg")
279
+ def hello_return_none(myArg: str):
280
+ if myArg == "London":
281
+ return None
282
+ else:
283
+ return "Hello" + myArg
284
+
264
285
  def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
265
286
  return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema)
266
287
 
@@ -270,13 +291,13 @@ def add_timer_fired_events(context_builder: ContextBuilder, id_: int, timestamp:
270
291
  context_builder.add_orchestrator_started_event()
271
292
  context_builder.add_timer_fired_event(id_=id_, fire_at=fire_at)
272
293
 
273
- def add_hello_action(state: OrchestratorState, input_: str):
274
- action = CallActivityAction(function_name='Hello', input_=input_)
294
+ def add_hello_action(state: OrchestratorState, input_: str, activity_name="Hello"):
295
+ action = CallActivityAction(function_name=activity_name, input_=input_)
275
296
  state.actions.append([action])
276
297
 
277
298
  def add_hello_completed_events(
278
- context_builder: ContextBuilder, id_: int, result: str, is_played=False):
279
- context_builder.add_task_scheduled_event(name='Hello', id_=id_)
299
+ context_builder: ContextBuilder, id_: int, result: str, is_played=False, activity_name="Hello"):
300
+ context_builder.add_task_scheduled_event(name=activity_name, id_=id_)
280
301
  context_builder.add_orchestrator_completed_event()
281
302
  context_builder.add_orchestrator_started_event()
282
303
  context_builder.add_task_completed_event(id_=id_, result=result, is_played=is_played)
@@ -365,6 +386,25 @@ def test_call_activity_with_name():
365
386
  assert_valid_schema(result)
366
387
  assert_orchestration_state_equals(expected, result)
367
388
 
389
+ def test_call_activity_with_none_return():
390
+ context_builder = ContextBuilder('test_call_activity_with_none_return')
391
+ add_hello_completed_events(context_builder, 0, "\"Hello Tokyo!\"", "hello_return_none")
392
+ add_hello_completed_events(context_builder, 1, "\"Hello Seattle!\"", "hello_return_none")
393
+ add_hello_completed_events(context_builder, 2, None, "hello_return_none")
394
+ result = get_orchestration_state_result(
395
+ context_builder, generator_function_call_activity_with_none_return)
396
+
397
+ expected_state = base_expected_state(
398
+ ['Hello Tokyo!', 'Hello Seattle!', None])
399
+ add_hello_action(expected_state, 'Tokyo', "hello_return_none")
400
+ add_hello_action(expected_state, 'Seattle', "hello_return_none")
401
+ add_hello_action(expected_state, 'London', "hello_return_none")
402
+ expected_state._is_done = True
403
+ expected = expected_state.to_json()
404
+
405
+ assert_valid_schema(result)
406
+ assert_orchestration_state_equals(expected, result)
407
+
368
408
  def test_call_activity_function_callable_exception():
369
409
  context_builder = ContextBuilder('test_call_activity_by_name_exception')
370
410
 
@@ -1 +0,0 @@
1
- 444cba0cf0b2971a19cfc83cdcf1cfa11fd177c1b528f99a3d582120beb538ee