From 1e9e27e05a3d7d1f0bc129c248c95743398afd48 Mon Sep 17 00:00:00 2001 From: Anton Smorodskyi Date: Mon, 9 Dec 2024 18:21:47 +0100 Subject: [PATCH] Introduce new method get_latest_build One of many common tasks which you need to address when interacting with openQA programatically is to detect what was latest build in certain Job Group. This is implementation of such function in this lib, so users of this lib may delete same logic duplicated many times --- src/openqa_client/client.py | 31 +++++++++++++++++++++++++++++-- tests/test_client.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/openqa_client/client.py b/src/openqa_client/client.py index 18bdfb0..9fecdec 100644 --- a/src/openqa_client/client.py +++ b/src/openqa_client/client.py @@ -35,9 +35,9 @@ import openqa_client.exceptions if sys.version_info >= (3, 8): - from typing import Literal, TypedDict + from typing import Literal, TypedDict, Callable else: # pragma: no cover - from typing_extensions import Literal, TypedDict # pragma: no cover + from typing_extensions import Literal, TypedDict, Callable # pragma: no cover logger = logging.getLogger(__name__) @@ -377,3 +377,30 @@ def get_jobs( # there as it only considers the jobs queried. jobdicts = self.find_clones(jobdicts) return jobdicts + + def get_latest_build( + self, + group_id: int, + all_passed: bool = True, + sort_key: Callable = int, + ) -> str: + """Identify latest build number in target Job Group + + Args: + group_id (int): Job Group ID + all_passed (bool, optional): Controls whether just last build will be selected + or the last with all jobs passed. Defaults to True. + sorted_key (Callable, optional): To find the latest build we need to order the builds. + The specified callable will be passed to sorted() to sort the builds. + Defaults to int. + + Returns: + str: string representation of last BUILD + """ + resp = self.openqa_request("GET", f"/group_overview/{group_id}.json") + if all_passed: + passed = [r for r in resp["build_results"] if r["all_passed"] == 1] + builds = [r["build"] for r in passed if r["build"].isdigit()] + else: + builds = [r["build"] for r in resp["build_results"] if r["build"].isdigit()] + return sorted(builds, key=sort_key)[-1] if builds else "" diff --git a/tests/test_client.py b/tests/test_client.py index 092b0a3..8389be4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -393,3 +393,32 @@ def test_client_errors(self): err = oqe.ConnectionError("oh no") assert err.args[0] == "oh no" assert err.err == "oh no" + + @mock.patch("openqa_client.client.OpenQA_Client.openqa_request", autospec=True) + def test_get_latest_build(self, fakerequest): + client = oqc.OpenQA_Client() + fakerequest.return_value = {"build_results": [{"all_passed": 0, "build": "1"}]} + ret = client.get_latest_build(42) + # returns default when no passed builds available + assert ret == "" + ret = client.get_latest_build(42, all_passed=False) + # returns build with all_passed=0 when all_passed is False + assert ret == "1" + fakerequest.return_value = { + "build_results": [ + {"all_passed": 1, "build": "2"}, + {"all_passed": 1, "build": "3"}, + {"all_passed": 1, "build": "4"}, + {"all_passed": 0, "build": "5"}, + {"all_passed": 1, "build": "qq"}, + {"all_passed": 1, "build": "001"}, + ] + } + ret = client.get_latest_build(42) + # returns lastest passed build when all_passed flag set to True + assert ret == "4" + ret = client.get_latest_build(42, all_passed=False) + # returns lastest failed build when all_passed flag set to False + assert ret == "5" + ret = client.get_latest_build(42, sort_key=len) + assert ret == "001"