diff --git a/conda-store-server/README.md b/conda-store-server/README.md index 39d786da1..ba42cfd7c 100644 --- a/conda-store-server/README.md +++ b/conda-store-server/README.md @@ -2,3 +2,30 @@ A multi-tenant server for managing conda environments. See the [documentation](https://conda.store/) for more information. + +## Running tests + +### Run tests with pytest +``` +# ignoring integration tests +$ python -m pytest -m "not extended_prefix and not user_journey" tests/ + +# ignoring long running tests +$ python -m pytest -m "not extended_prefix and not user_journey and not long_running_test" tests/ +``` + +### Run tests with code coverage +Ensure you have pytest-cov install +``` +$ pip install pytest-cov +``` + +Run tests +``` +$ python -m pytest -m "not extended_prefix and not user_journey" --cov=conda_store_server tests/ +``` + +Check coverage report +``` +$ coverage report +``` diff --git a/conda-store-server/pyproject.toml b/conda-store-server/pyproject.toml index 7a04593a0..c838bc124 100644 --- a/conda-store-server/pyproject.toml +++ b/conda-store-server/pyproject.toml @@ -147,4 +147,6 @@ markers = [ "playwright: mark a test as a playwright test", "integration: mark a test as an integration test", "user_journey: mark a test as a user journey test", + "extended_prefix: mark a test as for windows extended_prefix", + "long_running_test: mark a test that takes a long time to run", ] diff --git a/conda-store-server/tests/_internal/__init__.py b/conda-store-server/tests/_internal/__init__.py new file mode 100644 index 000000000..b559bd2ff --- /dev/null +++ b/conda-store-server/tests/_internal/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. diff --git a/conda-store-server/tests/_internal/action/__init__.py b/conda-store-server/tests/_internal/action/__init__.py new file mode 100644 index 000000000..b559bd2ff --- /dev/null +++ b/conda-store-server/tests/_internal/action/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. diff --git a/conda-store-server/tests/test_actions.py b/conda-store-server/tests/_internal/action/test_actions.py similarity index 98% rename from conda-store-server/tests/test_actions.py rename to conda-store-server/tests/_internal/action/test_actions.py index 90445c5c5..2fd810bce 100644 --- a/conda-store-server/tests/test_actions.py +++ b/conda-store-server/tests/_internal/action/test_actions.py @@ -84,6 +84,7 @@ def test_function(context): @mock.patch.object(generate_lockfile, "yaml", wraps=yaml) @mock.patch("conda_store_server._internal.action.generate_lockfile.logged_command") @mock.patch("conda_store_server._internal.action.generate_lockfile.run_lock") +@pytest.mark.long_running_test def test_solve_lockfile( mock_run_lock, mock_logged_command, @@ -144,6 +145,7 @@ def test_solve_lockfile_valid_conda_flags(conda_store, simple_specification): # Checks that conda_flags is used by conda-lock +@pytest.mark.long_running_test def test_solve_lockfile_invalid_conda_flags(conda_store, simple_specification): with pytest.raises( Exception, match=(r"Command.*--this-is-invalid.*returned non-zero exit status") @@ -163,6 +165,7 @@ def test_solve_lockfile_invalid_conda_flags(conda_store, simple_specification): "simple_specification_with_pip", ], ) +@pytest.mark.long_running_test def test_solve_lockfile_multiple_platforms(conda_store, specification, request): specification = request.getfixturevalue(specification) context = action.action_solve_lockfile( @@ -260,6 +263,7 @@ def test_fetch_and_extract_conda_packages(tmp_path, simple_conda_lock): assert context.stdout.getvalue() +@pytest.mark.long_running_test def test_install_specification(tmp_path, conda_store, simple_specification): conda_prefix = tmp_path / "test" @@ -282,6 +286,7 @@ def test_install_lockfile(tmp_path, conda_store, simple_conda_lock): assert conda_utils.is_conda_prefix(conda_prefix) +@pytest.mark.long_running_test def test_generate_conda_export(conda_store, conda_prefix): context = action.action_generate_conda_export( conda_command=conda_store.conda_command, conda_prefix=conda_prefix @@ -293,6 +298,7 @@ def test_generate_conda_export(conda_store, conda_prefix): schema.CondaSpecification.parse_obj(context.result) +@pytest.mark.long_running_test def test_generate_conda_pack(tmp_path, conda_prefix): output_filename = tmp_path / "environment.tar.gz" @@ -310,6 +316,7 @@ def test_generate_conda_pack(tmp_path, conda_prefix): "https://github.com/conda-incubator/conda-store/issues/666" ) ) +@pytest.mark.long_running_test def test_generate_conda_docker(conda_store, conda_prefix): action.action_generate_conda_docker( conda_prefix=conda_prefix, @@ -376,6 +383,7 @@ def test_get_conda_prefix_stats(tmp_path, conda_store, simple_conda_lock): assert context.result["disk_usage"] > 0 +@pytest.mark.long_running_test def test_add_conda_prefix_packages(db, conda_store, simple_specification, conda_prefix): build_id = conda_store.register_environment( db, specification=simple_specification, namespace="pytest" @@ -391,6 +399,7 @@ def test_add_conda_prefix_packages(db, conda_store, simple_specification, conda_ assert len(build.package_builds) > 0 +@pytest.mark.long_running_test def test_add_lockfile_packages( db, conda_store, @@ -424,6 +433,7 @@ def test_add_lockfile_packages( (True, 1), # build_key_version doesn't matter because there's no lockfile ], ) +@pytest.mark.long_running_test def test_api_get_build_lockfile( request, conda_store, @@ -540,6 +550,7 @@ def lockfile_url(build_key): assert res.status_code == 307 +@pytest.mark.long_running_test def test_api_get_build_installer( request, conda_store, db, simple_specification_with_pip, conda_prefix ): diff --git a/conda-store-server/tests/_internal/server/__init__.py b/conda-store-server/tests/_internal/server/__init__.py new file mode 100644 index 000000000..b559bd2ff --- /dev/null +++ b/conda-store-server/tests/_internal/server/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. diff --git a/conda-store-server/tests/_internal/server/views/__init__.py b/conda-store-server/tests/_internal/server/views/__init__.py new file mode 100644 index 000000000..b559bd2ff --- /dev/null +++ b/conda-store-server/tests/_internal/server/views/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. diff --git a/conda-store-server/tests/test_server.py b/conda-store-server/tests/_internal/server/views/test_api.py similarity index 98% rename from conda-store-server/tests/test_server.py rename to conda-store-server/tests/_internal/server/views/test_api.py index 8c3a7a510..cfb38b8cd 100644 --- a/conda-store-server/tests/test_server.py +++ b/conda-store-server/tests/_internal/server/views/test_api.py @@ -876,30 +876,6 @@ def test_delete_build_auth(testclient, seed_conda_store, authenticate, celery_wo # assert r.status == schema.APIStatus.ERROR -def test_prometheus_metrics(testclient): - response = testclient.get("metrics") - d = { - line.split()[0]: line.split()[1] - for line in response.content.decode("utf-8").split("\n") - } - assert { - "conda_store_disk_free", - "conda_store_disk_total", - "conda_store_disk_usage", - } <= d.keys() - - -def test_celery_stats(testclient, celery_worker): - response = testclient.get("celery") - assert response.json().keys() == { - "active_tasks", - "availability", - "registered_tasks", - "scheduled_tasks", - "stats", - } - - @pytest.mark.parametrize( "route", [ diff --git a/conda-store-server/tests/_internal/server/views/test_metrics.py b/conda-store-server/tests/_internal/server/views/test_metrics.py new file mode 100644 index 000000000..4db6479dd --- /dev/null +++ b/conda-store-server/tests/_internal/server/views/test_metrics.py @@ -0,0 +1,27 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + + +def test_prometheus_metrics(testclient): + response = testclient.get("metrics") + d = { + line.split()[0]: line.split()[1] + for line in response.content.decode("utf-8").split("\n") + } + assert { + "conda_store_disk_free", + "conda_store_disk_total", + "conda_store_disk_usage", + } <= d.keys() + + +def test_celery_stats(testclient, celery_worker): + response = testclient.get("celery") + assert response.json().keys() == { + "active_tasks", + "availability", + "registered_tasks", + "scheduled_tasks", + "stats", + } diff --git a/conda-store-server/tests/test_usage.py b/conda-store-server/tests/_internal/test_utils.py similarity index 100% rename from conda-store-server/tests/test_usage.py rename to conda-store-server/tests/_internal/test_utils.py diff --git a/conda-store-server/tests/server/__init__.py b/conda-store-server/tests/server/__init__.py new file mode 100644 index 000000000..b559bd2ff --- /dev/null +++ b/conda-store-server/tests/server/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) conda-store development team. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. diff --git a/conda-store-server/tests/test_auth.py b/conda-store-server/tests/server/test_auth.py similarity index 100% rename from conda-store-server/tests/test_auth.py rename to conda-store-server/tests/server/test_auth.py diff --git a/conda-store-server/tests/test_db_api.py b/conda-store-server/tests/test_api.py similarity index 100% rename from conda-store-server/tests/test_db_api.py rename to conda-store-server/tests/test_api.py diff --git a/conda-store-server/tests/test_app_api.py b/conda-store-server/tests/test_app.py similarity index 98% rename from conda-store-server/tests/test_app_api.py rename to conda-store-server/tests/test_app.py index c3146beb2..1cda3d628 100644 --- a/conda-store-server/tests/test_app_api.py +++ b/conda-store-server/tests/test_app.py @@ -4,12 +4,15 @@ import sys +import pytest + from celery.result import AsyncResult from conda_store_server import api from conda_store_server._internal import action, conda_utils, schema +@pytest.mark.long_running_test def test_conda_store_app_register_solve( db, conda_store, simple_specification, simple_conda_lock, celery_worker ): @@ -41,6 +44,7 @@ def test_conda_store_app_register_solve( assert len(solve.package_builds) > 0 +@pytest.mark.long_running_test def test_conda_store_register_environment_workflow( db, simple_specification, conda_store, celery_worker ):