@@ -833,6 +833,134 @@ def test_ensure_can_publish_raises(
833
833
with pytest .raises (RuntimeError , match = err ):
834
834
azure_service .ensure_can_publish ("ffffffff-ffff-ffff-ffff-ffffffffffff" )
835
835
836
+ @mock .patch ("cloudpub.ms_azure.AzureService.get_submission_state" )
837
+ @mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
838
+ @mock .patch ("cloudpub.ms_azure.AzureService._is_submission_in_preview" )
839
+ def test_publish_preview_success_on_retry (
840
+ self ,
841
+ mock_is_sbpreview : mock .MagicMock ,
842
+ mock_subst : mock .MagicMock ,
843
+ mock_getsubst : mock .MagicMock ,
844
+ product_obj : Product ,
845
+ azure_service : AzureService ,
846
+ ) -> None :
847
+ # Prepare mocks
848
+ mock_config_res = mock .MagicMock ()
849
+ mock_config_res .job_result = "succeeded"
850
+ mock_is_sbpreview .return_value = False
851
+ mock_subst .side_effect = [mock_config_res for _ in range (3 )]
852
+ mock_getsubst .side_effect = [
853
+ None , # Fail on 1st call
854
+ None ,
855
+ mock .MagicMock (), # Success on 3rd call
856
+ ]
857
+ # Remove the retry sleep
858
+ azure_service ._publish_preview .retry .sleep = mock .Mock () # type: ignore
859
+
860
+ # Test
861
+ azure_service ._publish_preview (product_obj , "test-product" )
862
+
863
+ mock_subst .assert_has_calls (
864
+ [mock .call (product_id = product_obj .id , status = "preview" ) for _ in range (3 )]
865
+ )
866
+ mock_getsubst .assert_has_calls (
867
+ [mock .call (product_obj .id , state = "preview" ) for _ in range (3 )]
868
+ )
869
+
870
+ @mock .patch ("cloudpub.ms_azure.AzureService.get_submission_state" )
871
+ @mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
872
+ @mock .patch ("cloudpub.ms_azure.AzureService._is_submission_in_preview" )
873
+ def test_publish_preview_fail_on_retry (
874
+ self ,
875
+ mock_is_sbpreview : mock .MagicMock ,
876
+ mock_subst : mock .MagicMock ,
877
+ mock_getsubst : mock .MagicMock ,
878
+ product_obj : Product ,
879
+ azure_service : AzureService ,
880
+ ) -> None :
881
+ # Prepare mocks
882
+ err_resp = ConfigureStatus .from_json (
883
+ {
884
+ "jobId" : "1" ,
885
+ "jobStatus" : "completed" ,
886
+ "jobResult" : "failed" ,
887
+ "errors" : ["failure1" , "failure2" ],
888
+ }
889
+ )
890
+ mock_is_sbpreview .return_value = False
891
+ mock_subst .side_effect = [err_resp for _ in range (3 )]
892
+ mock_getsubst .side_effect = [None for _ in range (3 )]
893
+ # Remove the retry sleep
894
+ azure_service ._publish_preview .retry .sleep = mock .Mock () # type: ignore
895
+ expected_err = (
896
+ f"Failed to submit the product { product_obj .id } to preview. "
897
+ "Status: failed Errors: failure1\n failure2"
898
+ )
899
+
900
+ # Test
901
+ with pytest .raises (RuntimeError , match = expected_err ):
902
+ azure_service ._publish_preview (product_obj , "test-product" )
903
+
904
+ @mock .patch ("cloudpub.ms_azure.AzureService.get_submission_state" )
905
+ @mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
906
+ def test_publish_live_success_on_retry (
907
+ self ,
908
+ mock_subst : mock .MagicMock ,
909
+ mock_getsubst : mock .MagicMock ,
910
+ product_obj : Product ,
911
+ azure_service : AzureService ,
912
+ ) -> None :
913
+ # Prepare mocks
914
+ mock_config_res = mock .MagicMock ()
915
+ mock_config_res .job_result = "succeeded"
916
+ mock_subst .side_effect = [mock_config_res for _ in range (3 )]
917
+ mock_getsubst .side_effect = [
918
+ None , # Fail on 1st call
919
+ None ,
920
+ mock .MagicMock (), # Success on 3rd call
921
+ ]
922
+ # Remove the retry sleep
923
+ azure_service ._publish_live .retry .sleep = mock .Mock () # type: ignore
924
+
925
+ # Test
926
+ azure_service ._publish_live (product_obj , "test-product" )
927
+
928
+ mock_subst .assert_has_calls (
929
+ [mock .call (product_id = product_obj .id , status = "live" ) for _ in range (3 )]
930
+ )
931
+ mock_getsubst .assert_has_calls ([mock .call (product_obj .id , state = "live" ) for _ in range (3 )])
932
+
933
+ @mock .patch ("cloudpub.ms_azure.AzureService.get_submission_state" )
934
+ @mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
935
+ def test_publish_live_fail_on_retry (
936
+ self ,
937
+ mock_subst : mock .MagicMock ,
938
+ mock_getsubst : mock .MagicMock ,
939
+ product_obj : Product ,
940
+ azure_service : AzureService ,
941
+ ) -> None :
942
+ # Prepare mocks
943
+ err_resp = ConfigureStatus .from_json (
944
+ {
945
+ "jobId" : "1" ,
946
+ "jobStatus" : "completed" ,
947
+ "jobResult" : "failed" ,
948
+ "errors" : ["failure1" , "failure2" ],
949
+ }
950
+ )
951
+ mock_subst .side_effect = [err_resp for _ in range (3 )]
952
+ mock_getsubst .side_effect = [None for _ in range (3 )]
953
+ # Remove the retry sleep
954
+ azure_service ._publish_live .retry .sleep = mock .Mock () # type: ignore
955
+ expected_err = (
956
+ f"Failed to submit the product { product_obj .id } to live. "
957
+ "Status: failed Errors: failure1\n failure2"
958
+ )
959
+
960
+ # Test
961
+ with pytest .raises (RuntimeError , match = expected_err ):
962
+ azure_service ._publish_live (product_obj , "test-product" )
963
+
836
964
@mock .patch ("cloudpub.ms_azure.AzureService.configure" )
837
965
@mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
838
966
@mock .patch ("cloudpub.ms_azure.service.update_skus" )
@@ -1184,6 +1312,7 @@ def test_is_submission_in_preview(
1184
1312
mock_substt .assert_called_once_with (current .product_id , "live" )
1185
1313
1186
1314
@mock .patch ("cloudpub.ms_azure.AzureService.ensure_can_publish" )
1315
+ @mock .patch ("cloudpub.ms_azure.AzureService.get_submission_state" )
1187
1316
@mock .patch ("cloudpub.ms_azure.AzureService.diff_offer" )
1188
1317
@mock .patch ("cloudpub.ms_azure.AzureService.configure" )
1189
1318
@mock .patch ("cloudpub.ms_azure.AzureService.submit_to_status" )
@@ -1202,6 +1331,7 @@ def test_publish_live(
1202
1331
mock_submit : mock .MagicMock ,
1203
1332
mock_configure : mock .MagicMock ,
1204
1333
mock_diff_offer : mock .MagicMock ,
1334
+ mock_getsubst : mock .MagicMock ,
1205
1335
mock_ensure_publish : mock .MagicMock ,
1206
1336
product_obj : Product ,
1207
1337
plan_summary_obj : PlanSummary ,
@@ -1221,6 +1351,11 @@ def test_publish_live(
1221
1351
[technical_config_obj ],
1222
1352
[submission_obj ],
1223
1353
]
1354
+ mock_getsubst .side_effect = ["preview" , "live" ]
1355
+ mock_res_preview = mock .MagicMock ()
1356
+ mock_res_live = mock .MagicMock ()
1357
+ mock_res_preview .job_result = mock_res_live .job_result = "succeeded"
1358
+ mock_submit .side_effect = [mock_res_preview , mock_res_live ]
1224
1359
mock_is_sas .return_value = False
1225
1360
expected_source = VMImageSource (
1226
1361
source_type = "sasUri" ,
@@ -1237,6 +1372,7 @@ def test_publish_live(
1237
1372
technical_config_obj .disk_versions = [disk_version_obj ]
1238
1373
technical_config_obj .disk_versions = [disk_version_obj ]
1239
1374
1375
+ # Test
1240
1376
azure_service .publish (metadata_azure_obj )
1241
1377
mock_getprpl_name .assert_called_once_with ("example-product" , "plan-1" )
1242
1378
filter_calls = [
0 commit comments