Skip to content

Commit 5393ab7

Browse files
[test] Added upsert(dict) unit tests
- Test all possible input combination. - Negative tests for missing \ excess keys - Negative tests for wrong data types
1 parent 37c7c0a commit 5393ab7

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

tests/unit/test_grpc_index.py

+120
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,126 @@ def test_upsert_vectors_upsertInputVectorsSparse(self, mocker):
8787
sparse_values=SparseValues(indices=self.sparse_indices_2, values=self.sparse_values_2))],
8888
)
8989

90+
def test_upsert_dict(self, mocker):
91+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
92+
dict1 = {'id': 'vec1', 'values': self.vals1}
93+
dict2 = {'id': 'vec2', 'values': self.vals2}
94+
self.index.upsert([dict1, dict2], namespace='ns')
95+
self._assert_called_once([
96+
self.expected_vec1,
97+
self.expected_vec2]
98+
)
99+
100+
def test_upsert_dict_md(self, mocker):
101+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
102+
dict1 = {'id': 'vec1', 'values': self.vals1, 'metadata': self.md1}
103+
dict2 = {'id': 'vec2', 'values': self.vals2, 'metadata': self.md2}
104+
self.index.upsert([dict1, dict2], namespace='ns')
105+
self._assert_called_once([
106+
self.expected_vec_md1,
107+
self.expected_vec_md2]
108+
)
109+
110+
def test_upsert_dict_sparse(self, mocker):
111+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
112+
dict1 = {'id': 'vec1', 'values': self.vals1,
113+
'sparse_values': {'indices': self.sparse_indices_1, 'values': self.sparse_values_1}}
114+
dict2 = {'id': 'vec2', 'values': self.vals2,
115+
'sparse_values': {'indices': self.sparse_indices_2, 'values': self.sparse_values_2}}
116+
self.index.upsert([dict1, dict2], namespace='ns')
117+
self._assert_called_once([
118+
Vector(id='vec1', values=self.vals1, metadata={},
119+
sparse_values=SparseValues(indices=self.sparse_indices_1, values=self.sparse_values_1)),
120+
Vector(id='vec2', values=self.vals2, metadata={},
121+
sparse_values=SparseValues(indices=self.sparse_indices_2, values=self.sparse_values_2))]
122+
)
123+
124+
def test_upsert_dict_sparse_md(self, mocker):
125+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
126+
dict1 = {'id': 'vec1', 'values': self.vals1,
127+
'sparse_values': {'indices': self.sparse_indices_1, 'values': self.sparse_values_1},
128+
'metadata': self.md1}
129+
dict2 = {'id': 'vec2', 'values': self.vals2,
130+
'sparse_values': {'indices': self.sparse_indices_2, 'values': self.sparse_values_2},
131+
'metadata': self.md2}
132+
self.index.upsert([dict1, dict2], namespace='ns')
133+
self._assert_called_once([
134+
Vector(id='vec1', values=self.vals1, metadata=dict_to_proto_struct(self.md1),
135+
sparse_values=SparseValues(indices=self.sparse_indices_1, values=self.sparse_values_1)),
136+
Vector(id='vec2', values=self.vals2, metadata=dict_to_proto_struct(self.md2),
137+
sparse_values=SparseValues(indices=self.sparse_indices_2, values=self.sparse_values_2))]
138+
)
139+
140+
def test_upsert_dict_negative(self, mocker):
141+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
142+
143+
# Missing required keys
144+
dict1 = {'values': self.vals1}
145+
dict2 = {'id': 'vec2'}
146+
with pytest.raises(ValueError):
147+
self.index.upsert([dict1, dict2])
148+
with pytest.raises(ValueError):
149+
self.index.upsert([dict1])
150+
with pytest.raises(ValueError):
151+
self.index.upsert([dict2])
152+
153+
# Excess keys
154+
dict1 = {'id': 'vec1', 'values': self.vals1}
155+
dict2 = {'id': 'vec2', 'values': self.vals2, 'animal': 'dog'}
156+
with pytest.raises(ValueError) as e:
157+
self.index.upsert([dict1, dict2])
158+
assert 'animal' in str(e.value)
159+
160+
dict1 = {'id': 'vec1', 'values': self.vals1, 'metadatta': self.md2}
161+
dict2 = {'id': 'vec2', 'values': self.vals2}
162+
with pytest.raises(ValueError) as e:
163+
self.index.upsert([dict1, dict2])
164+
assert 'metadatta' in str(e.value)
165+
166+
@pytest.mark.parametrize("key,new_val", [
167+
("id", 4.2),
168+
("id", ['vec1']),
169+
("values", ['the', 'lazy', 'fox']),
170+
("values", 'the lazy fox'),
171+
("values", 0.5),
172+
("metadata", np.nan),
173+
("metadata", ['key1', 'key2']),
174+
("sparse_values", 'cat'),
175+
("sparse_values", []),
176+
])
177+
def test_upsert_dict_negative_types(self, mocker, key, new_val):
178+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
179+
180+
full_dict1 = {'id': 'vec1', 'values': self.vals1,
181+
'sparse_values': {'indices': self.sparse_indices_1, 'values': self.sparse_values_1},
182+
'metadata': self.md1}
183+
184+
dict1 = deepcopy(full_dict1)
185+
dict1[key] = new_val
186+
with pytest.raises(TypeError) as e:
187+
self.index.upsert([dict1])
188+
assert key in str(e.value)
189+
190+
@pytest.mark.parametrize("key,new_val", [
191+
("indices", 3),
192+
("indices", [1.2, 0.5]),
193+
("values", ['1', '4.4']),
194+
("values", 0.5),
195+
])
196+
def test_upsert_dict_negative_types_sparse(self, mocker, key, new_val):
197+
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
198+
199+
full_dict1 = {'id': 'vec1', 'values': self.vals1,
200+
'sparse_values': {'indices': self.sparse_indices_1, 'values': self.sparse_values_1},
201+
'metadata': self.md1}
202+
203+
dict1 = deepcopy(full_dict1)
204+
dict1['sparse_values'][key] = new_val
205+
with pytest.raises(TypeError) as e:
206+
self.index.upsert([dict1])
207+
assert 'sparse' in str(e.value)
208+
assert key in str(e.value)
209+
90210
def test_upsert_async_upsertInputVectorsAsync(self, mocker):
91211
mocker.patch.object(self.index, '_wrap_grpc_call', autospec=True)
92212
self.index.upsert([self.expected_vec_md1,

0 commit comments

Comments
 (0)