From f77ec428856162370d84ee9d7fc975694b3cfe33 Mon Sep 17 00:00:00 2001 From: kevindiu Date: Wed, 28 Sep 2022 16:19:43 +0900 Subject: [PATCH 1/7] draft create and save index test case Signed-off-by: kevindiu --- pkg/agent/core/ngt/handler/grpc/index_test.go | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index c39037e4a2..a2e1a221a9 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1061,6 +1061,31 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { } return nil } + + /* + - Equivalence Class Testing (with copy on write disable) + - case 1.1: success to create and save 1 uncommitted insert index + - case 1.2: success to create and save 100 uncommitted insert index + - case 2.1: success to create and save 1 uncommitted delete index + - case 2.2: success to create and save 100 uncommitted delete index + - case 3.1: success to create and save 1 uncommitted update index + - case 3.2: success to create and save 100 uncommitted update index + - Boundary Value Testing + - case 1.1: fail to create and save 0 index + - case 2.1: success to create and save index with invalid dimension + - the invalid index will be removed from NGT and the index file + - Decision Table Testing + - case 1.1: success to create and save index with in-memory mode + - do nothing and no file will be created + - case 2.1: success to create and save 1 inserted index with copy-on-write enabled + - case 2.2: success to create and save 100 inserted index with copy-on-write enabled + + // with uncommitted index count 100 + - case 3.1: success to create and save index with poolSize > uncommitted index count + - case 3.2: success to create and save index with poolSize < uncommitted index count + - case 3.3: success to create and save index with poolSize = uncommitted index count + - case 3.4: success to create and save index with poolSize = 0 + */ tests := []test{ // TODO test cases /* From cfc0f6c0497ee2ef21b9aa286f2f913c0fd4bf9e Mon Sep 17 00:00:00 2001 From: Kevin Diu Date: Tue, 4 Oct 2022 09:14:00 +0900 Subject: [PATCH 2/7] Update pkg/agent/core/ngt/handler/grpc/index_test.go --- pkg/agent/core/ngt/handler/grpc/index_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index a2e1a221a9..f01cc79554 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1075,7 +1075,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { - case 2.1: success to create and save index with invalid dimension - the invalid index will be removed from NGT and the index file - Decision Table Testing - - case 1.1: success to create and save index with in-memory mode + - case 1.1: success to create and save 100 index with in-memory mode - do nothing and no file will be created - case 2.1: success to create and save 1 inserted index with copy-on-write enabled - case 2.2: success to create and save 100 inserted index with copy-on-write enabled From aa1efa603ebe2a8599846c5f7ee1b41dda9e2441 Mon Sep 17 00:00:00 2001 From: kevindiu Date: Tue, 11 Oct 2022 17:14:19 +0900 Subject: [PATCH 3/7] add impl stub for test Signed-off-by: kevindiu --- pkg/agent/core/ngt/handler/grpc/index_test.go | 266 +++++++++++++++--- 1 file changed, 225 insertions(+), 41 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index f01cc79554..10f82f1e0d 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1087,47 +1087,231 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { - case 3.4: success to create and save index with poolSize = 0 */ tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - ctx: nil, - c: nil, - }, - fields: fields { - name: "", - ip: "", - ngt: nil, - eg: nil, - streamConcurrency: 0, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - ctx: nil, - c: nil, - }, - fields: fields { - name: "", - ip: "", - ngt: nil, - eg: nil, - streamConcurrency: 0, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ + // { + // name: "Equivalence Class Testing case 1.1: success to create and save 1 uncommitted insert index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Equivalence Class Testing case 1.2: success to create and save 100 uncommitted insert index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Equivalence Class Testing case 2.1: success to create and save 1 uncommitted delete index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Equivalence Class Testing case 2.2: success to create and save 100 uncommitted delete index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Equivalence Class Testing case 3.1: success to create and save 1 uncommitted update index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Equivalence Class Testing case 3.2: success to create and save 100 uncommitted update index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Boundary Value Testing case 1.1: fail to create and save 0 index", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Boundary Value Testing case 2.1: success to create and save index with invalid dimension", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 1.1: success to create and save 100 index with in-memory mode", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 2.1: success to create and save 1 inserted index with copy-on-write enabled", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 2.2: success to create and save 100 inserted index with copy-on-write enabled", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 3.1: success to create and save index with poolSize > uncommitted index count", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 3.2: success to create and save index with poolSize < uncommitted index count", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 3.3: success to create and save index with poolSize = uncommitted index count", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, + // { + // name: "Decision Table Testing case 3.4: success to create and save index with poolSize = 0", + // args: args{ + // ctx: nil, + // c: nil, + // }, + // fields: fields{ + // name: "", + // ip: "", + // ngt: nil, + // eg: nil, + // streamConcurrency: 0, + // }, + // want: want{}, + // }, } for _, tc := range tests { From 1db24a1643fe2b72037638233aae98b2f871278f Mon Sep 17 00:00:00 2001 From: kevindiu Date: Wed, 12 Oct 2022 17:31:25 +0900 Subject: [PATCH 4/7] impl test cases Signed-off-by: kevindiu --- pkg/agent/core/ngt/handler/grpc/index_test.go | 1054 +++++++++++++---- 1 file changed, 794 insertions(+), 260 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index 10f82f1e0d..e728227890 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1029,39 +1029,137 @@ func Test_server_SaveIndex(t *testing.T) { func Test_server_CreateAndSaveIndex(t *testing.T) { t.Parallel() type args struct { - ctx context.Context - c *payload.Control_CreateIndexRequest + c *payload.Control_CreateIndexRequest } type fields struct { - name string - ip string - ngt service.NGT - eg errgroup.Group - streamConcurrency int + srvOpts []Option + svcCfg *config.NGT + svcOpts []service.Option + indexPath string // index path for svcOpts } type want struct { wantRes *payload.Empty - err error + errCode codes.Code } type test struct { name string args args fields fields want want - checkFunc func(want, *payload.Empty, error) error - beforeFunc func(args) - afterFunc func(args) + checkFunc func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error + beforeFunc func(*testing.T, context.Context, Server, service.NGT, test) + afterFunc func(*testing.T, test) } - defaultCheckFunc := func(w want, gotRes *payload.Empty, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) + + // common variables for test + const ( + name = "vald-agent-ngt-1" // agent name + dim = 3 // vector dimension + id = "uuid-1" // id for getObject request + ) + var ( + // agent ip address + ip = net.LoadLocalIP() + + // default NGT configuration for test + defaultSvcCfg = &config.NGT{ + Dimension: dim, + DistanceType: ngt.Angle.String(), + ObjectType: ngt.Float.String(), + KVSDB: &config.KVSDB{}, + VQueue: &config.VQueue{}, } - if !reflect.DeepEqual(gotRes, w.wantRes) { + defaultSrvOpts = []Option{ + WithName(name), + WithIP(ip), + } + defaultSvcOpts = []service.Option{ + service.WithEnableInMemoryMode(false), + } + defaultInsertConfig = &payload.Insert_Config{} + emptyPayload = &payload.Empty{} + ) + + defaultCheckFunc := func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if (err == nil && w.errCode != 0) || (err != nil && w.errCode == 0) { + return errors.Errorf("got error is %v, but want error code is %v", err, w.errCode) + } + if err != nil { + st, ok := status.FromError(err) + if !ok { + return errors.Errorf("got error cannot convert to Status: \"%#v\"", err) + } + if st.Code() != w.errCode { + return errors.Errorf("got code: \"%#v\",\n\t\t\t\twant code: \"%#v\"", st.Code(), w.errCode) + } + } + + if diff := comparator.Diff(gotRes, w.wantRes, comparator.IgnoreUnexported(payload.Empty{})); diff != "" { return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes) } return nil } + mkdirTemp := func() string { + d, err := os.MkdirTemp("", "") + if err != nil { + t.Error(err) + } + return d + } + defaultAfterFunc := func(t *testing.T, test test) { + t.Helper() + os.RemoveAll(test.fields.indexPath) + } + + // this function checks the backup file can be loaded and check if it contain the wantVecs indexes. + // it creates a new ngt and server instance with the backup file, and checks if we can retrieve all of wantVecs indexes + // and check the total index count matches with wantVecs count. + checkBackupFolder := func(fields fields, ctx context.Context, wantVecs []*payload.Insert_Request) error { + // create another server instance to check if any vector is inserted and saved to the backup dir + eg, _ := errgroup.New(ctx) + ngt, err := service.New(fields.svcCfg, append(fields.svcOpts, + service.WithErrGroup(eg), + service.WithIndexPath(fields.indexPath))...) + if err != nil { + return errors.Errorf("failed to init ngt service, error = %v", err) + } + srv, err := New(append(fields.srvOpts, WithNGT(ngt), WithErrGroup(eg))...) + if err != nil { + return errors.Errorf("failed to init server, error= %v", err) + } + + // get object and check if the vector is equals to inserted one + for _, ir := range wantVecs { + obj, err := srv.GetObject(ctx, &payload.Object_VectorRequest{ + Id: &payload.Object_ID{ + Id: ir.GetVector().GetId(), + }, + }) + if err != nil { + return err + } + if !reflect.DeepEqual(obj, ir.GetVector()) { + return errors.Errorf("vector is not match, got: %v, want: %v", obj, ir) + } + } + + // check total index count is same + ii, err := srv.IndexInfo(ctx, emptyPayload) + if err != nil { + return err + } + + wantIndexInfo := &payload.Info_Index_Count{ + Stored: uint32(len(wantVecs)), + } + if !reflect.DeepEqual(ii, wantIndexInfo) { + return errors.Errorf("stored index count not correct, got: %v, want: %v", ii, wantIndexInfo) + } + + return nil + } + /* - Equivalence Class Testing (with copy on write disable) - case 1.1: success to create and save 1 uncommitted insert index @@ -1087,257 +1185,693 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { - case 3.4: success to create and save index with poolSize = 0 */ tests := []test{ - // { - // name: "Equivalence Class Testing case 1.1: success to create and save 1 uncommitted insert index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Equivalence Class Testing case 1.2: success to create and save 100 uncommitted insert index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Equivalence Class Testing case 2.1: success to create and save 1 uncommitted delete index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Equivalence Class Testing case 2.2: success to create and save 100 uncommitted delete index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Equivalence Class Testing case 3.1: success to create and save 1 uncommitted update index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Equivalence Class Testing case 3.2: success to create and save 100 uncommitted update index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Boundary Value Testing case 1.1: fail to create and save 0 index", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Boundary Value Testing case 2.1: success to create and save index with invalid dimension", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 1.1: success to create and save 100 index with in-memory mode", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 2.1: success to create and save 1 inserted index with copy-on-write enabled", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 2.2: success to create and save 100 inserted index with copy-on-write enabled", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 3.1: success to create and save index with poolSize > uncommitted index count", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 3.2: success to create and save index with poolSize < uncommitted index count", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 3.3: success to create and save index with poolSize = uncommitted index count", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - // { - // name: "Decision Table Testing case 3.4: success to create and save index with poolSize = 0", - // args: args{ - // ctx: nil, - // c: nil, - // }, - // fields: fields{ - // name: "", - // ip: "", - // ngt: nil, - // eg: nil, - // streamConcurrency: 0, - // }, - // want: want{}, - // }, - } + func() test { + insertCnt := 1 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) + } - for _, tc := range tests { - test := tc - t.Run(test.name, func(tt *testing.T) { - tt.Parallel() - if test.beforeFunc != nil { - test.beforeFunc(test.args) + return test{ + name: "Equivalence Class Testing case 1.1: success to create and save 1 uncommitted insert index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, ir.GetRequests()) + }, } - if test.afterFunc != nil { - defer test.afterFunc(test.args) + }(), + func() test { + insertCnt := 100 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) } - checkFunc := test.checkFunc - if test.checkFunc == nil { - checkFunc = defaultCheckFunc + + return test{ + name: "Equivalence Class Testing case 1.2: success to create and save 100 uncommitted insert index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, ir.GetRequests()) + }, } - s := &server{ - name: test.fields.name, - ip: test.fields.ip, - ngt: test.fields.ngt, - eg: test.fields.eg, - streamConcurrency: test.fields.streamConcurrency, + }(), + func() test { + insertCnt := 100 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) } + removeID := ir.GetRequests()[0].GetVector().GetId() - gotRes, err := s.CreateAndSaveIndex(test.args.ctx, test.args.c) - if err := checkFunc(test.want, gotRes, err); err != nil { + return test{ + name: "Equivalence Class Testing case 2.1: success to create and save 1 uncommitted delete index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + // insert 100 request + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + if _, err := s.CreateAndSaveIndex(ctx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }); err != nil { + t.Error(err) + } + + // delete 1 request + if _, err := s.Remove(ctx, &payload.Remove_Request{ + Id: &payload.Object_ID{ + Id: removeID, + }, + }); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + // we expect the request[0] is removed and shouldn't be exists in backup files + expectedVecs := ir.GetRequests()[1:] + return checkBackupFolder(test.fields, ctx, expectedVecs) + }, + } + }(), + func() test { + insertCnt := 200 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) + } + + // remove requests + rr := make([]*payload.Remove_Request, 100) + for i := 0; i < 100; i++ { + rr[i] = &payload.Remove_Request{ + Id: &payload.Object_ID{ + Id: ir.GetRequests()[i].GetVector().GetId(), + }, + } + } + + return test{ + name: "Equivalence Class Testing case 2.2: success to create and save 100 uncommitted delete index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + // insert 200 request + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + if _, err := s.CreateAndSaveIndex(ctx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }); err != nil { + t.Error(err) + } + + // delete 100 request + if _, err := s.MultiRemove(ctx, &payload.Remove_MultiRequest{ + Requests: rr, + }); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + // we expect the request[0-99] is removed and shouldn't be exists in backup files + expectedVecs := ir.GetRequests()[100:] + return checkBackupFolder(test.fields, ctx, expectedVecs) + }, + } + }(), + func() test { + insertCnt := 1 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) + } + + updateID := ir.GetRequests()[0].GetVector().GetId() + updateVecs, err := vector.GenF32Vec(vector.Gaussian, 1, dim) + if err != nil { + t.Error(err) + } + updateVec := updateVecs[0] + + return test{ + name: "Equivalence Class Testing case 3.1: success to create and save 1 uncommitted update index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + // insert 1 request + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + if _, err := s.CreateAndSaveIndex(ctx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }); err != nil { + t.Error(err) + } + + // update vector request + if _, err := s.Update(ctx, &payload.Update_Request{ + Vector: &payload.Object_Vector{ + Id: updateID, + Vector: updateVec, + }, + }); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + // we expect vector is the update vec + expectedVecs := ir.GetRequests() + expectedVecs[0].Vector.Vector = updateVec + return checkBackupFolder(test.fields, ctx, expectedVecs) + }, + } + }(), + func() test { + insertCnt := 100 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) + } + + // generate another set of vectors for update + updateVecs, err := vector.GenF32Vec(vector.Gaussian, insertCnt, dim) + if err != nil { + t.Error(err) + } + + // generate update requests for insert + updateReqs := make([]*payload.Update_Request, insertCnt) + for i := range ir.GetRequests() { + updateReqs[i] = &payload.Update_Request{ + Vector: &payload.Object_Vector{ + Id: ir.GetRequests()[i].GetVector().GetId(), + Vector: updateVecs[i], + }, + } + } + + return test{ + name: "Equivalence Class Testing case 3.2: success to create and save 100 uncommitted update index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + // insert 100 request + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + if _, err := s.CreateAndSaveIndex(ctx, &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }); err != nil { + t.Error(err) + } + + // update vector request + if _, err := s.MultiUpdate(ctx, &payload.Update_MultiRequest{ + Requests: updateReqs, + }); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + // we expect vector is the update vec + expectedVecs := ir.GetRequests() + for i := range expectedVecs { + expectedVecs[i].GetVector().Vector = updateVecs[i] + } + + return checkBackupFolder(test.fields, ctx, expectedVecs) + }, + } + }(), + func() test { + return test{ + name: "Boundary Value Testing case 1.1: fail to create and save 0 index", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: 0, + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + want: want{ + wantRes: &payload.Empty{}, + }, + } + }(), + func() test { + return test{ + name: "Boundary Value Testing case 2.1: success to create and save index with invalid dimension", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: 1, + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: defaultSvcOpts, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + invalidDim := dim + 1 + vecs, err := vector.GenF32Vec(vector.Gaussian, 1, invalidDim) + if err != nil { + t.Error(err) + } + + // insert invalid vector to ngt directly + if err := n.Insert("uuid-1", vecs[0]); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + // the invalid index will be removed inside ngt + return checkBackupFolder(test.fields, ctx, nil) + }, + } + }(), + func() test { + insertCnt := 100 + ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 1.1: success to create and save 100 index with in-memory mode", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: []service.Option{ + service.WithEnableInMemoryMode(true), + }, + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + if _, err := s.MultiInsert(ctx, ir); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: &payload.Empty{}, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, gotRes *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, gotRes, err); err != nil { + return err + } + files, err := file.ListInDir(test.fields.indexPath) + if err != nil { + return err + } + + // check any file is generated in backup directory + if len(files) > 0 { + return errors.New("no file should be created when in memory mode is enabled") + } + return nil + }, + } + }(), + func() test { + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, 1, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 2.1: success to create and save 1 inserted index with copy-on-write enabled", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: 1, + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.Insert(ctx, irs.Requests[0]); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + func() test { + insertCnt := 100 + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 2.2: success to create and save 100 inserted index with copy-on-write enabled", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.MultiInsert(ctx, irs); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + func() test { + insertCnt := 100 + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 3.1: success to create and save index with poolSize > uncommitted index count", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt + 1), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.MultiInsert(ctx, irs); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + func() test { + insertCnt := 100 + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 3.2: success to create and save index with poolSize < uncommitted index count", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt - 1), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.MultiInsert(ctx, irs); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + func() test { + insertCnt := 100 + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 3.3: success to create and save index with poolSize = uncommitted index count", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: uint32(insertCnt), + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.MultiInsert(ctx, irs); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + func() test { + insertCnt := 100 + irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) + if err != nil { + t.Error(err) + } + + return test{ + name: "Decision Table Testing case 3.4: success to create and save index with poolSize = 0", + args: args{ + c: &payload.Control_CreateIndexRequest{ + PoolSize: 0, + }, + }, + fields: fields{ + srvOpts: defaultSrvOpts, + svcCfg: defaultSvcCfg, + svcOpts: append(defaultSvcOpts, service.WithCopyOnWrite(true)), + indexPath: mkdirTemp(), + }, + beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + if _, err := s.MultiInsert(ctx, irs); err != nil { + t.Error(err) + } + }, + want: want{ + wantRes: emptyPayload, + }, + checkFunc: func(test test, ctx context.Context, s Server, n service.NGT, w want, e *payload.Empty, err error) error { + if err := defaultCheckFunc(test, ctx, s, n, w, e, err); err != nil { + return err + } + return checkBackupFolder(test.fields, ctx, irs.Requests) + }, + } + }(), + } + + for _, tc := range tests { + test := tc + t.Run(test.name, func(tt *testing.T) { + tt.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + afterFunc := test.afterFunc + if test.afterFunc == nil { + afterFunc = defaultAfterFunc + } + defer afterFunc(tt, test) + + checkFunc := test.checkFunc + if test.checkFunc == nil { + checkFunc = defaultCheckFunc + } + + eg, _ := errgroup.New(ctx) + ngt, err := service.New(test.fields.svcCfg, append(test.fields.svcOpts, + service.WithErrGroup(eg), + service.WithIndexPath(test.fields.indexPath))...) + if err != nil { + tt.Errorf("failed to init ngt service, error = %v", err) + } + + s, err := New(append(test.fields.srvOpts, WithNGT(ngt), WithErrGroup(eg))...) + if err != nil { + tt.Errorf("failed to init server, error= %v", err) + } + + if test.beforeFunc != nil { + test.beforeFunc(tt, ctx, s, ngt, test) + } + + gotRes, err := s.CreateAndSaveIndex(ctx, test.args.c) + if err := checkFunc(test, ctx, s, ngt, test.want, gotRes, err); err != nil { tt.Errorf("error = %v", err) } }) From 73684665355aedc69e52c841e72d39920a745577 Mon Sep 17 00:00:00 2001 From: kevindiu Date: Fri, 14 Oct 2022 17:32:55 +0900 Subject: [PATCH 5/7] fix comment Signed-off-by: kevindiu --- pkg/agent/core/ngt/handler/grpc/index_test.go | 201 ++++++++++-------- 1 file changed, 113 insertions(+), 88 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index e728227890..30ee8514c9 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1187,10 +1187,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { tests := []test{ func() test { insertCnt := 1 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } + var ir *payload.Insert_MultiRequest return test{ name: "Equivalence Class Testing case 1.1: success to create and save 1 uncommitted insert index", @@ -1207,6 +1204,10 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) } @@ -1224,10 +1225,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } + var ir *payload.Insert_MultiRequest return test{ name: "Equivalence Class Testing case 1.2: success to create and save 100 uncommitted insert index", @@ -1244,6 +1242,10 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) } @@ -1261,11 +1263,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } - removeID := ir.GetRequests()[0].GetVector().GetId() + var ir *payload.Insert_MultiRequest return test{ name: "Equivalence Class Testing case 2.1: success to create and save 1 uncommitted delete index", @@ -1282,6 +1280,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } + // insert 100 request if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) @@ -1295,7 +1298,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { // delete 1 request if _, err := s.Remove(ctx, &payload.Remove_Request{ Id: &payload.Object_ID{ - Id: removeID, + Id: ir.GetRequests()[0].GetVector().GetId(), }, }); err != nil { t.Error(err) @@ -1316,20 +1319,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 200 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } - - // remove requests - rr := make([]*payload.Remove_Request, 100) - for i := 0; i < 100; i++ { - rr[i] = &payload.Remove_Request{ - Id: &payload.Object_ID{ - Id: ir.GetRequests()[i].GetVector().GetId(), - }, - } - } + var ir *payload.Insert_MultiRequest return test{ name: "Equivalence Class Testing case 2.2: success to create and save 100 uncommitted delete index", @@ -1346,6 +1336,21 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } + + // remove requests + rr := make([]*payload.Remove_Request, 100) + for i := 0; i < 100; i++ { + rr[i] = &payload.Remove_Request{ + Id: &payload.Object_ID{ + Id: ir.GetRequests()[i].GetVector().GetId(), + }, + } + } + // insert 200 request if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) @@ -1378,17 +1383,8 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 1 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } - - updateID := ir.GetRequests()[0].GetVector().GetId() - updateVecs, err := vector.GenF32Vec(vector.Gaussian, 1, dim) - if err != nil { - t.Error(err) - } - updateVec := updateVecs[0] + var ir *payload.Insert_MultiRequest + var updateVec []float32 // the updated vector return test{ name: "Equivalence Class Testing case 3.1: success to create and save 1 uncommitted update index", @@ -1405,6 +1401,18 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } + + updateID := ir.GetRequests()[0].GetVector().GetId() + updateVecs, err := vector.GenF32Vec(vector.Gaussian, 1, dim) + if err != nil { + t.Error(err) + } + updateVec = updateVecs[0] + // insert 1 request if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) @@ -1441,27 +1449,9 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } - - // generate another set of vectors for update - updateVecs, err := vector.GenF32Vec(vector.Gaussian, insertCnt, dim) - if err != nil { - t.Error(err) - } - - // generate update requests for insert + var ir *payload.Insert_MultiRequest + var updateVecs [][]float32 updateReqs := make([]*payload.Update_Request, insertCnt) - for i := range ir.GetRequests() { - updateReqs[i] = &payload.Update_Request{ - Vector: &payload.Object_Vector{ - Id: ir.GetRequests()[i].GetVector().GetId(), - Vector: updateVecs[i], - }, - } - } return test{ name: "Equivalence Class Testing case 3.2: success to create and save 100 uncommitted update index", @@ -1478,6 +1468,27 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } + + // generate another set of vectors for update + updateVecs, err = vector.GenF32Vec(vector.Gaussian, insertCnt, dim) + if err != nil { + t.Error(err) + } + + // generate update requests for insert + for i := range ir.GetRequests() { + updateReqs[i] = &payload.Update_Request{ + Vector: &payload.Object_Vector{ + Id: ir.GetRequests()[i].GetVector().GetId(), + Vector: updateVecs[i], + }, + } + } + // insert 100 request if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) @@ -1571,10 +1582,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - ir, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig) - if err != nil { - t.Error(err) - } + var ir *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 1.1: success to create and save 100 index with in-memory mode", @@ -1593,6 +1601,10 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { t.Helper() + var err error + if ir, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, ir); err != nil { t.Error(err) } @@ -1618,16 +1630,14 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { } }(), func() test { - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, 1, dim, nil) - if err != nil { - t.Error(err) - } + insertCnt := 1 + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 2.1: success to create and save 1 inserted index with copy-on-write enabled", args: args{ c: &payload.Control_CreateIndexRequest{ - PoolSize: 1, + PoolSize: uint32(insertCnt), }, }, fields: fields{ @@ -1637,6 +1647,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.Insert(ctx, irs.Requests[0]); err != nil { t.Error(err) } @@ -1654,10 +1669,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) - if err != nil { - t.Error(err) - } + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 2.2: success to create and save 100 inserted index with copy-on-write enabled", @@ -1673,6 +1685,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, irs); err != nil { t.Error(err) } @@ -1690,10 +1707,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) - if err != nil { - t.Error(err) - } + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 3.1: success to create and save index with poolSize > uncommitted index count", @@ -1709,6 +1723,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, irs); err != nil { t.Error(err) } @@ -1726,10 +1745,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) - if err != nil { - t.Error(err) - } + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 3.2: success to create and save index with poolSize < uncommitted index count", @@ -1745,6 +1761,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, irs); err != nil { t.Error(err) } @@ -1762,10 +1783,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) - if err != nil { - t.Error(err) - } + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 3.3: success to create and save index with poolSize = uncommitted index count", @@ -1781,6 +1799,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, irs); err != nil { t.Error(err) } @@ -1798,10 +1821,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { }(), func() test { insertCnt := 100 - irs, err := request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, nil) - if err != nil { - t.Error(err) - } + var irs *payload.Insert_MultiRequest return test{ name: "Decision Table Testing case 3.4: success to create and save index with poolSize = 0", @@ -1817,6 +1837,11 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { indexPath: mkdirTemp(), }, beforeFunc: func(t *testing.T, ctx context.Context, s Server, n service.NGT, test test) { + t.Helper() + var err error + if irs, err = request.GenMultiInsertReq(request.Float, vector.Gaussian, insertCnt, dim, defaultInsertConfig); err != nil { + t.Error(err) + } if _, err := s.MultiInsert(ctx, irs); err != nil { t.Error(err) } From 757e24feeb3aab4fd0a2061276c722bc44b9d6bf Mon Sep 17 00:00:00 2001 From: Kevin Diu Date: Fri, 14 Oct 2022 17:33:48 +0900 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Kiichiro YUKAWA --- pkg/agent/core/ngt/handler/grpc/index_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index 30ee8514c9..bc0905e949 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1112,7 +1112,7 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { os.RemoveAll(test.fields.indexPath) } - // this function checks the backup file can be loaded and check if it contain the wantVecs indexes. + // this function checks the backup file can be loaded and check if it contains the wantVecs indexes. // it creates a new ngt and server instance with the backup file, and checks if we can retrieve all of wantVecs indexes // and check the total index count matches with wantVecs count. checkBackupFolder := func(fields fields, ctx context.Context, wantVecs []*payload.Insert_Request) error { From 26f604f1f5783e0a355b45ecb60a82d463ff2c35 Mon Sep 17 00:00:00 2001 From: kevindiu Date: Mon, 17 Oct 2022 12:05:20 +0900 Subject: [PATCH 7/7] fix format Signed-off-by: kevindiu --- pkg/agent/core/ngt/handler/grpc/index_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/agent/core/ngt/handler/grpc/index_test.go b/pkg/agent/core/ngt/handler/grpc/index_test.go index bc0905e949..9587f8d0c1 100644 --- a/pkg/agent/core/ngt/handler/grpc/index_test.go +++ b/pkg/agent/core/ngt/handler/grpc/index_test.go @@ -1879,9 +1879,12 @@ func Test_server_CreateAndSaveIndex(t *testing.T) { } eg, _ := errgroup.New(ctx) - ngt, err := service.New(test.fields.svcCfg, append(test.fields.svcOpts, - service.WithErrGroup(eg), - service.WithIndexPath(test.fields.indexPath))...) + ngt, err := service.New( + test.fields.svcCfg, + append(test.fields.svcOpts, + service.WithErrGroup(eg), + service.WithIndexPath(test.fields.indexPath), + )...) if err != nil { tt.Errorf("failed to init ngt service, error = %v", err) }