2022-06-20 14:06:12 +00:00
|
|
|
package httpserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"testing"
|
|
|
|
|
2023-09-21 01:45:27 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2023-06-08 17:28:37 +00:00
|
|
|
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
|
|
|
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
2022-06-20 14:06:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestFieldData_AsSchemapb(t *testing.T) {
|
2022-09-30 10:48:55 +00:00
|
|
|
t.Run("varchar_ok", func(t *testing.T) {
|
2022-06-20 14:06:12 +00:00
|
|
|
fieldData := FieldData{
|
2022-09-30 10:48:55 +00:00
|
|
|
Type: schemapb.DataType_VarChar,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
2022-09-30 10:48:55 +00:00
|
|
|
t.Run("varchar_error", func(t *testing.T) {
|
2022-06-20 14:06:12 +00:00
|
|
|
fieldData := FieldData{
|
2022-09-30 10:48:55 +00:00
|
|
|
Type: schemapb.DataType_VarChar,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[1, 2, 3]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("bool_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Bool,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[true, true, false]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("bool_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Bool,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[1, 2, 3]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("int8_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int8,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[1, 2, 3]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("int8_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int8,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("int32_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int32,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[1, 2, 3]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("int32_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int32,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("int64_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int64,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte("[1, 2, 3]"),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("int64_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Int64,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("float_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Float,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`[1.1, 2.1, 3.1]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("float_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Float,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("double_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Double,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`[1.1, 2.1, 3.1]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("double_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_Double,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2022-09-30 10:48:55 +00:00
|
|
|
t.Run("string_not_support", func(t *testing.T) {
|
2022-06-20 14:06:12 +00:00
|
|
|
fieldData := FieldData{
|
2022-09-30 10:48:55 +00:00
|
|
|
Type: schemapb.DataType_String,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
// vectors
|
|
|
|
|
|
|
|
t.Run("floatvector_ok", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_FloatVector,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`[
|
|
|
|
[1.1, 2.2, 3.1],
|
|
|
|
[1.1, 2.2, 3.1],
|
|
|
|
[1.1, 2.2, 3.1]
|
|
|
|
]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
t.Run("floatvector_empty_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_FloatVector,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(""),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("floatvector_dim=0_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
2022-11-25 02:43:12 +00:00
|
|
|
Type: schemapb.DataType_FloatVector,
|
|
|
|
Field: []byte(`[]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("floatvector_vectorTypeError_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
2022-11-25 02:43:12 +00:00
|
|
|
Type: schemapb.DataType_FloatVector,
|
|
|
|
Field: []byte(`["1"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
t.Run("floatvector_error", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_FloatVector,
|
2022-11-25 02:43:12 +00:00
|
|
|
Field: []byte(`["a", "b", "c"]`),
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
enhance: add sparse float vector support to restful v2 (#33231)
issue: #29419
also re-enabled an e2e test using restful api, which is previously
disabled due to https://github.com/milvus-io/milvus/issues/32214.
In restful api, the accepted json formats of sparse float vector are:
* `{"indices": [1, 100, 1000], "values": [0.1, 0.2, 0.3]}`
* {"1": 0.1, "100": 0.2, "1000": 0.3}
for accepted indice and value range, see
https://milvus.io/docs/sparse_vector.md#FAQ
Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2024-05-26 16:47:40 +00:00
|
|
|
|
|
|
|
t.Run("sparsefloatvector_ok_1", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"1": 0.1, "2": 0.2},
|
|
|
|
{"3": 0.1, "5": 0.2},
|
|
|
|
{"4": 0.1, "6": 0.2}
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_ok_2", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"indices": [1, 2], "values": [0.1, 0.2]},
|
|
|
|
{"indices": [3, 5], "values": [0.1, 0.2]},
|
|
|
|
{"indices": [4, 6], "values": [0.1, 0.2]}
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_ok_3", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"indices": [1, 2], "values": [0.1, 0.2]},
|
|
|
|
{"3": 0.1, "5": 0.2},
|
|
|
|
{"indices": [4, 6], "values": [0.1, 0.2]}
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_empty_err", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_invalid_json_err", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"3": 0.1, : 0.2}
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_invalid_row_1_err", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"indices": [1, 2], "values": [-0.1, 0.2]},
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("sparsefloatvector_invalid_row_2_err", func(t *testing.T) {
|
|
|
|
fieldData := FieldData{
|
|
|
|
Type: schemapb.DataType_SparseFloatVector,
|
|
|
|
Field: []byte(`[
|
|
|
|
{"indices": [1, -2], "values": [0.1, 0.2]},
|
|
|
|
]`),
|
|
|
|
}
|
|
|
|
raw, _ := json.Marshal(fieldData)
|
|
|
|
json.Unmarshal(raw, &fieldData)
|
|
|
|
_, err := fieldData.AsSchemapb()
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2022-06-20 14:06:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func Test_vector2Bytes(t *testing.T) {
|
|
|
|
ret := vector2Bytes([][]float32{{1.1, 1.2}})
|
|
|
|
assert.NotEmpty(t, ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_binaryVector2Bytes(t *testing.T) {
|
|
|
|
ret := binaryVector2Bytes([][]byte{
|
|
|
|
[]byte("somebytes"),
|
|
|
|
})
|
|
|
|
assert.NotEmpty(t, ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVectorsArray_AsPbVectorArray(t *testing.T) {
|
|
|
|
dim := int64(1)
|
|
|
|
t.Run("vector_ok", func(t *testing.T) {
|
|
|
|
vector := []float32{1, 2}
|
|
|
|
v := VectorsArray{
|
|
|
|
Dim: dim,
|
|
|
|
Vectors: vector,
|
|
|
|
}
|
|
|
|
ret := v.AsPbVectorArray()
|
|
|
|
da, ok := ret.Array.(*milvuspb.VectorsArray_DataArray)
|
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, dim, da.DataArray.Dim)
|
|
|
|
assert.Equal(t, vector, da.DataArray.GetFloatVector().Data)
|
|
|
|
})
|
|
|
|
t.Run("binary_vector_ok", func(t *testing.T) {
|
|
|
|
bv := []byte("somebytes")
|
|
|
|
v := VectorsArray{
|
|
|
|
// IDs: ,
|
|
|
|
Dim: dim,
|
|
|
|
BinaryVectors: bv,
|
|
|
|
}
|
|
|
|
ret := v.AsPbVectorArray()
|
|
|
|
da, ok := ret.Array.(*milvuspb.VectorsArray_DataArray)
|
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, dim, da.DataArray.Dim)
|
|
|
|
assert.Equal(t, bv, da.DataArray.GetBinaryVector())
|
|
|
|
})
|
|
|
|
t.Run("ids_ok", func(t *testing.T) {
|
|
|
|
ids := []int64{1, 2, 3}
|
|
|
|
cn := "collection"
|
|
|
|
paritions := []string{"p1", "p2"}
|
|
|
|
field := "field"
|
|
|
|
v := VectorsArray{
|
|
|
|
IDs: &VectorIDs{
|
|
|
|
CollectionName: cn,
|
|
|
|
PartitionNames: paritions,
|
|
|
|
FieldName: field,
|
|
|
|
IDArray: ids,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
ret := v.AsPbVectorArray()
|
|
|
|
ia, ok := ret.Array.(*milvuspb.VectorsArray_IdArray)
|
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, cn, ia.IdArray.CollectionName)
|
|
|
|
assert.Equal(t, paritions, ia.IdArray.PartitionNames)
|
|
|
|
assert.Equal(t, field, ia.IdArray.FieldName)
|
|
|
|
ints, ok := ia.IdArray.IdArray.IdField.(*schemapb.IDs_IntId)
|
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, ids, ints.IntId.Data)
|
|
|
|
})
|
|
|
|
}
|