diff --git a/test/asynchronous/test_index_management.py b/test/asynchronous/test_index_management.py index 09b4f364c0..59ce89e686 100644 --- a/test/asynchronous/test_index_management.py +++ b/test/asynchronous/test_index_management.py @@ -18,7 +18,6 @@ import asyncio import os -import pathlib import sys import time import uuid @@ -27,6 +26,8 @@ import pytest +from test.asynchronous.utils import flaky + sys.path[0:0] = [""] from pymongo.errors import OperationFailure @@ -112,6 +113,18 @@ async def wait_for_ready(self, coll, name=_NAME, predicate=None): return indices[0] await asyncio.sleep(5) + async def drop_and_wait(self, coll, name): + """Drop a search index and wait for it to be dropped.""" + await coll.drop_search_index(name) + start = time.time() + while True: + indices = await (await coll.list_search_indexes(name)).to_list() + if not indices: + return + if (time.time() - start) / 60 > 5: + raise TimeoutError("Timed out waiting for index deletion") + await asyncio.sleep(5) + class TestSearchIndexIntegration(SearchIndexIntegrationBase): db_name = "test_search_index" @@ -138,12 +151,14 @@ async def test_comment_field(self): class TestSearchIndexProse(SearchIndexIntegrationBase): db_name = "test_search_index_prose" + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_1(self): """Driver can successfully create and list search indexes.""" # Create a new search index on ``self.coll0`` with the ``createSearchIndex`` helper. Use the following definition: model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = await self.coll0.create_search_index(model) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, _NAME) @@ -156,6 +171,7 @@ async def test_case_1(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_2(self): """Driver can successfully create multiple indexes in batch.""" @@ -170,6 +186,8 @@ async def test_case_2(self): await self.coll0.create_search_indexes( [SearchIndexModel(i["definition"], i["name"]) for i in index_definitions] ) + for index in index_definitions: + self.addAsyncCleanup(self.drop_and_wait, self.coll0, index["name"]) # .Assert that the command returns an array containing the new indexes' names: ``["test-search-index-1", "test-search-index-2"]``. indices = await (await self.coll0.list_search_indexes()).to_list() @@ -188,12 +206,14 @@ async def test_case_2(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], definition) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_3(self): """Driver can successfully drop search indexes.""" # Create a new search index on ``self.coll0``. model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = await self.coll0.create_search_index(model) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, "test-search-index") @@ -215,12 +235,14 @@ async def test_case_3(self): raise TimeoutError("Timed out waiting for index deletion") await asyncio.sleep(5) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_4(self): """Driver can update a search index.""" # Create a new search index on ``self.coll0``. model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = await self.coll0.create_search_index(model) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, _NAME) @@ -245,6 +267,7 @@ async def test_case_4(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model2["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_5(self): """``dropSearchIndex`` suppresses namespace not found errors.""" # Create a driver-side collection object for a randomly generated collection name. Do not create this collection on the server. @@ -253,6 +276,7 @@ async def test_case_5(self): # Run a ``dropSearchIndex`` command and assert that no error is thrown. await coll0.drop_search_index("foo") + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_6(self): """Driver can successfully create and list search indexes with non-default readConcern and writeConcern.""" @@ -265,6 +289,7 @@ async def test_case_6(self): name = "test-search-index-case6" model = {"name": name, "definition": {"mappings": {"dynamic": False}}} resp = await coll0.create_search_index(model) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, name) # Assert that the command returns the name of the index: ``"test-search-index-case6"``. self.assertEqual(resp, name) @@ -277,6 +302,7 @@ async def test_case_6(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) async def test_case_7(self): """Driver handles index types.""" @@ -297,6 +323,7 @@ async def test_case_7(self): implicit_search_resp = await self.coll0.create_search_index( model={"name": _NAME + "-implicit", "definition": search_definition} ) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME + "-implicit") # Get the index definition. resp = await (await self.coll0.list_search_indexes(name=implicit_search_resp)).next() @@ -308,6 +335,7 @@ async def test_case_7(self): explicit_search_resp = await self.coll0.create_search_index( model={"name": _NAME + "-explicit", "type": "search", "definition": search_definition} ) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME + "-explicit") # Get the index definition. resp = await (await self.coll0.list_search_indexes(name=explicit_search_resp)).next() @@ -323,6 +351,7 @@ async def test_case_7(self): "definition": vector_search_definition, } ) + self.addAsyncCleanup(self.drop_and_wait, self.coll0, _NAME + "-vector") # Get the index definition. resp = await (await self.coll0.list_search_indexes(name=explicit_vector_resp)).next() diff --git a/test/test_index_management.py b/test/test_index_management.py index 6dbd7b9c01..557f9ab93d 100644 --- a/test/test_index_management.py +++ b/test/test_index_management.py @@ -18,7 +18,6 @@ import asyncio import os -import pathlib import sys import time import uuid @@ -27,6 +26,8 @@ import pytest +from test.utils import flaky + sys.path[0:0] = [""] from pymongo.errors import OperationFailure @@ -112,6 +113,18 @@ def wait_for_ready(self, coll, name=_NAME, predicate=None): return indices[0] time.sleep(5) + def drop_and_wait(self, coll, name): + """Drop a search index and wait for it to be dropped.""" + coll.drop_search_index(name) + start = time.time() + while True: + indices = (coll.list_search_indexes(name)).to_list() + if not indices: + return + if (time.time() - start) / 60 > 5: + raise TimeoutError("Timed out waiting for index deletion") + time.sleep(5) + class TestSearchIndexIntegration(SearchIndexIntegrationBase): db_name = "test_search_index" @@ -136,12 +149,14 @@ def test_comment_field(self): class TestSearchIndexProse(SearchIndexIntegrationBase): db_name = "test_search_index_prose" + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_1(self): """Driver can successfully create and list search indexes.""" # Create a new search index on ``self.coll0`` with the ``createSearchIndex`` helper. Use the following definition: model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = self.coll0.create_search_index(model) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, _NAME) @@ -154,6 +169,7 @@ def test_case_1(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_2(self): """Driver can successfully create multiple indexes in batch.""" @@ -168,6 +184,8 @@ def test_case_2(self): self.coll0.create_search_indexes( [SearchIndexModel(i["definition"], i["name"]) for i in index_definitions] ) + for index in index_definitions: + self.addCleanup(self.drop_and_wait, self.coll0, index["name"]) # .Assert that the command returns an array containing the new indexes' names: ``["test-search-index-1", "test-search-index-2"]``. indices = (self.coll0.list_search_indexes()).to_list() @@ -186,12 +204,14 @@ def test_case_2(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], definition) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_3(self): """Driver can successfully drop search indexes.""" # Create a new search index on ``self.coll0``. model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = self.coll0.create_search_index(model) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, "test-search-index") @@ -213,12 +233,14 @@ def test_case_3(self): raise TimeoutError("Timed out waiting for index deletion") time.sleep(5) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_4(self): """Driver can update a search index.""" # Create a new search index on ``self.coll0``. model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}} resp = self.coll0.create_search_index(model) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME) # Assert that the command returns the name of the index: ``"test-search-index"``. self.assertEqual(resp, _NAME) @@ -243,6 +265,7 @@ def test_case_4(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model2["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_5(self): """``dropSearchIndex`` suppresses namespace not found errors.""" # Create a driver-side collection object for a randomly generated collection name. Do not create this collection on the server. @@ -251,6 +274,7 @@ def test_case_5(self): # Run a ``dropSearchIndex`` command and assert that no error is thrown. coll0.drop_search_index("foo") + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_6(self): """Driver can successfully create and list search indexes with non-default readConcern and writeConcern.""" @@ -263,6 +287,7 @@ def test_case_6(self): name = "test-search-index-case6" model = {"name": name, "definition": {"mappings": {"dynamic": False}}} resp = coll0.create_search_index(model) + self.addCleanup(self.drop_and_wait, self.coll0, name) # Assert that the command returns the name of the index: ``"test-search-index-case6"``. self.assertEqual(resp, name) @@ -275,6 +300,7 @@ def test_case_6(self): self.assertIn("latestDefinition", index) self.assertEqual(index["latestDefinition"], model["definition"]) + @flaky(reason="PYTHON-6056", affects_cpython_linux=True) def test_case_7(self): """Driver handles index types.""" @@ -295,6 +321,7 @@ def test_case_7(self): implicit_search_resp = self.coll0.create_search_index( model={"name": _NAME + "-implicit", "definition": search_definition} ) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME + "-implicit") # Get the index definition. resp = (self.coll0.list_search_indexes(name=implicit_search_resp)).next() @@ -306,6 +333,7 @@ def test_case_7(self): explicit_search_resp = self.coll0.create_search_index( model={"name": _NAME + "-explicit", "type": "search", "definition": search_definition} ) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME + "-explicit") # Get the index definition. resp = (self.coll0.list_search_indexes(name=explicit_search_resp)).next() @@ -321,6 +349,7 @@ def test_case_7(self): "definition": vector_search_definition, } ) + self.addCleanup(self.drop_and_wait, self.coll0, _NAME + "-vector") # Get the index definition. resp = (self.coll0.list_search_indexes(name=explicit_vector_resp)).next()