Skip to content

Commit 9ffe3ea

Browse files
committed
Add/Update unit tests for Azure
This commit updates and creates new tests to make sure the new implemented exception handlers for retrying on in progress submission/conflict are properly working. Assisted-by: Cursor Signed-off-by: Jonathan Gangi <[email protected]>
1 parent 907cb65 commit 9ffe3ea

File tree

3 files changed

+174
-11
lines changed

3 files changed

+174
-11
lines changed

tests/ms_azure/conftest.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,49 @@ def job_details_completed_failure(errors: List[Dict[str, Any]]) -> Dict[str, Any
9191
return job_details(status="completed", result="failed", errors=errors)
9292

9393

94+
@pytest.fixture
95+
def job_details_completed_conflict(errors_conflict: List[Dict[str, Any]]) -> Dict[str, Any]:
96+
return job_details(status="completed", result="failed", errors=errors_conflict)
97+
98+
99+
@pytest.fixture
100+
def job_details_completed_running_submission(
101+
errors_running_submission: List[Dict[str, Any]],
102+
) -> Dict[str, Any]:
103+
return job_details(status="completed", result="failed", errors=errors_running_submission)
104+
105+
94106
@pytest.fixture
95107
def errors() -> List[Dict[str, Any]]:
96108
return [
97109
{
110+
"resourceId": "resource-id",
111+
"code": "internalServerError",
112+
"message": "A catastrophic error occurred.",
113+
"details": [{"code": "invalidResource", "message": "Failure for resource"}],
114+
}
115+
]
116+
117+
118+
@pytest.fixture
119+
def errors_running_submission() -> List[Dict[str, Any]]:
120+
return [
121+
{
122+
"resourceId": "resource-id",
123+
"code": "internalServerError",
124+
"message": "An In Progress submission 1234567890 already exists.",
125+
"details": [{"code": "invalidResource", "message": "Failure for resource"}],
126+
}
127+
]
128+
129+
130+
@pytest.fixture
131+
def errors_conflict() -> List[Dict[str, Any]]:
132+
return [
133+
{
134+
"resourceId": "resource-id",
98135
"code": "conflict",
99-
"message": "Error message",
136+
"message": "The submission cannot be pushed to live as its not the latest submission.",
100137
"details": [{"code": "invalidResource", "message": "Failure for resource"}],
101138
}
102139
]
@@ -132,6 +169,7 @@ def configure_success_response() -> Dict[str, Any]:
132169
def configure_failure_response() -> Dict[str, Any]:
133170
return {
134171
"error": {
172+
"resourceId": "resource-id",
135173
"code": "badRequest",
136174
"message": "Invalid configuration: schema validation failed",
137175
"details": [
@@ -617,3 +655,17 @@ def job_details_completed_failure_obj(
617655
job_details_completed_failure: Dict[str, Any],
618656
) -> ConfigureStatus:
619657
return ConfigureStatus.from_json(job_details_completed_failure)
658+
659+
660+
@pytest.fixture
661+
def job_details_completed_conflict_obj(
662+
job_details_completed_conflict: Dict[str, Any],
663+
) -> ConfigureStatus:
664+
return ConfigureStatus.from_json(job_details_completed_conflict)
665+
666+
667+
@pytest.fixture
668+
def job_details_completed_running_submission_obj(
669+
job_details_completed_running_submission: Dict[str, Any],
670+
) -> ConfigureStatus:
671+
return ConfigureStatus.from_json(job_details_completed_running_submission)

tests/ms_azure/test_service.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
import logging
33
from copy import deepcopy
4-
from typing import Any, Dict, List
4+
from typing import Any, Dict
55
from unittest import mock
66

77
import pytest
@@ -13,7 +13,7 @@
1313
from tenacity.stop import stop_after_attempt
1414

1515
from cloudpub.common import BaseService
16-
from cloudpub.error import InvalidStateError, NotFoundError
16+
from cloudpub.error import ConflictError, InvalidStateError, NotFoundError, RunningSubmissionError
1717
from cloudpub.models.ms_azure import (
1818
ConfigureStatus,
1919
CustomerLeads,
@@ -214,6 +214,14 @@ def test_wait_for_job_completion_successful_completion(
214214
assert f"Job {job_id} failed" not in caplog.text
215215
assert f"Job {job_id} succeeded" in caplog.text
216216

217+
@pytest.mark.parametrize(
218+
"error_name",
219+
[
220+
"job_details_completed_failure_obj",
221+
"job_details_completed_conflict_obj",
222+
"job_details_completed_running_submission_obj",
223+
],
224+
)
217225
@mock.patch("cloudpub.ms_azure.utils.is_azure_job_not_complete")
218226
@mock.patch("cloudpub.ms_azure.AzureService._query_job_details")
219227
def test_get_job_details_after_failed_completion(
@@ -224,20 +232,26 @@ def test_get_job_details_after_failed_completion(
224232
caplog: LogCaptureFixture,
225233
job_details_running_obj: ConfigureStatus,
226234
job_details_completed_failure_obj: ConfigureStatus,
227-
errors: List[Dict[str, Any]],
235+
job_details_completed_conflict_obj: ConfigureStatus,
236+
job_details_completed_running_submission_obj: ConfigureStatus,
237+
error_name: str,
238+
request: pytest.FixtureRequest,
228239
) -> None:
240+
229241
mock_job_details.side_effect = [
230242
job_details_running_obj,
231243
job_details_running_obj,
232244
job_details_running_obj,
233-
job_details_completed_failure_obj,
245+
request.getfixturevalue(error_name),
234246
job_details_running_obj,
235247
]
236248

237249
azure_service._wait_for_job_completion.retry.sleep = mock.Mock() # type: ignore
238250
job_id = "job_id_111"
239251
with caplog.at_level(logging.ERROR):
240-
with pytest.raises(InvalidStateError) as e_info:
252+
with pytest.raises(
253+
(InvalidStateError, RunningSubmissionError, ConflictError)
254+
) as e_info:
241255
azure_service._wait_for_job_completion(job_id=job_id)
242256
assert f"Job {job_id} failed: \n" in str(e_info.value)
243257
assert mock_job_details.call_count == 4
@@ -861,7 +875,7 @@ def test_publish_preview_success_on_retry(
861875
None,
862876
mock.MagicMock(), # Success on 3rd call
863877
]
864-
# Remove the retry sleep
878+
# Remove the retry sleeptest_publish_preview_fail_on_retry
865879
azure_service._publish_preview.retry.sleep = mock.Mock() # type: ignore
866880

867881
# Test
@@ -891,7 +905,18 @@ def test_publish_preview_fail_on_retry(
891905
"jobId": "1",
892906
"jobStatus": "completed",
893907
"jobResult": "failed",
894-
"errors": ["failure1", "failure2"],
908+
"errors": [
909+
{
910+
"resourceId": "resource-id",
911+
"code": "internalServerError",
912+
"message": "failure1",
913+
},
914+
{
915+
"resourceId": "resource-id",
916+
"code": "internalServerError",
917+
"message": "failure2",
918+
},
919+
],
895920
}
896921
)
897922
mock_is_sbpreview.return_value = False
@@ -901,7 +926,7 @@ def test_publish_preview_fail_on_retry(
901926
azure_service._publish_preview.retry.sleep = mock.Mock() # type: ignore
902927
expected_err = (
903928
f"Failed to submit the product {product_obj.id} to preview. "
904-
"Status: failed Errors: failure1\nfailure2"
929+
"Status: failed Errors: internalServerError: failure1\ninternalServerError: failure2"
905930
)
906931

907932
# Test
@@ -952,7 +977,18 @@ def test_publish_live_fail_on_retry(
952977
"jobId": "1",
953978
"jobStatus": "completed",
954979
"jobResult": "failed",
955-
"errors": ["failure1", "failure2"],
980+
"errors": [
981+
{
982+
"resourceId": "resource-id",
983+
"code": "internalServerError",
984+
"message": "failure1",
985+
},
986+
{
987+
"resourceId": "resource-id",
988+
"code": "internalServerError",
989+
"message": "failure2",
990+
},
991+
],
956992
}
957993
)
958994
mock_subst.side_effect = [err_resp for _ in range(3)]
@@ -961,7 +997,7 @@ def test_publish_live_fail_on_retry(
961997
azure_service._publish_live.retry.sleep = mock.Mock() # type: ignore
962998
expected_err = (
963999
f"Failed to submit the product {product_obj.id} to live. "
964-
"Status: failed Errors: failure1\nfailure2"
1000+
"Status: failed Errors: internalServerError: failure1\ninternalServerError: failure2"
9651001
)
9661002

9671003
# Test

tests/ms_azure/test_utils.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
)
1616
from cloudpub.ms_azure.utils import (
1717
AzurePublishingMetadata,
18+
check_for_conflict,
19+
check_for_running_submission,
1820
create_disk_version_from_scratch,
1921
get_image_type_mapping,
2022
is_azure_job_not_complete,
@@ -580,3 +582,76 @@ def test_create_disk_version_from_scratch_arm64(
580582
res.vm_images = sorted(res.vm_images, key=attrgetter("image_type"))
581583

582584
assert res == disk_version_arm64_obj
585+
586+
@pytest.mark.parametrize(
587+
"error,expected_result",
588+
[
589+
(
590+
{
591+
"code": "conflict",
592+
"message": "The submission cannot be pushed to live as its not the latest submission.", # noqa: E501
593+
},
594+
True,
595+
),
596+
(
597+
{
598+
"code": "internalServerError",
599+
"message": "An In Progress submission 1234567890 already exists.",
600+
},
601+
False,
602+
),
603+
(
604+
{
605+
"code": "unknownError",
606+
"message": "An In Progress submission 1234567890 already exists.",
607+
},
608+
False,
609+
),
610+
({"code": "conflict", "message": "Something else happened"}, False),
611+
],
612+
)
613+
def test_check_for_conflict(self, error: Dict[str, Any], expected_result: bool) -> None:
614+
err_obj = ConfigureStatus.from_json(
615+
{
616+
"jobId": "1",
617+
"jobStatus": "completed",
618+
"jobResult": "failed",
619+
"errors": [error],
620+
}
621+
)
622+
assert err_obj
623+
assert check_for_conflict(err_obj) == expected_result
624+
625+
@pytest.mark.parametrize(
626+
"error,expected_result",
627+
[
628+
(
629+
{
630+
"code": "internalServerError",
631+
"message": "An In Progress submission 1234567890 already exists.",
632+
},
633+
True,
634+
),
635+
(
636+
{
637+
"code": "unknownError",
638+
"message": "An In Progress submission 1234567890 already exists.",
639+
},
640+
False,
641+
),
642+
({"code": "conflict", "message": "Something else happened"}, False),
643+
],
644+
)
645+
def test_check_for_running_submission(
646+
self, error: Dict[str, Any], expected_result: bool
647+
) -> None:
648+
err_obj = ConfigureStatus.from_json(
649+
{
650+
"jobId": "1",
651+
"jobStatus": "completed",
652+
"jobResult": "failed",
653+
"errors": [error],
654+
}
655+
)
656+
assert err_obj
657+
assert check_for_running_submission(err_obj) == expected_result

0 commit comments

Comments
 (0)