Skip to content

Commit da5bf82

Browse files
fix: use testcontainers for qdrant it test
1 parent 34629b9 commit da5bf82

2 files changed

Lines changed: 76 additions & 90 deletions

File tree

sdks/python/apache_beam/ml/rag/ingestion/qdrant_it_test.py

Lines changed: 75 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
import contextlib
18-
import tempfile
17+
import pytest
1918
import unittest
2019

2120
import apache_beam as beam
@@ -28,12 +27,16 @@
2827

2928
# pylint: disable=ungrouped-imports
3029
try:
31-
from qdrant_client import QdrantClient
3230
from qdrant_client import models
3331

3432
QDRANT_AVAILABLE = True
3533
except ImportError:
3634
QDRANT_AVAILABLE = False
35+
36+
try:
37+
from testcontainers.qdrant import QdrantContainer
38+
except ImportError:
39+
QdrantContainer = None
3740
# pylint: enable=ungrouped-imports
3841

3942
TEST_CORPUS = [
@@ -59,35 +62,35 @@
5962

6063

6164
@unittest.skipIf(not QDRANT_AVAILABLE, "qdrant dependencies not installed.")
65+
@unittest.skipIf(not QdrantContainer, "qdrant test_container not installed.")
66+
@pytest.mark.uses_testcontainers
6267
class TestQdrantIngestion(unittest.TestCase):
63-
@contextlib.contextmanager
64-
def qdrant_client(self) -> "QdrantClient":
65-
client = QdrantClient(path=self._temp_dir.name)
66-
try:
67-
yield client
68-
finally:
69-
client.close()
68+
@classmethod
69+
def setUpClass(cls):
70+
cls._container = QdrantContainer()
71+
cls._container.start()
72+
cls._host = cls._container.get_container_host_ip()
73+
cls._port = int(cls._container.get_exposed_port(6333))
74+
cls._connection_params = QdrantConnectionParameters(
75+
host=cls._host, port=cls._port)
76+
cls.client = cls._container.get_client()
7077

7178
def setUp(self):
72-
self._temp_dir = tempfile.TemporaryDirectory()
7379
self._collection_name = f"test_collection_{self._testMethodName}"
7480

75-
with self.qdrant_client() as client:
76-
client.create_collection(
77-
collection_name=self._collection_name,
78-
vectors_config={
79-
"dense": models.VectorParams(
80-
size=2, distance=models.Distance.COSINE)
81-
},
82-
sparse_vectors_config={"sparse": models.SparseVectorParams()},
83-
)
84-
assert client.collection_exists(collection_name=self._collection_name)
85-
86-
self._connection_params = QdrantConnectionParameters(
87-
path=self._temp_dir.name)
81+
self.client.create_collection(
82+
collection_name=self._collection_name,
83+
vectors_config={
84+
"dense": models.VectorParams(
85+
size=2, distance=models.Distance.COSINE)
86+
},
87+
sparse_vectors_config={"sparse": models.SparseVectorParams()},
88+
)
89+
assert self.client.collection_exists(collection_name=self._collection_name)
8890

89-
def tearDown(self):
90-
self._temp_dir.cleanup()
91+
@classmethod
92+
def tearDownClass(cls):
93+
cls._container.stop()
9194

9295
def test_write_on_non_existent_collection(self):
9396
non_existent = "nonexistent_collection"
@@ -98,9 +101,7 @@ def test_write_on_non_existent_collection(self):
98101
)
99102

100103
with self.assertRaises(Exception):
101-
p = TestPipeline()
102-
p.not_use_test_runner_api = True
103-
with p:
104+
with TestPipeline(is_integration_test=True) as p:
104105
_ = p | beam.Create(TEST_CORPUS) | write_config.create_write_transform()
105106

106107
def test_write_dense_embeddings_only(self):
@@ -110,21 +111,18 @@ def test_write_dense_embeddings_only(self):
110111
batch_size=len(TEST_CORPUS),
111112
)
112113

113-
p = TestPipeline()
114-
p.not_use_test_runner_api = True
115-
with p:
114+
with TestPipeline(is_integration_test=True) as p:
116115
_ = p | beam.Create(TEST_CORPUS) | write_config.create_write_transform()
117116

118-
with self.qdrant_client() as client:
119-
count_result = client.count(collection_name=self._collection_name)
120-
self.assertEqual(count_result.count, len(TEST_CORPUS))
117+
count_result = self.client.count(collection_name=self._collection_name)
118+
self.assertEqual(count_result.count, len(TEST_CORPUS))
121119

122-
points, _ = client.scroll(
123-
collection_name=self._collection_name,
124-
limit=100,
125-
with_payload=True,
126-
with_vectors=True,
127-
)
120+
points, _ = self.client.scroll(
121+
collection_name=self._collection_name,
122+
limit=100,
123+
with_payload=True,
124+
with_vectors=True,
125+
)
128126
points_by_id = {p.id: p for p in points}
129127

130128
for item in TEST_CORPUS:
@@ -157,21 +155,18 @@ def test_write_sparse_embeddings_only(self):
157155
batch_size=len(sparse_corpus),
158156
)
159157

160-
p = TestPipeline()
161-
p.not_use_test_runner_api = True
162-
with p:
158+
with TestPipeline(is_integration_test=True) as p:
163159
_ = p | beam.Create(sparse_corpus) | write_config.create_write_transform()
164160

165-
with self.qdrant_client() as client:
166-
count_result = client.count(collection_name=self._collection_name)
167-
self.assertEqual(count_result.count, len(sparse_corpus))
161+
count_result = self.client.count(collection_name=self._collection_name)
162+
self.assertEqual(count_result.count, len(sparse_corpus))
168163

169-
points, _ = client.scroll(
170-
collection_name=self._collection_name,
171-
limit=100,
172-
with_payload=True,
173-
with_vectors=True,
174-
)
164+
points, _ = self.client.scroll(
165+
collection_name=self._collection_name,
166+
limit=100,
167+
with_payload=True,
168+
with_vectors=True,
169+
)
175170
points_by_id = {p.id: p for p in points}
176171

177172
for item in sparse_corpus:
@@ -213,21 +208,18 @@ def test_write_both_dense_and_sparse(self):
213208
batch_size=len(hybrid_corpus),
214209
)
215210

216-
p = TestPipeline()
217-
p.not_use_test_runner_api = True
218-
with p:
211+
with TestPipeline(is_integration_test=True) as p:
219212
_ = p | beam.Create(hybrid_corpus) | write_config.create_write_transform()
220213

221-
with self.qdrant_client() as client:
222-
count_result = client.count(collection_name=self._collection_name)
223-
self.assertEqual(count_result.count, len(hybrid_corpus))
214+
count_result = self.client.count(collection_name=self._collection_name)
215+
self.assertEqual(count_result.count, len(hybrid_corpus))
224216

225-
points, _ = client.scroll(
226-
collection_name=self._collection_name,
227-
limit=100,
228-
with_payload=True,
229-
with_vectors=True,
230-
)
217+
points, _ = self.client.scroll(
218+
collection_name=self._collection_name,
219+
limit=100,
220+
with_payload=True,
221+
with_vectors=True,
222+
)
231223
points_by_id = {p.id: p for p in points}
232224

233225
for item in hybrid_corpus:
@@ -260,21 +252,18 @@ def test_write_with_batching(self):
260252
batch_size=3,
261253
)
262254

263-
p = TestPipeline()
264-
p.not_use_test_runner_api = True
265-
with p:
255+
with TestPipeline(is_integration_test=True) as p:
266256
_ = p | beam.Create(batch_corpus) | write_config.create_write_transform()
267257

268-
with self.qdrant_client() as client:
269-
count_result = client.count(collection_name=self._collection_name)
270-
self.assertEqual(count_result.count, len(batch_corpus))
258+
count_result = self.client.count(collection_name=self._collection_name)
259+
self.assertEqual(count_result.count, len(batch_corpus))
271260

272-
points, _ = client.scroll(
273-
collection_name=self._collection_name,
274-
limit=100,
275-
with_payload=True,
276-
with_vectors=True,
277-
)
261+
points, _ = self.client.scroll(
262+
collection_name=self._collection_name,
263+
limit=100,
264+
with_payload=True,
265+
with_vectors=True,
266+
)
278267
points_by_id = {p.id: p for p in points}
279268

280269
for item in batch_corpus:
@@ -304,24 +293,21 @@ def test_write_with_byte_size_limit(self):
304293
max_batch_byte_size=15_000,
305294
)
306295

307-
p = TestPipeline()
308-
p.not_use_test_runner_api = True
309-
with p:
296+
with TestPipeline(is_integration_test=True) as p:
310297
_ = (
311298
p
312299
| beam.Create(byte_size_corpus)
313300
| write_config.create_write_transform())
314301

315-
with self.qdrant_client() as client:
316-
count_result = client.count(collection_name=self._collection_name)
317-
self.assertEqual(count_result.count, len(byte_size_corpus))
302+
count_result = self.client.count(collection_name=self._collection_name)
303+
self.assertEqual(count_result.count, len(byte_size_corpus))
318304

319-
points, _ = client.scroll(
320-
collection_name=self._collection_name,
321-
limit=100,
322-
with_payload=True,
323-
with_vectors=True,
324-
)
305+
points, _ = self.client.scroll(
306+
collection_name=self._collection_name,
307+
limit=100,
308+
with_payload=True,
309+
with_vectors=True,
310+
)
325311
points_by_id = {p.id: p for p in points}
326312

327313
for item in byte_size_corpus:

sdks/python/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ def get_portability_package_data():
509509
'scikit-learn>=0.20.0,<1.8.0',
510510
'sqlalchemy>=1.3,<3.0',
511511
'psycopg2-binary>=2.8.5,<3.0',
512-
'testcontainers[mysql,kafka,milvus]>=4.0.0,<5.0.0',
512+
'testcontainers[mysql,kafka,milvus,qdrant]>=4.0.0,<5.0.0',
513513
'cryptography>=41.0.2',
514514
# TODO(https://github.com/apache/beam/issues/36951): need to
515515
# further investigate the cause

0 commit comments

Comments
 (0)