From f5717f03af390411945d690352458d554b7b4244 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 interucting 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 | 34 ++++++++++++++++++++++++++++++++-- tests/test_client.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/openqa_client/client.py b/src/openqa_client/client.py index 18bdfb0..675e6a8 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,33 @@ 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, + sorted_key: Callable = float, + default_return: str = "0", + ) -> str: + """Identify latest build number in target Job Group + + Args: + group_id (int): Job Group ID + all_passed (bool, optional): Controls whether just + last one will be selected or last with all jobs passed. Defaults to True. + sorted_key (Callable, optional): To judge about latest build we need to order them. + This is callback which will be used in sorted function to sort builds. + Defaults to float. + default_return (str, optional): In case all available builds have not acceptable format + or there is no builds in this job group this value identofy what to return. Defaults to "0". + + 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 list(sorted(builds, key=sorted_key))[-1] if builds else default_return diff --git a/tests/test_client.py b/tests/test_client.py index 092b0a3..9d694b8 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -393,3 +393,33 @@ 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() + with pytest.raises(TypeError): + client.get_latest_build() + fakerequest.return_value = {"build_results": [{"all_passed": 0, "build": "qq"}]} + ret = client.get_latest_build(42) + # returns default when no passed builds available + assert ret == "0" + ret = client.get_latest_build(42, all_passed=False) + # returns default when no passed builds available + assert ret == "0" + ret = client.get_latest_build(42, default_return="11") + # returns defined build when no builds were found + assert ret == "11" + 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"}, + ] + } + 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"