From 22906452663ff7e15079052670a8989be3a59d49 Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Fri, 13 Jun 2025 15:46:38 +0100 Subject: [PATCH 1/8] update to status checking that alligns with frontend --- src/ansys/conceptev/core/app.py | 9 +++++- src/ansys/conceptev/core/progress.py | 2 +- tests/test_app.py | 47 +++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/ansys/conceptev/core/app.py b/src/ansys/conceptev/core/app.py index 1b6751e3..bf0a31ab 100644 --- a/src/ansys/conceptev/core/app.py +++ b/src/ansys/conceptev/core/app.py @@ -451,7 +451,9 @@ def get_job_info(token, job_id): response = httpx.post( url=f"{OCM_URL}/job/load", headers={"authorization": token}, json={"jobId": job_id} ) + print(f"1 Response: {response.json()}") response = process_response(response) + print(f"2 Processed Response: {response}") job_info = { "job_id": job_id, "simulation_id": response["simulations"][0]["simulationId"], @@ -495,7 +497,12 @@ def get_status(job_info: dict, token: str) -> str: headers={"Authorization": token}, ) processed_response = process_response(response) - initial_status = processed_response["jobStatus"][-1]["jobStatus"] + if "finalStatus" in processed_response: + initial_status = processed_response["finalStatus"].upper() + elif "lastStatus" in processed_response: + initial_status = processed_response["lastStatus"].upper() + else: + raise ResponseError(f"Failed to get job status {processed_response}.") return initial_status diff --git a/src/ansys/conceptev/core/progress.py b/src/ansys/conceptev/core/progress.py index 30acdddd..6f5da299 100644 --- a/src/ansys/conceptev/core/progress.py +++ b/src/ansys/conceptev/core/progress.py @@ -38,7 +38,7 @@ else: import async_timeout -STATUS_COMPLETE = "complete" +STATUS_COMPLETE = "COMPLETED" STATUS_FINISHED = "FINISHED" STATUS_ERROR = "failed" OCM_SOCKET_URL = settings.ocm_socket_url diff --git a/tests/test_app.py b/tests/test_app.py index 6c6b3106..7c058918 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -352,7 +352,9 @@ def test_read_results(httpx_mock: HTTPXMock, client: httpx.Client): url=ocm_url + "/user/details", method="post", json={"userId": "user_123"} ) httpx_mock.add_response( - url=ocm_url + "/job/load", method="post", json={"jobStatus": [{"jobStatus": "complete"}]} + url=ocm_url + "/job/load", + method="post", + json={"finalStatus": "COMPLETED", "jobStatus": [{"jobStatus": "complete"}]}, ) results = app.read_results(client, example_job_info) assert example_results == results @@ -451,3 +453,46 @@ def test_get_job_file(httpx_mock: HTTPXMock): ) results = app.get_job_file(token, job_id, file_name) assert results == {"json": "1"} + + +def test_returns_final_status_when_present(mocker): + job_info = {"job_id": "123"} + token = "token" + mock_response = mocker.Mock() + mock_response.status_code = 200 + mock_response.json.return_value = {"finalStatus": "COMPLETED"} + mocker.patch("httpx.post", return_value=mock_response) + mocker.patch( + "ansys.conceptev.core.app.process_response", return_value={"finalStatus": "COMPLETED"} + ) + result = app.get_status(job_info, token) + assert result == "COMPLETED" + + +def test_returns_last_status_when_final_status_missing(mocker): + job_info = {"job_id": "123"} + token = "token" + mock_response = mocker.Mock() + mock_response.status_code = 200 + mock_response.json.return_value = {"lastStatus": "RUNNING"} + mocker.patch("httpx.post", return_value=mock_response) + mocker.patch( + "ansys.conceptev.core.app.process_response", return_value={"lastStatus": "RUNNING"} + ) + result = app.get_status(job_info, token) + assert result == "RUNNING" + + +def test_raises_error_when_no_status_fields(mocker): + job_info = {"job_id": "123"} + token = "token" + mock_response = mocker.Mock() + mock_response.status_code = 200 + mock_response.json.return_value = {"unexpected": "value"} + mocker.patch("httpx.post", return_value=mock_response) + mocker.patch("ansys.conceptev.core.app.process_response", return_value={"unexpected": "value"}) + import pytest + + with pytest.raises(app.ResponseError) as exc: + app.get_status(job_info, token) + assert "Failed to get job status" in str(exc.value) From 5c612921dd98c92029c3eec0de7ad85c2c4a11ea Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Mon, 16 Jun 2025 11:46:02 +0100 Subject: [PATCH 2/8] update test maked signals upper --- src/ansys/conceptev/core/app.py | 2 - src/ansys/conceptev/core/progress.py | 4 +- tests/test_app.py | 70 +++++++++++++++------------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/ansys/conceptev/core/app.py b/src/ansys/conceptev/core/app.py index bf0a31ab..66d19b45 100644 --- a/src/ansys/conceptev/core/app.py +++ b/src/ansys/conceptev/core/app.py @@ -451,9 +451,7 @@ def get_job_info(token, job_id): response = httpx.post( url=f"{OCM_URL}/job/load", headers={"authorization": token}, json={"jobId": job_id} ) - print(f"1 Response: {response.json()}") response = process_response(response) - print(f"2 Processed Response: {response}") job_info = { "job_id": job_id, "simulation_id": response["simulations"][0]["simulationId"], diff --git a/src/ansys/conceptev/core/progress.py b/src/ansys/conceptev/core/progress.py index 6f5da299..fa219b89 100644 --- a/src/ansys/conceptev/core/progress.py +++ b/src/ansys/conceptev/core/progress.py @@ -40,7 +40,7 @@ STATUS_COMPLETE = "COMPLETED" STATUS_FINISHED = "FINISHED" -STATUS_ERROR = "failed" +STATUS_ERROR = "FAILED" OCM_SOCKET_URL = settings.ocm_socket_url JOB_TIMEOUT = settings.job_timeout ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -62,7 +62,7 @@ def get_status(message: str, job_id: str): if message_type == "status": status = message_data.get("status", None) print(f"Status:{status}") - return status + return status.upper() elif message_type == "progress": progress = message_data.get("progress", None) print(f"Progress:{progress}") diff --git a/tests/test_app.py b/tests/test_app.py index 7c058918..20d3d905 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -27,6 +27,12 @@ from ansys.conceptev.core import app from ansys.conceptev.core.auth import AnsysIDAuth +from ansys.conceptev.core.progress import ( + STATUS_COMPLETE, + STATUS_ERROR, + STATUS_FINISHED, + check_status, +) from ansys.conceptev.core.settings import settings conceptev_url = settings.conceptev_url @@ -455,44 +461,42 @@ def test_get_job_file(httpx_mock: HTTPXMock): assert results == {"json": "1"} -def test_returns_final_status_when_present(mocker): - job_info = {"job_id": "123"} - token = "token" - mock_response = mocker.Mock() - mock_response.status_code = 200 - mock_response.json.return_value = {"finalStatus": "COMPLETED"} - mocker.patch("httpx.post", return_value=mock_response) - mocker.patch( - "ansys.conceptev.core.app.process_response", return_value={"finalStatus": "COMPLETED"} - ) - result = app.get_status(job_info, token) - assert result == "COMPLETED" - - -def test_returns_last_status_when_final_status_missing(mocker): - job_info = {"job_id": "123"} - token = "token" - mock_response = mocker.Mock() - mock_response.status_code = 200 - mock_response.json.return_value = {"lastStatus": "RUNNING"} - mocker.patch("httpx.post", return_value=mock_response) - mocker.patch( - "ansys.conceptev.core.app.process_response", return_value={"lastStatus": "RUNNING"} - ) - result = app.get_status(job_info, token) - assert result == "RUNNING" +statuses = [STATUS_COMPLETE, STATUS_FINISHED, STATUS_ERROR, None] -def test_raises_error_when_no_status_fields(mocker): +@pytest.mark.parametrize("last_status", statuses) +@pytest.mark.parametrize("final_status", statuses) +def test_returns_final_status_when_present(mocker, final_status, last_status): job_info = {"job_id": "123"} token = "token" mock_response = mocker.Mock() mock_response.status_code = 200 - mock_response.json.return_value = {"unexpected": "value"} + mock_response.json.return_value = {} + if final_status is not None: + mock_response.json.return_value["finalStatus"] = final_status + if last_status is not None: + mock_response.json.return_value["lastStatus"] = last_status mocker.patch("httpx.post", return_value=mock_response) - mocker.patch("ansys.conceptev.core.app.process_response", return_value={"unexpected": "value"}) - import pytest - with pytest.raises(app.ResponseError) as exc: - app.get_status(job_info, token) - assert "Failed to get job status" in str(exc.value) + if final_status is None and last_status is None: + with pytest.raises(app.ResponseError) as exc: + result = app.get_status(job_info, token) + return True + else: + result = app.get_status(job_info, token) + assert result in [final_status, last_status] + + +@pytest.mark.parametrize( + "result,expected", + [(STATUS_COMPLETE, True), (STATUS_FINISHED, True), (STATUS_ERROR, False), (None, False)], +) +def test_check_status(result, expected): + if expected: + assert check_status(result) + elif result is STATUS_ERROR: + with pytest.raises(Exception) as exc: + check_status(result) + assert "Job Failed" in str(exc.value) if result == STATUS_ERROR else True + else: + assert not check_status(result) From 41a1d98b284330cc95bce440152cb9d86336e669 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Mon, 16 Jun 2025 10:52:41 +0000 Subject: [PATCH 3/8] chore: adding changelog file 233.fixed.md [dependabot-skip] --- doc/changelog.d/233.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/233.fixed.md diff --git a/doc/changelog.d/233.fixed.md b/doc/changelog.d/233.fixed.md new file mode 100644 index 00000000..287e9a99 --- /dev/null +++ b/doc/changelog.d/233.fixed.md @@ -0,0 +1 @@ +fix/bug-in-job-status \ No newline at end of file From 522fc9c2323d799e1a0de1fcab3ed611e08925d1 Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Thu, 19 Jun 2025 10:05:44 +0100 Subject: [PATCH 4/8] added the change from the merge --- src/ansys/conceptev/core/ocm.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ansys/conceptev/core/ocm.py b/src/ansys/conceptev/core/ocm.py index 9b2e3492..cb083bf4 100644 --- a/src/ansys/conceptev/core/ocm.py +++ b/src/ansys/conceptev/core/ocm.py @@ -252,7 +252,12 @@ def get_status(job_info: dict, token: str) -> str: headers={"Authorization": token}, ) processed_response = process_response(response) - initial_status = processed_response["jobStatus"][-1]["jobStatus"] + if "finalStatus" in processed_response: + initial_status = processed_response["finalStatus"].upper() + elif "lastStatus" in processed_response: + initial_status = processed_response["lastStatus"].upper() + else: + raise ResponseError(f"Failed to get job status {processed_response}.") return initial_status From 59b384e2706beeeadf04a15857193878994ff6f3 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Fri, 20 Jun 2025 10:51:20 +0000 Subject: [PATCH 5/8] chore: adding changelog file 233.miscellaneous.md [dependabot-skip] --- doc/changelog.d/233.fixed.md | 1 - doc/changelog.d/233.miscellaneous.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 doc/changelog.d/233.fixed.md create mode 100644 doc/changelog.d/233.miscellaneous.md diff --git a/doc/changelog.d/233.fixed.md b/doc/changelog.d/233.fixed.md deleted file mode 100644 index 287e9a99..00000000 --- a/doc/changelog.d/233.fixed.md +++ /dev/null @@ -1 +0,0 @@ -fix/bug-in-job-status \ No newline at end of file diff --git a/doc/changelog.d/233.miscellaneous.md b/doc/changelog.d/233.miscellaneous.md new file mode 100644 index 00000000..0503d541 --- /dev/null +++ b/doc/changelog.d/233.miscellaneous.md @@ -0,0 +1 @@ +Fix/bug-in-job-status \ No newline at end of file From 76c8d7d24a0ceb6b421e1cfbc1120eedaaa524cb Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Tue, 24 Jun 2025 09:36:32 +0100 Subject: [PATCH 6/8] response error got moved --- tests/test_app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_app.py b/tests/test_app.py index e3f77be7..d46d0ea2 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -27,6 +27,7 @@ from ansys.conceptev.core import app from ansys.conceptev.core.auth import AnsysIDAuth +from ansys.conceptev.core.exceptions import ResponseError from ansys.conceptev.core.progress import ( STATUS_COMPLETE, STATUS_ERROR, @@ -521,7 +522,7 @@ def test_returns_final_status_when_present(mocker, final_status, last_status): mocker.patch("httpx.post", return_value=mock_response) if final_status is None and last_status is None: - with pytest.raises(app.ResponseError) as exc: + with pytest.raises(ResponseError) as exc: result = app.get_status(job_info, token) return True else: From 0de88abd878bfa4d8a9d57bae0bfb44b37aa34c9 Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Tue, 24 Jun 2025 09:49:00 +0100 Subject: [PATCH 7/8] updated defense against nonetype --- src/ansys/conceptev/core/ocm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/conceptev/core/ocm.py b/src/ansys/conceptev/core/ocm.py index cb083bf4..c598db07 100644 --- a/src/ansys/conceptev/core/ocm.py +++ b/src/ansys/conceptev/core/ocm.py @@ -252,9 +252,9 @@ def get_status(job_info: dict, token: str) -> str: headers={"Authorization": token}, ) processed_response = process_response(response) - if "finalStatus" in processed_response: + if "finalStatus" in processed_response and processed_response["finalStatus"] is not None: initial_status = processed_response["finalStatus"].upper() - elif "lastStatus" in processed_response: + elif "lastStatus" in processed_response and processed_response["lastStatus"] is not None: initial_status = processed_response["lastStatus"].upper() else: raise ResponseError(f"Failed to get job status {processed_response}.") From 84fdf33a4b0a8decb6a905d5afd20869befd4d25 Mon Sep 17 00:00:00 2001 From: Philip Usher Date: Wed, 25 Jun 2025 10:19:15 +0100 Subject: [PATCH 8/8] renames initial status to status --- src/ansys/conceptev/core/ocm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/conceptev/core/ocm.py b/src/ansys/conceptev/core/ocm.py index c598db07..df004f59 100644 --- a/src/ansys/conceptev/core/ocm.py +++ b/src/ansys/conceptev/core/ocm.py @@ -253,12 +253,12 @@ def get_status(job_info: dict, token: str) -> str: ) processed_response = process_response(response) if "finalStatus" in processed_response and processed_response["finalStatus"] is not None: - initial_status = processed_response["finalStatus"].upper() + status = processed_response["finalStatus"].upper() elif "lastStatus" in processed_response and processed_response["lastStatus"] is not None: - initial_status = processed_response["lastStatus"].upper() + status = processed_response["lastStatus"].upper() else: raise ResponseError(f"Failed to get job status {processed_response}.") - return initial_status + return status def get_project_ids(name: str, account_id: str, token: str) -> dict: