From b04494e0b21d0036d7490c774a761ee5f4583802 Mon Sep 17 00:00:00 2001 From: Gahyun Suh Date: Thu, 23 Nov 2023 15:18:27 +0000 Subject: [PATCH] fix: correct validation for Task ID format Signed-off-by: Gahyun Suh --- src/deadline/client/cli/_deadline_web_url.py | 21 +++++++---- .../cli/test_cli_handle_web_url.py | 37 +++++++++++++------ test/unit/deadline_client/shared_constants.py | 2 +- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/deadline/client/cli/_deadline_web_url.py b/src/deadline/client/cli/_deadline_web_url.py index e5a46a66..cf6e3ca4 100644 --- a/src/deadline/client/cli/_deadline_web_url.py +++ b/src/deadline/client/cli/_deadline_web_url.py @@ -22,6 +22,7 @@ DEADLINE_URL_SCHEME_NAME = "deadline" DEADLINE_ID_PATTERN = re.compile(r"^[0-9a-f]{32}$") +DEADLINE_TASK_ID_PATTERN = re.compile(r"^[0-9a-f]{32}-(0|([1-9][0-9]{0,9}))$") VALID_RESOURCE_NAMES_IN_ID = ["farm", "queue", "job", "step", "task"] @@ -73,6 +74,7 @@ def validate_resource_ids(ids: Dict[str, str]) -> None: """ Validates that the resource IDs are all valid. i.e. "-" + for Task ID: "task--<0 or a number up to 10 digits long>" Args: ids (Dict[str, str]): The resource IDs to validate. @@ -82,16 +84,17 @@ def validate_resource_ids(ids: Dict[str, str]) -> None: resource_type = id_str.split("-")[0] if not id_name.startswith(resource_type) or not validate_id_format(resource_type, id_str): raise DeadlineOperationError( - f'The ID "{id_name}": "{id_str}" is not valid. ' - "The ID format must be a valid resource name followed by a hyphen, then a hexadecimal string of 32 characters." + f'The given resource ID "{id_name}": "{id_str}" has invalid format.' ) def validate_id_format(resource_type: str, full_id_str: str) -> bool: """ Validates if the ID is in correct format. The ID must - - start with one of the resource names, and immediately followed by "-", and - - the rest of the string that follows must be a hexadecimal string of length 32. + - start with one of the resource names, and followed by a hyphen ("-"), and + - the string that follows must be a hexadecimal string of length 32. + - Additional for "task": followed by another hyphen ("-"), and ends with + a string of either 0 or a number up to 10 digits long. Args: full_id_str (str): The ID to validate. @@ -105,9 +108,13 @@ def validate_id_format(resource_type: str, full_id_str: str) -> bool: return False id_str = full_id_str[len(prefix) :] - if len(id_str) != 32: - return False - return bool(DEADLINE_ID_PATTERN.fullmatch(id_str)) + + if resource_type == "task": + return bool(DEADLINE_TASK_ID_PATTERN.fullmatch(id_str)) + else: + if len(id_str) != 32: + return False + return bool(DEADLINE_ID_PATTERN.fullmatch(id_str)) def install_deadline_web_url_handler(all_users: bool) -> None: diff --git a/test/unit/deadline_client/cli/test_cli_handle_web_url.py b/test/unit/deadline_client/cli/test_cli_handle_web_url.py index 87ceb067..307779f7 100644 --- a/test/unit/deadline_client/cli/test_cli_handle_web_url.py +++ b/test/unit/deadline_client/cli/test_cli_handle_web_url.py @@ -146,44 +146,54 @@ def test_validate_resource_ids_successful(ids: Dict[str, str]): @pytest.mark.parametrize( ("ids", "exception_message"), [ - ({"": ""}, 'The ID "": "" is not valid.'), - ({"farm_id": "farm-123"}, 'The ID "farm_id": "farm-123" is not valid.'), + ({"": ""}, 'The given resource ID "": "" has invalid format.'), + ( + {"farm_id": "farm-123"}, + 'The given resource ID "farm_id": "farm-123" has invalid format.', + ), ( {"farm_id": "farm-0123456789abcdefabcdefabcdefabc"}, - 'The ID "farm_id": "farm-0123456789abcdefabcdefabcdefabc" is not valid.', + 'The given resource ID "farm_id": "farm-0123456789abcdefabcdefabcdefabc" has invalid format.', ), ( {"farm_id": "farm-0123456789abcdefabcdefabcdefabcdef"}, - 'The ID "farm_id": "farm-0123456789abcdefabcdefabcdefabcdef" is not valid.', + 'The given resource ID "farm_id": "farm-0123456789abcdefabcdefabcdefabcdef" has invalid format.', ), ( {"farm_id": "0123456789abcdefabcdefabcdefabcd"}, - 'The ID "farm_id": "0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "farm_id": "0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ( {"farm_id": "far-0123456789abcdefabcdefabcdefabcd"}, - 'The ID "farm_id": "far-0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "farm_id": "far-0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ( {"farm_id": "-farm-0123456789abcdefabcdefabcdefabcd"}, - 'The ID "farm_id": "-farm-0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "farm_id": "-farm-0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ( {"farm_id": "farm--0123456789abcdefabcdefabcdefabcd"}, - 'The ID "farm_id": "farm--0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "farm_id": "farm--0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ( {"farm_id": "farm-farm-0123456789abcdefabcdefabcdefabcd"}, - 'The ID "farm_id": "farm-farm-0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "farm_id": "farm-farm-0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ( {"mission_id": "mission-0123456789abcdefabcdefabcdefabcd"}, - 'The ID "mission_id": "mission-0123456789abcdefabcdefabcdefabcd" is not valid.', + 'The given resource ID "mission_id": "mission-0123456789abcdefabcdefabcdefabcd" has invalid format.', + ), + ( + {"farm_id": MOCK_QUEUE_ID}, + f'The given resource ID "farm_id": "{MOCK_QUEUE_ID}" has invalid format.', ), - ({"farm_id": MOCK_QUEUE_ID}, f'The ID "farm_id": "{MOCK_QUEUE_ID}" is not valid.'), ( {"farm_id": MOCK_FARM_ID, "queue_id": "queue-123"}, - 'The ID "queue_id": "queue-123" is not valid.', + 'The given resource ID "queue_id": "queue-123" has invalid format.', + ), + ( + {"task_id": "task-0123456789abcdefabcdefabcdefabcd"}, + 'The given resource ID "task_id": "task-0123456789abcdefabcdefabcdefabcd" has invalid format.', ), ], ) @@ -228,6 +238,9 @@ def test_validate_id_format_successful(resource_type: str, full_id_str: str): ("farm", "queue-0123456789abcdefabcdefabcdefabcd"), ("farmfarm", "farmfarm-0123456789abcdefabcdefabcdefabcd"), ("mission", "mission-0123456789abcdefabcdefabcdefabcd"), + ("task", "task-0123456789abcdefabcdefabcdefabcd"), + ("task", "task-0123456789abcdefabcdefabcdefabcd-00"), + ("task", "task-0123456789abcdefabcdefabcdefabcd-12345678912345"), ], ) def test_validate_id_format_failed(resource_type: str, full_id_str: str): diff --git a/test/unit/deadline_client/shared_constants.py b/test/unit/deadline_client/shared_constants.py index 29732657..68a86049 100644 --- a/test/unit/deadline_client/shared_constants.py +++ b/test/unit/deadline_client/shared_constants.py @@ -6,7 +6,7 @@ MOCK_STORAGE_PROFILE_ID = "sp-0123456789abcdefabcdefabcdefabcd" MOCK_JOB_ID = "job-0123456789abcdefabcdefabcdefabcd" MOCK_STEP_ID = "step-0123456789abcdefabcdefabcdefabcd" -MOCK_TASK_ID = "task-0123456789abcdefabcdefabcdefabcd" +MOCK_TASK_ID = "task-0123456789abcdefabcdefabcdefabcd-99" MOCK_PROFILE_NAME = "my-studio-profile" MOCK_QUEUES_LIST = [ {