diff --git a/tests/conftest.py b/tests/conftest.py index 26b08a4..8184e3d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -19,25 +19,25 @@ Since we're using session-scoped fixtures, declare everything in here. """ -import pytest_asyncio +import asyncio + +import pytest from hexkit.providers.akafka.testutils import get_kafka_fixture from hexkit.providers.mongodb.testutils import get_mongodb_fixture -from hexkit.providers.testing.utils import get_event_loop from tests.fixtures.joint import JointFixture, get_joint_fixture -@pytest_asyncio.fixture(autouse=True) -async def reset_state(joint_fixture: JointFixture): +@pytest.fixture(autouse=True) +def reset_state(joint_fixture: JointFixture): """Clear joint_fixture state before tests. This is a function-level fixture because it needs to run in each test. """ + loop = asyncio.get_event_loop() joint_fixture.remove_db_data() - await joint_fixture.load_test_data() - + loop.run_until_complete(joint_fixture.load_test_data()) -event_loop = get_event_loop("session") kafka_fixture = get_kafka_fixture("session") mongodb_fixture = get_mongodb_fixture("session") diff --git a/tests/test_api.py b/tests/test_api.py index b03f88b..bdc510c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -57,7 +57,7 @@ def compare( assert results.hits == hits -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_health_check(joint_fixture: JointFixture): """Test that the health check endpoint works.""" response = await joint_fixture.rest_client.get("/health") @@ -66,7 +66,7 @@ async def test_health_check(joint_fixture: JointFixture): assert response.json() == {"status": "OK"} -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search_options(joint_fixture: JointFixture): """Verify that we can request the configured resource class information correctly""" response = await joint_fixture.rest_client.get(url="/rpc/search-options") @@ -74,7 +74,7 @@ async def test_search_options(joint_fixture: JointFixture): assert response.json() == joint_fixture.config.model_dump()["searchable_classes"] -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_malformed_document( joint_fixture: JointFixture, caplog: pytest.LogCaptureFixture ): @@ -116,7 +116,7 @@ async def test_malformed_document( assert "type=string_type, input_value=42, input_type=int" in msg -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search(joint_fixture: JointFixture): """Basic query to pull back all documents for class name""" search_parameters: JsonObject = { @@ -130,7 +130,7 @@ async def test_search(joint_fixture: JointFixture): compare(results=results, count=3, hit_length=3) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search_with_limit(joint_fixture: JointFixture): """Make sure we get a count of 3 but only 1 hit""" search_parameters: JsonObject = { @@ -159,7 +159,7 @@ async def test_search_with_limit(joint_fixture: JointFixture): compare(results=results, count=3, hit_length=1, hits=hits) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search_keywords(joint_fixture: JointFixture): """Make sure the query string is passed through intact""" search_parameters: JsonObject = { @@ -173,7 +173,7 @@ async def test_search_keywords(joint_fixture: JointFixture): compare(results=results, count=2, hit_length=2) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search_filters(joint_fixture: JointFixture): """Make sure filters work""" search_parameters: JsonObject = { @@ -187,7 +187,7 @@ async def test_search_filters(joint_fixture: JointFixture): compare(results=results, count=1, hit_length=1) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_search_invalid_class(joint_fixture: JointFixture): """Verify that searching with a bad class name results in a 422""" search_parameters: JsonObject = { @@ -202,7 +202,7 @@ async def test_search_invalid_class(joint_fixture: JointFixture): await joint_fixture.call_search_endpoint(search_parameters) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_auto_recreation_of_indexes( joint_fixture: JointFixture, caplog: pytest.LogCaptureFixture ): diff --git a/tests/test_consumer.py b/tests/test_consumer.py index 7553c7a..9a80953 100644 --- a/tests/test_consumer.py +++ b/tests/test_consumer.py @@ -29,7 +29,7 @@ ("1HotelAlpha-id", False), # this ID exists in the test data already ], ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_upsert( joint_fixture: JointFixture, resource_id: str, is_insert: bool ): @@ -84,7 +84,7 @@ async def test_resource_upsert( assert resource not in results_all.hits -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_delete(joint_fixture: JointFixture): """Test resource deletion via event consumption""" # get all the documents in the collection diff --git a/tests/test_index_creation.py b/tests/test_index_creation.py index abe7fa5..b6898f6 100644 --- a/tests/test_index_creation.py +++ b/tests/test_index_creation.py @@ -30,7 +30,7 @@ @pytest.mark.parametrize("create_index_manually", (False, True)) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_index_creation(joint_fixture: JointFixture, create_index_manually: bool): """Test the index creation function.""" # indexes will have been created in fixture setup, so we actually need to del those diff --git a/tests/test_logging.py b/tests/test_logging.py index 09d8368..cbed68c 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -91,7 +91,7 @@ "Deletion failure due to non-existent accession", ], ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_event_sub_logging( joint_fixture: JointFixture, caplog, diff --git a/tests/test_relevance.py b/tests/test_relevance.py index 08eac56..ab7efe5 100644 --- a/tests/test_relevance.py +++ b/tests/test_relevance.py @@ -104,7 +104,7 @@ def sorted_reference_results( return [result["_id"] for result in sorted_results] -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_happy_relevance(joint_fixture: JointFixture): """Make sure default works as expected""" query = "test" @@ -127,7 +127,7 @@ async def test_happy_relevance(joint_fixture: JointFixture): assert [hit.id_ for hit in results.hits] == reference_ids -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_happy_relevance_descending_id(joint_fixture: JointFixture): """Make sure default Pydantic model parameter works as expected""" query = "test" @@ -153,7 +153,7 @@ async def test_happy_relevance_descending_id(joint_fixture: JointFixture): assert [hit.id_ for hit in results.hits] == reference_ids -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_with_absent_term(joint_fixture: JointFixture): """Make sure nothing is pulled back with an absent term (sanity check)""" search_parameters = { @@ -169,7 +169,7 @@ async def test_with_absent_term(joint_fixture: JointFixture): assert results.count == 0 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_limited_term(joint_fixture: JointFixture): """Make sure only results with the term are retrieved""" query = "alternative" @@ -189,7 +189,7 @@ async def test_limited_term(joint_fixture: JointFixture): assert [hit.id_ for hit in results.hits] == reference_ids -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_two_words(joint_fixture: JointFixture): """Test with two different terms that appear in different fields""" query = "alternative test" @@ -209,7 +209,7 @@ async def test_two_words(joint_fixture: JointFixture): assert [hit.id_ for hit in results.hits] == reference_ids -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_with_filters(joint_fixture: JointFixture): """Test with filters applied but no sorting parameters""" query = "test" @@ -234,7 +234,7 @@ async def test_with_filters(joint_fixture: JointFixture): assert [hit.id_ for hit in results.hits] == reference_ids -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_with_filters_and_sorts(joint_fixture: JointFixture): """Test with filters applied and at least one sorting parameter (not relevance)""" query = "test" diff --git a/tests/test_resources.py b/tests/test_resources.py index 29164c6..7573f8f 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -23,7 +23,7 @@ from tests.fixtures.joint import JointFixture -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_basic_query(joint_fixture: JointFixture): """Make sure we can pull back the documents as expected""" # pull back all 3 test documents @@ -34,7 +34,7 @@ async def test_basic_query(joint_fixture: JointFixture): assert results.count == 3 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_text_search(joint_fixture: JointFixture): """Test basic text search""" results_text = await joint_fixture.query_handler.handle_query( @@ -45,7 +45,7 @@ async def test_text_search(joint_fixture: JointFixture): assert results_text.hits[0].id_ == "1HotelAlpha-id" -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_filters_work(joint_fixture: JointFixture): """Test a query with filters selected but no query string""" results_filtered = await joint_fixture.query_handler.handle_query( @@ -70,7 +70,7 @@ async def test_filters_work(joint_fixture: JointFixture): assert results_multi_filter.hits[0].id_ == "1HotelAlpha-id" -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_facets_returned(joint_fixture: JointFixture): """Verify that facet fields are returned correctly""" results_faceted = await joint_fixture.query_handler.handle_query( @@ -112,7 +112,7 @@ async def test_facets_returned(joint_fixture: JointFixture): assert kitchen_options[0].count == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_limit_parameter(joint_fixture: JointFixture): """Test that the limit parameter works""" results_limited = await joint_fixture.query_handler.handle_query( @@ -121,7 +121,7 @@ async def test_limit_parameter(joint_fixture: JointFixture): assert len(results_limited.hits) == 2 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_skip_parameter(joint_fixture: JointFixture): """Test that the skip parameter works""" results_skip = await joint_fixture.query_handler.handle_query( @@ -131,7 +131,7 @@ async def test_skip_parameter(joint_fixture: JointFixture): assert [x.id_ for x in results_skip.hits] == ["2HotelBeta-id", "3zoo-id"] -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_all_parameters(joint_fixture: JointFixture): """Sanity check - make sure it all works together""" results_all = await joint_fixture.query_handler.handle_query( @@ -146,7 +146,7 @@ async def test_all_parameters(joint_fixture: JointFixture): assert results_all.hits[0].id_ == "2HotelBeta-id" -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_load(joint_fixture: JointFixture): """Test the load function in the query handler""" # get all the documents in the collection @@ -187,7 +187,7 @@ async def test_resource_load(joint_fixture: JointFixture): assert validated_resource.content == resource.content -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_loading_non_configured_resource(joint_fixture: JointFixture): """Test that we get the right warning for loading a non-configured class_name""" # define and load a new resource @@ -206,7 +206,7 @@ async def test_loading_non_configured_resource(joint_fixture: JointFixture): ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_error_from_malformed_resource(joint_fixture: JointFixture): """Make sure we get an error when the DB has malformed content, since that has to be fixed""" # define and load a new resource without all the required facets @@ -229,7 +229,7 @@ async def test_error_from_malformed_resource(joint_fixture: JointFixture): ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_absent_resource(joint_fixture: JointFixture): """Make sure we get an error when looking for a resource type that doesn't exist""" with pytest.raises(joint_fixture.query_handler.ClassNotConfiguredError): @@ -238,7 +238,7 @@ async def test_absent_resource(joint_fixture: JointFixture): ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_deletion(joint_fixture: JointFixture): """Make sure we can delete a resource. @@ -264,7 +264,7 @@ async def test_resource_deletion(joint_fixture: JointFixture): assert resource.id_ != "1HotelAlpha-id" -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_deletion_failure(joint_fixture: JointFixture): """Test for correct error when failing to delete a resource""" all_resources = await joint_fixture.query_handler.handle_query( @@ -287,7 +287,7 @@ async def test_resource_deletion_failure(joint_fixture: JointFixture): assert all_resources_again.count == all_resources.count -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_resource_deletion_not_configured(joint_fixture: JointFixture): """Test for correct error when trying to delete a non-configured resource""" with pytest.raises(joint_fixture.query_handler.ClassNotConfiguredError): diff --git a/tests/test_sorting.py b/tests/test_sorting.py index 7c2e7ba..be5542b 100644 --- a/tests/test_sorting.py +++ b/tests/test_sorting.py @@ -71,7 +71,7 @@ def multi_column_sort( ) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_api_without_sort_parameters(joint_fixture: JointFixture): """Make sure default Pydantic model parameter works as expected""" search_parameters: JsonObject = { @@ -88,7 +88,7 @@ async def test_api_without_sort_parameters(joint_fixture: JointFixture): assert results.hits == expected -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_id_not_last(joint_fixture: JointFixture): """Test sorting parameters that contain id_, but id_ is not final sorting field. @@ -116,7 +116,7 @@ async def test_sort_with_id_not_last(joint_fixture: JointFixture): assert results.hits == multi_column_sort(results.hits, sorts_in_model_form) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_params_but_not_id(joint_fixture: JointFixture): """Test supplying sorting parameters but omitting id_. @@ -138,7 +138,7 @@ async def test_sort_with_params_but_not_id(joint_fixture: JointFixture): assert results.hits == multi_column_sort(results.hits, BASIC_SORT_PARAMETERS) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_invalid_field(joint_fixture: JointFixture): """Test supplying an invalid field name as a sort field. @@ -163,7 +163,7 @@ async def test_sort_with_invalid_field(joint_fixture: JointFixture): @pytest.mark.parametrize("order", [-7, 17, "some_string"]) -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_invalid_sort_order(joint_fixture: JointFixture, order): """Test supplying an invalid value for the sort order""" search_parameters: JsonObject = { @@ -179,7 +179,7 @@ async def test_sort_with_invalid_sort_order(joint_fixture: JointFixture, order): assert response.status_code == 422 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_invalid_field_and_sort_order(joint_fixture: JointFixture): """Test with both invalid field name and invalid sort order.""" search_parameters: JsonObject = { @@ -195,7 +195,7 @@ async def test_sort_with_invalid_field_and_sort_order(joint_fixture: JointFixtur assert response.status_code == 422 -@pytest.mark.asyncio +@pytest.mark.asyncio(scope="session") async def test_sort_with_duplicate_field(joint_fixture: JointFixture): """Supply sorting parameters with two instances of the same sort field.