From 78d1bf75a6ee856e64fef72afe68821d07ddee50 Mon Sep 17 00:00:00 2001 From: ThreadDao Date: Thu, 11 Jul 2024 12:04:39 +0800 Subject: [PATCH] test: add cases for gosdk v2 partitions Signed-off-by: ThreadDao --- tests/go_client/testcases/collection_test.go | 2 +- tests/go_client/testcases/index_test.go | 8 +- tests/go_client/testcases/partition_test.go | 197 +++++++++++++++++++ 3 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 tests/go_client/testcases/partition_test.go diff --git a/tests/go_client/testcases/collection_test.go b/tests/go_client/testcases/collection_test.go index 0b01637a3bf0..98dba74bf977 100644 --- a/tests/go_client/testcases/collection_test.go +++ b/tests/go_client/testcases/collection_test.go @@ -463,7 +463,7 @@ func TestCreateCollectionWithInvalidCollectionName(t *testing.T) { common.CheckErr(t, err, false, "collection name should not be empty", "the first character of a collection name must be an underscore or letter", "collection name can only contain numbers, letters and underscores", - "the length of a collection name must be less than 255 characters") + fmt.Sprintf("the length of a collection name must be less than %d characters", common.MaxCollectionNameLen)) // collection option has invalid name schema.WithName(collName) diff --git a/tests/go_client/testcases/index_test.go b/tests/go_client/testcases/index_test.go index 0900b67f580b..8e23c7743a0b 100644 --- a/tests/go_client/testcases/index_test.go +++ b/tests/go_client/testcases/index_test.go @@ -992,15 +992,13 @@ func TestCreateIndexInvalidParams(t *testing.T) { } // invalid IvfPq params m dim ≡ 0 (mod m), nbits [1, 16] - t.Log("https://github.com/milvus-io/milvus/issues/34426") - /*for _, invalidNBits := range []int{0, 17} { + for _, invalidNBits := range []int{0, 65} { // IvfFlat idxIvfPq := index.NewIvfPQIndex(entity.L2, 128, 8, invalidNBits) _, err := mc.CreateIndex(ctx, client.NewCreateIndexOption(schema.CollectionName, common.DefaultFloatVecFieldName, idxIvfPq)) - common.CheckErr(t, err, false, "nbits has to be in range [1, 16]") - }*/ + common.CheckErr(t, err, false, "parameter `nbits` out of range, expect range [1,64]") + } - // TODO unclear error message idxIvfPq := index.NewIvfPQIndex(entity.L2, 128, 7, 8) _, err := mc.CreateIndex(ctx, client.NewCreateIndexOption(schema.CollectionName, common.DefaultFloatVecFieldName, idxIvfPq)) common.CheckErr(t, err, false, "dimension must be able to be divided by `m`") diff --git a/tests/go_client/testcases/partition_test.go b/tests/go_client/testcases/partition_test.go new file mode 100644 index 000000000000..42b2dabf9823 --- /dev/null +++ b/tests/go_client/testcases/partition_test.go @@ -0,0 +1,197 @@ +package testcases + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "github.com/milvus-io/milvus/client/v2" + "github.com/milvus-io/milvus/client/v2/entity" + "github.com/milvus-io/milvus/pkg/log" + "github.com/milvus-io/milvus/tests/go_client/common" + hp "github.com/milvus-io/milvus/tests/go_client/testcases/helper" +) + +func TestPartitionsDefault(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + + // create collection + _, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption()) + + // create multi partitions + expPar := []string{common.DefaultPartition} + for i := 0; i < 10; i++ { + // create par + parName := common.GenRandomString("par", 4) + err := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err, true) + + // has par + has, errHas := mc.HasPartition(ctx, client.NewHasPartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, errHas, true) + require.Truef(t, has, "should has partition") + expPar = append(expPar, parName) + } + + // list partitions + partitionNames, errList := mc.ListPartitions(ctx, client.NewListPartitionOption(schema.CollectionName)) + common.CheckErr(t, errList, true) + require.ElementsMatch(t, expPar, partitionNames) + + // drop partitions + for _, par := range partitionNames { + err := mc.DropPartition(ctx, client.NewDropPartitionOption(schema.CollectionName, par)) + if par == common.DefaultPartition { + common.CheckErr(t, err, false, "default partition cannot be deleted") + } else { + common.CheckErr(t, err, true) + has2, _ := mc.HasPartition(ctx, client.NewHasPartitionOption(schema.CollectionName, par)) + require.False(t, has2) + } + } + + // list partitions + partitionNames, errList = mc.ListPartitions(ctx, client.NewListPartitionOption(schema.CollectionName)) + common.CheckErr(t, errList, true) + require.Equal(t, []string{common.DefaultPartition}, partitionNames) +} + +func TestCreatePartitionInvalid(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + + // create collection + _, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption()) + + // create partition with invalid name + expPars := []string{common.DefaultPartition} + for _, invalidName := range common.GenInvalidNames() { + log.Debug("invalidName", zap.String("currentName", invalidName)) + err := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, invalidName)) + if invalidName == "1" { + common.CheckErr(t, err, true) + expPars = append(expPars, invalidName) + continue + } + common.CheckErr(t, err, false, "Partition name should not be empty", + "Partition name can only contain numbers, letters and underscores", + "The first character of a partition name must be an underscore or letter", + fmt.Sprintf("The length of a partition name must be less than %d characters", common.MaxCollectionNameLen)) + } + + // create partition with existed partition name -> no error + parName := common.GenRandomString("par", 3) + err1 := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err1, true) + err1 = mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err1, true) + expPars = append(expPars, parName) + + // create partition with not existed collection name + err2 := mc.CreatePartition(ctx, client.NewCreatePartitionOption("aaa", common.GenRandomString("par", 3))) + common.CheckErr(t, err2, false, "not found") + + // create default partition + err3 := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, common.DefaultPartition)) + common.CheckErr(t, err3, true) + + // list partitions + pars, errList := mc.ListPartitions(ctx, client.NewListPartitionOption(schema.CollectionName)) + common.CheckErr(t, errList, true) + require.ElementsMatch(t, expPars, pars) +} + +func TestPartitionsNumExceedsMax(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + + // create collection + _, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption()) + + // create multi partitions + for i := 0; i < common.MaxPartitionNum-1; i++ { + // create par + parName := common.GenRandomString("par", 4) + err := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err, true) + } + pars, errList := mc.ListPartitions(ctx, client.NewListPartitionOption(schema.CollectionName)) + common.CheckErr(t, errList, true) + require.Len(t, pars, common.MaxPartitionNum) + + // create partition exceed max + parName := common.GenRandomString("par", 4) + err := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err, false, fmt.Sprintf("exceeds max configuration (%d)", common.MaxPartitionNum)) +} + +func TestDropPartitionInvalid(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + _, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption()) + + errDrop := mc.DropPartition(ctx, client.NewDropPartitionOption("aaa", "aaa")) + common.CheckErr(t, errDrop, false, "collection not found") + + errDrop1 := mc.DropPartition(ctx, client.NewDropPartitionOption(schema.CollectionName, "aaa")) + common.CheckErr(t, errDrop1, true) + + err := mc.DropPartition(ctx, client.NewDropPartitionOption(schema.CollectionName, common.DefaultPartition)) + common.CheckErr(t, err, false, "default partition cannot be deleted") + + // list partitions + pars, errList := mc.ListPartitions(ctx, client.NewListPartitionOption(schema.CollectionName)) + common.CheckErr(t, errList, true) + require.ElementsMatch(t, []string{common.DefaultPartition}, pars) +} + +func TestListHasPartitionInvalid(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + + // list partitions + _, errList := mc.ListPartitions(ctx, client.NewListPartitionOption("aaa")) + common.CheckErr(t, errList, false, "collection not found") + + // list partitions + _, errHas := mc.HasPartition(ctx, client.NewHasPartitionOption("aaa", "aaa")) + common.CheckErr(t, errHas, false, "collection not found") +} + +func TestDropPartitionData(t *testing.T) { + ctx := hp.CreateContext(t, time.Second*common.DefaultTimeout) + mc := createDefaultMilvusClient(ctx, t) + + // create collection + prepare, schema := hp.CollPrepare.CreateCollection(ctx, t, mc, hp.NewCreateCollectionParams(hp.Int64Vec), hp.TNewFieldsOption(), hp.TNewSchemaOption()) + prepare.CreateIndex(ctx, t, mc, hp.TNewIndexParams(schema)) + prepare.Load(ctx, t, mc, hp.NewLoadParams(schema.CollectionName)) + + // create multi partitions + parName := common.GenRandomString("par", 4) + err := mc.CreatePartition(ctx, client.NewCreatePartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, err, true) + + // has par + has, errHas := mc.HasPartition(ctx, client.NewHasPartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, errHas, true) + require.Truef(t, has, "should has partition") + + // insert data into partition -> query check + prepare.InsertData(ctx, t, mc, hp.NewInsertParams(schema, common.DefaultNb).TWithPartitionName(parName), hp.TNewDataOption()) + res, errQ := mc.Query(ctx, client.NewQueryOption(schema.CollectionName).WithConsistencyLevel(entity.ClStrong).WithPartitions([]string{parName}).WithOutputFields([]string{common.QueryCountFieldName})) + common.CheckErr(t, errQ, true) + count, _ := res.GetColumn(common.QueryCountFieldName).Get(0) + require.EqualValues(t, common.DefaultNb, count) + + // drop partition + errDrop := mc.DropPartition(ctx, client.NewDropPartitionOption(schema.CollectionName, parName)) + common.CheckErr(t, errDrop, false, "partition cannot be dropped, partition is loaded, please release it first") + + // release -> drop -> load -> query check + t.Log("waiting for release implement") +}