Skip to content

Commit 6436177

Browse files
authored
Re enable batch endpoints/deployments e2etests (Azure#27177)
* Re enable batch/online endpoints e2etests
1 parent 389861c commit 6436177

8 files changed

+8145
-43
lines changed

sdk/ml/azure-ai-ml/tests/batch_services/e2etests/test_batch_deployment.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def deployEndpointAndDeployment(client: MLClient, endpoint: BatchEndpoint, deplo
3535
client.batch_endpoints.begin_delete(name=endpoint.name)
3636

3737

38-
@pytest.mark.skip(
39-
reason="Tests failing in internal automation due to lack of quota. Cannot record or run in live mode."
40-
)
38+
@pytest.mark.e2etest
4139
@pytest.mark.usefixtures("recorded_test")
4240
@pytest.mark.production_experience_test
4341
class TestBatchDeployment(AzureRecordedTestCase):
@@ -76,14 +74,13 @@ def test_batch_deployment(self, client: MLClient, data_with_2_versions: str) ->
7674
)
7775
client.batch_endpoints.begin_delete(name=endpoint.name)
7876

79-
@pytest.mark.e2etest
80-
def test_batch_deployment_dependency_label_resolution(self, client: MLClient, randstr: Callable[[], str]) -> None:
77+
def test_batch_deployment_dependency_label_resolution(self, client: MLClient, randstr: Callable[[], str], rand_batch_name: Callable[[], str], rand_batch_deployment_name: Callable[[], str]) -> None:
8178
endpoint_yaml = "./tests/test_configs/endpoints/batch/batch_endpoint_mlflow_new.yaml"
82-
name = "batch-ept-" + uuid.uuid4().hex[:15]
79+
name = rand_batch_name("name")
8380
deployment_yaml = "./tests/test_configs/deployments/batch/batch_deployment_mlflow_new.yaml"
84-
deployment_name = "batch-dpm-" + uuid.uuid4().hex[:15]
81+
deployment_name = rand_batch_deployment_name("deployment_name")
8582

86-
environment_name = randstr()
83+
environment_name = randstr("environment_name")
8784
environment_versions = ["foo", "bar"]
8885

8986
for version in environment_versions:
@@ -94,7 +91,7 @@ def test_batch_deployment_dependency_label_resolution(self, client: MLClient, ra
9491
)
9592
)
9693

97-
model_name = randstr()
94+
model_name = randstr("model_name")
9895
model_versions = ["1", "2"]
9996

10097
for version in model_versions:
@@ -134,15 +131,16 @@ def test_batch_deployment_dependency_label_resolution(self, client: MLClient, ra
134131
)
135132
assert resolved_model.asset_name == model_name and resolved_model.asset_version == model_versions[-1]
136133

137-
@pytest.mark.e2etest
138-
def test_batch_job_download(self, client: MLClient, tmp_path: Path) -> str:
134+
def test_batch_job_download(self, client: MLClient, tmp_path: Path, rand_batch_name: Callable[[], str], rand_batch_deployment_name: Callable[[], str]) -> str:
135+
endpoint_name = rand_batch_name("name")
139136
endpoint = load_batch_endpoint(
140137
"./tests/test_configs/endpoints/batch/batch_endpoint_mlflow_new.yaml",
141-
params_override=[{"name": "batch-ept-" + uuid.uuid4().hex[:15]}],
138+
params_override=[{"name": endpoint_name}],
142139
)
140+
deployment_name = rand_batch_deployment_name("deployment_name")
143141
deployment = load_batch_deployment(
144142
"./tests/test_configs/deployments/batch/batch_deployment_quick.yaml",
145-
params_override=[{"endpoint_name": endpoint.name}, {"name": "batch-dpm-" + uuid.uuid4().hex[:15]}],
143+
params_override=[{"endpoint_name": endpoint.name}, {"name": deployment_name}],
146144
)
147145
endpoint.traffic = {deployment.name: 100}
148146

sdk/ml/azure-ai-ml/tests/batch_services/e2etests/test_batch_endpoint.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
1-
import uuid
1+
from typing import Callable
22

33
import pytest
44

55
from azure.ai.ml import MLClient, load_batch_endpoint, load_batch_deployment
6-
from azure.ai.ml.entities._assets import Model
76
from azure.ai.ml.entities._inputs_outputs import Input
87
from azure.core.exceptions import ResourceNotFoundError
98

109
from devtools_testutils import AzureRecordedTestCase
1110

1211

1312
@pytest.mark.e2etest
13+
@pytest.mark.usefixtures("recorded_test")
1414
@pytest.mark.production_experience_test
1515
class TestBatchEndpoint(AzureRecordedTestCase):
16-
@pytest.mark.skip(
17-
reason="Tests failing in internal automation due to lack of quota. Cannot record or run in live mode."
18-
)
19-
def test_batch_endpoint_create_and_invoke(
20-
self, client: MLClient, data_with_2_versions: str, batch_endpoint_model: Model
16+
def test_batch_endpoint_create(
17+
self, client: MLClient, rand_batch_name: Callable[[], str]
2118
) -> None:
2219
endpoint_yaml = "./tests/test_configs/endpoints/batch/batch_endpoint.yaml"
23-
name = "be-e2e-" + uuid.uuid4().hex[:25]
20+
name = rand_batch_name("name")
2421
# Bug in MFE that batch endpoint properties are not preserved, uncomment below after it's fixed in MFE
2522
# properties = {"property1": "value1", "property2": "value2"}
2623
endpoint = load_batch_endpoint(endpoint_yaml)
2724
endpoint.name = name
2825
# endpoint.properties = properties
29-
obj = client.batch_endpoints.begin_create_or_update(endpoint=endpoint, no_wait=False)
26+
obj = client.batch_endpoints.begin_create_or_update(endpoint=endpoint)
3027
obj = obj.result()
3128
assert obj is not None
3229
assert name == obj.name
@@ -45,16 +42,13 @@ def test_batch_endpoint_create_and_invoke(
4542

4643
raise Exception(f"Batch endpoint {name} is supposed to be deleted.")
4744

48-
@pytest.mark.skip(
49-
reason="Tests failing in internal automation due to lack of quota. Cannot record or run in live mode."
50-
)
51-
@pytest.mark.e2etest
45+
5246
@pytest.mark.usefixtures("light_gbm_model")
53-
def test_mlflow_batch_endpoint_create_and_update(self, client: MLClient) -> None:
47+
def test_mlflow_batch_endpoint_create_and_update(self, client: MLClient, rand_batch_name: Callable[[], str]) -> None:
5448
# light_gbm_model fixture is not used directly, but it makes sure the model being used by the batch endpoint exists
5549

5650
endpoint_yaml = "./tests/test_configs/endpoints/batch/batch_endpoint_mlflow.yaml"
57-
name = "be-e2e-" + uuid.uuid4().hex[:25]
51+
name = rand_batch_name("name")
5852
endpoint = load_batch_endpoint(endpoint_yaml)
5953
endpoint.name = name
6054
obj = client.batch_endpoints.begin_create_or_update(endpoint=endpoint)
@@ -76,14 +70,14 @@ def test_mlflow_batch_endpoint_create_and_update(self, client: MLClient) -> None
7670
raise Exception(f"Batch endpoint {name} is supposed to be deleted.")
7771

7872

79-
def test_batch_invoke(self, client: MLClient, variable_recorder) -> None:
73+
def test_batch_invoke(self, client: MLClient, rand_batch_name: Callable[[], str], rand_batch_deployment_name: Callable[[], str]) -> None:
8074
endpoint_yaml = "./tests/test_configs/endpoints/batch/simple_batch_endpoint.yaml"
81-
endpoint_name = variable_recorder.get_or_record("endpoint_name", "be-e2e-" + uuid.uuid4().hex[:15])
75+
endpoint_name = rand_batch_name("endpoint_name")
8276
endpoint = load_batch_endpoint(endpoint_yaml)
8377
endpoint.name = endpoint_name
8478

8579
deployment_yaml = "./tests/test_configs/deployments/batch/batch_deployment_3.yaml"
86-
deployment_name = variable_recorder.get_or_record("deployment_name", "batch-dpm-" + uuid.uuid4().hex[:15])
80+
deployment_name = rand_batch_deployment_name("deployment_name")
8781

8882
deployment = load_batch_deployment(deployment_yaml)
8983
deployment.endpoint_name = endpoint_name

sdk/ml/azure-ai-ml/tests/conftest.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def add_sanitizers(test_proxy, fake_datastore_key):
7171
add_body_key_sanitizer(json_path="$.properties.properties.hash_sha256", value="0000000000000")
7272
add_body_key_sanitizer(json_path="$.properties.properties.hash_version", value="0000000000000")
7373
add_body_key_sanitizer(json_path="$.properties.properties.['azureml.git.dirty']", value="fake_git_dirty_value")
74+
add_body_key_sanitizer(json_path="$.accessToken", value="Sanitized")
7475
add_general_regex_sanitizer(value="", regex=f"\\u0026tid={os.environ.get('ML_TENANT_ID')}")
7576
add_general_string_sanitizer(value="", target=f"&tid={os.environ.get('ML_TENANT_ID')}")
7677
add_general_regex_sanitizer(
@@ -205,6 +206,45 @@ def generate_random_string(variable_name: str):
205206

206207
return generate_random_string
207208

209+
@pytest.fixture
210+
def rand_batch_name(variable_recorder: VariableRecorder) -> Callable[[str], str]:
211+
"""return a random batch endpoint name string e.g. batch-ept-xxx"""
212+
213+
def generate_random_string(variable_name: str):
214+
random_string = f"batch-ept-{uuid.uuid4().hex[:15]}"
215+
return variable_recorder.get_or_record(variable_name, random_string)
216+
217+
return generate_random_string
218+
219+
@pytest.fixture
220+
def rand_batch_deployment_name(variable_recorder: VariableRecorder) -> Callable[[str], str]:
221+
"""return a random batch deployment name string e.g. batch-dpm-xxx"""
222+
223+
def generate_random_string(variable_name: str):
224+
random_string = f"batch-dpm-{uuid.uuid4().hex[:15]}"
225+
return variable_recorder.get_or_record(variable_name, random_string)
226+
227+
return generate_random_string
228+
229+
@pytest.fixture
230+
def rand_online_name(variable_recorder: VariableRecorder) -> Callable[[str], str]:
231+
"""return a random online endpoint name string e.g. online-ept-xxx"""
232+
233+
def generate_random_string(variable_name: str):
234+
random_string = f"online-ept-{uuid.uuid4().hex[:15]}"
235+
return variable_recorder.get_or_record(variable_name, random_string)
236+
237+
return generate_random_string
238+
239+
@pytest.fixture
240+
def rand_online_deployment_name(variable_recorder: VariableRecorder) -> Callable[[str], str]:
241+
"""return a random online deployment name string e.g. online-dpm-xxx"""
242+
243+
def generate_random_string(variable_name: str):
244+
random_string = f"online-dpm-{uuid.uuid4().hex[:15]}"
245+
return variable_recorder.get_or_record(variable_name, random_string)
246+
247+
return generate_random_string
208248

209249
@pytest.fixture
210250
def rand_compute_name(variable_recorder: VariableRecorder) -> Callable[[str], str]:
@@ -321,8 +361,8 @@ def batch_endpoint_model(client: MLClient) -> Model:
321361

322362

323363
@pytest.fixture
324-
def light_gbm_model(client: MLClient) -> Model:
325-
job_name = "light_gbm_job_" + uuid.uuid4().hex
364+
def light_gbm_model(client: MLClient, variable_recorder: VariableRecorder) -> Model:
365+
job_name = variable_recorder.get_or_record("job_name", "light_gbm_job_" + uuid.uuid4().hex)
326366
model_name = "lightgbm_predict" # specified in the mlflow training script
327367

328368
try:

sdk/ml/azure-ai-ml/tests/online_services/e2etests/test_online_deployment.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import uuid
1+
from typing import Callable
22

33
import pytest
44

@@ -10,36 +10,38 @@
1010

1111

1212
@pytest.mark.e2etest
13+
@pytest.mark.usefixtures("recorded_test")
1314
@pytest.mark.production_experience_test
1415
class TestOnlineDeployment(AzureRecordedTestCase):
1516
@pytest.mark.skip(
1617
reason="Tests failing in internal automation due to lack of quota. Cannot record or run in live mode."
1718
)
18-
def test_online_deployment(self, client: MLClient) -> None:
19+
def test_online_deployment(self, client: MLClient, rand_online_name: Callable[[], str], rand_online_deployment_name: Callable[[], str]) -> None:
1920
endpoint_yaml = "tests/test_configs/deployments/online/simple_online_endpoint_mir.yaml"
2021
deployment_yaml = "tests/test_configs/deployments/online/online_deployment_1.yaml"
21-
name = "online-ept-" + uuid.uuid4().hex[:15]
22+
name = rand_online_name("name")
2223
endpoint = load_online_endpoint(endpoint_yaml)
2324
endpoint.name = name
2425

26+
deployment_name = rand_online_deployment_name("deployment_name")
2527
deployment = load_online_deployment(deployment_yaml)
2628
deployment.endpoint_name = name
27-
deployment.name = "online-dpm-" + uuid.uuid4().hex[:15]
29+
deployment.name = deployment_name
2830

2931
# create a endpoint
30-
client.online_endpoints.begin_create_or_update(endpoint)
32+
client.online_endpoints.begin_create_or_update(endpoint).result()
3133

3234
try:
3335
# create a deployment
34-
client.online_deployments.begin_create_or_update(deployment)
36+
client.online_deployments.begin_create_or_update(deployment).result()
3537
dep = client.online_deployments.get(name=deployment.name, endpoint_name=endpoint.name)
3638
assert dep.name == deployment.name
3739

3840
deps = client.online_deployments.list(endpoint_name=endpoint.name)
3941
assert len(list(deps)) > 0
4042

4143
endpoint.traffic = {deployment.name: 100}
42-
client.online_endpoints.begin_create_or_update(endpoint)
44+
client.online_endpoints.begin_create_or_update(endpoint).result()
4345
endpoint_updated = client.online_endpoints.get(endpoint.name)
4446
assert endpoint_updated.traffic[deployment.name] == 100
4547
client.online_endpoints.invoke(
@@ -52,9 +54,9 @@ def test_online_deployment(self, client: MLClient) -> None:
5254
client.online_endpoints.begin_delete(name=endpoint.name)
5355

5456
@pytest.mark.skip(reason="Known failure")
55-
def test_online_deployment_skip_script_validation(self, client: MLClient,variable_recorder) -> None:
56-
online_endpoint_name = variable_recorder.get_or_record("online_endpoint_name", "online-endp" + uuid.uuid4().hex[:15])
57-
online_deployment_name = variable_recorder.get_or_record("online_deployment_name", "online-dpm" + uuid.uuid4().hex[:15])
57+
def test_online_deployment_skip_script_validation(self, client: MLClient, rand_online_name: Callable[[], str], rand_online_deployment_name: Callable[[], str]) -> None:
58+
online_endpoint_name = rand_online_name("online_endpoint_name")
59+
online_deployment_name = rand_online_deployment_name("online_deployment_name")
5860

5961
# create an online endpoint
6062
endpoint = ManagedOnlineEndpoint(

0 commit comments

Comments
 (0)