From 1399681c818c03326b6742c410aca97dc9c96b60 Mon Sep 17 00:00:00 2001 From: Massimiliano Pippi Date: Thu, 17 Nov 2022 16:22:02 +0100 Subject: [PATCH] move milvus tests to their own module (#3596) --- .github/workflows/tests.yml | 117 ++++++-------------- test/document_stores/test_document_store.py | 4 +- test/document_stores/test_milvus.py | 97 ++++++++++++++++ 3 files changed, 134 insertions(+), 84 deletions(-) create mode 100644 test/document_stores/test_milvus.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index db6ed614ee..f465c2febe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -392,6 +392,42 @@ jobs: channel: '#haystack' if: failure() && github.repository_owner == 'deepset-ai' && github.ref == 'refs/heads/main' + integration-tests-milvus: + name: Integration / Milvus / ${{ matrix.os }} + needs: + - unit-tests + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Setup Python + uses: ./.github/actions/python_cache/ + + - name: Setup Milvus + run: | + cd ../../ # Avoid causing permission issues on hashFiles later by creating unreadable folders like "volumes" + wget https://github.com/milvus-io/milvus/releases/download/v2.0.0/milvus-standalone-docker-compose.yml -O docker-compose.yml + sudo docker-compose up -d + sudo docker-compose ps + + - name: Install Haystack + run: pip install .[milvus] + + - name: Run tests + run: | + pytest --maxfail=5 -m "document_store and integration" test/document_stores/test_milvus.py + + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + channel: '#haystack' + if: failure() && github.repository_owner == 'deepset-ai' && github.ref == 'refs/heads/main' + # # TODO: the following steps need to be revisited @@ -491,87 +527,6 @@ jobs: channel: '#haystack' if: failure() && github.repository_owner == 'deepset-ai' && github.ref == 'refs/heads/main' - milvus-tests-linux: - needs: [mypy, pylint, black] - runs-on: ubuntu-latest - if: contains(github.event.pull_request.labels.*.name, 'topic:milvus') || !github.event.pull_request.draft - - steps: - - uses: actions/checkout@v3 - - - name: Setup Python - uses: ./.github/actions/python_cache/ - - - name: Setup Milvus - run: | - cd ../../ # Avoid causing permission issues on hashFiles later by creating unreadable folders like "volumes" - wget https://github.com/milvus-io/milvus/releases/download/v2.0.0/milvus-standalone-docker-compose.yml -O docker-compose.yml - sudo docker-compose up -d - sudo docker-compose ps - # TODO Let's try to remove this one from the unit tests - - name: Install pdftotext - run: wget --no-check-certificate https://dl.xpdfreader.com/xpdf-tools-linux-4.04.tar.gz && tar -xvf xpdf-tools-linux-4.04.tar.gz && sudo cp xpdf-tools-linux-4.04/bin64/pdftotext /usr/local/bin - - - name: Install Haystack - run: pip install .[milvus] - - - name: Run tests - env: - TOKENIZERS_PARALLELISM: 'false' - run: | - pytest ${{ env.PYTEST_PARAMS }} -m "milvus and not integration" test/document_stores/ --document_store_type=milvus - - - name: Dump docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v1 - - - uses: act10ns/slack@v1 - with: - status: ${{ job.status }} - channel: '#haystack' - if: failure() && github.repository_owner == 'deepset-ai' && github.ref == 'refs/heads/main' - -# FIXME: seems like we can't run containers on Windows - # milvus-tests-windows: - # needs: - # - mypy - # - pylint - # runs-on: windows-latest - # if: contains(github.event.pull_request.labels.*.name, 'topic:milvus') && contains(github.event.pull_request.labels.*.name, 'topic:windows') || !github.event.pull_request.draft || !github.event.pull_request.draft - - # steps: - # - uses: actions/checkout@v3 - - # - name: Setup Python - # uses: ./.github/actions/python_cache/ - # with: - # prefix: windows - - # - name: Setup Milvus - # run: | - # cd ../../ # Avoid causing permission issues on hashFiles later by creating unreadable folders like "volumes" - # wget https://github.com/milvus-io/milvus/releases/download/v2.0.0/milvus-standalone-docker-compose.yml -O docker-compose.yml - # sudo docker-compose up -d - # sudo docker-compose ps - - # - name: Install pdftotext - # run: | - # choco install xpdf-utils - # choco install openjdk11 - # refreshenv - - # - name: Install Haystack - # run: pip install .[milvus] - - # - name: Run tests - # env: - # TOKENIZERS_PARALLELISM: 'false' - # run: | - # pytest ${{ env.PYTEST_PARAMS }} -m "milvus and not integration" ${{ env.SUITES_EXCLUDED_FROM_WINDOWS }} test/document_stores/ --document_store_type=milvus - - - - rest-and-ui: needs: [mypy, pylint, black] diff --git a/test/document_stores/test_document_store.py b/test/document_stores/test_document_store.py index cd8bc46519..26a5cbacaa 100644 --- a/test/document_stores/test_document_store.py +++ b/test/document_stores/test_document_store.py @@ -1082,9 +1082,7 @@ def test_multilabel_meta_aggregations(document_store: BaseDocumentStore): assert multi_label.filters == l.filters -@pytest.mark.parametrize( - "document_store", ["elasticsearch", "faiss", "milvus", "weaviate", "pinecone", "memory"], indirect=True -) +@pytest.mark.parametrize("document_store", ["memory"], indirect=True) def test_update_meta(document_store: BaseDocumentStore): documents = [ Document(content="Doc1", meta={"meta_key_1": "1", "meta_key_2": "1"}), diff --git a/test/document_stores/test_milvus.py b/test/document_stores/test_milvus.py new file mode 100644 index 0000000000..bc7650a4ee --- /dev/null +++ b/test/document_stores/test_milvus.py @@ -0,0 +1,97 @@ +import pytest +import numpy as np + +from haystack.document_stores.milvus import MilvusDocumentStore +from haystack.schema import Document + +from .test_base import DocumentStoreBaseTestAbstract + + +class TestMilvusDocumentStore(DocumentStoreBaseTestAbstract): + @pytest.fixture + def ds(self, tmp_path): + db_url = f"sqlite:///{tmp_path}/haystack_test_milvus.db" + return MilvusDocumentStore(sql_url=db_url, return_embedding=True) + + @pytest.fixture + def documents(self): + """ + write_documents will raise an exception if receives a document without + embeddings, so we customize the documents fixture and always provide + embeddings + """ + documents = [] + for i in range(3): + documents.append( + Document( + content=f"A Foo Document {i}", + meta={"name": f"name_{i}", "year": "2020", "month": "01", "numbers": [2, 4]}, + embedding=np.random.rand(768).astype(np.float32), + ) + ) + + documents.append( + Document( + content=f"A Bar Document {i}", + meta={"name": f"name_{i}", "year": "2021", "month": "02", "numbers": [-2, -4]}, + embedding=np.random.rand(768).astype(np.float32), + ) + ) + + documents.append( + Document( + content=f"Document {i}", + meta={"name": f"name_{i}", "month": "03"}, + embedding=np.random.rand(768).astype(np.float32), + ) + ) + + return documents + + @pytest.mark.integration + def test_delete_index(self, ds, documents): + """Contrary to other Document Stores, MilvusDocumentStore doesn't raise if the index is empty""" + ds.write_documents(documents, index="custom_index") + assert ds.get_document_count(index="custom_index") == len(documents) + ds.delete_index(index="custom_index") + assert ds.get_document_count(index="custom_index") == 0 + + # NOTE: MilvusDocumentStore derives from the SQL one and behaves differently to the others when filters are applied. + # While this should be considered a bug, the relative tests are skipped in the meantime + + @pytest.mark.skip + @pytest.mark.integration + def test_ne_filters(self, ds, documents): + pass + + @pytest.mark.skip + @pytest.mark.integration + def test_nin_filters(self, ds, documents): + pass + + @pytest.mark.skip + @pytest.mark.integration + def test_comparison_filters(self, ds, documents): + pass + + @pytest.mark.skip + @pytest.mark.integration + def test_nested_condition_filters(self, ds, documents): + pass + + @pytest.mark.skip + @pytest.mark.integration + def test_nested_condition_not_filters(self, ds, documents): + pass + + # NOTE: again inherithed from the SQLDocumentStore, labels metadata are not supported + + @pytest.mark.skip + @pytest.mark.integration + def test_delete_labels_by_filter(self, ds, labels): + pass + + @pytest.mark.skip + @pytest.mark.integration + def test_delete_labels_by_filter_id(self, ds, labels): + pass