File size: 4,091 Bytes
3932407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import pytest
import requests

from .fixtures import create_collection, drop_collection, upsert_random_points
from .utils import kill_all_processes, start_cluster

COLL_NAME = "test_collection"


@pytest.fixture(scope="module")
def setup(tmp_path_factory: pytest.TempPathFactory):
    extra_env = {
        "QDRANT__SERVICE__SLOW_QUERY_SECS": "0.001",  # "Always" try to trigger slow search issue
    }

    tmp_path = tmp_path_factory.mktemp("qdrant")

    peer_api_uris, _peer_dirs, _bootstrap_uri = start_cluster(
        tmp_path=tmp_path, num_peers=1, extra_env=extra_env
    )

    uri = peer_api_uris[0]

    yield uri

    kill_all_processes()


@pytest.fixture
def setup_with_big_collection(setup):
    uri = setup

    create_collection(uri, COLL_NAME)

    upsert_random_points(uri, 10000, collection_name=COLL_NAME, with_sparse_vector=False)

    yield uri

    drop_collection(uri, COLL_NAME)


def get_issues(uri):
    response = requests.get(
        f"{uri}/issues",
    )
    assert response.ok
    return response.json()["result"]["issues"]


def search_with_city_filter(uri):
    response = requests.post(
        f"{uri}/collections/{COLL_NAME}/points/search",
        json={
            "vector": [0.2, 0.1, 0.9, 0.7],
            "limit": 1000,
            "filter": {"must": [{"key": "city", "match": {"any": ["London", "Moscow"]}}]},
        },
    )
    assert response.ok, response.json()


def test_unindexed_field_is_gone_when_deleting_collection(setup_with_big_collection):
    uri = setup_with_big_collection

    expected_issue_code = "UNINDEXED_FIELD/test_collection/city"
    issues = get_issues(uri)
    assert expected_issue_code not in [issue["code"] for issue in issues]

    search_with_city_filter(uri)

    issues = get_issues(uri)

    # check the issue is now active
    assert expected_issue_code in [issue["id"] for issue in issues]

    # delete collection
    drop_collection(uri, COLL_NAME)

    # check the issue is not active anymore
    issues = get_issues(uri)
    assert expected_issue_code not in [issue["id"] for issue in issues]


def test_unindexed_field_is_gone_when_indexing(setup_with_big_collection):
    uri = setup_with_big_collection

    expected_issue_code = "UNINDEXED_FIELD/test_collection/city"

    issues = get_issues(uri)
    assert expected_issue_code not in [issue["id"] for issue in issues]

    search_with_city_filter(uri)

    issues = get_issues(uri)

    # check the issue is now active
    issue_present = False
    solution = None
    timestamp = None
    for issue in issues:
        if issue["id"] == expected_issue_code:
            issue_present = True
            solution = issue["solution"]["immediate"]["action"]
            timestamp = issue["timestamp"]
            break
    assert issue_present
    assert solution is not None
    assert timestamp is not None
    
    # search again
    search_with_city_filter(uri)

    issues = get_issues(uri)

    # check the timestamp has not changed
    issue_present = False
    for issue in issues:
        if issue["id"] == expected_issue_code:
            issue_present = True
            assert timestamp == issue["timestamp"]
            break
    assert issue_present
    assert solution is not None
    assert timestamp is not None

    assert solution == {
        "method": "PUT",
        "uri": f"/collections/{COLL_NAME}/index",
        "body": {"field_name": "city", "field_schema": "keyword"},
        "headers": {"content-type": "application/json"},
    }

    # use provided solution to create index
    response = requests.request(
        method=solution["method"],
        url=uri + solution["uri"],
        params={"wait": "true"},
        json=solution["body"],
    )
    assert response.ok

    # check the issue is not active anymore
    issues = get_issues(uri)
    assert expected_issue_code not in [issue["id"] for issue in issues]

    # search again
    search_with_city_filter(uri)

    # check the issue is not triggered again
    issues = get_issues(uri)
    assert expected_issue_code not in [issue["id"] for issue in issues]