From b411c32bb64fdbf080c2b5e6cdd11bc6e07bd65f Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Mon, 11 May 2026 10:18:13 +0200 Subject: [PATCH 01/11] Skip create_by/modified_by tests, not there yet --- tests/jms/test_job_definitions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/jms/test_job_definitions.py b/tests/jms/test_job_definitions.py index 7c923c8ac..1e0ccb404 100644 --- a/tests/jms/test_job_definitions.py +++ b/tests/jms/test_job_definitions.py @@ -104,8 +104,9 @@ def test_task_definition_fields(client, has_hps_version_ge_1_3_45, has_hps_versi if has_hps_version_gt_1_3_45: assert task_def.working_directory == "/tmp" - assert auth_api.get_user(id=task_def.created_by).username == client.username - assert auth_api.get_user(id=task_def.modified_by).username == client.username + if task_def.created_by is not None: + assert auth_api.get_user(id=task_def.created_by).username == client.username + assert auth_api.get_user(id=task_def.modified_by).username == client.username jms_api.delete_project(project) From 1f6f8308cfdd4092fae38eb945de9ec147e30e5e Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Mon, 11 May 2026 15:42:42 +0200 Subject: [PATCH 02/11] Disable tests related to project archive/restore/copy --- tests/jms/test_projects.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/jms/test_projects.py b/tests/jms/test_projects.py index 154e50eab..efcba6dff 100644 --- a/tests/jms/test_projects.py +++ b/tests/jms/test_projects.py @@ -131,6 +131,7 @@ def test_project_replace(client): assert p.name == "Replaced Project" +@pytest.mark.skip("not in mk2 at the moment") def test_project_copy(client): jms_api = JmsApi(client) proj_name = "test_jms_ProjectCopyTest" @@ -227,8 +228,9 @@ def test_project_delete_job_definition(client): jms_api.delete_project(proj) - +@pytest.mark.skip("not in mk2 at the moment") def test_project_archive_restore(client): + num_jobs = 2 jms_api = JmsApi(client) proj_name = "test_jms_project_archive_restore" From 453ea28a4a411c06fc1481ddf88e3bc7279e8db1 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Tue, 12 May 2026 11:04:21 +0200 Subject: [PATCH 03/11] Skip task def template permission tests for now --- tests/jms/test_task_definition_templates.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/jms/test_task_definition_templates.py b/tests/jms/test_task_definition_templates.py index 0fb1bf211..babf39ea7 100644 --- a/tests/jms/test_task_definition_templates.py +++ b/tests/jms/test_task_definition_templates.py @@ -25,6 +25,7 @@ import uuid from marshmallow.utils import missing +import pytest from ansys.hps.client import HPSError from ansys.hps.client.auth import AuthApi @@ -200,6 +201,7 @@ def test_template_integration(jms_api, request): jms_api.delete_task_definition_templates([new_template]) +@pytest.mark.skip("not in mk2 at the moment") def test_template_permissions(client, keycloak_client, is_admin, request): jms_api = JmsApi(client) @@ -296,7 +298,7 @@ def test_template_permissions(client, keycloak_client, is_admin, request): # Delete user delete_user(keycloak_client, user1) - +@pytest.mark.skip("not in mk2 at the moment") def test_template_permissions_update(jms_api, request): xfail_for_hps_version_under(HpsRelease.v1_3_45, jms_api, request) @@ -322,6 +324,7 @@ def test_template_permissions_update(jms_api, request): jms_api.delete_task_definition_templates([template]) +@pytest.mark.skip("not in mk2 at the moment") def test_template_anyone_permission(client, keycloak_client, request): jms_api = JmsApi(client) xfail_for_hps_version_under(HpsRelease.v1_3_45, jms_api, request) @@ -386,6 +389,7 @@ def test_template_anyone_permission(client, keycloak_client, request): delete_user(keycloak_client, user1) +@pytest.mark.skip("not in mk2 at the moment") def test_template_delete(client, keycloak_client, request): xfail_for_hps_version_under(HpsRelease.v1_3_45, JmsApi(client), request) From e3c7005676c18311592958f1d0eaf2cc56041121 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Tue, 12 May 2026 13:19:34 +0200 Subject: [PATCH 04/11] Adjust task test --- tests/jms/test_tasks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/jms/test_tasks.py b/tests/jms/test_tasks.py index 1ad0499ad..a16229b85 100644 --- a/tests/jms/test_tasks.py +++ b/tests/jms/test_tasks.py @@ -305,11 +305,14 @@ def test_register_external_job(client): job = Job( name="Fluent Session", - eval_status="running", + eval_status="pending", job_definition_id=job_def.id, ) job = project_api.create_jobs([job])[0] + job.eval_status = "running" + job = project_api.update_jobs([job])[0] + # add custom data to the task tasks = project_api.get_tasks(job_id=job.id) assert len(tasks) == 1 From fc31da87b6fb5bfd5cf6bb75ffab285e73bf0e71 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Tue, 12 May 2026 14:38:50 +0200 Subject: [PATCH 05/11] Adjust test for missing auth --- tests/jms/test_jobs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/jms/test_jobs.py b/tests/jms/test_jobs.py index 2df1e13d6..1dcb1e11d 100644 --- a/tests/jms/test_jobs.py +++ b/tests/jms/test_jobs.py @@ -184,8 +184,10 @@ def test_job_integration(client): assert job.executed_level is not None assert job.modified_by is not missing assert job.created_by is not missing - assert auth_api.get_user(id=job.created_by).username == client.username - assert auth_api.get_user(id=job.modified_by).username == client.username + if job.created_by is not None: + assert auth_api.get_user(id=job.created_by).username == client.username + if job.modified_by is not None: + assert auth_api.get_user(id=job.modified_by).username == client.username # fill some of them job.creator = "hps-client" job.note = f"test job{job.id} update" From 47effa2626619c30ab6df6c21b32b46a5923a953 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Tue, 12 May 2026 14:40:48 +0200 Subject: [PATCH 06/11] DIsable project permission tests --- tests/jms/test_project_permissions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/jms/test_project_permissions.py b/tests/jms/test_project_permissions.py index 010c06399..d0459d4f5 100644 --- a/tests/jms/test_project_permissions.py +++ b/tests/jms/test_project_permissions.py @@ -24,6 +24,8 @@ import time import uuid +import pytest + from ansys.hps.client import Client from ansys.hps.client.auth import AuthApi, User from ansys.hps.client.exceptions import ClientError @@ -61,7 +63,7 @@ def remove_permissions(project_api: ProjectApi, user): permissions = project_api.update_permissions(permissions) log.info(f"Permissions after: {permissions}") - +@pytest.mark.skip("not available in mk2 at the moment") def test_get_project_permissions(client): jms_api = JmsApi(client) proj_name = "test_jms_get_permissions_test" @@ -80,6 +82,7 @@ def test_get_project_permissions(client): jms_api.delete_project(proj) +@pytest.mark.skip("not available in mk2 at the moment") def test_modify_project_permissions(client, keycloak_client): user_credentials = { "user1": {"username": f"testuser-{uuid.uuid4().hex[:8]}", "password": "test"}, From 3fcb4d1850cf6171ee24d41268f2cd4282b690be Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Wed, 13 May 2026 11:37:13 +0200 Subject: [PATCH 07/11] Adjust exceptions test --- tests/test_exceptions.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index c53a18fe4..8faf0af73 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -36,12 +36,22 @@ def test_server_error(client): try: jms_api.get_projects(wrong_query_param="value") except APIError as e: + # JMS mk1 + except_obj = e + log.error(str(e)) + except ClientError as e: + # JMS mk2 except_obj = e log.error(str(e)) - assert except_obj.reason == "500 Internal Server Error" - assert except_obj.description == "type object 'Project' has no attribute 'wrong_query_param'" - assert except_obj.response.status_code == 500 + if except_obj.response.status_code == 500: + assert except_obj.reason == "500 Internal Server Error" + assert except_obj.description == "type object 'Project' has no attribute 'wrong_query_param'" + elif except_obj.response.status_code == 400: + assert "Bad Request" in except_obj.reason + assert "invalid field filter" in except_obj.description + else: + raise AssertionError(f"Unexpected status code: {except_obj.response.status_code}") @pytest.mark.xfail From 482fea5789de1f740cc3917debbb4f6d06d3e227 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Wed, 13 May 2026 11:37:29 +0200 Subject: [PATCH 08/11] Adjust exception handling --- src/ansys/hps/client/exceptions.py | 73 ++++++++++++++++-------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/ansys/hps/client/exceptions.py b/src/ansys/hps/client/exceptions.py index 5090fea9b..fe77f38d8 100644 --- a/src/ansys/hps/client/exceptions.py +++ b/src/ansys/hps/client/exceptions.py @@ -22,7 +22,9 @@ """Module providing the base class for all client and server HPS-related errors.""" from requests.exceptions import RequestException +import logging +log = logging.getLogger(__name__) class HPSError(RequestException): """Provides the base class for all HPS-related errors. @@ -76,42 +78,47 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) +description_fields = ["description", "error_description", "detail"] + +def _build_error_message(category, response): + """Builds an error message from a response object.""" + r_content = {} + try: + r_content = response.json() + except ValueError: + pass + + reason = r_content.get("title", None) # jms api + if not reason: + reason = r_content.get("error", None) # auth api + if not reason: + reason = response.reason + + description = None + for field in description_fields: + description = r_content.get(field, None) + if description: + break + + msg = ( + f"{response.status_code} {category}: {reason} for:" + f" {response.request.method} {response.url}" + ) + if description: + msg += f"\n{description}" + + return reason, description, msg + + def raise_for_status(response, *args, **kwargs): """Automatically checks HTTP errors. This method mimics the requests.Response.raise_for_status() method. """ - if 400 <= response.status_code < 600: - r_content = {} - try: - r_content = response.json() - except ValueError: - pass - - reason = r_content.get("title", None) # jms api - if not reason: - reason = r_content.get("error", None) # auth api - if not reason: - reason = response.reason - - description = r_content.get("description", None) # jms api - if not description: - description = r_content.get("error_description", None) # auth api - - if 400 <= response.status_code < 500: - error_msg = ( - f"{response.status_code} Client Error: {reason} for:" - f" {response.request.method} {response.url}" - ) - if description: - error_msg += f"\n{description}" - raise ClientError(error_msg, reason=reason, description=description, response=response) - elif 500 <= response.status_code < 600: - error_msg = ( - f"{response.status_code} Server Error: {reason} for:" - f" {response.request.method} {response.url}" - ) - if description: - error_msg += f"\n{description}" - raise APIError(error_msg, reason=reason, description=description, response=response) + if 400 <= response.status_code < 500: + reason, description, message = _build_error_message("Client Error", response) + raise ClientError(message, reason=reason, description=description, response=response) + elif 500 <= response.status_code < 600: + reason, description, message = _build_error_message("Server Error", response) + raise APIError(message, reason=reason, description=description, response=response) return response From c584e27cd10b781a0dd7b49282f13234be4d77a0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 09:38:01 +0000 Subject: [PATCH 09/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/ansys/hps/client/exceptions.py | 10 ++++++---- tests/jms/test_project_permissions.py | 1 + tests/jms/test_projects.py | 1 + tests/jms/test_task_definition_templates.py | 3 ++- tests/test_exceptions.py | 4 +++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ansys/hps/client/exceptions.py b/src/ansys/hps/client/exceptions.py index fe77f38d8..927de0fc4 100644 --- a/src/ansys/hps/client/exceptions.py +++ b/src/ansys/hps/client/exceptions.py @@ -21,11 +21,13 @@ # SOFTWARE. """Module providing the base class for all client and server HPS-related errors.""" -from requests.exceptions import RequestException import logging +from requests.exceptions import RequestException + log = logging.getLogger(__name__) + class HPSError(RequestException): """Provides the base class for all HPS-related errors. @@ -80,6 +82,7 @@ def __init__(self, *args, **kwargs): description_fields = ["description", "error_description", "detail"] + def _build_error_message(category, response): """Builds an error message from a response object.""" r_content = {} @@ -99,10 +102,9 @@ def _build_error_message(category, response): description = r_content.get(field, None) if description: break - + msg = ( - f"{response.status_code} {category}: {reason} for:" - f" {response.request.method} {response.url}" + f"{response.status_code} {category}: {reason} for: {response.request.method} {response.url}" ) if description: msg += f"\n{description}" diff --git a/tests/jms/test_project_permissions.py b/tests/jms/test_project_permissions.py index d0459d4f5..f0458204a 100644 --- a/tests/jms/test_project_permissions.py +++ b/tests/jms/test_project_permissions.py @@ -63,6 +63,7 @@ def remove_permissions(project_api: ProjectApi, user): permissions = project_api.update_permissions(permissions) log.info(f"Permissions after: {permissions}") + @pytest.mark.skip("not available in mk2 at the moment") def test_get_project_permissions(client): jms_api = JmsApi(client) diff --git a/tests/jms/test_projects.py b/tests/jms/test_projects.py index efcba6dff..3cfa0bac3 100644 --- a/tests/jms/test_projects.py +++ b/tests/jms/test_projects.py @@ -228,6 +228,7 @@ def test_project_delete_job_definition(client): jms_api.delete_project(proj) + @pytest.mark.skip("not in mk2 at the moment") def test_project_archive_restore(client): diff --git a/tests/jms/test_task_definition_templates.py b/tests/jms/test_task_definition_templates.py index babf39ea7..18877e025 100644 --- a/tests/jms/test_task_definition_templates.py +++ b/tests/jms/test_task_definition_templates.py @@ -24,8 +24,8 @@ import logging import uuid -from marshmallow.utils import missing import pytest +from marshmallow.utils import missing from ansys.hps.client import HPSError from ansys.hps.client.auth import AuthApi @@ -298,6 +298,7 @@ def test_template_permissions(client, keycloak_client, is_admin, request): # Delete user delete_user(keycloak_client, user1) + @pytest.mark.skip("not in mk2 at the moment") def test_template_permissions_update(jms_api, request): xfail_for_hps_version_under(HpsRelease.v1_3_45, jms_api, request) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 8faf0af73..a1a2ba929 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -46,7 +46,9 @@ def test_server_error(client): if except_obj.response.status_code == 500: assert except_obj.reason == "500 Internal Server Error" - assert except_obj.description == "type object 'Project' has no attribute 'wrong_query_param'" + assert ( + except_obj.description == "type object 'Project' has no attribute 'wrong_query_param'" + ) elif except_obj.response.status_code == 400: assert "Bad Request" in except_obj.reason assert "invalid field filter" in except_obj.description From fc7035660faf378e56267f5ad686251a5eacdc29 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Tue, 19 May 2026 09:02:32 +0200 Subject: [PATCH 10/11] Disable impersxonate test --- tests/auth/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auth/test_api.py b/tests/auth/test_api.py index bd92e7c0b..b4c0978f9 100644 --- a/tests/auth/test_api.py +++ b/tests/auth/test_api.py @@ -101,7 +101,7 @@ def test_get_user_permissions(client): assert api.user_is_admin is not None - +@pytest.mark.skip(reason="no auth in mk2 yet") def test_impersonate_user(url, keycloak_client): """Test token exchange for impersonation, see https://www.rfc-editor.org/rfc/rfc8693.html. From 4421e2b3d8aa27690df8d3e5934c6d54e1173a2b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 07:02:43 +0000 Subject: [PATCH 11/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/auth/test_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auth/test_api.py b/tests/auth/test_api.py index b4c0978f9..d46e0987e 100644 --- a/tests/auth/test_api.py +++ b/tests/auth/test_api.py @@ -101,6 +101,7 @@ def test_get_user_permissions(client): assert api.user_is_admin is not None + @pytest.mark.skip(reason="no auth in mk2 yet") def test_impersonate_user(url, keycloak_client): """Test token exchange for impersonation, see https://www.rfc-editor.org/rfc/rfc8693.html.