How to use Upsert method of config Package

Best Testkube code snippet using config.Upsert

upsert_test.go

Source:upsert_test.go Github

copy

Full Screen

...29 "github.com/vdaas/vald/internal/test/data/request"30 "github.com/vdaas/vald/internal/test/data/vector"31 "github.com/vdaas/vald/pkg/agent/core/ngt/service"32)33func Test_server_Upsert(t *testing.T) {34 t.Parallel()35 // optIdx is used for additional vector before upsert test.36 type optIdx struct {37 id string38 vec []float3239 }40 type args struct {41 optIdx optIdx42 req *payload.Upsert_Request43 }44 type want struct {45 code codes.Code46 wantUUID string47 }48 type test struct {49 name string50 args args51 want want52 checkFunc func(want, *payload.Object_Location, error) error53 beforeFunc func(context.Context, optIdx) (Server, error)54 afterFunc func()55 }56 defaultCheckFunc := func(w want, gotRes *payload.Object_Location, err error) error {57 if err != nil {58 st, ok := status.FromError(err)59 if !ok {60 errors.Errorf("got error cannot convert to Status: \"%#v\"", err)61 }62 if st.Code() != w.code {63 return errors.Errorf("got code: \"%#v\",\n\t\t\t\twant code: \"%#v\"", st.Code(), w.code)64 }65 } else {66 if uuid := gotRes.GetUuid(); w.wantUUID != uuid {67 return errors.Errorf("got uuid: \"%#v\",\n\t\t\t\twant uuid: \"%#v\"", uuid, w.wantUUID)68 }69 }70 return nil71 }72 const (73 defaultInsertNum = 100074 dimension = 12875 )76 utf8Str := "こんにちは"77 eucjpStr, err := conv.Utf8ToEucjp(utf8Str)78 if err != nil {79 t.Error(err)80 }81 sjisStr, err := conv.Utf8ToSjis(utf8Str)82 if err != nil {83 t.Error(err)84 }85 defaultUpsertConfig := &payload.Upsert_Config{86 SkipStrictExistCheck: true,87 }88 defaultInsertConfig := &payload.Insert_Config{89 SkipStrictExistCheck: true,90 }91 defaultBeforeFunc := func(objectType string, insertNum int) func(context.Context, optIdx) (Server, error) {92 cfg := &config.NGT{93 Dimension: dimension,94 DistanceType: ngt.L2.String(),95 ObjectType: objectType,96 CreationEdgeSize: 60,97 SearchEdgeSize: 20,98 KVSDB: &config.KVSDB{99 Concurrency: 10,100 },101 VQueue: &config.VQueue{102 InsertBufferPoolSize: 1000,103 DeleteBufferPoolSize: 1000,104 },105 }106 return func(ctx context.Context, opt optIdx) (Server, error) {107 var overwriteID []string108 if opt.id != "" {109 overwriteID = []string{110 opt.id,111 }112 }113 var overwriteVec [][]float32114 if opt.vec != nil {115 overwriteVec = [][]float32{116 opt.vec,117 }118 }119 return buildIndex(ctx, request.Float, vector.Gaussian, insertNum, defaultInsertConfig, cfg, nil, overwriteID, overwriteVec)120 }121 }122 /*123 Upsert test cases (only test float32 unless otherwise specified):124 - Equivalence Class Testing ( 1000 vectors inserted before an upsert )125 - case 1.1: success upsert with new ID126 - case 1.2: success upsert with existent ID127 - case 2.1: fail upsert with one different dimension vector (type: uint8)128 - case 2.2: fail upsert with one different dimension vector (type: float32)129 - Boundary Value Testing ( 1000 vectors inserted before an upsert if not specified )130 - case 1.1: fail upsert with "" as ID131 - case 1.2: fail upsert to empty index with "" as ID132 - case 2.1: success upsert with ^@ as duplicated ID133 - case 2.2: success upsert with ^@ as new ID134 - case 2.3: success upsert to empty index with ^@ as new ID135 - case 2.4: success upsert with ^I as duplicated ID136 - case 2.5: success upsert with ^I as new ID137 - case 2.6: success upsert to empty index with ^I as new ID138 - case 2.7: success upsert with ^J as duplicated ID139 - case 2.8: success upsert with ^J as new ID140 - case 2.9: success upsert to empty index with ^J as new ID141 - case 2.10: success upsert with ^M as duplicated ID142 - case 2.11: success upsert with ^M as new ID143 - case 2.12: success upsert to empty index with ^M as new ID144 - case 2.13: success upsert with ^[ as duplicated ID145 - case 2.14: success upsert with ^[ as new ID146 - case 2.15: success upsert to empty index with ^[ as new ID147 - case 2.16: success upsert with ^? as duplicated ID148 - case 2.17: success upsert with ^? as new ID149 - case 2.18: success upsert to empty index with ^? as new ID150 - case 3.1: success upsert with utf-8 ID from utf-8 index151 - case 3.2: success upsert with utf-8 ID from s-jis index152 - case 3.3: success upsert with utf-8 ID from euc-jp index153 - case 3.4: success upsert with s-jis ID from utf-8 index154 - case 3.5: success upsert with s-jis ID from s-jis index155 - case 3.6: success upsert with s-jis ID from euc-jp index156 - case 3.7: success upsert with euc-jp ID from utf-8 index157 - case 3.8: success upsert with euc-jp ID from s-jis index158 - case 3.9: success upsert with euc-jp ID from euc-jp index159 - case 4.1: success upsert with 😀 as duplicated ID160 - case 4.2: success upsert with 😀 as new ID161 - case 4.3: success upsert to empty index with 😀 as new ID162 - case 5.1: success upsert with one 0 value vector with duplicated ID (type: uint8)163 - case 5.2: success upsert with one 0 value vector with new ID (type: uint8)164 - case 5.3: success upsert to empty index with one 0 value vector with new ID (type: uint8)165 - case 5.4: success upsert with one +0 value vector with duplicated ID (type: float32)166 - case 5.5: success upsert with one +0 value vector with new ID (type: float32)167 - case 5.6: success upsert to empty index with one +0 value vector with new ID (type: float32)168 - case 5.7: success upsert with one -0 value vector with duplicated ID (type: float32)169 - case 5.8: success upsert with one -0 value vector with new ID (type: float32)170 - case 5.9: success upsert to empty index with one -0 value vector with new ID (type: float32)171 - case 6.1: success upsert with one min value vector with duplicated ID (type: uint8)172 - case 6.2: success upsert with one min value vector with new ID (type: uint8)173 - case 6.3: success upsert to empty index with one min value vector with new ID (type: uint8)174 - case 6.4: success upsert with one min value vector with duplicated ID (type: float32)175 - case 6.5: success upsert with one min value vector with new ID (type: float32)176 - case 6.6: success upsert to empty index with one min value vector with new ID (type: float32)177 - case 7.1: success upsert with one max value vector with duplicated ID (type: uint8)178 - case 7.2: success upsert with one max value vector with new ID (type: uint8)179 - case 7.3: success upsert to empty index with one max value vector with new ID (type: uint8)180 - case 7.4: success upsert with one max value vector with duplicated ID (type: float32)181 - case 7.5: success upsert with one max value vector (type: float32)182 - case 7.6: success upsert to empty index with one max value vector (type: float32)183 - case 8.1: success upsert with one NaN value vector with duplicated ID (type: float32) // NOTE: To fix it, it is necessary to check all of vector value184 - case 8.2: success upsert with one NaN value vector with new ID (type: float32) // NOTE: To fix it, it is necessary to check all of vector value185 - case 8.3: success upsert to empty index with one NaN value vector with new ID (type: float32) // NOTE: To fix it, it is necessary to check all of vector value186 - case 9.1: success upsert with one +inf value vector with duplicated ID (type: float32)187 - case 9.2: success upsert with one +inf value vector with new ID (type: float32)188 - case 9.3: success upsert to empty index with one +inf value vector with new ID (type: float32)189 - case 9.4: success upsert with one -inf value vector with duplicated ID (type: float32)190 - case 9.5: success upsert with one -inf value vector with new ID (type: float32)191 - case 9.6: success upsert to empty index with one -inf value vector with new ID (type: float32)192 - case 10.1: fail upsert with one nil vector193 - case 10.2: fail upsert to empty index with one nil vector194 - case 11.1: fail upsert with one empty vector195 - case 11.2: fail upsert to empty index with one empty vector196 - Decision Table Testing197 - case 1.1: fail upsert with one duplicated vector, duplicated ID and SkipStrictExistCheck is true198 - case 1.2: success upsert with one different vector, duplicated ID and SkipStrictExistsCheck is true199 - case 1.3: success upsert with one duplicated vector, different ID and SkipStrictExistCheck is true200 - case 1.4: success upsert with one different vector, different ID and SkipStrictExistsCheck is true201 - case 2.1: fail upsert with one duplicated vector, duplicated ID and SkipStrictExistCheck is false202 - case 2.2: success upsert with one different vector, duplicated ID and SkipStrictExistsCheck is false203 - case 2.3: success upsert with one duplicated vector, different ID and SkipStrictExistCheck is false204 - case 2.4: success upsert with one different vector, different ID and SkipStrictExistsCheck is false205 */206 tests := []test{207 {208 name: "Equivalent Class Testing case 1.1: success upsert with new ID",209 args: args{210 req: &payload.Upsert_Request{211 Vector: &payload.Object_Vector{212 Id: "test",213 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],214 },215 Config: defaultUpsertConfig,216 },217 },218 want: want{219 wantUUID: "test",220 },221 },222 {223 name: "Equivalent Class Testing case 1.2: success upsert with existent ID",224 args: args{225 optIdx: optIdx{226 id: "test",227 },228 req: &payload.Upsert_Request{229 Vector: &payload.Object_Vector{230 Id: "test",231 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],232 },233 Config: defaultUpsertConfig,234 },235 },236 want: want{237 wantUUID: "test",238 },239 },240 {241 name: "Equivalent Class Testing case 2.1: fail upsert with one different dimension vector (type: uint8)",242 args: args{243 optIdx: optIdx{244 id: "test",245 },246 req: &payload.Upsert_Request{247 Vector: &payload.Object_Vector{248 Id: "test",249 Vector: vector.ConvertVectorsUint8ToFloat32(vector.GaussianDistributedUint8VectorGenerator(1, dimension+1))[0],250 },251 Config: defaultUpsertConfig,252 },253 },254 want: want{255 code: codes.InvalidArgument,256 },257 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), defaultInsertNum),258 },259 {260 name: "Equivalent Class Testing case 2.2: fail upsert with one different dimension vector (type: float32)",261 args: args{262 optIdx: optIdx{263 id: "test",264 },265 req: &payload.Upsert_Request{266 Vector: &payload.Object_Vector{267 Id: "test",268 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension+1)[0],269 },270 Config: defaultUpsertConfig,271 },272 },273 want: want{274 code: codes.InvalidArgument,275 },276 },277 {278 name: "Boundary Value Testing case 1.1: fail upsert with \"\" as ID",279 args: args{280 req: &payload.Upsert_Request{281 Vector: &payload.Object_Vector{282 Id: "",283 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],284 },285 Config: defaultUpsertConfig,286 },287 },288 want: want{289 code: codes.InvalidArgument,290 },291 },292 {293 name: "Boundary Value Testing case 1.2: fail upsert to empty index with \"\" as ID",294 args: args{295 req: &payload.Upsert_Request{296 Vector: &payload.Object_Vector{297 Id: "",298 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],299 },300 Config: defaultUpsertConfig,301 },302 },303 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),304 want: want{305 code: codes.InvalidArgument,306 },307 },308 {309 name: "Boundary Value Testing case 2.1: success upsert with ^@ as duplicated ID",310 args: args{311 optIdx: optIdx{312 id: string([]byte{0}),313 },314 req: &payload.Upsert_Request{315 Vector: &payload.Object_Vector{316 Id: string([]byte{0}),317 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],318 },319 Config: defaultUpsertConfig,320 },321 },322 want: want{323 wantUUID: string([]byte{0}),324 },325 },326 {327 name: "Boundary Value Testing case 2.2: success upsert with ^@ as new ID",328 args: args{329 req: &payload.Upsert_Request{330 Vector: &payload.Object_Vector{331 Id: string([]byte{0}),332 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],333 },334 Config: defaultUpsertConfig,335 },336 },337 want: want{338 wantUUID: string([]byte{0}),339 },340 },341 {342 name: "Boundary Value Testing case 2.3: success upsert to empty index with ^@ as new ID",343 args: args{344 req: &payload.Upsert_Request{345 Vector: &payload.Object_Vector{346 Id: string([]byte{0}),347 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],348 },349 Config: defaultUpsertConfig,350 },351 },352 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),353 want: want{354 wantUUID: string([]byte{0}),355 },356 },357 {358 name: "Boundary Value Testing case 2.4: success upsert with ^I as duplicated ID",359 args: args{360 optIdx: optIdx{361 id: "\t",362 },363 req: &payload.Upsert_Request{364 Vector: &payload.Object_Vector{365 Id: "\t",366 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],367 },368 Config: defaultUpsertConfig,369 },370 },371 want: want{372 wantUUID: "\t",373 },374 },375 {376 name: "Boundary Value Testing case 2.5: success upsert with ^I as new ID",377 args: args{378 req: &payload.Upsert_Request{379 Vector: &payload.Object_Vector{380 Id: "\t",381 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],382 },383 Config: defaultUpsertConfig,384 },385 },386 want: want{387 wantUUID: "\t",388 },389 },390 {391 name: "Boundary Value Testing case 2.6: success upsert to empty index with ^I as new ID",392 args: args{393 req: &payload.Upsert_Request{394 Vector: &payload.Object_Vector{395 Id: "\t",396 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],397 },398 Config: defaultUpsertConfig,399 },400 },401 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),402 want: want{403 wantUUID: "\t",404 },405 },406 {407 name: "Boundary Value Testing case 2.7: success upsert with ^J as duplicated ID",408 args: args{409 optIdx: optIdx{410 id: "\n",411 },412 req: &payload.Upsert_Request{413 Vector: &payload.Object_Vector{414 Id: "\n",415 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],416 },417 Config: defaultUpsertConfig,418 },419 },420 want: want{421 wantUUID: "\n",422 },423 },424 {425 name: "Boundary Value Testing case 2.8: success upsert with ^J as new ID",426 args: args{427 req: &payload.Upsert_Request{428 Vector: &payload.Object_Vector{429 Id: "\n",430 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],431 },432 Config: defaultUpsertConfig,433 },434 },435 want: want{436 wantUUID: "\n",437 },438 },439 {440 name: "Boundary Value Testing case 2.9: success upsert to empty index with ^J as new ID",441 args: args{442 req: &payload.Upsert_Request{443 Vector: &payload.Object_Vector{444 Id: "\n",445 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],446 },447 Config: defaultUpsertConfig,448 },449 },450 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),451 want: want{452 wantUUID: "\n",453 },454 },455 {456 name: "Boundary Value Testing case 2.10: success upsert with ^M as duplicated ID",457 args: args{458 optIdx: optIdx{459 id: "\r",460 },461 req: &payload.Upsert_Request{462 Vector: &payload.Object_Vector{463 Id: "\r",464 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],465 },466 Config: defaultUpsertConfig,467 },468 },469 want: want{470 wantUUID: "\r",471 },472 },473 {474 name: "Boundary Value Testing case 2.11: success upsert with ^M as new ID",475 args: args{476 req: &payload.Upsert_Request{477 Vector: &payload.Object_Vector{478 Id: "\r",479 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],480 },481 Config: defaultUpsertConfig,482 },483 },484 want: want{485 wantUUID: "\r",486 },487 },488 {489 name: "Boundary Value Testing case 2.12: success upsert to empty index with ^M as new ID",490 args: args{491 req: &payload.Upsert_Request{492 Vector: &payload.Object_Vector{493 Id: "\r",494 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],495 },496 Config: defaultUpsertConfig,497 },498 },499 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),500 want: want{501 wantUUID: "\r",502 },503 },504 {505 name: "Boundary Value Testing case 2.13: success upsert with ^[ as duplicated ID",506 args: args{507 optIdx: optIdx{508 id: string([]byte{27}),509 },510 req: &payload.Upsert_Request{511 Vector: &payload.Object_Vector{512 Id: string([]byte{27}),513 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],514 },515 Config: defaultUpsertConfig,516 },517 },518 want: want{519 wantUUID: string([]byte{27}),520 },521 },522 {523 name: "Boundary Value Testing case 2.14: success upsert with ^[ as new ID",524 args: args{525 req: &payload.Upsert_Request{526 Vector: &payload.Object_Vector{527 Id: string([]byte{27}),528 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],529 },530 Config: defaultUpsertConfig,531 },532 },533 want: want{534 wantUUID: string([]byte{27}),535 },536 },537 {538 name: "Boundary Value Testing case 2.15: success upsert to empty index with ^[ as new ID",539 args: args{540 req: &payload.Upsert_Request{541 Vector: &payload.Object_Vector{542 Id: string([]byte{27}),543 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],544 },545 Config: defaultUpsertConfig,546 },547 },548 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),549 want: want{550 wantUUID: string([]byte{27}),551 },552 },553 {554 name: "Boundary Value Testing case 2.16: success upsert with ^? as duplicated ID",555 args: args{556 optIdx: optIdx{557 id: string([]byte{127}),558 },559 req: &payload.Upsert_Request{560 Vector: &payload.Object_Vector{561 Id: string([]byte{127}),562 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],563 },564 Config: defaultUpsertConfig,565 },566 },567 want: want{568 wantUUID: string([]byte{127}),569 },570 },571 {572 name: "Boundary Value Testing case 2.17: success upsert with ^? as new ID",573 args: args{574 req: &payload.Upsert_Request{575 Vector: &payload.Object_Vector{576 Id: string([]byte{127}),577 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],578 },579 Config: defaultUpsertConfig,580 },581 },582 want: want{583 wantUUID: string([]byte{127}),584 },585 },586 {587 name: "Boundary Value Testing case 2.18: success upsert to empty index with ^? as new ID",588 args: args{589 req: &payload.Upsert_Request{590 Vector: &payload.Object_Vector{591 Id: string([]byte{127}),592 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],593 },594 Config: defaultUpsertConfig,595 },596 },597 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),598 want: want{599 wantUUID: string([]byte{127}),600 },601 },602 {603 name: "Boundary Value Testing case 3.1: success upsert with utf-8 ID from utf-8 index",604 args: args{605 optIdx: optIdx{606 id: utf8Str,607 },608 req: &payload.Upsert_Request{609 Vector: &payload.Object_Vector{610 Id: utf8Str,611 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],612 },613 Config: defaultUpsertConfig,614 },615 },616 want: want{617 wantUUID: utf8Str,618 },619 },620 {621 name: "Boundary Value Testing case 3.2: success upsert with utf-8 ID from s-jis index",622 args: args{623 optIdx: optIdx{624 id: sjisStr,625 },626 req: &payload.Upsert_Request{627 Vector: &payload.Object_Vector{628 Id: utf8Str,629 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],630 },631 Config: defaultUpsertConfig,632 },633 },634 want: want{635 wantUUID: utf8Str,636 },637 },638 {639 name: "Boundary Value Testing case 3.3: success upsert with utf-8 ID from euc-jp index",640 args: args{641 optIdx: optIdx{642 id: eucjpStr,643 },644 req: &payload.Upsert_Request{645 Vector: &payload.Object_Vector{646 Id: utf8Str,647 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],648 },649 Config: defaultUpsertConfig,650 },651 },652 want: want{653 wantUUID: utf8Str,654 },655 },656 {657 name: "Boundary Value Testing case 3.4: success upsert with s-jis ID from utf-8 index",658 args: args{659 optIdx: optIdx{660 id: utf8Str,661 },662 req: &payload.Upsert_Request{663 Vector: &payload.Object_Vector{664 Id: sjisStr,665 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],666 },667 Config: defaultUpsertConfig,668 },669 },670 want: want{671 wantUUID: sjisStr,672 },673 },674 {675 name: "Boundary Value Testing case 3.5: success upsert with s-jis ID from s-jis index",676 args: args{677 optIdx: optIdx{678 id: sjisStr,679 },680 req: &payload.Upsert_Request{681 Vector: &payload.Object_Vector{682 Id: sjisStr,683 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],684 },685 Config: defaultUpsertConfig,686 },687 },688 want: want{689 wantUUID: sjisStr,690 },691 },692 {693 name: "Boundary Value Testing case 3.6: success upsert with s-jis ID from euc-jp index",694 args: args{695 optIdx: optIdx{696 id: eucjpStr,697 },698 req: &payload.Upsert_Request{699 Vector: &payload.Object_Vector{700 Id: sjisStr,701 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],702 },703 Config: defaultUpsertConfig,704 },705 },706 want: want{707 wantUUID: sjisStr,708 },709 },710 {711 name: "Boundary Value Testing case 3.7: success upsert with euc-jp ID from utf-8 index",712 args: args{713 optIdx: optIdx{714 id: utf8Str,715 },716 req: &payload.Upsert_Request{717 Vector: &payload.Object_Vector{718 Id: eucjpStr,719 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],720 },721 Config: defaultUpsertConfig,722 },723 },724 want: want{725 wantUUID: eucjpStr,726 },727 },728 {729 name: "Boundary Value Testing case 3.8: success upsert with euc-jp ID from s-jis index",730 args: args{731 optIdx: optIdx{732 id: sjisStr,733 },734 req: &payload.Upsert_Request{735 Vector: &payload.Object_Vector{736 Id: eucjpStr,737 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],738 },739 Config: defaultUpsertConfig,740 },741 },742 want: want{743 wantUUID: eucjpStr,744 },745 },746 {747 name: "Boundary Value Testing case 3.9: success upsert with euc-jp ID from euc-jp index",748 args: args{749 optIdx: optIdx{750 id: eucjpStr,751 },752 req: &payload.Upsert_Request{753 Vector: &payload.Object_Vector{754 Id: eucjpStr,755 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],756 },757 Config: defaultUpsertConfig,758 },759 },760 want: want{761 wantUUID: eucjpStr,762 },763 },764 {765 name: "Boundary Value Testing case 4.1: success upsert with 😀 as duplicated ID",766 args: args{767 optIdx: optIdx{768 id: "😀",769 },770 req: &payload.Upsert_Request{771 Vector: &payload.Object_Vector{772 Id: "😀",773 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],774 },775 Config: defaultUpsertConfig,776 },777 },778 want: want{779 wantUUID: "😀",780 },781 },782 {783 name: "Boundary Value Testing case 4.2: success upsert with 😀 as new ID",784 args: args{785 req: &payload.Upsert_Request{786 Vector: &payload.Object_Vector{787 Id: "😀",788 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],789 },790 Config: defaultUpsertConfig,791 },792 },793 want: want{794 wantUUID: "😀",795 },796 },797 {798 name: "Boundary Value Testing case 4.3: success upsert to empty index with 😀 as new ID",799 args: args{800 req: &payload.Upsert_Request{801 Vector: &payload.Object_Vector{802 Id: "😀",803 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],804 },805 Config: defaultUpsertConfig,806 },807 },808 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),809 want: want{810 wantUUID: "😀",811 },812 },813 {814 name: "Boundary Value Testing case 5.1: success upsert with one 0 value vector with duplicated ID (type: uint8)",815 args: args{816 optIdx: optIdx{817 id: "test",818 },819 req: &payload.Upsert_Request{820 Vector: &payload.Object_Vector{821 Id: "test",822 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),823 },824 Config: defaultUpsertConfig,825 },826 },827 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),828 want: want{829 wantUUID: "test",830 },831 },832 {833 name: "Boundary Value Testing case 5.2: success upsert with one 0 value vector with new ID (type: uint8)",834 args: args{835 req: &payload.Upsert_Request{836 Vector: &payload.Object_Vector{837 Id: "test",838 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),839 },840 Config: defaultUpsertConfig,841 },842 },843 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),844 want: want{845 wantUUID: "test",846 },847 },848 {849 name: "Boundary Value Testing case 5.3: success upsert to empty index with one 0 value vector with new ID (type: uint8)",850 args: args{851 req: &payload.Upsert_Request{852 Vector: &payload.Object_Vector{853 Id: "test",854 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),855 },856 Config: defaultUpsertConfig,857 },858 },859 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 0),860 want: want{861 wantUUID: "test",862 },863 },864 {865 name: "Boundary Value Testing case 5.4: success upsert with one +0 value vector with duplicated ID (type: float32)",866 args: args{867 optIdx: optIdx{868 id: "test",869 },870 req: &payload.Upsert_Request{871 Vector: &payload.Object_Vector{872 Id: "test",873 Vector: vector.GenSameValueVec(dimension, 0),874 },875 Config: defaultUpsertConfig,876 },877 },878 want: want{879 wantUUID: "test",880 },881 },882 {883 name: "Boundary Value Testing case 5.5: success upsert with one +0 value vector with new ID (type: float32)",884 args: args{885 req: &payload.Upsert_Request{886 Vector: &payload.Object_Vector{887 Id: "test",888 Vector: vector.GenSameValueVec(dimension, 0),889 },890 Config: defaultUpsertConfig,891 },892 },893 want: want{894 wantUUID: "test",895 },896 },897 {898 name: "Boundary Value Testing case 5.6: success upsert to empty index with one +0 value vector with new ID (type: float32)",899 args: args{900 req: &payload.Upsert_Request{901 Vector: &payload.Object_Vector{902 Id: "test",903 Vector: vector.GenSameValueVec(dimension, 0),904 },905 Config: defaultUpsertConfig,906 },907 },908 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),909 want: want{910 wantUUID: "test",911 },912 },913 {914 name: "Boundary Value Testing case 5.7: success upsert with one -0 value vector with duplicated ID (type: float32)",915 args: args{916 optIdx: optIdx{917 id: "test",918 },919 req: &payload.Upsert_Request{920 Vector: &payload.Object_Vector{921 Id: "test",922 Vector: vector.GenSameValueVec(dimension, float32(math.Copysign(0, -1.0))),923 },924 Config: defaultUpsertConfig,925 },926 },927 want: want{928 wantUUID: "test",929 },930 },931 {932 name: "Boundary Value Testing case 5.8: success upsert with one -0 value vector with new ID (type: float32)",933 args: args{934 req: &payload.Upsert_Request{935 Vector: &payload.Object_Vector{936 Id: "test",937 Vector: vector.GenSameValueVec(dimension, float32(math.Copysign(0, -1.0))),938 },939 Config: defaultUpsertConfig,940 },941 },942 want: want{943 wantUUID: "test",944 },945 },946 {947 name: "Boundary Value Testing case 5.9: success upsert to empty index with one -0 value vector with new ID (type: float32)",948 args: args{949 req: &payload.Upsert_Request{950 Vector: &payload.Object_Vector{951 Id: "test",952 Vector: vector.GenSameValueVec(dimension, float32(math.Copysign(0, -1.0))),953 },954 Config: defaultUpsertConfig,955 },956 },957 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),958 want: want{959 wantUUID: "test",960 },961 },962 {963 name: "Boundary Value Testing case 6.1: success upsert with one min value vector with duplicated ID (type: uint8)",964 args: args{965 optIdx: optIdx{966 id: "test",967 },968 req: &payload.Upsert_Request{969 Vector: &payload.Object_Vector{970 Id: "test",971 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),972 },973 Config: defaultUpsertConfig,974 },975 },976 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),977 want: want{978 wantUUID: "test",979 },980 },981 {982 name: "Boundary Value Testing case 6.2: success upsert with one min value vector with new ID (type: uint8)",983 args: args{984 req: &payload.Upsert_Request{985 Vector: &payload.Object_Vector{986 Id: "test",987 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),988 },989 Config: defaultUpsertConfig,990 },991 },992 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),993 want: want{994 wantUUID: "test",995 },996 },997 {998 name: "Boundary Value Testing case 6.3: success upsert to empty index with one min value vector with new ID (type: uint8)",999 args: args{1000 req: &payload.Upsert_Request{1001 Vector: &payload.Object_Vector{1002 Id: "test",1003 Vector: vector.GenSameValueVec(dimension, float32(uint8(0))),1004 },1005 Config: defaultUpsertConfig,1006 },1007 },1008 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 0),1009 want: want{1010 wantUUID: "test",1011 },1012 },1013 {1014 name: "Boundary Value Testing case 6.4: success upsert with one min value vector with duplicated ID (type: float32)",1015 args: args{1016 optIdx: optIdx{1017 id: "test",1018 },1019 req: &payload.Upsert_Request{1020 Vector: &payload.Object_Vector{1021 Id: "test",1022 Vector: vector.GenSameValueVec(dimension, -math.MaxFloat32),1023 },1024 Config: defaultUpsertConfig,1025 },1026 },1027 want: want{1028 wantUUID: "test",1029 },1030 },1031 {1032 name: "Boundary Value Testing case 6.5: success upsert with one min value vector with new ID (type: float32)",1033 args: args{1034 req: &payload.Upsert_Request{1035 Vector: &payload.Object_Vector{1036 Id: "test",1037 Vector: vector.GenSameValueVec(dimension, -math.MaxFloat32),1038 },1039 Config: defaultUpsertConfig,1040 },1041 },1042 want: want{1043 wantUUID: "test",1044 },1045 },1046 {1047 name: "Boundary Value Testing case 6.6: success upsert with one min value vector with new ID (type: float32)",1048 args: args{1049 req: &payload.Upsert_Request{1050 Vector: &payload.Object_Vector{1051 Id: "test",1052 Vector: vector.GenSameValueVec(dimension, -math.MaxFloat32),1053 },1054 Config: defaultUpsertConfig,1055 },1056 },1057 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1058 want: want{1059 wantUUID: "test",1060 },1061 },1062 {1063 name: "Boundary Value Testing case 7.1: success upsert with one max value vector with ID (type: uint8)",1064 args: args{1065 optIdx: optIdx{1066 id: "test",1067 },1068 req: &payload.Upsert_Request{1069 Vector: &payload.Object_Vector{1070 Id: "test",1071 Vector: vector.GenSameValueVec(dimension, float32(math.MaxUint8)),1072 },1073 Config: defaultUpsertConfig,1074 },1075 },1076 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),1077 want: want{1078 wantUUID: "test",1079 },1080 },1081 {1082 name: "Boundary Value Testing case 7.2: success upsert with one max value vector with new ID (type: uint8)",1083 args: args{1084 req: &payload.Upsert_Request{1085 Vector: &payload.Object_Vector{1086 Id: "test",1087 Vector: vector.GenSameValueVec(dimension, float32(math.MaxUint8)),1088 },1089 Config: defaultUpsertConfig,1090 },1091 },1092 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 1000),1093 want: want{1094 wantUUID: "test",1095 },1096 },1097 {1098 name: "Boundary Value Testing case 7.3: success upsert to empty index with one max value vector with new ID (type: uint8)",1099 args: args{1100 req: &payload.Upsert_Request{1101 Vector: &payload.Object_Vector{1102 Id: "test",1103 Vector: vector.GenSameValueVec(dimension, float32(math.MaxUint8)),1104 },1105 Config: defaultUpsertConfig,1106 },1107 },1108 beforeFunc: defaultBeforeFunc(ngt.Uint8.String(), 0),1109 want: want{1110 wantUUID: "test",1111 },1112 },1113 {1114 name: "Boundary Value Testing case 7.4: success upsert with one max value vector with duplicated ID (type: float32)",1115 args: args{1116 optIdx: optIdx{1117 id: "test",1118 },1119 req: &payload.Upsert_Request{1120 Vector: &payload.Object_Vector{1121 Id: "test",1122 Vector: vector.GenSameValueVec(dimension, math.MaxFloat32),1123 },1124 Config: defaultUpsertConfig,1125 },1126 },1127 want: want{1128 wantUUID: "test",1129 },1130 },1131 {1132 name: "Boundary Value Testing case 7.5: success upsert with one max value vector with new ID (type: float32)",1133 args: args{1134 req: &payload.Upsert_Request{1135 Vector: &payload.Object_Vector{1136 Id: "test",1137 Vector: vector.GenSameValueVec(dimension, math.MaxFloat32),1138 },1139 Config: defaultUpsertConfig,1140 },1141 },1142 want: want{1143 wantUUID: "test",1144 },1145 },1146 {1147 name: "Boundary Value Testing case 7.6: success upsert to empty index with one max value vector with new ID (type: float32)",1148 args: args{1149 req: &payload.Upsert_Request{1150 Vector: &payload.Object_Vector{1151 Id: "test",1152 Vector: vector.GenSameValueVec(dimension, math.MaxFloat32),1153 },1154 Config: defaultUpsertConfig,1155 },1156 },1157 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1158 want: want{1159 wantUUID: "test",1160 },1161 },1162 {1163 name: "Boundary Value Testing case 8.1: success upsert with one NaN value vector with duplicated ID (type: float32)",1164 args: args{1165 optIdx: optIdx{1166 id: "test",1167 },1168 req: &payload.Upsert_Request{1169 Vector: &payload.Object_Vector{1170 Id: "test",1171 Vector: vector.GenSameValueVec(dimension, float32(math.NaN())),1172 },1173 Config: defaultUpsertConfig,1174 },1175 },1176 want: want{1177 wantUUID: "test",1178 },1179 },1180 {1181 name: "Boundary Value Testing case 8.2: success upsert with one NaN value vector with new ID (type: float32)",1182 args: args{1183 req: &payload.Upsert_Request{1184 Vector: &payload.Object_Vector{1185 Id: "test",1186 Vector: vector.GenSameValueVec(dimension, float32(math.NaN())),1187 },1188 Config: defaultUpsertConfig,1189 },1190 },1191 want: want{1192 wantUUID: "test",1193 },1194 },1195 {1196 name: "Boundary Value Testing case 8.3: success upsert to empty index with one NaN value vector with new ID (type: float32)",1197 args: args{1198 req: &payload.Upsert_Request{1199 Vector: &payload.Object_Vector{1200 Id: "test",1201 Vector: vector.GenSameValueVec(dimension, float32(math.NaN())),1202 },1203 Config: defaultUpsertConfig,1204 },1205 },1206 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1207 want: want{1208 wantUUID: "test",1209 },1210 },1211 {1212 name: "Boundary Value Testing case 9.1: success upsert with one +inf value vector with duplicated ID (type: float32)",1213 args: args{1214 optIdx: optIdx{1215 id: "test",1216 },1217 req: &payload.Upsert_Request{1218 Vector: &payload.Object_Vector{1219 Id: "test",1220 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(1.0))),1221 },1222 Config: defaultUpsertConfig,1223 },1224 },1225 want: want{1226 wantUUID: "test",1227 },1228 },1229 {1230 name: "Boundary Value Testing case 9.2: success upsert with one +inf value vector with new ID (type: float32)",1231 args: args{1232 req: &payload.Upsert_Request{1233 Vector: &payload.Object_Vector{1234 Id: "test",1235 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(1.0))),1236 },1237 Config: defaultUpsertConfig,1238 },1239 },1240 want: want{1241 wantUUID: "test",1242 },1243 },1244 {1245 name: "Boundary Value Testing case 9.3: success upsert to empty index with one +inf value vector with new ID (type: float32)",1246 args: args{1247 req: &payload.Upsert_Request{1248 Vector: &payload.Object_Vector{1249 Id: "test",1250 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(1.0))),1251 },1252 Config: defaultUpsertConfig,1253 },1254 },1255 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1256 want: want{1257 wantUUID: "test",1258 },1259 },1260 {1261 name: "Boundary Value Testing case 9.4: success upsert with one -inf value vector with duplicated ID (type: float32)",1262 args: args{1263 optIdx: optIdx{1264 id: "test",1265 },1266 req: &payload.Upsert_Request{1267 Vector: &payload.Object_Vector{1268 Id: "test",1269 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(-1.0))),1270 },1271 Config: defaultUpsertConfig,1272 },1273 },1274 want: want{1275 wantUUID: "test",1276 },1277 },1278 {1279 name: "Boundary Value Testing case 9.5: success upsert with one -inf value vector with new ID (type: float32)",1280 args: args{1281 req: &payload.Upsert_Request{1282 Vector: &payload.Object_Vector{1283 Id: "test",1284 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(-1.0))),1285 },1286 Config: defaultUpsertConfig,1287 },1288 },1289 want: want{1290 wantUUID: "test",1291 },1292 },1293 {1294 name: "Boundary Value Testing case 9.6: success upsert to empty index with one -inf value vector with new ID (type: float32)",1295 args: args{1296 req: &payload.Upsert_Request{1297 Vector: &payload.Object_Vector{1298 Id: "test",1299 Vector: vector.GenSameValueVec(dimension, float32(math.Inf(-1.0))),1300 },1301 Config: defaultUpsertConfig,1302 },1303 },1304 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1305 want: want{1306 wantUUID: "test",1307 },1308 },1309 {1310 name: "Boundary Value Testing case 10.1: fail upsert with one nil vector",1311 args: args{1312 optIdx: optIdx{1313 id: "test",1314 },1315 req: &payload.Upsert_Request{1316 Vector: &payload.Object_Vector{1317 Id: "test",1318 Vector: nil,1319 },1320 Config: defaultUpsertConfig,1321 },1322 },1323 want: want{1324 code: codes.InvalidArgument,1325 },1326 },1327 {1328 name: "Boundary Value Testing case 10.2: fail upsert to empty with one nil vector",1329 args: args{1330 req: &payload.Upsert_Request{1331 Vector: &payload.Object_Vector{1332 Id: "test",1333 Vector: nil,1334 },1335 Config: defaultUpsertConfig,1336 },1337 },1338 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1339 want: want{1340 code: codes.InvalidArgument,1341 },1342 },1343 {1344 name: "Boundary Value Testing case 11.1: fail upsert with one empty vector",1345 args: args{1346 optIdx: optIdx{1347 id: "test",1348 },1349 req: &payload.Upsert_Request{1350 Vector: &payload.Object_Vector{1351 Id: "test",1352 Vector: []float32{},1353 },1354 Config: defaultUpsertConfig,1355 },1356 },1357 want: want{1358 code: codes.InvalidArgument,1359 },1360 },1361 {1362 name: "Boundary Value Testing case 11.2: fail upsert to empty index with one empty vector",1363 args: args{1364 optIdx: optIdx{1365 id: "test",1366 },1367 req: &payload.Upsert_Request{1368 Vector: &payload.Object_Vector{1369 Id: "test",1370 Vector: []float32{},1371 },1372 Config: defaultUpsertConfig,1373 },1374 },1375 beforeFunc: defaultBeforeFunc(ngt.Float.String(), 0),1376 want: want{1377 code: codes.InvalidArgument,1378 },1379 },1380 {1381 name: "Decision Table Testing case 1.1: fail upsert with one duplicated vector, duplicated ID and SkipStrictExistCheck is true",1382 args: func() args {1383 vector := vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0]1384 return args{1385 optIdx: optIdx{1386 id: "test",1387 vec: vector,1388 },1389 req: &payload.Upsert_Request{1390 Vector: &payload.Object_Vector{1391 Id: "test",1392 Vector: vector,1393 },1394 Config: defaultUpsertConfig,1395 },1396 }1397 }(),1398 want: want{1399 code: codes.AlreadyExists,1400 },1401 },1402 {1403 name: "Decision Table Testing case 1.2: success upsert with one different vector, duplicated ID and SkipStrictExistCheck is true",1404 args: args{1405 optIdx: optIdx{1406 id: "test",1407 },1408 req: &payload.Upsert_Request{1409 Vector: &payload.Object_Vector{1410 Id: "test",1411 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],1412 },1413 Config: defaultUpsertConfig,1414 },1415 },1416 want: want{1417 wantUUID: "test",1418 },1419 },1420 {1421 name: "Decision Table Testing case 1.3: success upsert with one duplicated vector, different ID and SkipStrictExistCheck is true",1422 args: func() args {1423 vector := vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0]1424 return args{1425 optIdx: optIdx{1426 id: "test",1427 vec: vector,1428 },1429 req: &payload.Upsert_Request{1430 Vector: &payload.Object_Vector{1431 Id: "uuid-2", // the first uuid is overwritten, so use the second one1432 Vector: vector,1433 },1434 Config: defaultUpsertConfig,1435 },1436 }1437 }(),1438 want: want{1439 wantUUID: "uuid-2",1440 },1441 },1442 {1443 name: "Decision Table Testing case 1.4: success upsert with one different vector, different ID and SkipStrictExistCheck is true",1444 args: args{1445 req: &payload.Upsert_Request{1446 Vector: &payload.Object_Vector{1447 Id: "test",1448 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],1449 },1450 Config: defaultUpsertConfig,1451 },1452 },1453 want: want{1454 wantUUID: "test",1455 },1456 },1457 {1458 name: "Decision Table Testing case 2.1: fail upsert with one duplicated vector, duplicated ID and SkipStrictExistCheck is false",1459 args: func() args {1460 vector := vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0]1461 return args{1462 optIdx: optIdx{1463 id: "test",1464 vec: vector,1465 },1466 req: &payload.Upsert_Request{1467 Vector: &payload.Object_Vector{1468 Id: "test",1469 Vector: vector,1470 },1471 Config: &payload.Upsert_Config{1472 SkipStrictExistCheck: false,1473 },1474 },1475 }1476 }(),1477 want: want{1478 code: codes.AlreadyExists,1479 },1480 },1481 {1482 name: "Decision Table Testing case 2.2: success upsert with one duplicated vector, duplicated ID and SkipStrictExistCheck is false",1483 args: args{1484 optIdx: optIdx{1485 id: "test",1486 },1487 req: &payload.Upsert_Request{1488 Vector: &payload.Object_Vector{1489 Id: "test",1490 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],1491 },1492 Config: &payload.Upsert_Config{1493 SkipStrictExistCheck: false,1494 },1495 },1496 },1497 want: want{1498 wantUUID: "test",1499 },1500 },1501 {1502 name: "Decision Table Testing case 2.3: success upsert with one duplicated vector, different ID and SkipStrictExistCheck is false",1503 args: func() args {1504 vector := vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0]1505 return args{1506 optIdx: optIdx{1507 id: "test",1508 vec: vector,1509 },1510 req: &payload.Upsert_Request{1511 Vector: &payload.Object_Vector{1512 Id: "uuid-2", // the first uuid is overwritten, so use the second one1513 Vector: vector,1514 },1515 Config: &payload.Upsert_Config{1516 SkipStrictExistCheck: false,1517 },1518 },1519 }1520 }(),1521 want: want{1522 wantUUID: "uuid-2",1523 },1524 },1525 {1526 name: "Decision Table Testing case 2.4: success upsert with one different vector, different ID and SkipStrictExistCheck is false",1527 args: args{1528 req: &payload.Upsert_Request{1529 Vector: &payload.Object_Vector{1530 Id: "test",1531 Vector: vector.GaussianDistributedFloat32VectorGenerator(1, dimension)[0],1532 },1533 Config: &payload.Upsert_Config{1534 SkipStrictExistCheck: false,1535 },1536 },1537 },1538 want: want{1539 wantUUID: "test",1540 },1541 },1542 }1543 for _, tc := range tests {1544 test := tc1545 t.Run(test.name, func(tt *testing.T) {1546 tt.Parallel()1547 ctx, cancel := context.WithCancel(context.Background())1548 defer cancel()1549 if test.beforeFunc == nil {1550 test.beforeFunc = defaultBeforeFunc(ngt.Float.String(), defaultInsertNum)1551 }1552 s, err := test.beforeFunc(ctx, test.args.optIdx)1553 if err != nil {1554 tt.Errorf("error = %v", err)1555 }1556 if test.afterFunc != nil {1557 defer test.afterFunc()1558 }1559 checkFunc := test.checkFunc1560 if test.checkFunc == nil {1561 checkFunc = defaultCheckFunc1562 }1563 gotLoc, err := s.Upsert(ctx, test.args.req)1564 if err := checkFunc(test.want, gotLoc, err); err != nil {1565 tt.Errorf("error = %v", err)1566 }1567 })1568 }1569}1570func Test_server_StreamUpsert(t *testing.T) {1571 t.Parallel()1572 type args struct {1573 stream vald.Upsert_StreamUpsertServer1574 }1575 type fields struct {1576 name string1577 ip string1578 ngt service.NGT1579 eg errgroup.Group1580 streamConcurrency int1581 }1582 type want struct {1583 err error1584 }1585 type test struct {1586 name string1587 args args1588 fields fields1589 want want1590 checkFunc func(want, error) error1591 beforeFunc func(args)1592 afterFunc func(args)1593 }1594 defaultCheckFunc := func(w want, err error) error {1595 if !errors.Is(err, w.err) {1596 return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err)1597 }1598 return nil1599 }1600 tests := []test{1601 // TODO test cases1602 /*1603 {1604 name: "test_case_1",1605 args: args {1606 stream: nil,1607 },1608 fields: fields {1609 name: "",1610 ip: "",1611 ngt: nil,1612 eg: nil,1613 streamConcurrency: 0,1614 },1615 want: want{},1616 checkFunc: defaultCheckFunc,1617 },1618 */1619 // TODO test cases1620 /*1621 func() test {1622 return test {1623 name: "test_case_2",1624 args: args {1625 stream: nil,1626 },1627 fields: fields {1628 name: "",1629 ip: "",1630 ngt: nil,1631 eg: nil,1632 streamConcurrency: 0,1633 },1634 want: want{},1635 checkFunc: defaultCheckFunc,1636 }1637 }(),1638 */1639 }1640 for _, tc := range tests {1641 test := tc1642 t.Run(test.name, func(tt *testing.T) {1643 tt.Parallel()1644 if test.beforeFunc != nil {1645 test.beforeFunc(test.args)1646 }1647 if test.afterFunc != nil {1648 defer test.afterFunc(test.args)1649 }1650 checkFunc := test.checkFunc1651 if test.checkFunc == nil {1652 checkFunc = defaultCheckFunc1653 }1654 s := &server{1655 name: test.fields.name,1656 ip: test.fields.ip,1657 ngt: test.fields.ngt,1658 eg: test.fields.eg,1659 streamConcurrency: test.fields.streamConcurrency,1660 }1661 err := s.StreamUpsert(test.args.stream)1662 if err := checkFunc(test.want, err); err != nil {1663 tt.Errorf("error = %v", err)1664 }1665 })1666 }1667}1668func Test_server_MultiUpsert(t *testing.T) {1669 t.Parallel()1670 type args struct {1671 ctx context.Context1672 reqs *payload.Upsert_MultiRequest1673 }1674 type fields struct {1675 name string1676 ip string1677 ngt service.NGT1678 eg errgroup.Group1679 streamConcurrency int1680 }1681 type want struct {1682 wantRes *payload.Object_Locations1683 err error1684 }1685 type test struct {1686 name string1687 args args1688 fields fields1689 want want1690 checkFunc func(want, *payload.Object_Locations, error) error1691 beforeFunc func(args)1692 afterFunc func(args)1693 }1694 defaultCheckFunc := func(w want, gotRes *payload.Object_Locations, err error) error {1695 if !errors.Is(err, w.err) {1696 return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err)1697 }1698 if !reflect.DeepEqual(gotRes, w.wantRes) {1699 return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes)1700 }1701 return nil1702 }1703 tests := []test{1704 // TODO test cases1705 /*1706 {1707 name: "test_case_1",1708 args: args {1709 ctx: nil,1710 reqs: nil,1711 },1712 fields: fields {1713 name: "",1714 ip: "",1715 ngt: nil,1716 eg: nil,1717 streamConcurrency: 0,1718 },1719 want: want{},1720 checkFunc: defaultCheckFunc,1721 },1722 */1723 // TODO test cases1724 /*1725 func() test {1726 return test {1727 name: "test_case_2",1728 args: args {1729 ctx: nil,1730 reqs: nil,1731 },1732 fields: fields {1733 name: "",1734 ip: "",1735 ngt: nil,1736 eg: nil,1737 streamConcurrency: 0,1738 },1739 want: want{},1740 checkFunc: defaultCheckFunc,1741 }1742 }(),1743 */1744 }1745 for _, tc := range tests {1746 test := tc1747 t.Run(test.name, func(tt *testing.T) {1748 tt.Parallel()1749 if test.beforeFunc != nil {1750 test.beforeFunc(test.args)1751 }1752 if test.afterFunc != nil {1753 defer test.afterFunc(test.args)1754 }1755 checkFunc := test.checkFunc1756 if test.checkFunc == nil {1757 checkFunc = defaultCheckFunc1758 }1759 s := &server{1760 name: test.fields.name,1761 ip: test.fields.ip,1762 ngt: test.fields.ngt,1763 eg: test.fields.eg,1764 streamConcurrency: test.fields.streamConcurrency,1765 }1766 gotRes, err := s.MultiUpsert(test.args.ctx, test.args.reqs)1767 if err := checkFunc(test.want, gotRes, err); err != nil {1768 tt.Errorf("error = %v", err)1769 }1770 })1771 }1772}...

Full Screen

Full Screen

kvaccessor.go

Source:kvaccessor.go Github

copy

Full Screen

...100 return resp, nil101}102// UpdateSpanConfigEntries is part of the KVAccessor interface.103func (k *KVAccessor) UpdateSpanConfigEntries(104 ctx context.Context, toDelete []roachpb.Span, toUpsert []roachpb.SpanConfigEntry,105) error {106 if !enabledSetting.Get(&k.settings.SV) {107 return errDisabled108 }109 if err := validateUpdateArgs(toDelete, toUpsert); err != nil {110 return err111 }112 var deleteStmt string113 var deleteQueryArgs []interface{}114 if len(toDelete) > 0 {115 deleteStmt, deleteQueryArgs = k.constructDeleteStmtAndArgs(toDelete)116 }117 var upsertStmt, validationStmt string118 var upsertQueryArgs, validationQueryArgs []interface{}119 if len(toUpsert) > 0 {120 var err error121 upsertStmt, upsertQueryArgs, err = k.constructUpsertStmtAndArgs(toUpsert)122 if err != nil {123 return err124 }125 validationStmt, validationQueryArgs = k.constructValidationStmtAndArgs(toUpsert)126 }127 if err := k.db.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error {128 if len(toDelete) > 0 {129 n, err := k.ie.ExecEx(ctx, "delete-span-cfgs", txn,130 sessiondata.InternalExecutorOverride{User: security.RootUserName()},131 deleteStmt, deleteQueryArgs...,132 )133 if err != nil {134 return err135 }136 if n != len(toDelete) {137 return errors.AssertionFailedf("expected to delete %d row(s), deleted %d", len(toDelete), n)138 }139 }140 if len(toUpsert) == 0 {141 // Nothing left to do142 return nil143 }144 if n, err := k.ie.ExecEx(ctx, "upsert-span-cfgs", txn,145 sessiondata.InternalExecutorOverride{User: security.RootUserName()},146 upsertStmt, upsertQueryArgs...,147 ); err != nil {148 return err149 } else if n != len(toUpsert) {150 return errors.AssertionFailedf("expected to upsert %d row(s), upserted %d", len(toUpsert), n)151 }152 if datums, err := k.ie.QueryRowEx(ctx, "validate-span-cfgs", txn,153 sessiondata.InternalExecutorOverride{User: security.RootUserName()},154 validationStmt, validationQueryArgs...,155 ); err != nil {156 return err157 } else if valid := bool(tree.MustBeDBool(datums[0])); !valid {158 return errors.AssertionFailedf("expected to find single row containing upserted spans")159 }160 return nil161 }); err != nil {162 return err163 }164 return nil165}166// constructGetStmtAndArgs constructs the statement and query arguments needed167// to fetch span configs for the given spans.168func (k *KVAccessor) constructGetStmtAndArgs(spans []roachpb.Span) (string, []interface{}) {169 // We want to fetch the overlapping span configs for each requested span in170 // a single round trip and using only constrained index scans. For a single171 // requested span, we effectively want to query the following:172 //173 // -- to find spans overlapping with [$start, $end)174 // SELECT * FROM system.span_configurations175 // WHERE start_key < $end AND end_key > $start176 //177 // With the naive form above that translates to an unbounded index scan on178 // followed by a filter. We can do better by observing that start_key <179 // end_key, and that spans are non-overlapping.180 //181 // SELECT * FROM span_configurations182 // WHERE start_key >= $start AND start_key < $end183 // UNION ALL184 // SELECT * FROM (185 // SELECT * FROM span_configurations186 // WHERE start_key < $start ORDER BY start_key DESC LIMIT 1187 // ) WHERE end_key > $start;188 //189 // The idea is to first find all spans that start within the query span, and190 // then to include the span with the start key immediately preceding the191 // query start if it also overlaps with the query span (achieved by192 // the outer filter). We're intentional about not pushing the filter down into193 // the query -- we want to select using only the start_key index. Doing so194 // results in an unbounded index scan [ - $start) with the filter and limit195 // applied after.196 //197 // To batch multiple query spans into the same statement, we make use of198 // UNION ALL.199 //200 // ( ... statement above for 1st query span ...)201 // UNION ALL202 // ( ... statement above for 2nd query span ...)203 // UNION ALL204 // ...205 //206 var getStmtBuilder strings.Builder207 queryArgs := make([]interface{}, len(spans)*2)208 for i, sp := range spans {209 if i > 0 {210 getStmtBuilder.WriteString(`UNION ALL`)211 }212 startKeyIdx, endKeyIdx := i*2, (i*2)+1213 queryArgs[startKeyIdx] = sp.Key214 queryArgs[endKeyIdx] = sp.EndKey215 fmt.Fprintf(&getStmtBuilder, `216SELECT start_key, end_key, config FROM %[1]s217 WHERE start_key >= $%[2]d AND start_key < $%[3]d218UNION ALL219SELECT start_key, end_key, config FROM (220 SELECT start_key, end_key, config FROM %[1]s221 WHERE start_key < $%[2]d ORDER BY start_key DESC LIMIT 1222) WHERE end_key > $%[2]d223`,224 k.tableName, // [1]225 startKeyIdx+1, // [2] -- prepared statement placeholder (1-indexed)226 endKeyIdx+1, // [3] -- prepared statement placeholder (1-indexed)227 )228 }229 return getStmtBuilder.String(), queryArgs230}231// constructDeleteStmtAndArgs constructs the statement and query arguments232// needed to delete span configs for the given spans.233func (k *KVAccessor) constructDeleteStmtAndArgs(toDelete []roachpb.Span) (string, []interface{}) {234 // We're constructing a single delete statement to delete all requested235 // spans. It's of the form:236 //237 // DELETE FROM span_configurations WHERE (start_key, end_key) IN238 // (VALUES ( ... 1st span ... ), ( ... 2nd span ...), ... );239 //240 values := make([]string, len(toDelete))241 deleteQueryArgs := make([]interface{}, len(toDelete)*2)242 for i, sp := range toDelete {243 startKeyIdx, endKeyIdx := i*2, (i*2)+1244 deleteQueryArgs[startKeyIdx] = sp.Key245 deleteQueryArgs[endKeyIdx] = sp.EndKey246 values[i] = fmt.Sprintf("($%d::BYTES, $%d::BYTES)",247 startKeyIdx+1, endKeyIdx+1) // prepared statement placeholders (1-indexed)248 }249 deleteStmt := fmt.Sprintf(`DELETE FROM %[1]s WHERE (start_key, end_key) IN (VALUES %[2]s)`,250 k.tableName, strings.Join(values, ", "))251 return deleteStmt, deleteQueryArgs252}253// constructUpsertStmtAndArgs constructs the statement and query arguments254// needed to upsert the given span config entries.255func (k *KVAccessor) constructUpsertStmtAndArgs(256 toUpsert []roachpb.SpanConfigEntry,257) (string, []interface{}, error) {258 // We're constructing a single upsert statement to upsert all requested259 // spans. It's of the form:260 //261 // UPSERT INTO span_configurations (start_key, end_key, config)262 // VALUES ( ... 1st span ... ), ( ... 2nd span ...), ... ;263 //264 upsertValues := make([]string, len(toUpsert))265 upsertQueryArgs := make([]interface{}, len(toUpsert)*3)266 for i, entry := range toUpsert {267 marshaled, err := protoutil.Marshal(&entry.Config)268 if err != nil {269 return "", nil, err270 }271 startKeyIdx, endKeyIdx, configIdx := i*3, (i*3)+1, (i*3)+2272 upsertQueryArgs[startKeyIdx] = entry.Span.Key273 upsertQueryArgs[endKeyIdx] = entry.Span.EndKey274 upsertQueryArgs[configIdx] = marshaled275 upsertValues[i] = fmt.Sprintf("($%d::BYTES, $%d::BYTES, $%d::BYTES)",276 startKeyIdx+1, endKeyIdx+1, configIdx+1) // prepared statement placeholders (1-indexed)277 }278 upsertStmt := fmt.Sprintf(`UPSERT INTO %[1]s (start_key, end_key, config) VALUES %[2]s`,279 k.tableName, strings.Join(upsertValues, ", "))280 return upsertStmt, upsertQueryArgs, nil281}282// constructValidationStmtAndArgs constructs the statement and query arguments283// needed to validate that the spans being upserted don't violate table284// invariants (spans are non overlapping).285func (k *KVAccessor) constructValidationStmtAndArgs(286 toUpsert []roachpb.SpanConfigEntry,287) (string, []interface{}) {288 // We want to validate that upserting spans does not break the invariant289 // that spans in the table are non-overlapping. We only need to validate290 // the spans that are being upserted, and can use a query similar to291 // what we do in GetSpanConfigEntriesFor. For a single upserted span, we292 // want effectively validate using:293 //294 // SELECT count(*) = 1 FROM system.span_configurations295 // WHERE start_key < $end AND end_key > $start296 //297 // Applying the GetSpanConfigEntriesFor treatment, we can arrive at:298 //299 // SELECT count(*) = 1 FROM (300 // SELECT * FROM span_configurations301 // WHERE start_key >= 100 AND start_key < 105302 // UNION ALL303 // SELECT * FROM (304 // SELECT * FROM span_configurations305 // WHERE start_key < 100 ORDER BY start_key DESC LIMIT 1306 // ) WHERE end_key > 100307 // )308 //309 // To batch multiple query spans into the same statement, we make use of310 // ALL and UNION ALL.311 //312 // SELECT true = ALL(313 // ( ... validation statement for 1st query span ...),314 // UNION ALL315 // ( ... validation statement for 2nd query span ...),316 // ...317 // )318 //319 var validationInnerStmtBuilder strings.Builder320 validationQueryArgs := make([]interface{}, len(toUpsert)*2)321 for i, entry := range toUpsert {322 if i > 0 {323 validationInnerStmtBuilder.WriteString(`UNION ALL`)324 }325 startKeyIdx, endKeyIdx := i*2, (i*2)+1326 validationQueryArgs[startKeyIdx] = entry.Span.Key327 validationQueryArgs[endKeyIdx] = entry.Span.EndKey328 fmt.Fprintf(&validationInnerStmtBuilder, `329SELECT count(*) = 1 FROM (330 SELECT start_key, end_key, config FROM %[1]s331 WHERE start_key >= $%[2]d AND start_key < $%[3]d332 UNION ALL333 SELECT start_key, end_key, config FROM (334 SELECT start_key, end_key, config FROM %[1]s335 WHERE start_key < $%[2]d ORDER BY start_key DESC LIMIT 1336 ) WHERE end_key > $%[2]d337)338`,339 k.tableName, // [1]340 startKeyIdx+1, // [2] -- prepared statement placeholder (1-indexed)341 endKeyIdx+1, // [3] -- prepared statement placeholder (1-indexed)342 )343 }344 validationStmt := fmt.Sprintf("SELECT true = ALL(%s)", validationInnerStmtBuilder.String())345 return validationStmt, validationQueryArgs346}347// validateUpdateArgs returns an error the arguments to UpdateSpanConfigEntries348// are malformed. All spans included in the toDelete and toUpsert list are349// expected to be valid and to have non-empty end keys. Spans are also expected350// to be non-overlapping with other spans in the same list.351func validateUpdateArgs(toDelete []roachpb.Span, toUpsert []roachpb.SpanConfigEntry) error {352 spansToUpdate := func(ents []roachpb.SpanConfigEntry) []roachpb.Span {353 spans := make([]roachpb.Span, len(ents))354 for i, ent := range ents {355 spans[i] = ent.Span356 }357 return spans358 }(toUpsert)359 for _, list := range [][]roachpb.Span{toDelete, spansToUpdate} {360 if err := validateSpans(list); err != nil {361 return err362 }363 spans := make([]roachpb.Span, len(list))364 copy(spans, list)365 sort.Sort(roachpb.Spans(spans))366 for i := range spans {367 if i == 0 {368 continue369 }370 if spans[i].Overlaps(spans[i-1]) {371 return errors.AssertionFailedf("overlapping spans %s and %s in same list",372 spans[i-1], spans[i])...

Full Screen

Full Screen

scheduler.go

Source:scheduler.go Github

copy

Full Screen

...43}44const (45 // CleanJobScheduler ...46 CleanJobScheduler = "CleanJobScheduler"47 // UpsertWorkflowScheduler ...48 UpsertWorkflowScheduler = "UpsertWorkflowScheduler"49 // UpsertTestScheduler ...50 UpsertTestScheduler = "UpsertTestScheduler"51 // UpsertColliePipelineScheduler ...52 UpsertColliePipelineScheduler = "UpsertColliePipelineScheduler"53 //CleanProductScheduler ...54 CleanProductScheduler = "CleanProductScheduler"55 //InitBuildStatScheduler56 InitStatScheduler = "InitStatScheduler"57 //InitOperationStatScheduler58 InitOperationStatScheduler = "InitOperationStatScheduler"59 //InitPullSonarStatScheduler60 InitPullSonarStatScheduler = "InitPullSonarStatScheduler"61 // SystemCapacityGC periodically triggers garbage collection for system data based on its retention policy.62 SystemCapacityGC = "SystemCapacityGC"63 //InitHealthCheckScheduler64 InitHealthCheckScheduler = "InitHealthCheckScheduler"65 // FreestyleType 自由编排工作流66 freestyleType = "freestyle"67)68// NewCronClient ...69// 服务初始化70func NewCronClient() *CronClient {71 nsqLookupAddrs := config.NsqLookupAddrs()72 aslanCli := client.NewAslanClient(fmt.Sprintf("%s/api", configbase.AslanServiceAddress()), config.RootToken())73 collieCli := client.NewCollieClient(config.CollieAPI(), config.CollieToken())74 //初始化nsq75 config := nsq.NewConfig()76 // 注意 WD_POD_NAME 必须使用 Downward API 配置环境变量77 config.UserAgent = "ASLAN_CRONJOB"78 config.MaxAttempts = 5079 config.LookupdPollInterval = 1 * time.Second80 //nsqClient := nsqcli.NewNsqClient(nsqLookupAddrs, "127.0.0.1:4151")81 //// 初始化nsq topic82 //err := nsqClient.EnsureNsqdTopics([]string{setting.TopicAck, setting.TopicItReport, setting.TopicNotification})83 //if err != nil {84 // //FIXME85 // log.Fatalf("cannot ensure nsq topic, the error is %v", err)86 //}87 //Cronjob Client88 cronjobClient, err := nsq.NewConsumer(setting.TopicCronjob, "cronjob", config)89 if err != nil {90 log.Fatalf("failed to init nsq consumer cronjob, error is %v", err)91 }92 cronjobClient.SetLogger(stdlog.New(os.Stdout, "nsq consumer:", 0), nsq.LogLevelError)93 cronjobScheduler := cronlib.New()94 cronjobScheduler.Start()95 cronjobHandler := NewCronjobHandler(aslanCli, cronjobScheduler)96 cronjobClient.AddConcurrentHandlers(cronjobHandler, 10)97 if err := cronjobClient.ConnectToNSQLookupds(nsqLookupAddrs); err != nil {98 errInfo := fmt.Sprintf("nsq consumer for cron job failed to start, the error is: %s", err)99 panic(errInfo)100 }101 return &CronClient{102 AslanCli: aslanCli,103 CollieCli: collieCli,104 Schedulers: make(map[string]*gocron.Scheduler),105 lastSchedulers: make(map[string][]*service.Schedule),106 lastServiceSchedulers: make(map[string]*service.SvcRevision),107 SchedulerController: make(map[string]chan bool),108 enabledMap: make(map[string]bool),109 log: log.SugaredLogger(),110 }111}112// 初始化轮询任务113func (c *CronClient) Init() {114 // 每天1点清理跑过的jobs115 c.InitCleanJobScheduler()116 // 每天2点 根据系统配额策略 清理系统过期数据117 c.InitSystemCapacityGCScheduler()118 // 定时任务触发119 c.InitJobScheduler()120 // 测试管理的定时任务触发121 c.InitTestScheduler()122 // 自由编排工作流定时任务触发123 features, _ := getFeatures()124 if strings.Contains(features, freestyleType) {125 c.InitColliePipelineScheduler()126 }127 // 定时清理环境128 c.InitCleanProductScheduler()129 // 定时初始化构建数据130 c.InitBuildStatScheduler()131 // 定时器初始化话运营统计数据132 c.InitOperationStatScheduler()133 // 定时更新质效看板的统计数据134 c.InitPullSonarStatScheduler()135 // 定时初始化健康检查136 c.InitHealthCheckScheduler()137}138func getFeatures() (string, error) {139 cl := poetry.New(configbase.PoetryServiceAddress(), config.RootToken())140 fs, err := cl.ListFeatures()141 if err != nil {142 return "", err143 }144 return strings.Join(fs, ","), nil145}146// InitCleanJobScheduler ...147func (c *CronClient) InitCleanJobScheduler() {148 c.Schedulers[CleanJobScheduler] = gocron.NewScheduler()149 c.Schedulers[CleanJobScheduler].Every(1).Day().At("01:00").Do(c.AslanCli.TriggerCleanjobs, c.log)150 c.Schedulers[CleanJobScheduler].Start()151}152// InitCleanProductScheduler ...153func (c *CronClient) InitCleanProductScheduler() {154 c.Schedulers[CleanProductScheduler] = gocron.NewScheduler()155 c.Schedulers[CleanProductScheduler].Every(5).Minutes().Do(c.AslanCli.TriggerCleanProducts, c.log)156 c.Schedulers[CleanProductScheduler].Start()157}158// InitJobScheduler ...159func (c *CronClient) InitJobScheduler() {160 c.Schedulers[UpsertWorkflowScheduler] = gocron.NewScheduler()161 c.Schedulers[UpsertWorkflowScheduler].Every(1).Minutes().Do(c.UpsertWorkflowScheduler, c.log)162 c.Schedulers[UpsertWorkflowScheduler].Start()163}164// InitTestScheduler ...165func (c *CronClient) InitTestScheduler() {166 c.Schedulers[UpsertTestScheduler] = gocron.NewScheduler()167 c.Schedulers[UpsertTestScheduler].Every(1).Minutes().Do(c.UpsertTestScheduler, c.log)168 c.Schedulers[UpsertTestScheduler].Start()169}170// InitJobScheduler ...171func (c *CronClient) InitColliePipelineScheduler() {172 c.Schedulers[UpsertColliePipelineScheduler] = gocron.NewScheduler()173 c.Schedulers[UpsertColliePipelineScheduler].Every(1).Minutes().Do(c.UpsertColliePipelineScheduler, c.log)174 c.Schedulers[UpsertColliePipelineScheduler].Start()175}176// InitBuildStatScheduler ...177func (c *CronClient) InitBuildStatScheduler() {178 c.Schedulers[InitStatScheduler] = gocron.NewScheduler()179 c.Schedulers[InitStatScheduler].Every(1).Day().At("01:00").Do(c.AslanCli.InitStatData, c.log)180 c.Schedulers[InitStatScheduler].Start()181}182// InitOperationStatScheduler ...183func (c *CronClient) InitOperationStatScheduler() {184 c.Schedulers[InitOperationStatScheduler] = gocron.NewScheduler()185 c.Schedulers[InitOperationStatScheduler].Every(1).Hour().Do(c.AslanCli.InitOperationStatData, c.log)186 c.Schedulers[InitOperationStatScheduler].Start()187}188// InitPullSonarStatScheduler ...189func (c *CronClient) InitPullSonarStatScheduler() {190 c.Schedulers[InitPullSonarStatScheduler] = gocron.NewScheduler()191 c.Schedulers[InitPullSonarStatScheduler].Every(10).Minutes().Do(c.AslanCli.InitPullSonarStatScheduler, c.log)192 c.Schedulers[InitPullSonarStatScheduler].Start()193}194func (c *CronClient) InitSystemCapacityGCScheduler() {195 c.Schedulers[SystemCapacityGC] = gocron.NewScheduler()196 c.Schedulers[SystemCapacityGC].Every(1).Day().At("02:00").Do(c.AslanCli.TriggerCleanCache, c.log)197 c.Schedulers[SystemCapacityGC].Start()198}199func (c *CronClient) InitHealthCheckScheduler() {200 c.Schedulers[InitHealthCheckScheduler] = gocron.NewScheduler()201 c.Schedulers[InitHealthCheckScheduler].Every(1).Minutes().Do(c.UpsertEnvServiceScheduler, c.log)202 c.Schedulers[InitHealthCheckScheduler].Start()203}...

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 panic(fmt.Errorf("Fatal error config file: %s \n", err))4 }5 viper.Set("newkey", "newvalue")6 viper.WriteConfig()7}8import (9func main() {10 panic(fmt.Errorf("Fatal error config file: %s \n", err))11 }12 value := viper.Get("newkey")13 fmt.Println(value)14}15import (16func main() {17 panic(fmt.Errorf("Fatal error config

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 conf, err := config.NewConfig("ini", "conf/app.conf")4 if err != nil {5 panic(err)6 }7 conf.Upsert("newkey", "newvalue")8 fmt.Println(conf.String("newkey"))9}

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 config := viper.New()4 config.SetConfigName("config")5 config.AddConfigPath(".")6 err := config.ReadInConfig()7 if err != nil {8 fmt.Println("Error reading config file, %s", err)9 }10 config.Set("name", "newName")11 config.Set("age", "newAge")12 config.WriteConfig()13}

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 viper.SetConfigName("config")4 viper.SetConfigType("json")5 viper.AddConfigPath(".")6 viper.SetDefault("database.host", "localhost")7 err := viper.ReadInConfig()8 if err != nil {9 fmt.Println("Error reading config file, %s", err)10 }11 viper.Set("database.host", "

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 conf, err := config.NewConfig("ini", "config.ini")4 if err != nil {5 panic(err)6 }7 fmt.Println(conf.String("appname"))8 fmt.Println(conf.String("httpport"))9 fmt.Println(conf.String("runmode"))10 conf.Set("appname", "beego")11 conf.Set("httpport", "8080")12 conf.SaveConfigFile("config.ini")13}

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 if len(os.Args) < 5 {4 fmt.Println("Usage: go run 2.go <clusterName> <clusterID> <configName> <configValue> <configPath>")5 os.Exit(1)6 } else {7 }8 trace.Logger = trace.NewLogger("true")9 ibmCloudClient, err := bluemix.NewClient("")10 if err != nil {11 fmt.Println(err)12 }13 containerClient, err := containerv1.New(ibmCloudClient)14 if err != nil {15 fmt.Println(err)16 }17 configAPI := containerClient.Config()18 config, err := configAPI.Upsert(clusterName, clusterID, configName, configValue, configPath)19 if err != nil {20 fmt.Println(err)21 }22 fmt.Println("Upserted the config to the cluster")23 utils.PrettyPrint(config)24 config, err = configAPI.Get(clusterName, clusterID, configPath)25 if err != nil {26 fmt.Println(err)27 }28 fmt.Println("Got the config from the cluster")29 utils.PrettyPrint(config)30 err = configAPI.Delete(clusterName, clusterID, configName, configPath)31 if err != nil {

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1func main() {2 c.Upsert("foo", "bar")3 c.Upsert("foo", "baz")4 fmt.Println(c.Get("foo"))5}6type Config struct {7 data map[string]interface{}8}9func (c *Config) Upsert(key string, value interface{}) {10 if c.data == nil {11 c.data = make(map[string]interface{})12 }13}14func (c *Config) Get(key string) interface{} {15}16import "testing"17func TestUpsert(t *testing.T) {18 c.Upsert("foo", "bar")19 if c.Get("foo") != "bar" {20 t.Error("Expected foo to be bar")21 }22 c.Upsert("foo", "baz")23 if c.Get("foo") != "baz" {24 t.Error("Expected foo to be baz")25 }26}

Full Screen

Full Screen

Upsert

Using AI Code Generation

copy

Full Screen

1import (2type Config struct {3}4type Server struct {5}6func main() {7 raw := map[string]interface{}{8 "servers": []map[string]interface{}{9 map[string]interface{}{10 },11 map[string]interface{}{12 },13 },14 }15 decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{16 DecodeHook: mapstructure.ComposeDecodeHookFunc(17 mapstructure.StringToTimeDurationHookFunc(),18 mapstructure.StringToSliceHookFunc(","),19 })20 if err != nil {21 panic(err)22 }23 if err := decoder.Decode(raw); err != nil {24 panic(err)25 }26 fmt.Println(config)27}28{app 1.0 [{server1 web} {server2 db}]}29import (30type Config struct {31}32type Server struct {33}34func main() {35 raw := map[string]interface{}{36 "servers": []map[string]interface{}{37 map[string]interface{}{38 },39 map[string]interface{}{40 },41 },42 }

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful