Skip to content

Commit bd22839

Browse files
[load] support for advanced urls test
1 parent 72f3a36 commit bd22839

27 files changed

+7495
-7918
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def create_test(
3131
test_id,
3232
display_name=None,
3333
test_plan=None,
34+
test_type=None,
3435
resource_group_name=None,
3536
load_test_config_file=None,
3637
test_description=None,
@@ -68,6 +69,7 @@ def create_test(
6869
body,
6970
display_name=display_name,
7071
test_description=test_description,
72+
test_type=test_type,
7173
engine_instances=engine_instances,
7274
env=env,
7375
secrets=secrets,
@@ -87,6 +89,7 @@ def create_test(
8789
yaml_test_body,
8890
display_name=display_name,
8991
test_description=test_description,
92+
test_type=test_type,
9093
engine_instances=engine_instances,
9194
env=env,
9295
secrets=secrets,
@@ -104,7 +107,7 @@ def create_test(
104107
)
105108
logger.info("Uploading files to test %s", test_id)
106109
upload_files_helper(
107-
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait
110+
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait, test_type or yaml_test_body.get("kind") if yaml_test_body else None
108111
)
109112
response = client.get_test(test_id)
110113
logger.info("Upload files to test %s has completed", test_id)
@@ -189,7 +192,7 @@ def update_test(
189192
)
190193
logger.info("Uploading files to test %s", test_id)
191194
upload_files_helper(
192-
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait
195+
client, test_id, yaml, test_plan, load_test_config_file, not custom_no_wait, body.get("kind")
193196
)
194197
response = client.get_test(test_id)
195198
logger.info("Upload files to test %s has completed", test_id)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def load_arguments(self, _):
1515
with self.argument_context("load test create") as c:
1616
c.argument("test_id", argtypes.test_id_no_completer)
1717
c.argument("test_plan", argtypes.test_plan)
18+
c.argument("test_type", argtypes.test_type)
1819
c.argument("display_name", argtypes.test_display_name)
1920
c.argument("test_description", argtypes.test_description)
2021
c.argument("env", argtypes.env, help="space-separated environment variables: key[=value] [key[=value] ...].")

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@
9595
help="Path to the JMeter script.",
9696
)
9797

98+
test_type = CLIArgumentType(
99+
validator=validators.validate_test_type,
100+
options_list=["--test-type"],
101+
type=str,
102+
help=f"Type of the load test. Allowed values: {', '.join(utils.get_enum_values(models.AllowedTestTypes))}.",
103+
)
104+
98105
load_test_config_file = CLIArgumentType(
99106
validator=validators.validate_load_test_config_file,
100107
options_list=["--load-test-config-file"],

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class AllowedFileTypes(str, Enum):
1616
JMX_FILE = "JMX_FILE"
1717
USER_PROPERTIES = "USER_PROPERTIES"
1818
ZIPPED_ARTIFACTS = "ZIPPED_ARTIFACTS"
19+
URL_TEST_CONFIG = "URL_TEST_CONFIG",
20+
TEST_SCRIPT = 'TEST_SCRIPT',
1921

2022

2123
class AllowedIntervals(str, Enum):
@@ -29,3 +31,7 @@ class AllowedIntervals(str, Enum):
2931
class AllowedMetricNamespaces(str, Enum):
3032
LoadTestRunMetrics = "LoadTestRunMetrics"
3133
EngineHealthMetrics = "EngineHealthMetrics"
34+
35+
class AllowedTestTypes(str, Enum):
36+
JMX = "JMX"
37+
URL = "URL"

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

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from azure.mgmt.core.tools import is_valid_resource_id, parse_resource_id
2020
from knack.log import get_logger
2121

22-
from .models import IdentityType, AllowedFileTypes
22+
from .models import IdentityType, AllowedFileTypes, AllowedTestTypes
2323

2424
logger = get_logger(__name__)
2525

@@ -180,7 +180,7 @@ def upload_file_to_test(client, test_id, file_path, file_type=None, wait=False):
180180
# pylint: disable-next=protected-access
181181
file_path = validators._validate_path(file_path, is_dir=False)
182182
# pylint: disable-next=protected-access
183-
validators._validate_file_stats(file_path, file_type)
183+
validators._validate_file_stats(file_path, file_type)
184184
with open(file_path, "rb") as file:
185185
upload_poller = client.begin_upload_test_file(
186186
test_id,
@@ -294,6 +294,8 @@ def convert_yaml_to_test(data):
294294
new_body["displayName"] = data["displayName"]
295295
if "description" in data:
296296
new_body["description"] = data["description"]
297+
if "testType" in data:
298+
new_body["kind"] = data["testType"]
297299
new_body["keyvaultReferenceIdentityType"] = IdentityType.SystemAssigned
298300
if "keyVaultReferenceIdentity" in data:
299301
new_body["keyvaultReferenceIdentityId"] = data["keyVaultReferenceIdentity"]
@@ -338,6 +340,7 @@ def create_or_update_test_with_config(
338340
yaml_test_body,
339341
display_name=None,
340342
test_description=None,
343+
test_type=None,
341344
engine_instances=None,
342345
env=None,
343346
secrets=None,
@@ -358,6 +361,7 @@ def create_or_update_test_with_config(
358361
or body.get("displayName")
359362
or test_id
360363
)
364+
new_body["kind"] = test_type or yaml_test_body.get("kind") or body.get("kind")
361365

362366
test_description = test_description or yaml_test_body.get("description")
363367
if test_description:
@@ -493,6 +497,7 @@ def create_or_update_test_without_config(
493497
body,
494498
display_name=None,
495499
test_description=None,
500+
test_type=None,
496501
engine_instances=None,
497502
env=None,
498503
secrets=None,
@@ -508,6 +513,7 @@ def create_or_update_test_without_config(
508513
)
509514
new_body = {}
510515
new_body["displayName"] = display_name or body.get("displayName") or test_id
516+
new_body["kind"] = test_type or body.get("kind")
511517
test_description = test_description or body.get("description")
512518
if test_description:
513519
new_body["description"] = test_description
@@ -702,32 +708,49 @@ def upload_zipped_artifacts_helper(
702708
)
703709

704710

711+
def _evaluate_file_type_for_test_script(test_type, test_plan):
712+
if test_type == AllowedTestTypes.URL.value:
713+
_, file_extension = os.path.splitext(test_plan)
714+
if file_extension == ".json":
715+
return AllowedFileTypes.URL_TEST_CONFIG
716+
if file_extension == ".jmx":
717+
return AllowedFileTypes.JMX_FILE
718+
return AllowedFileTypes.TEST_SCRIPT
719+
720+
705721
def upload_test_plan_helper(
706-
client, test_id, yaml_data, test_plan, load_test_config_file, existing_test_files, wait
722+
client, test_id, yaml_data, test_plan, load_test_config_file, existing_test_files, wait, test_type
707723
):
708724
if test_plan is None and yaml_data is not None and yaml_data.get("testPlan"):
709725
test_plan = yaml_data.get("testPlan")
710726
existing_test_plan_files = []
711727
for file in existing_test_files:
712-
if validators.AllowedFileTypes.JMX_FILE.value == file["fileType"]:
728+
if validators.AllowedFileTypes.JMX_FILE.value == file["fileType"] or \
729+
file["fileType"] == AllowedFileTypes.TEST_SCRIPT.value:
713730
existing_test_plan_files.append(file)
714731
if test_plan:
715732
logger.info("Uploading test plan file %s", test_plan)
716-
file_response = upload_generic_files_helper(
717-
client=client,
718-
test_id=test_id, load_test_config_file=load_test_config_file,
719-
existing_files=existing_test_plan_files, file_to_upload=test_plan,
720-
file_type=validators.AllowedFileTypes.JMX_FILE,
721-
wait=wait
722-
)
723-
if wait and file_response.get("validationStatus") != "VALIDATION_SUCCESS":
724-
raise FileOperationError(
725-
f"Test plan file {test_plan} is not valid. Please check the file and try again."
733+
file_type = _evaluate_file_type_for_test_script(test_type, test_plan)
734+
try:
735+
file_response = upload_generic_files_helper(
736+
client=client,
737+
test_id=test_id, load_test_config_file=load_test_config_file,
738+
existing_files=existing_test_files, file_to_upload=test_plan,
739+
file_type=file_type,
740+
wait=wait
726741
)
742+
if wait and file_response.get("validationStatus") != "VALIDATION_SUCCESS":
743+
raise FileOperationError(
744+
f"Test plan file {test_plan} is not valid. Please check the file and try again."
745+
)
746+
except Exception as e:
747+
raise FileOperationError(
748+
f"Error occurred while uploading test plan file {test_plan} for test {test_id} of type {test_type}: {str(e)}"
749+
) from e
727750

728751

729752
def upload_files_helper(
730-
client, test_id, yaml_data, test_plan, load_test_config_file, wait
753+
client, test_id, yaml_data, test_plan, load_test_config_file, wait, test_type
731754
):
732755
files = client.list_test_files(test_id)
733756

@@ -749,4 +772,5 @@ def upload_files_helper(
749772
upload_test_plan_helper(
750773
client=client,
751774
test_id=test_id, yaml_data=yaml_data, test_plan=test_plan,
752-
load_test_config_file=load_test_config_file, existing_test_files=files, wait=wait)
775+
load_test_config_file=load_test_config_file, existing_test_files=files, wait=wait,
776+
test_type=test_type)

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from knack.log import get_logger
1515

1616
from . import utils
17-
from .models import AllowedFileTypes, AllowedIntervals, AllowedMetricNamespaces
17+
from .models import AllowedFileTypes, AllowedIntervals, AllowedMetricNamespaces, AllowedTestTypes
1818

1919
logger = get_logger(__name__)
2020

@@ -233,6 +233,20 @@ def validate_test_plan_path(namespace):
233233
)
234234

235235

236+
def validate_test_type(namespace):
237+
if namespace.test_type is None:
238+
return
239+
if not isinstance(namespace.test_type, str):
240+
raise InvalidArgumentValueError(
241+
f"Invalid test-type type: {type(namespace.test_type)}"
242+
)
243+
allowed_test_types = utils.get_enum_values(AllowedTestTypes)
244+
if namespace.test_type not in allowed_test_types:
245+
raise InvalidArgumentValueError(
246+
f"Invalid test-type value: {namespace.test_type}. Allowed values: {', '.join(allowed_test_types)}"
247+
)
248+
249+
236250
def _validate_path(path, is_dir=False):
237251
logger.info("path: %s", path)
238252
if not isinstance(path, str):

0 commit comments

Comments
 (0)