From 7193ecb7d01a95293b9346ea5f5b859cfd7deb2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Ingebrigtsen=20=C3=98vergaard?= Date: Fri, 17 Nov 2023 11:02:05 +0100 Subject: [PATCH 1/3] Add tests for HTTP endpoints/web module --- tests/fiaas_deploy_daemon/web/test_web.py | 99 +++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tests/fiaas_deploy_daemon/web/test_web.py diff --git a/tests/fiaas_deploy_daemon/web/test_web.py b/tests/fiaas_deploy_daemon/web/test_web.py new file mode 100644 index 00000000..1cf1ea20 --- /dev/null +++ b/tests/fiaas_deploy_daemon/web/test_web.py @@ -0,0 +1,99 @@ +from fiaas_deploy_daemon import HealthCheck +from fiaas_deploy_daemon.specs.factory import SpecFactory + +from fiaas_deploy_daemon.web import WebBindings + +from unittest import mock + +import pkgutil +import pytest + + +@pytest.fixture +def health_check(): + yield mock.create_autospec(HealthCheck) + + +@pytest.fixture() +def spec_factory(): + yield mock.create_autospec(SpecFactory) + + +@pytest.fixture +def app(health_check, spec_factory): + bindings = WebBindings() + yield bindings.provide_webapp(spec_factory, health_check) + + +@pytest.fixture() +def client(app): + return app.test_client() + + +class TestEndpoints: + def test_frontpage(self, client): + resp = client.get("/") + assert resp.status_code == 200 + assert b"

Welcome to the FIAAS deploy daemon.

" in resp.data + + def test_metrics(self, client): + # because only the web module of the appliction is under test here and other parts are unavailable or mocked, + # only the metrics defined in that module will be on the response + expected_metrics = [ + b"web_request_started_total", + b"web_request_finished_total", + b"web_request_exception_total", + ] + + resp = client.get("/internal-backstage/prometheus") + + assert resp.status_code == 200 + for metric_name in expected_metrics: + assert metric_name in resp.data + + def test_defaults(self, client): + defaults_raw = pkgutil.get_data("fiaas_deploy_daemon.specs.v3", "defaults.yml") + + resp = client.get("/defaults") + + assert resp.status_code == 200 + assert resp.data == defaults_raw + + @pytest.mark.parametrize("version", ("2", "3")) + def test_defaults_versioned(self, client, version): + defaults_raw = pkgutil.get_data(f"fiaas_deploy_daemon.specs.v{version}", "defaults.yml") + + resp = client.get(f"/defaults/{version}") + + assert resp.status_code == 200 + assert resp.data == defaults_raw + + @pytest.mark.parametrize( + "is_healthy, status_code", + ( + (True, 200), + (False, 500), + ), + ) + def test_healthcheck(self, client, health_check, is_healthy, status_code): + health_check.is_healthy.return_value = is_healthy + + resp = client.get("/healthz") + assert resp.status_code == status_code + + def test_transform_get(self, client): + resp = client.get("/transform") + + assert resp.status_code == 200 + assert b"

Transform fiaas applicaton config.

" in resp.data + + def test_transform_post(self, spec_factory, client): + app_config = "version: 2" + expected_response = b"version: 3\n" + + spec_factory.transform.return_value = {"version": 3} + + resp = client.post("/transform", data=app_config) + + assert resp.status_code == 200 + assert resp.data == expected_response From d854d3a7946d76cd5f32f855f22bcd8c49924ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Ingebrigtsen=20=C3=98vergaard?= Date: Tue, 28 Nov 2023 12:08:01 +0100 Subject: [PATCH 2/3] Update flask and related dependencies Flask and its transitive dependencies were pinned to old versions which supported python 2. Upgrade to the most recent versions, since python 2 support is no longer relevant. html test reports were disabled in 9f42cd9cebaf2aeed8a54aafc3bb19bfda99b383 because of an interaction issue with the older version of pytest-html which was used. Since flask and jinja2 is updated now, it is possible to use the most recent version of pytest-html, which does not have the duplicate test number reporting issue. Update pytest-html and and re-enable html reports for tests. --- setup.py | 17 ++++++++--------- tox.ini | 8 ++------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/setup.py b/setup.py index 5f2f9ce1..0e2ccf52 100755 --- a/setup.py +++ b/setup.py @@ -41,14 +41,13 @@ def read(filename): ] WEB_REQ = [ - # TODO: upgrade flask and associated dependencies to 2.x - "Flask == 1.1.1", - "flask-talisman==0.7.0", - "jinja2 <= 2.11.3", # jinja 3.x requires also upgrading flask to 2.x - "markupsafe <= 1.1.1", # markupsafe 2.x requires also upgrading flask to 2.x - "itsdangerous <= 1.1.0", # markupsafe 2.x requires also upgrading flask to 2.x - "werkzeug <= 1.0.1", # markupsafe 2.x requires also upgrading flask to 2.x - "blinker == 1.4", + "Flask == 3.0.0", + "flask-talisman >= 1.1.0", + "jinja2 >= 3.0.1", + "markupsafe >= 2.1.3", + "itsdangerous >= 2.1.2", + "werkzeug >= 3.0.1", + "blinker >= 1.7.0", ] DEPLOY_REQ = [ @@ -67,7 +66,7 @@ def read(filename): TESTS_REQ = [ "pytest-xdist == 3.3.1", "pytest-sugar == 0.9.7", - "pytest-html == 3.2.0", + "pytest-html == 4.1.1", "pytest-cov == 4.1.0", "pytest-helpers-namespace == 2021.12.29", "pytest == 7.4.2", diff --git a/tox.ini b/tox.ini index 64e245c8..1a2d62fe 100644 --- a/tox.ini +++ b/tox.ini @@ -14,9 +14,5 @@ passenv = DOCKER_HOST commands= codestyle: flake8 '--format=%(path)-50s: [%(code)s] %(text)s [line:%(row)d, column:%(col)d]' {posargs} - # --cov-report html and --html disabled temporarily until pytest-html can be upgraded to 4.x - # test: python -m pytest -m "not integration_test" -n auto -ra --cov=fiaas_deploy_daemon --cov-report html --cov-report xml --cov-report term --junit-xml=build/reports/tests.xml --html=build/reports/tests.html --disable-warnings {posargs} - test: python -m pytest -m "not integration_test" -n auto -ra --cov=fiaas_deploy_daemon --cov-report xml --cov-report term --junit-xml=build/reports/tests.xml {posargs} - # --html disabled temporarily until pytest-html can be upgraded to 4.x - # integration_test: python -m pytest -m integration_test -n 2 -ra --junit-xml=build/reports/integration_tests.xml --html=build/reports/integration_tests.html --disable-warnings {posargs} - integration_test: python -m pytest -m integration_test -n 2 -ra --junit-xml=build/reports/integration_tests.xml {posargs} + test: python -m pytest -m "not integration_test" -n auto -ra --cov=fiaas_deploy_daemon --cov-report html --cov-report xml --cov-report term --junit-xml=build/reports/tests.xml --html=build/reports/tests.html {posargs} + integration_test: python -m pytest -m integration_test -n 2 -ra --junit-xml=build/reports/integration_tests.xml --html=build/reports/integration_tests.html {posargs} From b0d2df803a954c44ea14477a764c1771e10607d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Ingebrigtsen=20=C3=98vergaard?= Date: Wed, 29 Nov 2023 12:39:45 +0100 Subject: [PATCH 3/3] Use stricter mocks in web module test --- tests/fiaas_deploy_daemon/web/test_web.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fiaas_deploy_daemon/web/test_web.py b/tests/fiaas_deploy_daemon/web/test_web.py index 1cf1ea20..a3abb997 100644 --- a/tests/fiaas_deploy_daemon/web/test_web.py +++ b/tests/fiaas_deploy_daemon/web/test_web.py @@ -11,12 +11,12 @@ @pytest.fixture def health_check(): - yield mock.create_autospec(HealthCheck) + yield mock.create_autospec(HealthCheck, spec_set=True) @pytest.fixture() def spec_factory(): - yield mock.create_autospec(SpecFactory) + yield mock.create_autospec(SpecFactory, spec_set=True) @pytest.fixture