From b2c2f0d187032c9e0b4397f5fc1f1d762ffc053c Mon Sep 17 00:00:00 2001 From: Guilherme Gallo Date: Thu, 14 Nov 2024 23:44:07 -0300 Subject: [PATCH] ci/lava: Set default exit code to 1 for failed jobs Sets the default exit code to 1 to ensure the GitLab job fails when the LAVA job fails or is interrupted. Adds tests to verify the exit code is correctly set based on the logs or the lack of them (unexpected finishing: timeouts and canceling). Signed-off-by: Guilherme Gallo Part-of: --- .gitlab-ci/lava/utils/lava_job.py | 5 ++- .gitlab-ci/tests/test_lava_job_submitter.py | 41 ++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci/lava/utils/lava_job.py b/.gitlab-ci/lava/utils/lava_job.py index 7450e574361..2326c399b59 100644 --- a/.gitlab-ci/lava/utils/lava_job.py +++ b/.gitlab-ci/lava/utils/lava_job.py @@ -35,7 +35,10 @@ class LAVAJob: self._is_finished = False self.log: dict[str, Any] = log self.status = "not_submitted" - self._exit_code = None + # Set the default exit code to 1 because we should set it to 0 only if the job has passed. + # If it fails or if it is interrupted, the exit code should be set to a non-zero value to + # make the GitLab job fail. + self._exit_code: int = 1 self.__exception: Optional[Exception] = None def heartbeat(self) -> None: diff --git a/.gitlab-ci/tests/test_lava_job_submitter.py b/.gitlab-ci/tests/test_lava_job_submitter.py index c69d9cbf71a..cd08da6b488 100644 --- a/.gitlab-ci/tests/test_lava_job_submitter.py +++ b/.gitlab-ci/tests/test_lava_job_submitter.py @@ -9,7 +9,7 @@ import os import xmlrpc.client from contextlib import nullcontext as does_not_raise from datetime import datetime -from itertools import islice, repeat +from itertools import cycle, islice, repeat from pathlib import Path from typing import Generator from unittest.mock import MagicMock, patch @@ -507,3 +507,42 @@ def test_job_combined_status( assert STRUCTURAL_LOG["job_combined_status"] == expected_combined_status assert STRUCTURAL_LOG["job_exit_code"] == job_exit_code + + +SUBMIT_SCENARIOS = { + "submit job pass": (cycle(mock_logs(result="pass", exit_code=0)), does_not_raise(), 0), + "submit job fails": ( + cycle(mock_logs(result="fail", exit_code=1)), + pytest.raises(SystemExit), + 1, + ), + "user interrupts the script": ( + (jobs_logs_response(), KeyboardInterrupt, jobs_logs_response()), + pytest.raises(SystemExit), + 1, + ), + "job finishes without hwci response": ( + (jobs_logs_response(), jobs_logs_response()), + pytest.raises(SystemExit), + 1, + ), +} + + +@pytest.mark.parametrize( + "test_log, expectation, exit_code", + SUBMIT_SCENARIOS.values(), + ids=SUBMIT_SCENARIOS.keys(), +) +def test_submission_exit_code( + request, mock_proxy, lava_job_submitter, test_log, expectation, exit_code +): + lava_job_submitter._LAVAJobSubmitter__prepare_submission = MagicMock() + proxy = mock_proxy(side_effect=test_log) + lava_job_submitter.proxy = proxy + + with expectation as e: + lava_job_submitter.submit() + # If the job fails, there should be a SystemExit exception + if e: + assert e.value.code == exit_code