From 4bc19b910bb8e016ac1c74248288072f2209e5f1 Mon Sep 17 00:00:00 2001 From: Kamoltat Sirivadhna Date: Wed, 1 Nov 2023 11:53:40 -0400 Subject: [PATCH] src/services: Init unit-tests for kill & suite service Signed-off-by: Kamoltat Sirivadhna --- pytest.ini | 6 ++ src/teuthology_api/services/suite.py | 2 +- tests/test_helpers.py | 57 +++++++++++++++ tests/test_kill.py | 49 +++++++++++++ tests/test_suite.py | 102 +++++++++++++++++++++++++++ 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 pytest.ini create mode 100644 tests/test_helpers.py create mode 100644 tests/test_kill.py create mode 100644 tests/test_suite.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..b478d07 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,6 @@ +[pytest] +pythonpath = src +log_cli = 1 +log_cli_level = INFO +log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s) +log_cli_date_format=%Y-%m-%d %H:%M:%S \ No newline at end of file diff --git a/src/teuthology_api/services/suite.py b/src/teuthology_api/services/suite.py index 7e251da..8f1d0f7 100644 --- a/src/teuthology_api/services/suite.py +++ b/src/teuthology_api/services/suite.py @@ -68,7 +68,7 @@ def make_run_name(run_dic): str(run_dic["timestamp"]), run_dic["suite"], run_dic["ceph_branch"], - run_dic["kernel_branch"] or "-", + run_dic["kernel_branch"] or "distro", run_dic["flavor"], worker, ] diff --git a/tests/test_helpers.py b/tests/test_helpers.py new file mode 100644 index 0000000..cda9a64 --- /dev/null +++ b/tests/test_helpers.py @@ -0,0 +1,57 @@ +from fastapi.testclient import TestClient +from fastapi import HTTPException +import pytest +from teuthology_api.main import app +from unittest.mock import patch +from teuthology_api.services.helpers import Request, get_token, get_username + +client = TestClient(app) + + +class MockRequest: + def __init__(self, access_token="testToken123", bad=False): + if bad: + self.session = {} + else: + self.session = { + "user": { + "username": "user1", + "access_token": access_token, + } + } + + +# get_token +@patch("teuthology_api.services.helpers.Request") +def test_get_token_success(m_request): + m_request = MockRequest() + expected = {"access_token": "testToken123", "token_type": "bearer"} + actual = get_token(m_request) + assert expected == actual + + +@patch("teuthology_api.services.helpers.Request") +def test_get_token_fail(m_request): + with pytest.raises(HTTPException) as err: + m_request = MockRequest(bad=True) + get_token(m_request) + assert err.value.status_code == 401 + assert err.value.detail == "You need to be logged in" + + +# get username +@patch("teuthology_api.services.helpers.Request") +def test_get_username_success(m_request): + m_request = MockRequest() + expected = "user1" + actual = get_username(m_request) + assert expected == actual + + +@patch("teuthology_api.services.helpers.Request") +def test_get_username_fail(m_request): + with pytest.raises(HTTPException) as err: + m_request = MockRequest(bad=True) + get_username(m_request) + assert err.value.status_code == 401 + assert err.value.detail == "You need to be logged in" diff --git a/tests/test_kill.py b/tests/test_kill.py new file mode 100644 index 0000000..90adef8 --- /dev/null +++ b/tests/test_kill.py @@ -0,0 +1,49 @@ +from fastapi.testclient import TestClient +from teuthology_api.main import app +from unittest.mock import patch +from teuthology_api.services.helpers import get_token +from teuthology_api.services.kill import get_username, get_run_details +import json +from teuthology_api.schemas.kill import KillArgs + +client = TestClient(app) + + +async def override_get_token(): + return {"access_token": "token_123", "token_type": "bearer"} + + +app.dependency_overrides[get_token] = override_get_token + +mock_kill_args = { + "--dry-run": False, + "--non-interactive": False, + "--verbose": 1, + "--help": False, + "--user": "mock_user", + "--owner": "user1", + "--run": "mock_run", + "--preserve-queue": None, + "--job": None, + "--jobspec": None, + "--machine-type": "testnode", + "--archive": None, +} + + +@patch("teuthology_api.services.kill.teuthology.kill.main") +@patch("teuthology_api.services.kill.get_run_details") +@patch("teuthology_api.services.kill.get_username") +def test_kill_run_success(m_get_username, m_get_run_details, m_teuth_kill_main): + m_get_username.return_value = "user1" + m_get_run_details.return_value = {"id": "7451978", "user": "user1"} + m_teuth_kill_main.return_value = None + response = client.post("/kill", data=json.dumps(mock_kill_args)) + assert response.status_code == 200 + assert response.json() == {"kill": "success"} + + +def test_kill_run_fail(): + response = client.post("/kill", data=json.dumps(mock_kill_args)) + assert response.status_code == 401 + assert response.json() == {"detail": "You need to be logged in"} diff --git a/tests/test_suite.py b/tests/test_suite.py new file mode 100644 index 0000000..d39f1e8 --- /dev/null +++ b/tests/test_suite.py @@ -0,0 +1,102 @@ +from fastapi.testclient import TestClient +from teuthology_api.main import app +from unittest.mock import patch +from teuthology_api.services.helpers import get_token +from teuthology_api.services.suite import make_run_name, get_run_details +import json + +client = TestClient(app) + + +async def override_get_token(): + return {"access_token": "token_123", "token_type": "bearer"} + + +app.dependency_overrides[get_token] = override_get_token + +mock_suite_args = { + "--dry-run": False, + "--non-interactive": False, + "--verbose": 1, + "--help": False, + "--user": "mock_user", + "--timestamp": "2023-10-21_14:30:00", + "--owner": "user1", + "--suite": "rados", + "--ceph": "ceph1", + "--kernel": "kernel1", + "--flavor": "test-flavor", + "--machine-type": "testnode", +} + +# suite +@patch("teuthology_api.services.suite.teuthology.suite.main") +@patch("teuthology_api.services.suite.get_run_details") +def test_suite_run_success(m_get_run_details, m_teuth_suite_main): + m_get_run_details.return_value = {"id": "7451978", "user": "user1"} + response = client.post("/suite", data=json.dumps(mock_suite_args)) + assert response.status_code == 200 + assert response.json() == {"run": {"id": "7451978", "user": "user1"}, "logs": []} + + +# make_run_name + + +def test_make_run_name(): + m_run_dic = { + "user": "testuser", + "timestamp": "2022-03-21_14:30:00", + "suite": "rados", + "ceph_branch": "ceph1", + "kernel_branch": "kernel1", + "flavor": "test-flavor", + "machine_type": "test-machine", + } + expected = ( + "testuser-2022-03-21_14:30:00-rados-ceph1-kernel1-test-flavor-test-machine" + ) + assert make_run_name(m_run_dic) == expected + + +def test_make_run_name_with_single_worker(): + m_run_dic = { + "user": "test_user", + "timestamp": "2022-03-21_14:30:00", + "suite": "rados", + "ceph_branch": "ceph1", + "kernel_branch": "kernel1", + "flavor": "test-flavor", + "machine_type": "worker1", + } + expected = "test_user-2022-03-21_14:30:00-rados-ceph1-kernel1-test-flavor-worker1" + assert make_run_name(m_run_dic) == expected + + +def test_make_run_name_with_multi_worker(): + m_run_dic = { + "user": "test_user", + "timestamp": "2022-03-21_14:30:00", + "suite": "rados", + "ceph_branch": "ceph1", + "kernel_branch": "kernel1", + "flavor": "test-flavor", + "machine_type": "worker1,worker2,worker3", + } + expected = "test_user-2022-03-21_14:30:00-rados-ceph1-kernel1-test-flavor-multi" + assert make_run_name(m_run_dic) == expected + + +def test_make_run_name_with_no_kernel_branch(): + m_run_dic = { + "user": "teuthology", + "timestamp": "2022-03-21_14:30:00", + "suite": "rados", + "ceph_branch": "ceph1", + "kernel_branch": None, + "flavor": "test-flavor", + "machine_type": "test-machine", + } + expected = ( + "teuthology-2022-03-21_14:30:00-rados-ceph1-distro-test-flavor-test-machine" + ) + assert make_run_name(m_run_dic) == expected