Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.

Commit b461181

Browse files
mohitpavanbavneetsingh16
authored andcommitted
[load] CLI changes for the CICD improvements. (Azure#8546)
* changes. * check-point tests for ref-ids. * updates. * correcting all the new tests. * pf-criteria-tests addition. * app components tests. * changes for app-components. * small chgange in the reeturn. * few changes. * pr comments and updating the tests. * pr-comments. * pr-comments. * updating resource-id for app-components. * pr comments. * adding version changes. * pr comments. * changes for errors. * few changes for tests. * running tests and pre-push commands. * updating recordings with masked secrets. * indentation in version change. * changes for build failure. * trying to resolve pipeline error.
1 parent 823bef5 commit b461181

File tree

79 files changed

+81641
-77331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+81641
-77331
lines changed

src/load/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
Release History
44
===============
55

6+
1.7.0
7+
++++++
8+
* Add support for metrics reference identity. Metrics reference identity can be set using `--metrics-reference-identity` argument in 'az load test create' and 'az load test update' commands. Metrics reference identity set in YAML config file under key `referenceIdentities` with `kind` as `Metrics` will also be honoured.
9+
610

711
1.6.0
812
++++++

src/load/azext_load/data_plane/load_test/custom.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
load_yaml,
2222
upload_file_to_test,
2323
upload_files_helper,
24+
merge_existing_app_components,
25+
merge_existing_server_metrics,
26+
parse_app_comps_and_server_metrics,
27+
is_not_empty_dictionary,
2428
)
2529
from azext_load.data_plane.utils.models import (
2630
AllowedTestTypes,
@@ -48,6 +52,7 @@ def create_test(
4852
secrets=None,
4953
certificate=None,
5054
key_vault_reference_identity=None,
55+
metrics_reference_identity=None,
5156
subnet_id=None,
5257
split_csv=None,
5358
disable_public_ip=None,
@@ -66,12 +71,14 @@ def create_test(
6671
body = client.get_test(test_id)
6772
except ResourceNotFoundError:
6873
pass
74+
6975
if body is not None:
7076
msg = f"Test with given test ID : {test_id} already exist."
7177
logger.debug(msg)
7278
raise InvalidArgumentValueError(msg)
7379
body = {}
7480
yaml, yaml_test_body = None, None
81+
app_components, add_defaults_to_app_components, server_metrics = None, None, None
7582
autostop_criteria = create_autostop_criteria_from_args(
7683
autostop=autostop, error_rate=autostop_error_rate, time_window=autostop_error_rate_time_window)
7784
if load_test_config_file is None:
@@ -88,6 +95,7 @@ def create_test(
8895
secrets=secrets,
8996
certificate=certificate,
9097
key_vault_reference_identity=key_vault_reference_identity,
98+
metrics_reference_identity=metrics_reference_identity,
9199
subnet_id=subnet_id,
92100
split_csv=split_csv,
93101
disable_public_ip=disable_public_ip,
@@ -99,6 +107,7 @@ def create_test(
99107
else:
100108
yaml = load_yaml(load_test_config_file)
101109
yaml_test_body = convert_yaml_to_test(cmd, yaml)
110+
app_components, add_defaults_to_app_components, server_metrics = parse_app_comps_and_server_metrics(data=yaml)
102111
test_type = (
103112
test_type or
104113
yaml.get(LoadTestConfigKeys.TEST_TYPE) or
@@ -118,6 +127,7 @@ def create_test(
118127
secrets=secrets,
119128
certificate=certificate,
120129
key_vault_reference_identity=key_vault_reference_identity,
130+
metrics_reference_identity=metrics_reference_identity,
121131
subnet_id=subnet_id,
122132
split_csv=split_csv,
123133
disable_public_ip=disable_public_ip,
@@ -136,8 +146,32 @@ def create_test(
136146
upload_files_helper(
137147
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait, evaluated_test_type
138148
)
139-
response = client.get_test(test_id)
140149
logger.info("Upload files to test %s has completed", test_id)
150+
if is_not_empty_dictionary(app_components):
151+
# only get and patch the app components if its present in the yaml.
152+
app_component_response = client.create_or_update_app_components(
153+
test_id=test_id, body={"testId": test_id, "components": app_components}
154+
)
155+
logger.warning(
156+
"Added app components for test ID: %s and response is %s", test_id, app_component_response
157+
)
158+
if is_not_empty_dictionary(server_metrics):
159+
# only get and patch the app components if its present in the yaml.
160+
server_metrics_existing = None
161+
try:
162+
server_metrics_existing = client.get_server_metrics_config(test_id)
163+
except ResourceNotFoundError:
164+
server_metrics_existing = {"metrics": {}}
165+
server_metrics_merged = merge_existing_server_metrics(
166+
add_defaults_to_app_components, server_metrics, server_metrics_existing.get("metrics", {})
167+
)
168+
server_metric_response = client.create_or_update_server_metrics_config(
169+
test_id=test_id, body={"testId": test_id, "metrics": server_metrics_merged}
170+
)
171+
logger.warning(
172+
"Added server metrics for test ID: %s and response is %s", test_id, server_metric_response
173+
)
174+
response = client.get_test(test_id)
141175
logger.info("Test %s has been created successfully", test_id)
142176
return response.as_dict()
143177

@@ -156,6 +190,7 @@ def update_test(
156190
secrets=None,
157191
certificate=None,
158192
key_vault_reference_identity=None,
193+
metrics_reference_identity=None,
159194
subnet_id=None,
160195
split_csv=None,
161196
disable_public_ip=None,
@@ -178,11 +213,13 @@ def update_test(
178213
logger.debug("Retrieved test with test ID: %s and body : %s", test_id, body)
179214

180215
yaml, yaml_test_body = None, None
216+
app_components, server_metrics, add_defaults_to_app_components = None, None, None
181217
autostop_criteria = create_autostop_criteria_from_args(
182218
autostop=autostop, error_rate=autostop_error_rate, time_window=autostop_error_rate_time_window)
183219
if load_test_config_file is not None:
184220
yaml = load_yaml(load_test_config_file)
185221
yaml_test_body = convert_yaml_to_test(cmd, yaml)
222+
app_components, add_defaults_to_app_components, server_metrics = parse_app_comps_and_server_metrics(data=yaml)
186223
body = create_or_update_test_with_config(
187224
test_id,
188225
body,
@@ -194,6 +231,7 @@ def update_test(
194231
secrets=secrets,
195232
certificate=certificate,
196233
key_vault_reference_identity=key_vault_reference_identity,
234+
metrics_reference_identity=metrics_reference_identity,
197235
subnet_id=subnet_id,
198236
split_csv=split_csv,
199237
disable_public_ip=disable_public_ip,
@@ -213,6 +251,7 @@ def update_test(
213251
secrets=secrets,
214252
certificate=certificate,
215253
key_vault_reference_identity=key_vault_reference_identity,
254+
metrics_reference_identity=metrics_reference_identity,
216255
subnet_id=subnet_id,
217256
split_csv=split_csv,
218257
disable_public_ip=disable_public_ip,
@@ -230,6 +269,37 @@ def update_test(
230269
upload_files_helper(
231270
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait, body.get("kind")
232271
)
272+
273+
if is_not_empty_dictionary(app_components):
274+
# only get and patch the app components if its present in the yaml.
275+
try:
276+
app_components_existing = client.get_app_components(test_id)
277+
except ResourceNotFoundError:
278+
app_components_existing = {"components": {}}
279+
app_components_merged = merge_existing_app_components(
280+
app_components, app_components_existing.get("components", {})
281+
)
282+
app_component_response = client.create_or_update_app_components(
283+
test_id=test_id, body={"testId": test_id, "components": app_components_merged}
284+
)
285+
logger.warning(
286+
"Added app components for test ID: %s and response is %s", test_id, app_component_response
287+
)
288+
if is_not_empty_dictionary(server_metrics):
289+
# only get and patch the app components if its present in the yaml.
290+
try:
291+
server_metrics_existing = client.get_server_metrics_config(test_id)
292+
except ResourceNotFoundError:
293+
server_metrics_existing = {"metrics": {}}
294+
server_metrics_merged = merge_existing_server_metrics(
295+
add_defaults_to_app_components, server_metrics_existing.get("metrics", {}), server_metrics
296+
)
297+
server_metric_response = client.create_or_update_server_metrics_config(
298+
test_id=test_id, body={"testId": test_id, "metrics": server_metrics_merged}
299+
)
300+
logger.warning(
301+
"Added server metrics for test ID: %s and response is %s", test_id, server_metric_response
302+
)
233303
response = client.get_test(test_id)
234304
logger.info("Upload files to test %s has completed", test_id)
235305
logger.info("Test %s has been updated successfully", test_id)

src/load/azext_load/data_plane/load_test/help.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
- name: Create a test with user assigned Managed Identity reference for engine.
5050
text: |
5151
az load test create --test-id sample-test-id --load-test-resource sample-alt-resource --resource-group sample-rg --display-name "Sample Name" --engine-ref-id-type UserAssigned --engine-ref-ids "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-rg/providers/microsoft.managedidentity/userassignedidentities/sample-mi"
52+
- name: Create a test with user assigned Managed Identity reference for accessing the metrics of the configured apps.
53+
text: |
54+
az load test create --test-id sample-test-id --load-test-resource sample-alt-resource --resource-group sample-rg --display-name "Sample Name" --engine-ref-id-type UserAssigned --metrics-reference-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-rg/providers/microsoft.managedidentity/userassignedidentities/sample-mi"
5255
"""
5356

5457
helps[

src/load/azext_load/data_plane/load_test/params.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ def load_arguments(self, _):
2727
c.argument(
2828
"key_vault_reference_identity", argtypes.key_vault_reference_identity
2929
)
30+
c.argument(
31+
"metrics_reference_identity", argtypes.metrics_reference_identity, help="The identity that will be used to access the metrics. This will be defaulted to SystemAssigned if not given."
32+
)
3033
c.argument("engine_instances", argtypes.engine_instances)
3134
c.argument("custom_no_wait", argtypes.custom_no_wait)
3235
c.argument("disable_public_ip", argtypes.disable_public_ip)
@@ -48,6 +51,9 @@ def load_arguments(self, _):
4851
c.argument(
4952
"key_vault_reference_identity", argtypes.key_vault_reference_identity, help="The identity that will be used to access the key vault. Provide `null` or `None` to use the system assigned identity of the load test resource."
5053
)
54+
c.argument(
55+
"metrics_reference_identity", argtypes.metrics_reference_identity, help="The identity that will be used to access the metrics. Provide `null` or `None` to use the system assigned identity of the load test resource."
56+
)
5157
c.argument("engine_instances", argtypes.engine_instances)
5258
c.argument("subnet_id", argtypes.subnet_id)
5359
c.argument("split_csv", argtypes.split_csv)

src/load/azext_load/data_plane/utils/argtypes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,19 @@
129129
)
130130

131131
key_vault_reference_identity = CLIArgumentType(
132+
validator=validators.validate_keyvault_identity_ref_id,
132133
options_list=["--keyvault-reference-id"],
133134
type=str,
134135
help="The identity that will be used to access the key vault.",
135136
)
136137

138+
metrics_reference_identity = CLIArgumentType(
139+
validator=validators.validate_metrics_identity_ref_id,
140+
options_list=["--metrics-reference-id"],
141+
type=str,
142+
help="The identity that will be used to get the metrics of the configured apps from server pass-fail criteria.",
143+
)
144+
137145
split_csv = CLIArgumentType(
138146
validator=validators.validate_split_csv,
139147
options_list=["--split-csv"],

src/load/azext_load/data_plane/utils/constants.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# --------------------------------------------------------------------------------------------
55

66
from dataclasses import dataclass
7+
from typing import ClassVar
78
from .models import AllowedTrendsResponseTimeAggregations
89

910

@@ -24,12 +25,25 @@ class LoadTestConfigKeys:
2425
AUTOSTOP_ERROR_RATE = "errorPercentage"
2526
AUTOSTOP_ERROR_RATE_TIME_WINDOW = "timeWindow"
2627
FAILURE_CRITERIA = "failureCriteria"
28+
CLIENT_METRICS_PF = "clientMetrics"
29+
SERVER_METRICS_PF = "serverMetrics"
30+
METRIC_NAME = "metricName"
31+
METRIC_NAME_SERVER_METRICS = "name"
32+
METRIC_NAMESPACE_SERVER_METRICS = "namespace"
33+
METRIC_NAMESPACE = "metricNamespace"
34+
RESOURCEID = "resourceId"
35+
AGGREGATION = "aggregation"
36+
CONDITION = "condition"
37+
APP_COMPONENTS = "appComponents"
38+
SERVER_METRICS_APP_COMPONENTS = "metrics"
2739
REGIONAL_LOADTEST_CONFIG = "regionalLoadTestConfig"
2840
REGION = "region"
2941
QUICK_START = "quickStartTest"
3042
SPLIT_CSV = "splitAllCSVs"
3143
REFERENCE_IDENTITIES = "referenceIdentities"
3244
ENGINE = "Engine"
45+
METRICS = "Metrics"
46+
KEY_VAULT = "KeyVault"
3347
TYPE = "type"
3448
KIND = "kind"
3549
VALUE = "value"
@@ -76,3 +90,11 @@ class LoadTestTrendsKeys:
7690
AllowedTrendsResponseTimeAggregations.P999.value: "pct999ResTime",
7791
AllowedTrendsResponseTimeAggregations.P9999.value: "pct9999ResTime",
7892
}
93+
94+
95+
@dataclass
96+
class LoadTestFailureCriteriaKeys:
97+
CONDITION_ENUM_MAP: ClassVar[dict[str, str]] = {
98+
"LessThan": "<",
99+
"GreaterThan": ">"
100+
}

0 commit comments

Comments
 (0)