From 4979f3da661cb8c2d17e82a1e10c932da8998929 Mon Sep 17 00:00:00 2001 From: kpango Date: Thu, 21 Sep 2023 07:44:48 +0900 Subject: [PATCH] add core ngt benchmark Signed-off-by: kpango --- .../vald-helm-operator/crds/valdrelease.yaml | 3 + charts/vald/README.md | 1 + charts/vald/values.schema.json | 5 + charts/vald/values.yaml | 3 + cmd/tools/cli/benchmark/core/main.go | 513 ++++++ cmd/tools/cli/benchmark/core/main_test.go | 265 +++ go.mod | 51 +- go.sum | 134 +- internal/client/v1/client/vald/vald_test.go | 222 +++ internal/config/ngt.go | 3 + internal/conv/conv.go | 2 +- internal/conv/conv_test.go | 2 +- internal/core/algorithm/ngt/ngt.go | 59 +- internal/core/algorithm/ngt/ngt_bench_test.go | 164 ++ internal/core/algorithm/ngt/ngt_test.go | 2 +- internal/core/algorithm/ngt/option.go | 12 + internal/db/kvs/bbolt/bbolt_test.go | 332 ++++ internal/errors/errors.go | 2 +- internal/io/copy_test.go | 320 ++++ internal/net/grpc/client.go | 26 +- internal/net/grpc/context.go | 3 +- internal/net/grpc/grpcconns.go | 251 --- internal/net/grpc/grpcconns_test.go | 1458 ----------------- internal/net/grpc/pool/pool.go | 63 +- internal/net/grpc/pool/pool_bench_test.go | 3 +- internal/net/grpc/pool/pool_test.go | 106 +- internal/net/grpc/stream_test.go | 89 + internal/strings/strings.go | 33 +- internal/sync/semaphore/semaphore_test.go | 40 +- .../sync/singleflight/singleflight_test.go | 2 +- k8s/agent/configmap.yaml | 1 + k8s/operator/helm/crds/valdrelease.yaml | 3 + pkg/agent/core/ngt/service/ngt.go | 1 + pkg/agent/core/ngt/service/ngt_test.go | 36 +- .../core/ngt/service/vqueue/queue_test.go | 109 ++ .../filter/handler/grpc/handler_test.go | 174 ++ pkg/gateway/lb/handler/grpc/handler_test.go | 138 ++ tests/chaos/chart/README.md | 2 +- versions/HELM_DOCS_VERSION | 2 +- versions/JAEGER_OPERATOR_VERSION | 2 +- versions/PROMETHEUS_STACK_VERSION | 2 +- versions/VALDCLI_VERSION | 2 +- 42 files changed, 2632 insertions(+), 2009 deletions(-) create mode 100644 cmd/tools/cli/benchmark/core/main.go create mode 100644 cmd/tools/cli/benchmark/core/main_test.go create mode 100644 internal/core/algorithm/ngt/ngt_bench_test.go delete mode 100644 internal/net/grpc/grpcconns.go delete mode 100644 internal/net/grpc/grpcconns_test.go diff --git a/charts/vald-helm-operator/crds/valdrelease.yaml b/charts/vald-helm-operator/crds/valdrelease.yaml index 46c151ab94..cb424153b8 100644 --- a/charts/vald-helm-operator/crds/valdrelease.yaml +++ b/charts/vald-helm-operator/crds/valdrelease.yaml @@ -250,6 +250,9 @@ spec: type: boolean enable_proactive_gc: type: boolean + error_buffer_limit: + type: integer + minimum: 1 index_path: type: string initial_delay_max_duration: diff --git a/charts/vald/README.md b/charts/vald/README.md index 7f77ca110a..f03b6de32c 100644 --- a/charts/vald/README.md +++ b/charts/vald/README.md @@ -84,6 +84,7 @@ Run the following command to install the chart, | agent.ngt.enable_copy_on_write | bool | `false` | enable copy on write saving for more stable backup | | agent.ngt.enable_in_memory_mode | bool | `true` | in-memory mode enabled | | agent.ngt.enable_proactive_gc | bool | `false` | enable proactive GC call for reducing heap memory allocation | +| agent.ngt.error_buffer_limit | int | `10` | maximum number of core ngt error buffer pool size limit | | agent.ngt.index_path | string | `""` | path to index data | | agent.ngt.initial_delay_max_duration | string | `"3m"` | maximum duration for initial delay | | agent.ngt.kvsdb.concurrency | int | `6` | kvsdb processing concurrency | diff --git a/charts/vald/values.schema.json b/charts/vald/values.schema.json index 6afe895d45..c1bd7f6322 100644 --- a/charts/vald/values.schema.json +++ b/charts/vald/values.schema.json @@ -241,6 +241,11 @@ "type": "boolean", "description": "enable proactive GC call for reducing heap memory allocation" }, + "error_buffer_limit": { + "type": "integer", + "description": "maximum number of core ngt error buffer pool size limit", + "minimum": 1 + }, "index_path": { "type": "string", "description": "path to index data" diff --git a/charts/vald/values.yaml b/charts/vald/values.yaml index b177e5a4e1..67bb7f393a 100644 --- a/charts/vald/values.yaml +++ b/charts/vald/values.yaml @@ -1723,6 +1723,9 @@ agent: # @schema {"name": "agent.ngt.broken_index_history_limit", "type": "integer", "minimum": 0} # agent.ngt.broken_index_history_limit -- maximum number of broken index generations to backup broken_index_history_limit: 0 + # @schema {"name": "agent.ngt.error_buffer_limit", "type": "integer", "minimum": 1} + # agent.ngt.error_buffer_limit -- maximum number of core ngt error buffer pool size limit + error_buffer_limit: 10 # @schema {"name": "agent.sidecar", "type": "object"} sidecar: # @schema {"name": "agent.sidecar.enabled", "type": "boolean"} diff --git a/cmd/tools/cli/benchmark/core/main.go b/cmd/tools/cli/benchmark/core/main.go new file mode 100644 index 0000000000..9a97418b2e --- /dev/null +++ b/cmd/tools/cli/benchmark/core/main.go @@ -0,0 +1,513 @@ +// +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package ngt provides implementation of Go API for https://github.com/yahoojapan/NGT +package main + +import ( + "context" + "fmt" + "net/http" + "os" + "runtime" + "strconv" + "sync" + "time" + + "github.com/vdaas/vald/internal/conv" + "github.com/vdaas/vald/internal/core/algorithm/ngt" + "github.com/vdaas/vald/internal/file" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/net/http/metrics" + "github.com/vdaas/vald/internal/strings" + "gonum.org/v1/hdf5" +) + +func main() { + var ( + buf []byte + err error + lines, fields []string + line string + vmpeak, + vmsize, + vmdata, + vmrss, + vmhwm, + vmstack, + vmswap, + vmexe, + vmlib, + vmlock, + vmpin, + vmpte, + gc, + save, + cls float64 + + pfile = fmt.Sprintf("/proc/%d/status", os.Getpid()) + zero = float64(0.0) + format = "%s\t" + strings.TrimSuffix(strings.Repeat("%.2f\t", 42), "\t") + ) + output := func(header string) { + buf, err = os.ReadFile(pfile) + if err != nil { + log.Fatal(err) + } + lines = strings.Split(conv.Btoa(buf), "\n") + for _, line = range lines { + fields = strings.Fields(line) + + switch { + case strings.HasPrefix(line, "VmPeak"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmpeak = f + } + case strings.HasPrefix(line, "VmSize"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmsize = f + } + case strings.HasPrefix(line, "VmHWM"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmhwm = f + } + case strings.HasPrefix(line, "VmRSS"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmrss = f + } + case strings.HasPrefix(line, "VmData"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmdata = f + } + case strings.HasPrefix(line, "VmStk"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmstack = f + } + case strings.HasPrefix(line, "VmExe"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmexe = f + } + case strings.HasPrefix(line, "VmLck"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmlock = f + } + case strings.HasPrefix(line, "VmLib"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmlib = f + } + case strings.HasPrefix(line, "VmPTE"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmpte = f + } + case strings.HasPrefix(line, "VmSwap"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmswap = f + } + case strings.HasPrefix(line, "VmPin"): + f, err := strconv.ParseFloat(fields[1], 64) + if err == nil { + vmpin = f + } + } + fields = fields[:0:0] + fields = nil + } + buf = buf[:0:0] + buf = nil + lines = lines[:0:0] + lines = nil + switch { + case strings.Contains(header, "gc"): + gc = vmpeak + save = zero + cls = zero + case strings.Contains(header, "save"): + save = vmpeak + gc = zero + cls = zero + case strings.Contains(header, "close"): + cls = vmpeak + gc = zero + save = zero + default: + gc = zero + save = zero + cls = zero + } + + var m runtime.MemStats + runtime.ReadMemStats(&m) + metrics := []interface{}{ + header, + vmpeak, + vmsize, + vmdata, + vmrss, + vmhwm, + vmstack, + vmswap, + vmexe, + vmlib, + vmlock, + vmpin, + vmpte, + float64(m.Alloc) / 1024.0, + float64(m.BuckHashSys), + float64(m.Frees), + float64(m.GCSys) / 1024.0, + float64(m.HeapAlloc) / 1024.0, + float64(m.HeapIdle) / 1024.0, + float64(m.HeapInuse) / 1024.0, + float64(m.HeapObjects), + float64(m.HeapReleased) / 1024.0, + float64(m.HeapSys) / 1024.0, + float64(m.HeapIdle-m.HeapReleased) / 1024.0, + float64(m.Lookups), + float64(m.MCacheInuse), + float64(m.MCacheSys), + float64(m.MSpanInuse) / 1024.0, + float64(m.MSpanSys), + float64(m.Mallocs), + float64(m.Mallocs - m.Frees), + float64(m.NextGC), + float64(m.NumForcedGC), + float64(m.NumGC), + float64(m.OtherSys), + float64(m.PauseTotalNs) / 1024.0, + float64(m.StackInuse), + float64(m.StackSys), + float64(m.Sys) / 1024.0, + float64(m.TotalAlloc) / 1024.0, + gc, + save, + cls, + } + log.Infof(format, metrics...) + switch { + case strings.Contains(header, "gc"), + strings.Contains(header, "save"), + strings.Contains(header, "close"): + log.Infof(format, metrics...) + } + } + defer output("end") + ctx, cancel := context.WithCancel(context.Background()) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + srv := &http.Server{ + Addr: "0.0.0.0:6060", + Handler: metrics.NewPProfHandler(), + } + go srv.ListenAndServe() + <-ctx.Done() + srv.Shutdown(context.Background()) + }() + + vectors, _, _ := load(os.Getenv("DATA_PATH")) + log.Infof("# of vectors: %v", len(vectors)) + log.Info(strings.Join([]string{ + "Operation", + "VmPeak", + "VmSize", + "VmData", + "VmRSS", + "VmHWM", + "VmStack", + "VmSwap", + "VmEXE", + "VmLib", + "VmLock", + "VmPin", + "VmPTE", + "Alloc", + "BuckHashSys", + "Frees", + "GCSys", + "HeapAlloc", + "HeapIdle", + "HeapInuse", + "HeapObjects", + "HeapReleased", + "HeapSys", + "HeapWillReturn", + "Lookups", + "MCacheInuse", + "MCacheSys", + "MSpanInuse", + "MSpanSys", + "Mallocs", + "LiveObjects", + "NextGC", + "NumForcedGC", + "NumGC", + "OtherSys", + "PauseTotalNs", + "StackInuse", + "StackSys", + "Sys", + "TotalAlloc", + "GC", + "Save", + "Close", + }, "\t")) + output("start") + path, _ := file.MkdirTemp("") + sleep(ctx, time.Second*5, time.Minute*4, func() { + output("waiting for start") + }, func() { + runtime.GC() + output("gc") + time.Sleep(time.Minute) + output("starting") + }) + + ids := make([]uint, len(vectors)) + run(ctx, false, path, len(vectors[0]), vectors, ids, time.Hour*2, output) + sleep(ctx, time.Second*5, time.Minute*4, func() { + output("waiting for next") + }, func() { + runtime.GC() + output("gc") + time.Sleep(time.Minute) + output("starting") + }) + run(ctx, true, path, len(vectors[0]), nil, nil, 0, output) + sleep(ctx, time.Second*5, time.Minute*4, func() { + output("waiting for next") + }, func() { + runtime.GC() + output("gc") + time.Sleep(time.Minute) + output("starting") + }) + run(ctx, true, path, len(vectors[0]), vectors, ids, time.Hour*2, output) + + ids = ids[:0:0] + ids = nil + vectors = vectors[:0:0] + vectors = nil + sleep(ctx, time.Second*5, time.Minute*5, func() { + output("waiting for gc") + }, func() { + runtime.GC() + output("gc") + }) + sleep(ctx, time.Second*5, time.Minute*5, func() { + output("waiting for gc") + }, func() { + runtime.GC() + output("gc") + }) + sleep(ctx, time.Second*5, time.Minute*5, func() { + output("finalizing") + }, func() { + cancel() + wg.Wait() + }) +} + +func run(ctx context.Context, load bool, path string, dim int, vectors [][]float32, ids []uint, dur time.Duration, output func(header string)) { + var n ngt.NGT + if load { + n, _ = ngt.Load( + ngt.WithDimension(dim), + ngt.WithDefaultPoolSize(8), + ngt.WithObjectType(ngt.Float), + ngt.WithDistanceType(ngt.L2), + ) + } else { + n, _ = ngt.New( + ngt.WithDimension(dim), + ngt.WithDefaultPoolSize(8), + ngt.WithObjectType(ngt.Float), + ngt.WithDistanceType(ngt.L2), + ) + } + + if vectors != nil { + var ( + i int + vector []float32 + id uint + err error + ) + if ids == nil { + ids = make([]uint, len(vectors)) + } else if load { + for _, id = range ids { + _ = n.Remove(id) + } + output("remove") + } + sleep(ctx, 0, dur, func() { + for i, vector = range vectors { + id, err = n.Insert(vector) + if err != nil { + log.Fatal(err) + } + ids[i] = id + } + output("insert") + if err = n.CreateIndex(8); err != nil { + log.Fatal(err) + } + output("create index") + for _, id = range ids { + if err = n.Remove(id); err != nil { + log.Fatal(err) + } + } + output("remove") + }, func() { + for _, vector = range vectors { + _, err = n.Insert(vector) + if err != nil { + log.Fatal(err) + } + } + output("insert") + if err = n.CreateIndex(8); err != nil { + log.Fatal(err) + } + output("create index") + if err = n.SaveIndex(); err != nil { + log.Fatal(err) + } + output("save index") + }) + } + sleep(ctx, time.Second*5, time.Minute*10, func() { + output("finalizing") + }, func() { + n.Close() + n = nil + output("close") + }) +} + +func sleep(ctx context.Context, duration, limit time.Duration, fn, efn func()) { + if limit == 0 { + fn() + efn() + return + } + defer efn() + end := time.NewTimer(limit) + defer end.Stop() + if duration == 0 { + for { + select { + case <-ctx.Done(): + return + case <-end.C: + return + default: + fn() + } + } + return + } + ticker := time.NewTicker(duration) + defer ticker.Stop() + for range ticker.C { + select { + case <-ctx.Done(): + return + case <-end.C: + return + default: + fn() + } + } + return +} + +// load function loads training and test vector from hdf file. The size of ids is same to the number of training data. +// Each id, which is an element of ids, will be set a random number. +func load(path string) (train, test [][]float32, err error) { + var f *hdf5.File + f, err = hdf5.OpenFile(path, hdf5.F_ACC_RDONLY) + if err != nil { + return nil, nil, err + } + defer f.Close() + + // readFn function reads vectors of the hierarchy with the given the name. + readFn := func(name string) ([][]float32, error) { + // Opens and returns a named Dataset. + // The returned dataset must be closed by the user when it is no longer needed. + d, err := f.OpenDataset(name) + if err != nil { + return nil, err + } + defer d.Close() + + // Space returns an identifier for a copy of the dataspace for a dataset. + sp := d.Space() + defer sp.Close() + + // SimpleExtentDims returns dataspace dimension size and maximum size. + dims, _, _ := sp.SimpleExtentDims() + row, dim := int(dims[0]), int(dims[1]) + + // Gets the stored vector. All are represented as one-dimensional arrays. + // The type of the slice depends on your dataset. + // For fashion-mnist-784-euclidean.hdf5, the datatype is float32. + vec := make([]float32, sp.SimpleExtentNPoints()) + if err := d.Read(&vec); err != nil { + return nil, err + } + + // Converts a one-dimensional array to a two-dimensional array. + // Use the `dim` variable as a separator. + vecs := make([][]float32, row) + for i := 0; i < row; i++ { + vecs[i] = make([]float32, dim) + for j := 0; j < dim; j++ { + vecs[i][j] = float32(vec[i*dim+j]) + } + } + + return vecs, nil + } + + // Gets vector of `train` hierarchy. + train, err = readFn("train") + if err != nil { + return nil, nil, err + } + + // Gets vector of `test` hierarchy. + test, err = readFn("test") + if err != nil { + return nil, nil, err + } + + return +} diff --git a/cmd/tools/cli/benchmark/core/main_test.go b/cmd/tools/cli/benchmark/core/main_test.go new file mode 100644 index 0000000000..3748eb8a90 --- /dev/null +++ b/cmd/tools/cli/benchmark/core/main_test.go @@ -0,0 +1,265 @@ +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package core + +// NOT IMPLEMENTED BELOW +// +// func Test_main(t *testing.T) { +// type want struct { +// } +// type test struct { +// name string +// want want +// checkFunc func(want) error +// beforeFunc func(*testing.T) +// afterFunc func(*testing.T) +// } +// defaultCheckFunc := func(w want) error { +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T,) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T,) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T,) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T,) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// +// main() +// if err := checkFunc(test.want); err != nil { +// tt.Errorf("error = %v", err) +// } +// }) +// } +// } +// +// func Test_run(t *testing.T) { +// type args struct { +// dur time.Duration +// output func(header string) +// } +// type want struct { +// } +// type test struct { +// name string +// args args +// want want +// checkFunc func(want) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want) error { +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// dur:nil, +// output:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// dur:nil, +// output:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// +// run(test.args.dur, test.args.output) +// if err := checkFunc(test.want); err != nil { +// tt.Errorf("error = %v", err) +// } +// }) +// } +// } +// +// func Test_load(t *testing.T) { +// type args struct { +// path string +// } +// type want struct { +// wantTrain [][]float32 +// wantTest [][]float32 +// err error +// } +// type test struct { +// name string +// args args +// want want +// checkFunc func(want, [][]float32, [][]float32, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotTrain [][]float32, gotTest [][]float32, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotTrain, w.wantTrain) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotTrain, w.wantTrain) +// } +// if !reflect.DeepEqual(gotTest, w.wantTest) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotTest, w.wantTest) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// path:"", +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// path:"", +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// +// gotTrain, gotTest, err := load(test.args.path) +// if err := checkFunc(test.want, gotTrain, gotTest, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } diff --git a/go.mod b/go.mod index 903703fb21..43e0543b94 100755 --- a/go.mod +++ b/go.mod @@ -36,34 +36,34 @@ replace ( github.com/Azure/go-autorest/tracing => github.com/Azure/go-autorest/tracing v0.6.1-0.20230905222633-df94ce56f001 github.com/BurntSushi/toml => github.com/BurntSushi/toml v1.3.2 github.com/DATA-DOG/go-sqlmock => github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/GoogleCloudPlatform/cloudsql-proxy => github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.10 + github.com/GoogleCloudPlatform/cloudsql-proxy => github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.11 github.com/Masterminds/semver/v3 => github.com/Masterminds/semver/v3 v3.2.1 github.com/ajstarks/deck => github.com/ajstarks/deck v0.0.0-20230917174535-ca5324ee72b2 github.com/ajstarks/deck/generate => github.com/ajstarks/deck/generate v0.0.0-20230917174535-ca5324ee72b2 github.com/ajstarks/svgo => github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b github.com/antihax/optional => github.com/antihax/optional v1.0.0 github.com/armon/go-socks5 => github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 - github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.45.12 + github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.45.15 github.com/aws/aws-sdk-go-v2 => github.com/aws/aws-sdk-go-v2 v1.21.0 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream => github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 - github.com/aws/aws-sdk-go-v2/config => github.com/aws/aws-sdk-go-v2/config v1.18.40 - github.com/aws/aws-sdk-go-v2/credentials => github.com/aws/aws-sdk-go-v2/credentials v1.13.38 + github.com/aws/aws-sdk-go-v2/config => github.com/aws/aws-sdk-go-v2/config v1.18.42 + github.com/aws/aws-sdk-go-v2/credentials => github.com/aws/aws-sdk-go-v2/credentials v1.13.40 github.com/aws/aws-sdk-go-v2/feature/ec2/imds => github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 - github.com/aws/aws-sdk-go-v2/feature/s3/manager => github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.84 + github.com/aws/aws-sdk-go-v2/feature/s3/manager => github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.86 github.com/aws/aws-sdk-go-v2/internal/configsources => github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 => github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 - github.com/aws/aws-sdk-go-v2/internal/ini => github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 + github.com/aws/aws-sdk-go-v2/internal/ini => github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding => github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 github.com/aws/aws-sdk-go-v2/service/internal/checksum => github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url => github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 github.com/aws/aws-sdk-go-v2/service/internal/s3shared => github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 github.com/aws/aws-sdk-go-v2/service/kms => github.com/aws/aws-sdk-go-v2/service/kms v1.24.5 - github.com/aws/aws-sdk-go-v2/service/s3 => github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5 + github.com/aws/aws-sdk-go-v2/service/s3 => github.com/aws/aws-sdk-go-v2/service/s3 v1.39.0 github.com/aws/aws-sdk-go-v2/service/secretsmanager => github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.21.3 github.com/aws/aws-sdk-go-v2/service/sns => github.com/aws/aws-sdk-go-v2/service/sns v1.22.0 github.com/aws/aws-sdk-go-v2/service/sqs => github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5 github.com/aws/aws-sdk-go-v2/service/ssm => github.com/aws/aws-sdk-go-v2/service/ssm v1.37.5 - github.com/aws/aws-sdk-go-v2/service/sso => github.com/aws/aws-sdk-go-v2/service/sso v1.14.0 + github.com/aws/aws-sdk-go-v2/service/sso => github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 github.com/aws/aws-sdk-go-v2/service/sts => github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 github.com/aws/smithy-go => github.com/aws/smithy-go v1.14.2 github.com/benbjohnson/clock => github.com/benbjohnson/clock v1.3.5 @@ -100,7 +100,7 @@ replace ( github.com/fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.6.0 github.com/gin-contrib/sse => github.com/gin-contrib/sse v0.1.0 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1 - github.com/go-errors/errors => github.com/go-errors/errors v1.5.0 + github.com/go-errors/errors => github.com/go-errors/errors v1.5.1 github.com/go-fonts/dejavu => github.com/go-fonts/dejavu v0.2.0 github.com/go-fonts/latin-modern => github.com/go-fonts/latin-modern v0.3.1 github.com/go-fonts/liberation => github.com/go-fonts/liberation v0.3.1 @@ -146,7 +146,7 @@ replace ( github.com/golang/protobuf => github.com/golang/protobuf v1.5.3 github.com/golang/snappy => github.com/golang/snappy v0.0.4 github.com/google/btree => github.com/google/btree v1.1.2 - github.com/google/gnostic => github.com/google/gnostic v0.6.9 + github.com/google/gnostic => github.com/google/gnostic v0.7.0 github.com/google/go-cmp => github.com/google/go-cmp v0.5.9 github.com/google/go-replayers/grpcreplay => github.com/google/go-replayers/grpcreplay v1.1.0 github.com/google/go-replayers/httpreplay => github.com/google/go-replayers/httpreplay v1.2.0 @@ -222,7 +222,7 @@ replace ( github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e github.com/nxadm/tail => github.com/nxadm/tail v1.4.8 github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.16.5 - github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.12.0 + github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.12.1 github.com/onsi/gomega => github.com/onsi/gomega v1.27.10 github.com/peterbourgon/diskv => github.com/peterbourgon/diskv v2.0.1+incompatible github.com/phpdave11/gofpdf => github.com/phpdave11/gofpdf v1.4.2 @@ -237,7 +237,7 @@ replace ( github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_model => github.com/prometheus/client_model v0.4.0 github.com/prometheus/common => github.com/prometheus/common v0.44.0 - github.com/prometheus/procfs => github.com/prometheus/procfs v0.11.1 + github.com/prometheus/procfs => github.com/prometheus/procfs v0.12.0 github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.99.0 github.com/quasilyte/go-ruleguard => github.com/quasilyte/go-ruleguard v0.4.0 github.com/quasilyte/go-ruleguard/dsl => github.com/quasilyte/go-ruleguard/dsl v0.3.22 @@ -257,7 +257,7 @@ replace ( github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.9.3 - github.com/spf13/afero => github.com/spf13/afero v1.9.5 + github.com/spf13/afero => github.com/spf13/afero v1.10.0 github.com/spf13/cobra => github.com/spf13/cobra v1.7.0 github.com/spf13/pflag => github.com/spf13/pflag v1.0.5 github.com/stoewer/go-strcase => github.com/stoewer/go-strcase v1.3.0 @@ -284,7 +284,7 @@ replace ( go.opentelemetry.io/otel/sdk/metric => go.opentelemetry.io/otel/sdk/metric v0.33.0 go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.11.1 go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v1.0.0 - go.starlark.net => go.starlark.net v0.0.0-20230912135651-745481cf39ed + go.starlark.net => go.starlark.net v0.0.0-20230921161717-a9587466d7a5 go.uber.org/atomic => go.uber.org/atomic v1.11.0 go.uber.org/automaxprocs => go.uber.org/automaxprocs v1.5.3 go.uber.org/goleak => go.uber.org/goleak v1.2.1 @@ -296,7 +296,7 @@ replace ( golang.org/x/exp/typeparams => golang.org/x/exp/typeparams v0.0.0-20230905200255-921286631fa9 golang.org/x/image => golang.org/x/image v0.12.0 golang.org/x/lint => golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 - golang.org/x/mobile => golang.org/x/mobile v0.0.0-20230906132913-2077a3224571 + golang.org/x/mobile => golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 golang.org/x/mod => golang.org/x/mod v0.12.0 golang.org/x/net => golang.org/x/net v0.15.0 golang.org/x/oauth2 => golang.org/x/oauth2 v0.12.0 @@ -311,12 +311,12 @@ replace ( gonum.org/v1/gonum => gonum.org/v1/gonum v0.14.0 gonum.org/v1/hdf5 => gonum.org/v1/hdf5 v0.0.0-20210714002203-8c5d23bc6946 gonum.org/v1/plot => gonum.org/v1/plot v0.14.0 - google.golang.org/api => google.golang.org/api v0.141.0 + google.golang.org/api => google.golang.org/api v0.142.0 google.golang.org/appengine => google.golang.org/appengine v1.6.8 - google.golang.org/genproto => google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb - google.golang.org/genproto/googleapis/api => google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb - google.golang.org/genproto/googleapis/rpc => google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb - google.golang.org/grpc => google.golang.org/grpc v1.58.1 + google.golang.org/genproto => google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13 + google.golang.org/genproto/googleapis/api => google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 + google.golang.org/genproto/googleapis/rpc => google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 + google.golang.org/grpc => google.golang.org/grpc v1.58.2 google.golang.org/grpc/cmd/protoc-gen-go-grpc => google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf => google.golang.org/protobuf v1.31.0 gopkg.in/check.v1 => gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c @@ -396,8 +396,8 @@ require ( golang.org/x/tools v0.13.0 gonum.org/v1/hdf5 v0.0.0-00010101000000-000000000000 gonum.org/v1/plot v0.10.1 - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d - google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 + google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920183334-c177e329c48b google.golang.org/grpc v1.58.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 @@ -410,10 +410,10 @@ require ( ) require ( - cloud.google.com/go v0.110.7 // indirect + cloud.google.com/go v0.110.8 // indirect cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.1 // indirect + cloud.google.com/go/iam v1.1.2 // indirect git.sr.ht/~sbinet/gg v0.5.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -446,6 +446,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect @@ -500,7 +501,7 @@ require ( gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect google.golang.org/api v0.134.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93 // indirect + google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.27.2 // indirect diff --git a/go.sum b/go.sum index 2f4fdb2dcc..3971f134d8 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,7 @@ cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5 cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= -cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.50.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= @@ -14,16 +14,16 @@ cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346 cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= -cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= -cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= +cloud.google.com/go/baremetalsolution v1.2.0/go.mod h1:68wi9AwPYkEWIUT4SvSGS9UJwKzNpshjHsH4lzk8iOw= +cloud.google.com/go/batch v1.4.1/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= cloud.google.com/go/bigquery v1.55.0/go.mod h1:9Y5I3PN9kQWuid6183JFhOGOW3GcirA5LpsKCUn+2ec= -cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= -cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= +cloud.google.com/go/billing v1.17.0/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= +cloud.google.com/go/binaryauthorization v1.7.0/go.mod h1:Zn+S6QqTMn6odcMU1zDZCJxPjU2tZPV1oDl45lWY154= cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= -cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= -cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= +cloud.google.com/go/channel v1.17.0/go.mod h1:RpbhJsGi/lXWAUM1eF4IbQGbsfVlg2o8Iiy2/YLfVT0= +cloud.google.com/go/cloudbuild v1.14.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/clouddms v1.7.0/go.mod h1:MW1dC6SOtI/tPNCciTsXtsGNEM0i0OccykPvv3hiYeM= cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= @@ -31,24 +31,24 @@ cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxB cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= +cloud.google.com/go/container v1.26.0/go.mod h1:YJCmRet6+6jnYYRS000T6k0D0xUXQgBSaJ7VwI8FBj4= +cloud.google.com/go/containeranalysis v0.11.0/go.mod h1:4n2e99ZwpGxpNcz+YsFT1dfOHPQFGcAC8FN2M2/ne/U= cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= -cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.17.1/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= -cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= +cloud.google.com/go/dataproc/v2 v2.2.0/go.mod h1:lZR7AQtwZPvmINx5J87DSOOpTfof9LVZju6/Qo4lmcY= cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.43.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= -cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.1/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= @@ -57,7 +57,7 @@ cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8 cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= -cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkebackup v1.3.1/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= @@ -65,13 +65,13 @@ cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6G cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4= cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= +cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY= cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= -cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= +cloud.google.com/go/language v1.11.0/go.mod h1:uDx+pFDdAKTY8ehpWbiXyQdz8tDSYLJbQcXsCkjYyvQ= cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= @@ -83,11 +83,11 @@ cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY= -cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= -cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= +cloud.google.com/go/networkconnectivity v1.13.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= +cloud.google.com/go/networkmanagement v1.9.0/go.mod h1:UTUaEU9YwbCAhhz3jEOHr+2/K/MrBk2XxOLS89LQzFw= cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= -cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= -cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= +cloud.google.com/go/notebooks v1.10.0/go.mod h1:SOPYMZnttHxqot0SGSFSkRrwE29eqnKPBJFqgWmiK2k= +cloud.google.com/go/optimization v1.5.0/go.mod h1:evo1OvTxeBRBu6ydPlrIRizKY/LJKo/drDMMRKqGEUU= cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= @@ -95,13 +95,13 @@ cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjw cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= -cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= +cloud.google.com/go/policytroubleshooter v1.9.0/go.mod h1:+E2Lga7TycpeSTj2FsH4oXxTnrbHJGRlKhVZBLGgU64= cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= -cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= +cloud.google.com/go/recommender v1.11.0/go.mod h1:kPiRQhPyTJ9kyXPCG6u/dlPLbYfFlkwHNRwdzPVAoII= cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= @@ -113,7 +113,7 @@ cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4A cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= -cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= +cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= cloud.google.com/go/storage v1.33.0 h1:PVrDOkIC8qQVa1P3SXGpQvfuJhN2LHOoyZvWs8D2X5M= cloud.google.com/go/storage v1.33.0/go.mod h1:Hhh/dogNRGca7IWv1RC2YqEn0c0G77ctA/OxflYkiD8= @@ -122,8 +122,8 @@ cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= -cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/translate v1.9.0/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/video v1.20.0/go.mod h1:U3G3FTnsvAGqglq9LxgqzOiBc/Nt8zis8S+850N2DUM= cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= @@ -131,7 +131,7 @@ cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkG cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= -cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= +cloud.google.com/go/workflows v1.12.0/go.mod h1:PYhSk2b6DhZ508tj8HXKaBh+OFe+xdl0dHF/tJdzPQM= code.cloudfoundry.org/bytefmt v0.0.0-20230612151507-41ef4d1f67a4 h1:9G5F8zgma5v0GdDvNz6iZwwJp3RS/z0SY/aHGfVwvTo= code.cloudfoundry.org/bytefmt v0.0.0-20230612151507-41ef4d1f67a4/go.mod h1:wYHCXH/gI19ujoFVuMkY48qPpPCoHLKBKXPkn67h/Yc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -176,26 +176,26 @@ github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/P github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-sdk-go v1.45.12 h1:+bKbbesGNPp+TeGrcqfrWuZoqcIEhjwKyBMHQPp80Jo= -github.com/aws/aws-sdk-go v1.45.12/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.45.15 h1:gYBTVSYuhXdatrLbsPaRgVcc637zzdgThWmsDRwXLOo= +github.com/aws/aws-sdk-go v1.45.15/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= -github.com/aws/aws-sdk-go-v2/config v1.18.40 h1:dbu1llI/nTIL+r6sYHMeVLl99DM8J8/o1I4EPurnhLg= -github.com/aws/aws-sdk-go-v2/config v1.18.40/go.mod h1:JjrCZQwSPGCoZRQzKHyZNNueaKO+kFaEy2sR6mCzd90= -github.com/aws/aws-sdk-go-v2/credentials v1.13.38 h1:gDAuCdVlA4lmmgQhvpZlscwicloCqH44vkxLklGkQLA= -github.com/aws/aws-sdk-go-v2/credentials v1.13.38/go.mod h1:sD4G/Ybgp6s89mWIES3Xn97CsRLpxvz9uVSdv0UxY8I= +github.com/aws/aws-sdk-go-v2/config v1.18.42 h1:28jHROB27xZwU0CB88giDSjz7M1Sba3olb5JBGwina8= +github.com/aws/aws-sdk-go-v2/config v1.18.42/go.mod h1:4AZM3nMMxwlG+eZlxvBKqwVbkDLlnN2a4UGTL6HjaZI= +github.com/aws/aws-sdk-go-v2/credentials v1.13.40 h1:s8yOkDh+5b1jUDhMBtngF6zKWLDs84chUk2Vk0c38Og= +github.com/aws/aws-sdk-go-v2/credentials v1.13.40/go.mod h1:VtEHVAAqDWASwdOqj/1huyT6uHbs5s8FUHfDQdky/Rs= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.84 h1:LENrVcqnWTyI8fbIUCvxAMe+fXbREIaXzcR8WPwco1U= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.84/go.mod h1:LHxCiYAStsgps4srke7HujyADd504MSkNXjLpOtICTc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.86 h1:tnn/U5bz5flqoTCFSgRMEdg93ULR9Q6+tL5LkwjJ0DM= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.86/go.mod h1:TJGNZIhz3fsaQ6PU9roZacAEMMnG89X2UzaDblNoeNw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 h1:GPUcE/Yq7Ur8YSUk6lVkoIMWnJNO0HT18GUzCWCgCI0= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 h1:g+qlObJH4Kn4n21g69DjspU0hKTjWtq7naZ9OLCv0ew= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.0 h1:U5yySdwt2HPo/pnQec04DImLzWORbeWML1fJiLkKruI= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.0/go.mod h1:EhC/83j8/hL/UB1WmExo3gkElaja/KlmZM/gl1rTfjM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0= @@ -206,10 +206,10 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKi github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5 h1:A42xdtStObqy7NGvzZKpnyNXvoOmm+FENobZ0/ssHWk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM= -github.com/aws/aws-sdk-go-v2/service/sso v1.14.0 h1:AR/hlTsCyk1CwlyKnPFvIMvnONydRjDDRT9OGb0i+/g= -github.com/aws/aws-sdk-go-v2/service/sso v1.14.0/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4= +github.com/aws/aws-sdk-go-v2/service/s3 v1.39.0 h1:VZ2WMkKLio5tVjYfThcy5+pb6YHGd6B6egq75FfM6hU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.39.0/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM= +github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 h1:YkNzx1RLS0F5qdf9v1Q8Cuv9NXCL2TkosOxhzlUPV64= +github.com/aws/aws-sdk-go-v2/service/sso v1.14.1/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.1 h1:hd0SKLMdOL/Sl6Z0np1PX9LeH2gqNtBe0MhTedA8MGI= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.1/go.mod h1:XO/VcyoQ8nKyKfFW/3DMsRQXsfh/052tHTWmg3xBXRg= github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 h1:s4bioTgjSFRwOoyEFzAVCmFmoowBgjTR8gkrF/sQ4wk= @@ -270,8 +270,8 @@ github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/Gr github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E= github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0= github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= -github.com/go-errors/errors v1.5.0 h1:/EuijeGOu7ckFxzhkj4CXJ8JaenxK7bKUxpPYqeLHqQ= -github.com/go-errors/errors v1.5.0/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.2.0 h1:F3lhaCFgvvovt9UzD/AIPnOACYoAddop/uZwIdsJ4hs= github.com/go-fonts/dejavu v0.2.0/go.mod h1:m+TzKY7ZEl09/a17t1593E4VYW8L1VaBXHzFZOIjGEY= github.com/go-fonts/latin-modern v0.3.1 h1:/cT8A7uavYKvglYXvrdDw4oS5ZLkcOU22fa2HJ1/JVM= @@ -347,8 +347,10 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic v0.7.0 h1:d7EpuFp8vVdML+y0JJJYiKeOLjKTdH/GvVkLOBWqJpw= +github.com/google/gnostic v0.7.0/go.mod h1:IAcUyMl6vtC95f60EZ8oXyqTsOersP6HbwjeG7EyDPM= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= @@ -486,8 +488,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= -github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= @@ -514,8 +516,8 @@ github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUo github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= @@ -543,7 +545,7 @@ github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1 github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -598,8 +600,8 @@ go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZX go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.starlark.net v0.0.0-20230912135651-745481cf39ed h1:kNt8RXSIU6IRBO9MP3m+6q3WpyBHQQXqSktcyVKDPOQ= -go.starlark.net v0.0.0-20230912135651-745481cf39ed/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.starlark.net v0.0.0-20230921161717-a9587466d7a5 h1:Hg7PpzzjFq0TBToBkMgmjY0W09rC52nmm+v2ME9ZT5w= +go.starlark.net v0.0.0-20230921161717-a9587466d7a5/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= @@ -622,7 +624,7 @@ golang.org/x/exp/typeparams v0.0.0-20230905200255-921286631fa9/go.mod h1:AbB0pIl golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20230906132913-2077a3224571/go.mod h1:wEyOn6VvNW7tcf+bW/wBz1sehi2s2BZ4TimyR7qZen4= +golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57/go.mod h1:wEyOn6VvNW7tcf+bW/wBz1sehi2s2BZ4TimyR7qZen4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= @@ -651,19 +653,19 @@ gonum.org/v1/hdf5 v0.0.0-20210714002203-8c5d23bc6946 h1:vJpL69PeUullhJyKtTjHjENE gonum.org/v1/hdf5 v0.0.0-20210714002203-8c5d23bc6946/go.mod h1:BQUWDHIAygjdt1HnUPQ0eWqLN2n5FwJycrpYUVUOx2I= gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= -google.golang.org/api v0.141.0 h1:Df6vfMgDoIM6ss0m7H4MPwFwY87WNXHfBIda/Bmfl4E= -google.golang.org/api v0.141.0/go.mod h1:iZqLkdPlXKyG0b90eu6KxVSE4D/ccRF2e/doKD2CnQQ= +google.golang.org/api v0.142.0 h1:mf+7EJ94fi5ZcnpPy+m0Yv2dkz8bKm+UL0snTCuwXlY= +google.golang.org/api v0.142.0/go.mod h1:zJAN5o6HRqR7O+9qJUFOWrZkYE66RH+efPBdTLA4xBA= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230911183012-2d3300fd4832/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13 h1:vlzZttNJGVqTsRFU9AmdnrcO1Znh8Ew9kCD//yjigk0= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= +google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 h1:U7+wNaVuSTaUqNvK2+osJ9ejEZxbjHHk8F2b6Hpx0AE= +google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230913181813-007df8e322eb/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/internal/client/v1/client/vald/vald_test.go b/internal/client/v1/client/vald/vald_test.go index 0a3bc6a440..98f17fc28a 100644 --- a/internal/client/v1/client/vald/vald_test.go +++ b/internal/client/v1/client/vald/vald_test.go @@ -3299,6 +3299,119 @@ package vald // } // } // +// func Test_client_RemoveByTimestamp(t *testing.T) { +// type args struct { +// ctx context.Context +// in *payload.Remove_TimestampRequest +// opts []grpc.CallOption +// } +// type fields struct { +// addrs []string +// c grpc.Client +// } +// type want struct { +// wantRes *payload.Object_Locations +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, *payload.Object_Locations, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotRes *payload.Object_Locations, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotRes, w.wantRes) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// ctx:nil, +// in:nil, +// opts:nil, +// }, +// fields: fields { +// addrs:nil, +// c:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// ctx:nil, +// in:nil, +// opts:nil, +// }, +// fields: fields { +// addrs:nil, +// c:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// c := &client{ +// addrs: test.fields.addrs, +// c: test.fields.c, +// } +// +// gotRes, err := c.RemoveByTimestamp(test.args.ctx, test.args.in, test.args.opts...) +// if err := checkFunc(test.want, gotRes, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// // func Test_client_GetObject(t *testing.T) { // type args struct { // ctx context.Context @@ -6627,6 +6740,115 @@ package vald // } // } // +// func Test_singleClient_RemoveByTimestamp(t *testing.T) { +// type args struct { +// ctx context.Context +// in *payload.Remove_TimestampRequest +// opts []grpc.CallOption +// } +// type fields struct { +// vc vald.Client +// } +// type want struct { +// wantRes *payload.Object_Locations +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, *payload.Object_Locations, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotRes *payload.Object_Locations, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotRes, w.wantRes) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// ctx:nil, +// in:nil, +// opts:nil, +// }, +// fields: fields { +// vc:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// ctx:nil, +// in:nil, +// opts:nil, +// }, +// fields: fields { +// vc:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// c := &singleClient{ +// vc: test.fields.vc, +// } +// +// gotRes, err := c.RemoveByTimestamp(test.args.ctx, test.args.in, test.args.opts...) +// if err := checkFunc(test.want, gotRes, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// // func Test_singleClient_GetObject(t *testing.T) { // type args struct { // ctx context.Context diff --git a/internal/config/ngt.go b/internal/config/ngt.go index f7b777867c..4048d3c7ff 100644 --- a/internal/config/ngt.go +++ b/internal/config/ngt.go @@ -91,6 +91,9 @@ type NGT struct { // BrokenIndexHistoryLimit represents the maximum number of broken index generations that will be backed up BrokenIndexHistoryLimit int `yaml:"broken_index_history_limit" json:"broken_index_history_limit,omitempty"` + + // ErrorBufferLimit represents the maximum number of core ngt error buffer pool size limit + ErrorBufferLimit uint64 `yaml:"error_buffer_limit" json:"error_buffer_limit,omitempty"` } // KVSDB represent the ngt vector bidirectional kv store configuration diff --git a/internal/conv/conv.go b/internal/conv/conv.go index 8a4cc49ae7..6ac71a156c 100644 --- a/internal/conv/conv.go +++ b/internal/conv/conv.go @@ -15,9 +15,9 @@ package conv import ( "io" - "strings" "unsafe" + "github.com/vdaas/vald/internal/strings" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) diff --git a/internal/conv/conv_test.go b/internal/conv/conv_test.go index 35330ce12b..6aab3fb3d1 100644 --- a/internal/conv/conv_test.go +++ b/internal/conv/conv_test.go @@ -16,11 +16,11 @@ package conv import ( "io" "reflect" - "strings" "testing" "testing/iotest" "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/strings" "github.com/vdaas/vald/internal/test/goleak" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" diff --git a/internal/core/algorithm/ngt/ngt.go b/internal/core/algorithm/ngt/ngt.go index f700adba93..557bbb49a7 100644 --- a/internal/core/algorithm/ngt/ngt.go +++ b/internal/core/algorithm/ngt/ngt.go @@ -97,9 +97,11 @@ type ( radius float32 epsilon float32 poolSize uint32 - cnt uint64 + cnt atomic.Uint64 prop C.NGTProperty - epool sync.Pool + epool sync.Pool // NGT error buffer pool + eps atomic.Uint64 // NGT error buffer pool size + epl uint64 // NGT error buffer pool size limit index C.NGTIndex ospace C.NGTObjectSpace mu *sync.RWMutex @@ -276,7 +278,7 @@ func (n *ngt) setup() error { }, } - for i := 0; i < 20; i++ { + for i := uint64(0); i < n.epl; i++ { n.PutErrorBuffer(C.ngt_create_error_object()) } @@ -411,7 +413,7 @@ func (n *ngt) Search(ctx context.Context, vec []float32, size int, epsilon, radi rsize := int(C.ngt_get_result_size(results, ebuf)) if rsize <= 0 { - if atomic.LoadUint64(&n.cnt) == 0 { + if n.cnt.Load() == 0 { n.PutErrorBuffer(ebuf) return nil, errors.ErrSearchResultEmptyButNoDataStored } @@ -476,7 +478,7 @@ func (n *ngt) LinearSearch(ctx context.Context, vec []float32, size int) (result rsize := int(C.ngt_get_result_size(results, ebuf)) if rsize <= 0 { - if atomic.LoadUint64(&n.cnt) == 0 { + if n.cnt.Load() == 0 { n.PutErrorBuffer(ebuf) return nil, errors.ErrSearchResultEmptyButNoDataStored } @@ -510,21 +512,24 @@ func (n *ngt) LinearSearch(ctx context.Context, vec []float32, size int) (result // Insert returns NGT object id. // This only stores not indexing, you must call CreateIndex and SaveIndex. func (n *ngt) Insert(vec []float32) (id uint, err error) { - dim := int(n.dimension) - if len(vec) != dim { - return 0, errors.ErrIncompatibleDimensionSize(len(vec), dim) + if len(vec) != int(n.dimension) { + return 0, errors.ErrIncompatibleDimensionSize(len(vec), int(n.dimension)) } - + dim := C.uint32_t(n.dimension) + cvec := (*C.float)(&vec[0]) ebuf := n.GetErrorBuffer() n.lock(true) - id = uint(C.ngt_insert_index_as_float(n.index, (*C.float)(&vec[0]), C.uint32_t(n.dimension), ebuf)) + oid := C.ngt_insert_index_as_float(n.index, cvec, dim, ebuf) n.unlock(true) + id = uint(oid) + cvec = nil + vec = vec[:0:0] vec = nil if id == 0 { return 0, n.newGoError(ebuf) } n.PutErrorBuffer(ebuf) - atomic.AddUint64(&n.cnt, 1) + n.cnt.Add(1) return id, nil } @@ -676,7 +681,7 @@ func (n *ngt) Remove(id uint) error { } n.PutErrorBuffer(ebuf) - atomic.AddUint64(&n.cnt, ^uint64(0)) + n.cnt.Add(^uint64(0)) return nil } @@ -742,32 +747,30 @@ func (n *ngt) newGoError(ebuf C.NGTError) (err error) { n.PutErrorBuffer(ebuf) return nil } - n.PutErrorBuffer(C.ngt_create_error_object()) + if n.epl == 0 || n.eps.Load() < n.epl { + n.PutErrorBuffer(C.ngt_create_error_object()) + } C.ngt_destroy_error_object(ebuf) return errors.NewNGTError(msg) } -// Close NGT index. -func (n *ngt) Close() { - if n.index != nil { - C.ngt_close_index(n.index) - n.index = nil - n.prop = nil - n.ospace = nil - } -} - func (n *ngt) GetErrorBuffer() (ebuf C.NGTError) { var ok bool ebuf, ok = n.epool.Get().(C.NGTError) if !ok { ebuf = C.ngt_create_error_object() } + n.eps.Add(^uint64(0)) return ebuf } func (n *ngt) PutErrorBuffer(ebuf C.NGTError) { + if n.epl != 0 && n.eps.Load() > n.epl { + C.ngt_destroy_error_object(ebuf) + return + } n.epool.Put(ebuf) + n.eps.Add(1) } func (n *ngt) lock(cLock bool) { @@ -797,3 +800,13 @@ func (n *ngt) rUnlock(cLock bool) { n.cmu.RUnlock() } } + +// Close NGT index. +func (n *ngt) Close() { + if n.index != nil { + C.ngt_close_index(n.index) + n.index = nil + n.prop = nil + n.ospace = nil + } +} diff --git a/internal/core/algorithm/ngt/ngt_bench_test.go b/internal/core/algorithm/ngt/ngt_bench_test.go new file mode 100644 index 0000000000..dc0b8404ba --- /dev/null +++ b/internal/core/algorithm/ngt/ngt_bench_test.go @@ -0,0 +1,164 @@ +// +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package ngt provides implementation of Go API for https://github.com/yahoojapan/NGT +package ngt + +import ( + "fmt" + "os" + "runtime" + "testing" + + "github.com/vdaas/vald/internal/strings" + "gonum.org/v1/hdf5" +) + +var ( + vectors [][]float32 + n NGT + pid int +) + +func init() { + vectors, _, _ = load("sift-128-euclidean.hdf5") + n, _ = New( + WithDimension(len(vectors[0])), + WithDefaultPoolSize(8), + WithObjectType(Float), + WithDistanceType(L2), + ) + pid = os.Getpid() +} + +func BenchmarkNGT(b *testing.B) { + b.Logf("# of vectors: %v", len(vectors)) + output := func(header string) { + status := fmt.Sprintf("/proc/%d/status", pid) + buf, err := os.ReadFile(status) + if err != nil { + b.Fatal(err) + } + var vmpeak, vmrss, vmhwm string + for _, line := range strings.Split(string(buf), "\n") { + switch { + case strings.HasPrefix(line, "VmPeak"): + vmpeak = strings.Fields(line)[1] + case strings.HasPrefix(line, "VmHWM"): + vmhwm = strings.Fields(line)[1] + case strings.HasPrefix(line, "VmRSS"): + vmrss = strings.Fields(line)[1] + } + } + + var m runtime.MemStats + runtime.ReadMemStats(&m) + b.Logf("%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v", header, vmpeak, vmhwm, vmrss, m.Alloc/1024, m.TotalAlloc/1024, m.HeapAlloc/1024, m.HeapSys/1024, m.HeapInuse/1024) + } + b.Logf(" operation\tVmPeak\tVmHWM\tVmRSS\tAlloc\tTotalAlloc\tHeapAlloc\tHeapSys\tHeapInuse") + b.ResetTimer() + output(" start") + defer output(" end") + for N := 0; N < b.N; N++ { + for i := 0; i < 3; i++ { + ids := make([]uint, len(vectors)) + for idx, vector := range vectors { + id, err := n.Insert(vector) + if err != nil { + b.Fatal(err) + } + ids[idx] = id + } + output(" insert") + + if err := n.CreateIndex(8); err != nil { + b.Fatal(err) + } + output("create index") + + for _, id := range ids { + if err := n.Remove(id); err != nil { + b.Fatal(err) + } + } + output(" remove") + } + } +} + +// load function loads training and test vector from hdf file. The size of ids is same to the number of training data. +// Each id, which is an element of ids, will be set a random number. +func load(path string) (train, test [][]float32, err error) { + var f *hdf5.File + f, err = hdf5.OpenFile(path, hdf5.F_ACC_RDONLY) + if err != nil { + return nil, nil, err + } + defer f.Close() + + // readFn function reads vectors of the hierarchy with the given the name. + readFn := func(name string) ([][]float32, error) { + // Opens and returns a named Dataset. + // The returned dataset must be closed by the user when it is no longer needed. + d, err := f.OpenDataset(name) + if err != nil { + return nil, err + } + defer d.Close() + + // Space returns an identifier for a copy of the dataspace for a dataset. + sp := d.Space() + defer sp.Close() + + // SimpleExtentDims returns dataspace dimension size and maximum size. + dims, _, _ := sp.SimpleExtentDims() + row, dim := int(dims[0]), int(dims[1]) + + // Gets the stored vector. All are represented as one-dimensional arrays. + // The type of the slice depends on your dataset. + // For fashion-mnist-784-euclidean.hdf5, the datatype is float32. + vec := make([]float32, sp.SimpleExtentNPoints()) + if err := d.Read(&vec); err != nil { + return nil, err + } + + // Converts a one-dimensional array to a two-dimensional array. + // Use the `dim` variable as a separator. + vecs := make([][]float32, row) + for i := 0; i < row; i++ { + vecs[i] = make([]float32, dim) + for j := 0; j < dim; j++ { + vecs[i][j] = float32(vec[i*dim+j]) + } + } + + return vecs, nil + } + + // Gets vector of `train` hierarchy. + train, err = readFn("train") + if err != nil { + return nil, nil, err + } + + // Gets vector of `test` hierarchy. + test, err = readFn("test") + if err != nil { + return nil, nil, err + } + + return +} diff --git a/internal/core/algorithm/ngt/ngt_test.go b/internal/core/algorithm/ngt/ngt_test.go index 04c25ac8cc..a90992b5c0 100644 --- a/internal/core/algorithm/ngt/ngt_test.go +++ b/internal/core/algorithm/ngt/ngt_test.go @@ -24,7 +24,6 @@ import ( "os" "path/filepath" "reflect" - "strings" "testing" "github.com/vdaas/vald/internal/core/algorithm" @@ -32,6 +31,7 @@ import ( "github.com/vdaas/vald/internal/file" "github.com/vdaas/vald/internal/log" "github.com/vdaas/vald/internal/log/logger" + "github.com/vdaas/vald/internal/strings" "github.com/vdaas/vald/internal/sync" "github.com/vdaas/vald/internal/test/comparator" "github.com/vdaas/vald/internal/test/goleak" diff --git a/internal/core/algorithm/ngt/option.go b/internal/core/algorithm/ngt/option.go index 4ff074dd5a..29f9f74c10 100644 --- a/internal/core/algorithm/ngt/option.go +++ b/internal/core/algorithm/ngt/option.go @@ -51,6 +51,7 @@ var ( WithObjectType(Float), WithDistanceType(L2), WithBulkInsertChunkSize(100), + WithErrorBufferLimit(10), } ) @@ -315,3 +316,14 @@ func WithDefaultEpsilon(epsilon float32) Option { return nil } } + +// WithErrorBufferLimit represents the option to set the default error buffer pool size limit for NGT. +func WithErrorBufferLimit(limit uint64) Option { + return func(n *ngt) error { + if limit == 0 { + return errors.NewErrInvalidOption("errorBufferLimit", limit) + } + n.epl = limit + return nil + } +} diff --git a/internal/db/kvs/bbolt/bbolt_test.go b/internal/db/kvs/bbolt/bbolt_test.go index cb94504d36..24589ad2dc 100644 --- a/internal/db/kvs/bbolt/bbolt_test.go +++ b/internal/db/kvs/bbolt/bbolt_test.go @@ -211,3 +211,335 @@ func Test_bbolt_AsyncSet(t *testing.T) { } // NOT IMPLEMENTED BELOW +// +// func Test_bbolt_Set(t *testing.T) { +// type args struct { +// key []byte +// val []byte +// } +// type fields struct { +// db *bolt.DB +// file string +// bucket []byte +// } +// type want struct { +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// key:nil, +// val:nil, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// key:nil, +// val:nil, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// b := &bbolt{ +// db: test.fields.db, +// file: test.fields.file, +// bucket: test.fields.bucket, +// } +// +// err := b.Set(test.args.key, test.args.val) +// if err := checkFunc(test.want, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// +// func Test_bbolt_Get(t *testing.T) { +// type args struct { +// key []byte +// } +// type fields struct { +// db *bolt.DB +// file string +// bucket []byte +// } +// type want struct { +// wantVal []byte +// wantOk bool +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, []byte, bool, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotVal []byte, gotOk bool, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotVal, w.wantVal) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotVal, w.wantVal) +// } +// if !reflect.DeepEqual(gotOk, w.wantOk) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotOk, w.wantOk) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// key:nil, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// key:nil, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// b := &bbolt{ +// db: test.fields.db, +// file: test.fields.file, +// bucket: test.fields.bucket, +// } +// +// gotVal, gotOk, err := b.Get(test.args.key) +// if err := checkFunc(test.want, gotVal, gotOk, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// +// func Test_bbolt_Close(t *testing.T) { +// type args struct { +// remove bool +// } +// type fields struct { +// db *bolt.DB +// file string +// bucket []byte +// } +// type want struct { +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// remove:false, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// remove:false, +// }, +// fields: fields { +// db:nil, +// file:"", +// bucket:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// b := &bbolt{ +// db: test.fields.db, +// file: test.fields.file, +// bucket: test.fields.bucket, +// } +// +// err := b.Close(test.args.remove) +// if err := checkFunc(test.want, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 3fd58dc0ec..28780cf817 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -22,8 +22,8 @@ import ( "fmt" "reflect" "runtime" - "strings" + "github.com/vdaas/vald/internal/strings" "github.com/vdaas/vald/internal/sync" ) diff --git a/internal/io/copy_test.go b/internal/io/copy_test.go index f1cf6bba79..8faf58f649 100644 --- a/internal/io/copy_test.go +++ b/internal/io/copy_test.go @@ -343,3 +343,323 @@ func Test_copier_Copy(t *testing.T) { } // NOT IMPLEMENTED BELOW +// +// func TestCopyBuffer(t *testing.T) { +// type args struct { +// src io.Reader +// buf []byte +// } +// type want struct { +// wantWritten int64 +// wantDst string +// err error +// } +// type test struct { +// name string +// args args +// want want +// checkFunc func(want, int64, string, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotWritten int64, gotDst string, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotWritten, w.wantWritten) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotWritten, w.wantWritten) +// } +// if !reflect.DeepEqual(gotDst, w.wantDst) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotDst, w.wantDst) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// src:nil, +// buf:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// src:nil, +// buf:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// dst := &bytes.Buffer{} +// +// gotWritten, err := CopyBuffer(dst, test.args.src, test.args.buf) +// if err := checkFunc(test.want, gotWritten, err, dst.String()); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// +// func Test_copier_CopyBuffer(t *testing.T) { +// type args struct { +// src io.Reader +// buf []byte +// } +// type fields struct { +// bufSize int64 +// } +// type want struct { +// wantWritten int64 +// wantDst string +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, int64, string, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotWritten int64, gotDst string, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotWritten, w.wantWritten) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotWritten, w.wantWritten) +// } +// if !reflect.DeepEqual(gotDst, w.wantDst) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotDst, w.wantDst) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// src:nil, +// buf:nil, +// }, +// fields: fields { +// bufSize:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// src:nil, +// buf:nil, +// }, +// fields: fields { +// bufSize:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// c := &copier{ +// bufSize: test.fields.bufSize, +// } +// dst := &bytes.Buffer{} +// +// gotWritten, err := c.CopyBuffer(dst, test.args.src, test.args.buf) +// if err := checkFunc(test.want, gotWritten, err, dst.String()); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// +// func Test_copier_copyBuffer(t *testing.T) { +// type args struct { +// src io.Reader +// buf *bytes.Buffer +// } +// type fields struct { +// bufSize int64 +// } +// type want struct { +// wantWritten int64 +// wantDst string +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, int64, string, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotWritten int64, gotDst string, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotWritten, w.wantWritten) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotWritten, w.wantWritten) +// } +// if !reflect.DeepEqual(gotDst, w.wantDst) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotDst, w.wantDst) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// src:nil, +// buf:bytes.Buffer{}, +// }, +// fields: fields { +// bufSize:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// src:nil, +// buf:bytes.Buffer{}, +// }, +// fields: fields { +// bufSize:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// c := &copier{ +// bufSize: test.fields.bufSize, +// } +// dst := &bytes.Buffer{} +// +// gotWritten, err := c.copyBuffer(dst, test.args.src, test.args.buf) +// if err := checkFunc(test.want, gotWritten, err, dst.String()); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } diff --git a/internal/net/grpc/client.go b/internal/net/grpc/client.go index c6c77b5ad9..29729a8516 100644 --- a/internal/net/grpc/client.go +++ b/internal/net/grpc/client.go @@ -95,7 +95,7 @@ type gRPCClient struct { addrs map[string]struct{} poolSize uint64 clientCount uint64 - conns grpcConns + conns sync.Map[string, pool.Conn] hcDur time.Duration prDur time.Duration dialer net.Dialer @@ -216,7 +216,7 @@ func (g *gRPCClient) StartConnectionMonitor(ctx context.Context) (<-chan error, return ctx.Err() case <-prTick.C: if g.enablePoolRebalance { - err = g.conns.Range(func(addr string, p pool.Conn) bool { + err = g.rangeConns(func(addr string, p pool.Conn) bool { // if addr or pool is nil or empty the registration of conns is invalid let's disconnect them if len(addr) == 0 || p == nil { disconnectTargets = append(disconnectTargets, addr) @@ -253,7 +253,7 @@ func (g *gRPCClient) StartConnectionMonitor(ctx context.Context) (<-chan error, }) } case <-hcTick.C: - err = g.conns.Range(func(addr string, p pool.Conn) bool { + err = g.rangeConns(func(addr string, p pool.Conn) bool { // if addr or pool is nil or empty the registration of conns is invalid let's disconnect them if len(addr) == 0 || p == nil { disconnectTargets = append(disconnectTargets, addr) @@ -367,7 +367,7 @@ func (g *gRPCClient) Range(ctx context.Context, if g.conns.Len() == 0 { return errors.ErrGRPCClientConnNotFound("*") } - err = g.conns.Range(func(addr string, p pool.Conn) bool { + err = g.rangeConns(func(addr string, p pool.Conn) bool { ssctx, sspan := trace.StartSpan(sctx, apiName+"/Client.Range/"+addr) defer func() { if sspan != nil { @@ -428,7 +428,7 @@ func (g *gRPCClient) RangeConcurrent(ctx context.Context, if g.conns.Len() == 0 { return errors.ErrGRPCClientConnNotFound("*") } - err = g.conns.Range(func(addr string, p pool.Conn) bool { + err = g.rangeConns(func(addr string, p pool.Conn) bool { eg.Go(safety.RecoverFunc(func() (err error) { ssctx, sspan := trace.StartSpan(egctx, apiName+"/Client.RangeConcurrent/"+addr) defer func() { @@ -644,7 +644,7 @@ func (g *gRPCClient) RoundRobin(ctx context.Context, f func(ctx context.Context, } do := func() (data interface{}, err error) { - cerr := g.conns.Range(func(addr string, p pool.Conn) bool { + cerr := g.rangeConns(func(addr string, p pool.Conn) bool { select { case <-ctx.Done(): err = ctx.Err() @@ -1010,7 +1010,7 @@ func (g *gRPCClient) Disconnect(ctx context.Context, addr string) error { func (g *gRPCClient) ConnectedAddrs() (addrs []string) { addrs = make([]string, 0, g.conns.Len()) - err := g.conns.Range(func(addr string, p pool.Conn) bool { + err := g.rangeConns(func(addr string, p pool.Conn) bool { if p != nil && p.IsHealthy(context.Background()) { addrs = append(addrs, addr) } @@ -1035,3 +1035,15 @@ func (g *gRPCClient) Close(ctx context.Context) (err error) { }) return err } + +func (g *gRPCClient) rangeConns(fn func(addr string, p pool.Conn) bool) error { + var cnt int + g.conns.Range(func(addr string, p pool.Conn) bool { + cnt++ + return fn(addr, p) + }) + if cnt == 0 { + return errors.ErrGRPCClientConnNotFound("*") + } + return nil +} diff --git a/internal/net/grpc/context.go b/internal/net/grpc/context.go index a95bfca402..827a19b440 100644 --- a/internal/net/grpc/context.go +++ b/internal/net/grpc/context.go @@ -15,7 +15,8 @@ package grpc import ( "context" - "strings" + + "github.com/vdaas/vald/internal/strings" ) type contextKey string diff --git a/internal/net/grpc/grpcconns.go b/internal/net/grpc/grpcconns.go deleted file mode 100644 index c38be7181e..0000000000 --- a/internal/net/grpc/grpcconns.go +++ /dev/null @@ -1,251 +0,0 @@ -// -// Copyright (C) 2019-2023 vdaas.org vald team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// You may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// Package grpc provides generic functionality for grpc -package grpc - -import ( - "sync/atomic" - "unsafe" - - "github.com/vdaas/vald/internal/errors" - "github.com/vdaas/vald/internal/net/grpc/pool" - "github.com/vdaas/vald/internal/sync" -) - -type grpcConns struct { - mu sync.Mutex - read atomic.Pointer[readOnlyGrpcConns] - dirty map[string]*entryGrpcConns - misses int -} - -type readOnlyGrpcConns struct { - m map[string]*entryGrpcConns - amended bool -} - -// skipcq: GSC-G103 -var expungedGrpcConns = unsafe.Pointer(new(pool.Conn)) - -type entryGrpcConns struct { - p unsafe.Pointer -} - -func newEntryGrpcConns(i pool.Conn) *entryGrpcConns { - // skipcq: GSC-G103 - return &entryGrpcConns{p: unsafe.Pointer(&i)} -} - -func (m *grpcConns) load() (read readOnlyGrpcConns) { - r := m.read.Load() - if r != nil { - return *r - } - read = readOnlyGrpcConns{} - old := m.read.Swap(&read) - if old != nil { - m.read.Store(old) - return *old - } - return read -} - -func (m *grpcConns) Load(key string) (value pool.Conn, ok bool) { - read := m.load() - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read = m.load() - e, ok = read.m[key] - if !ok && read.amended { - e, ok = m.dirty[key] - m.missLocked() - } - m.mu.Unlock() - } - if !ok { - return value, false - } - return e.load() -} - -func (e *entryGrpcConns) load() (value pool.Conn, ok bool) { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expungedGrpcConns { - return value, false - } - return *(*pool.Conn)(p), true -} - -func (m *grpcConns) Store(key string, value pool.Conn) { - read := m.load() - if e, ok := read.m[key]; ok && e.tryStore(&value) { - return - } - - m.mu.Lock() - read = m.load() - if e, ok := read.m[key]; ok { - if e.unexpungeLocked() { - m.dirty[key] = e - } - e.storeLocked(&value) - } else if e, ok := m.dirty[key]; ok { - e.storeLocked(&value) - } else { - if !read.amended { - m.dirtyLocked() - m.read.Store(&readOnlyGrpcConns{m: read.m, amended: true}) - } - m.dirty[key] = newEntryGrpcConns(value) - } - m.mu.Unlock() -} - -func (e *entryGrpcConns) tryStore(i *pool.Conn) bool { - for { - p := atomic.LoadPointer(&e.p) - if p == expungedGrpcConns { - return false - } - // skipcq: GSC-G103 - if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) { - return true - } - } -} - -func (e *entryGrpcConns) unexpungeLocked() (wasExpunged bool) { - return atomic.CompareAndSwapPointer(&e.p, expungedGrpcConns, nil) -} - -func (e *entryGrpcConns) storeLocked(i *pool.Conn) { - // skipcq: GSC-G103 - atomic.StorePointer(&e.p, unsafe.Pointer(i)) -} - -func (m *grpcConns) Delete(key string) { - read := m.load() - e, ok := read.m[key] - if !ok && read.amended { - m.mu.Lock() - read = m.load() - e, ok = read.m[key] - if !ok && read.amended { - delete(m.dirty, key) - } - m.mu.Unlock() - } - if ok { - e.delete() - } -} - -func (e *entryGrpcConns) delete() (hadValue bool) { - for { - p := atomic.LoadPointer(&e.p) - if p == nil || p == expungedGrpcConns { - return false - } - if atomic.CompareAndSwapPointer(&e.p, p, nil) { - return true - } - } -} - -func (m *grpcConns) Range(f func(key string, value pool.Conn) bool) (err error) { - read := m.load() - if read.amended { - m.mu.Lock() - read = m.load() - if read.amended { - read = readOnlyGrpcConns{m: m.dirty} - m.read.Store(&read) - m.dirty = nil - m.misses = 0 - } - m.mu.Unlock() - } - - var cnt int - for k, e := range read.m { - v, ok := e.load() - if !ok { - continue - } - cnt++ - if !f(k, v) { - return nil - } - } - if cnt == 0 { - return errors.ErrGRPCClientConnNotFound("*") - } - return nil -} - -func (m *grpcConns) Len() int { - read := m.load() - if read.amended { - m.mu.Lock() - read = m.load() - if read.amended { - read = readOnlyGrpcConns{m: m.dirty} - m.read.Store(&read) - m.dirty = nil - m.misses = 0 - } - m.mu.Unlock() - } - - return len(read.m) -} - -func (m *grpcConns) missLocked() { - m.misses++ - if m.misses < len(m.dirty) { - return - } - m.read.Store(&readOnlyGrpcConns{m: m.dirty}) - m.dirty = nil - m.misses = 0 -} - -func (m *grpcConns) dirtyLocked() { - if m.dirty != nil { - return - } - - read := m.load() - m.dirty = make(map[string]*entryGrpcConns, len(read.m)) - for k, e := range read.m { - if !e.tryExpungeLocked() { - m.dirty[k] = e - } - } -} - -func (e *entryGrpcConns) tryExpungeLocked() (isExpunged bool) { - p := atomic.LoadPointer(&e.p) - for p == nil { - if atomic.CompareAndSwapPointer(&e.p, nil, expungedGrpcConns) { - return true - } - p = atomic.LoadPointer(&e.p) - } - return p == expungedGrpcConns -} diff --git a/internal/net/grpc/grpcconns_test.go b/internal/net/grpc/grpcconns_test.go deleted file mode 100644 index 89c5ecc88a..0000000000 --- a/internal/net/grpc/grpcconns_test.go +++ /dev/null @@ -1,1458 +0,0 @@ -// Copyright (C) 2019-2023 vdaas.org vald team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// You may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package grpc - -// NOT IMPLEMENTED BELOW -// -// func Test_newEntryGrpcConns(t *testing.T) { -// type args struct { -// i pool.Conn -// } -// type want struct { -// want *entryGrpcConns -// } -// type test struct { -// name string -// args args -// want want -// checkFunc func(want, *entryGrpcConns) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want, got *entryGrpcConns) error { -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// i:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// i:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// -// got := newEntryGrpcConns(test.args.i) -// if err := checkFunc(test.want, got); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_load(t *testing.T) { -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// wantRead readOnlyGrpcConns -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, readOnlyGrpcConns) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, gotRead readOnlyGrpcConns) error { -// if !reflect.DeepEqual(gotRead, w.wantRead) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRead, w.wantRead) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// gotRead := m.load() -// if err := checkFunc(test.want, gotRead); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_Load(t *testing.T) { -// type args struct { -// key string -// } -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// wantValue pool.Conn -// wantOk bool -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want, pool.Conn, bool) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want, gotValue pool.Conn, gotOk bool) error { -// if !reflect.DeepEqual(gotValue, w.wantValue) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotValue, w.wantValue) -// } -// if !reflect.DeepEqual(gotOk, w.wantOk) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotOk, w.wantOk) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// key:"", -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// key:"", -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// gotValue, gotOk := m.Load(test.args.key) -// if err := checkFunc(test.want, gotValue, gotOk); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_entryGrpcConns_load(t *testing.T) { -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// wantValue pool.Conn -// wantOk bool -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, pool.Conn, bool) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, gotValue pool.Conn, gotOk bool) error { -// if !reflect.DeepEqual(gotValue, w.wantValue) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotValue, w.wantValue) -// } -// if !reflect.DeepEqual(gotOk, w.wantOk) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotOk, w.wantOk) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// gotValue, gotOk := e.load() -// if err := checkFunc(test.want, gotValue, gotOk); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_Store(t *testing.T) { -// type args struct { -// key string -// value pool.Conn -// } -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want) error { -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// key:"", -// value:nil, -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// key:"", -// value:nil, -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// m.Store(test.args.key, test.args.value) -// if err := checkFunc(test.want); err != nil { -// tt.Errorf("error = %v", err) -// } -// }) -// } -// } -// -// func Test_entryGrpcConns_tryStore(t *testing.T) { -// type args struct { -// i *pool.Conn -// } -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// want bool -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want, bool) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want, got bool) error { -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// i:nil, -// }, -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// i:nil, -// }, -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// got := e.tryStore(test.args.i) -// if err := checkFunc(test.want, got); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_entryGrpcConns_unexpungeLocked(t *testing.T) { -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// wantWasExpunged bool -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, bool) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, gotWasExpunged bool) error { -// if !reflect.DeepEqual(gotWasExpunged, w.wantWasExpunged) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotWasExpunged, w.wantWasExpunged) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// gotWasExpunged := e.unexpungeLocked() -// if err := checkFunc(test.want, gotWasExpunged); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_entryGrpcConns_storeLocked(t *testing.T) { -// type args struct { -// i *pool.Conn -// } -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want) error { -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// i:nil, -// }, -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// i:nil, -// }, -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// e.storeLocked(test.args.i) -// if err := checkFunc(test.want); err != nil { -// tt.Errorf("error = %v", err) -// } -// }) -// } -// } -// -// func Test_grpcConns_Delete(t *testing.T) { -// type args struct { -// key string -// } -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want) error { -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// key:"", -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// key:"", -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// m.Delete(test.args.key) -// if err := checkFunc(test.want); err != nil { -// tt.Errorf("error = %v", err) -// } -// }) -// } -// } -// -// func Test_entryGrpcConns_delete(t *testing.T) { -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// wantHadValue bool -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, bool) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, gotHadValue bool) error { -// if !reflect.DeepEqual(gotHadValue, w.wantHadValue) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotHadValue, w.wantHadValue) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// gotHadValue := e.delete() -// if err := checkFunc(test.want, gotHadValue); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_Range(t *testing.T) { -// type args struct { -// f func(key string, value pool.Conn) bool -// } -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// err error -// } -// type test struct { -// name string -// args args -// fields fields -// want want -// checkFunc func(want, error) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want, err error) error { -// if !errors.Is(err, w.err) { -// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// f:nil, -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// f:nil, -// }, -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// err := m.Range(test.args.f) -// if err := checkFunc(test.want, err); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_Len(t *testing.T) { -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// want int -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, int) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, got int) error { -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// got := m.Len() -// if err := checkFunc(test.want, got); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// -// func Test_grpcConns_missLocked(t *testing.T) { -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want) error { -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// m.missLocked() -// if err := checkFunc(test.want); err != nil { -// tt.Errorf("error = %v", err) -// } -// }) -// } -// } -// -// func Test_grpcConns_dirtyLocked(t *testing.T) { -// type fields struct { -// read atomic.Pointer[readOnlyGrpcConns] -// dirty map[string]*entryGrpcConns -// misses int -// } -// type want struct { -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want) error { -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// read:nil, -// dirty:nil, -// misses:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// m := &grpcConns{ -// read: test.fields.read, -// dirty: test.fields.dirty, -// misses: test.fields.misses, -// } -// -// m.dirtyLocked() -// if err := checkFunc(test.want); err != nil { -// tt.Errorf("error = %v", err) -// } -// }) -// } -// } -// -// func Test_entryGrpcConns_tryExpungeLocked(t *testing.T) { -// type fields struct { -// p unsafe.Pointer -// } -// type want struct { -// wantIsExpunged bool -// } -// type test struct { -// name string -// fields fields -// want want -// checkFunc func(want, bool) error -// beforeFunc func(*testing.T) -// afterFunc func(*testing.T) -// } -// defaultCheckFunc := func(w want, gotIsExpunged bool) error { -// if !reflect.DeepEqual(gotIsExpunged, w.wantIsExpunged) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotIsExpunged, w.wantIsExpunged) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// fields: fields { -// p:nil, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T,) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T,) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// e := &entryGrpcConns{ -// p: test.fields.p, -// } -// -// gotIsExpunged := e.tryExpungeLocked() -// if err := checkFunc(test.want, gotIsExpunged); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } diff --git a/internal/net/grpc/pool/pool.go b/internal/net/grpc/pool/pool.go index 8f195bc2c1..16980f4341 100644 --- a/internal/net/grpc/pool/pool.go +++ b/internal/net/grpc/pool/pool.go @@ -36,7 +36,6 @@ import ( "github.com/vdaas/vald/internal/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials/insecure" ) type ( @@ -95,31 +94,35 @@ func New(ctx context.Context, opts ...Option) (c Conn, err error) { p.init(true) p.closing.Store(false) - var isIPv4, isIPv6 bool + var ( + isIPv4, isIPv6 bool + port uint16 + ) p.host, p.port, _, isIPv4, isIPv6, err = net.Parse(p.addr) p.isIP = isIPv4 || isIPv6 if err != nil { log.Warnf("failed to parse addr %s: %s", p.addr, err) if p.host == "" { var ( - ok bool - port string + ok bool + portStr string ) - p.host, port, ok = strings.Cut(p.addr, ":") + p.host, portStr, ok = strings.Cut(p.addr, ":") if !ok { p.host = p.addr } else { - portNum, err := strconv.ParseUint(port, 10, 16) + portNum, err := strconv.ParseUint(portStr, 10, 16) if err != nil { p.port = uint16(portNum) } } } if p.port == 0 { - err = p.scanGRPCPort(ctx) + port, err = p.scanGRPCPort(ctx) if err != nil { return nil, err } + p.port = port } p.addr = net.JoinHostPort(p.host, p.port) } @@ -133,10 +136,12 @@ func New(ctx context.Context, opts ...Option) (c Conn, err error) { log.Warn("failed to close connection:", err) } } - err = p.scanGRPCPort(ctx) + + port, err := p.scanGRPCPort(ctx) if err != nil { return nil, err } + p.port = port p.addr = net.JoinHostPort(p.host, p.port) conn, err = grpc.DialContext(ctx, p.addr, p.dopts...) if err != nil { @@ -642,23 +647,33 @@ func (p *pool) lookupIPAddr(ctx context.Context) (ips []string, err error) { return ips, nil } -func (p *pool) scanGRPCPort(ctx context.Context) (err error) { +func (p *pool) scanGRPCPort(ctx context.Context) (port uint16, err error) { ports, err := net.ScanPorts(ctx, p.startPort, p.endPort, p.host) if err != nil { - return err + return 0, err } + var conn *ClientConn for _, port := range ports { select { case <-ctx.Done(): - return ctx.Err() + return 0, ctx.Err() default: - if isGRPCPort(ctx, p.host, port) { - p.port = port - return nil + // try gRPC dialing to target port + conn, err = grpc.DialContext(ctx, + net.JoinHostPort(p.host, port), + append(p.dopts, grpc.WithBlock())...) + + if err == nil && isHealthy(conn) && conn.Close() == nil { + // if no error and healthy the port is ready for gRPC + return port, nil + } + + if conn != nil { + _ = conn.Close() } } } - return errors.ErrInvalidGRPCPort(p.addr, p.host, p.port) + return 0, errors.ErrInvalidGRPCPort(p.addr, p.host, p.port) } func (p *pool) IsIPConn() (isIP bool) { @@ -733,22 +748,6 @@ func (pc *poolConn) Close(ctx context.Context, delay time.Duration) error { } } -func isGRPCPort(ctx context.Context, host string, port uint16) bool { - ctx, cancel := context.WithTimeout(ctx, time.Millisecond*5) - defer cancel() - conn, err := grpc.DialContext(ctx, - net.JoinHostPort(host, port), - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock()) - if err != nil { - if conn != nil { - _ = conn.Close() - } - return false - } - return conn.Close() == nil -} - func isHealthy(conn *ClientConn) bool { if conn == nil { log.Warn("gRPC target connection is nil") @@ -762,7 +761,7 @@ func isHealthy(conn *ClientConn) bool { log.Debugf("gRPC target %s's connection status will be Ready soon\tstatus: %s", conn.Target(), state.String()) return true case connectivity.Idle: - log.Debugf("gRPC target %s's connection status is waiting for target\tstatus: %s", conn.Target(), state.String()) + log.Warnf("gRPC target %s's connection status is waiting for target\tstatus: %s", conn.Target(), state.String()) return false case connectivity.Shutdown, connectivity.TransientFailure: log.Errorf("gRPC target %s's connection status is unhealthy\tstatus: %s", conn.Target(), state.String()) diff --git a/internal/net/grpc/pool/pool_bench_test.go b/internal/net/grpc/pool/pool_bench_test.go index 08823c4d5d..f287b64c43 100644 --- a/internal/net/grpc/pool/pool_bench_test.go +++ b/internal/net/grpc/pool/pool_bench_test.go @@ -33,7 +33,7 @@ import ( const ( DefaultServerAddr = "localhost:5001" - DefaultPoolSize = 10 + DefaultPoolSize = 4 ) type server struct { @@ -61,6 +61,7 @@ func (*server) Nodes(context.Context, *payload.Discoverer_Request) (*payload.Inf } func ListenAndServe(b *testing.B, addr string) func() { + b.Helper() lis, err := net.Listen("tcp", addr) if err != nil { b.Error(err) diff --git a/internal/net/grpc/pool/pool_test.go b/internal/net/grpc/pool/pool_test.go index b76a8e9640..a0455869c1 100644 --- a/internal/net/grpc/pool/pool_test.go +++ b/internal/net/grpc/pool/pool_test.go @@ -3533,21 +3533,25 @@ package pool // reconnectHash atomic.Pointer[string] // } // type want struct { -// err error +// wantPort uint16 +// err error // } // type test struct { // name string // args args // fields fields // want want -// checkFunc func(want, error) error +// checkFunc func(want, uint16, error) error // beforeFunc func(*testing.T, args) // afterFunc func(*testing.T, args) // } -// defaultCheckFunc := func(w want, err error) error { +// defaultCheckFunc := func(w want, gotPort uint16, err error) error { // if !errors.Is(err, w.err) { // return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) // } +// if !reflect.DeepEqual(gotPort, w.wantPort) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotPort, w.wantPort) +// } // return nil // } // tests := []test{ @@ -3663,8 +3667,8 @@ package pool // reconnectHash: test.fields.reconnectHash, // } // -// err := p.scanGRPCPort(test.args.ctx) -// if err := checkFunc(test.want, err); err != nil { +// gotPort, err := p.scanGRPCPort(test.args.ctx) +// if err := checkFunc(test.want, gotPort, err); err != nil { // tt.Errorf("error = %v", err) // } // @@ -4084,98 +4088,6 @@ package pool // } // } // -// func Test_isGRPCPort(t *testing.T) { -// type args struct { -// ctx context.Context -// host string -// port uint16 -// } -// type want struct { -// want bool -// } -// type test struct { -// name string -// args args -// want want -// checkFunc func(want, bool) error -// beforeFunc func(*testing.T, args) -// afterFunc func(*testing.T, args) -// } -// defaultCheckFunc := func(w want, got bool) error { -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) -// } -// return nil -// } -// tests := []test{ -// // TODO test cases -// /* -// { -// name: "test_case_1", -// args: args { -// ctx:nil, -// host:"", -// port:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// }, -// */ -// -// // TODO test cases -// /* -// func() test { -// return test { -// name: "test_case_2", -// args: args { -// ctx:nil, -// host:"", -// port:0, -// }, -// want: want{}, -// checkFunc: defaultCheckFunc, -// beforeFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// afterFunc: func(t *testing.T, args args) { -// t.Helper() -// }, -// } -// }(), -// */ -// } -// -// for _, tc := range tests { -// test := tc -// t.Run(test.name, func(tt *testing.T) { -// tt.Parallel() -// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) -// if test.beforeFunc != nil { -// test.beforeFunc(tt, test.args) -// } -// if test.afterFunc != nil { -// defer test.afterFunc(tt, test.args) -// } -// checkFunc := test.checkFunc -// if test.checkFunc == nil { -// checkFunc = defaultCheckFunc -// } -// -// got := isGRPCPort(test.args.ctx, test.args.host, test.args.port) -// if err := checkFunc(test.want, got); err != nil { -// tt.Errorf("error = %v", err) -// } -// -// }) -// } -// } -// // func Test_isHealthy(t *testing.T) { // type args struct { // conn *ClientConn diff --git a/internal/net/grpc/stream_test.go b/internal/net/grpc/stream_test.go index 27438cbdde..c65aebd935 100644 --- a/internal/net/grpc/stream_test.go +++ b/internal/net/grpc/stream_test.go @@ -295,3 +295,92 @@ func TestBidirectionalStream(t *testing.T) { // }) // } // } +// +// func Test_removeDuplicates(t *testing.T) { +// type args struct { +// x S +// less func(left, right E) int +// } +// type want struct { +// want S +// } +// type test struct { +// name string +// args args +// want want +// checkFunc func(want, S) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, got S) error { +// if !reflect.DeepEqual(got, w.want) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// x:nil, +// less:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// x:nil, +// less:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// +// got := removeDuplicates(test.args.x, test.args.less) +// if err := checkFunc(test.want, got); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } diff --git a/internal/strings/strings.go b/internal/strings/strings.go index 55060db866..e5ef6de97e 100644 --- a/internal/strings/strings.go +++ b/internal/strings/strings.go @@ -22,36 +22,63 @@ import ( ) type ( - Builder = strings.Builder + Builder = strings.Builder + Reader = strings.Reader + Replacer = strings.Replacer ) var ( + Clone = strings.Clone + Compare = strings.Compare Contains = strings.Contains + ContainsAny = strings.ContainsAny + ContainsFunc = strings.ContainsFunc + ContainsRune = strings.ContainsRune Count = strings.Count Cut = strings.Cut + CutPrefix = strings.CutPrefix + CutSuffix = strings.CutSuffix EqualFold = strings.EqualFold + Fields = strings.Fields + FieldsFunc = strings.FieldsFunc HasPrefix = strings.HasPrefix HasSuffix = strings.HasSuffix Index = strings.Index IndexAny = strings.IndexAny - NewReader = strings.NewReader - NewReplacer = strings.NewReplacer + IndexByte = strings.IndexByte + IndexFunc = strings.IndexFunc + IndexRune = strings.IndexRune + LastIndex = strings.LastIndex + LastIndexAny = strings.LastIndexAny + LastIndexByte = strings.LastIndexByte + LastIndexFunc = strings.LastIndexFunc + Map = strings.Map + Repeat = strings.Repeat Replace = strings.Replace ReplaceAll = strings.ReplaceAll Split = strings.Split SplitAfter = strings.SplitAfter SplitAfterN = strings.SplitAfterN SplitN = strings.SplitN + Title = strings.Title ToLower = strings.ToLower ToLowerSpecial = strings.ToLowerSpecial + ToTitle = strings.ToTitle + ToTitleSpecial = strings.ToTitleSpecial ToUpper = strings.ToUpper ToUpperSpecial = strings.ToUpperSpecial + ToValidUTF8 = strings.ToValidUTF8 Trim = strings.Trim + TrimFunc = strings.TrimFunc TrimLeft = strings.TrimLeft + TrimLeftFunc = strings.TrimLeftFunc TrimPrefix = strings.TrimPrefix TrimRight = strings.TrimRight + TrimRightFunc = strings.TrimRightFunc TrimSpace = strings.TrimSpace TrimSuffix = strings.TrimSuffix + NewReader = strings.NewReader + NewReplacer = strings.NewReplacer bufferPool = sync.Pool{ New: func() interface{} { diff --git a/internal/sync/semaphore/semaphore_test.go b/internal/sync/semaphore/semaphore_test.go index 6290b6affa..d55037c7f7 100644 --- a/internal/sync/semaphore/semaphore_test.go +++ b/internal/sync/semaphore/semaphore_test.go @@ -322,9 +322,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n int64 // } // type fields struct { +// waiters list.List // size int64 // cur int64 -// waiters list.List // } // type want struct { // err error @@ -354,9 +354,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -379,9 +379,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -412,9 +412,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // checkFunc = defaultCheckFunc // } // s := &Weighted{ +// waiters: test.fields.waiters, // size: test.fields.size, // cur: test.fields.cur, -// waiters: test.fields.waiters, // } // // err := s.Acquire(test.args.ctx, test.args.n) @@ -431,9 +431,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n int64 // } // type fields struct { +// waiters list.List // size int64 // cur int64 -// waiters list.List // } // type want struct { // want bool @@ -462,9 +462,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -486,9 +486,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -519,9 +519,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // checkFunc = defaultCheckFunc // } // s := &Weighted{ +// waiters: test.fields.waiters, // size: test.fields.size, // cur: test.fields.cur, -// waiters: test.fields.waiters, // } // // got := s.TryAcquire(test.args.n) @@ -538,9 +538,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n int64 // } // type fields struct { +// waiters list.List // size int64 // cur int64 -// waiters list.List // } // type want struct { // } @@ -565,9 +565,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -589,9 +589,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -622,9 +622,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // checkFunc = defaultCheckFunc // } // s := &Weighted{ +// waiters: test.fields.waiters, // size: test.fields.size, // cur: test.fields.cur, -// waiters: test.fields.waiters, // } // // s.Release(test.args.n) @@ -640,9 +640,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n int64 // } // type fields struct { +// waiters list.List // size int64 // cur int64 -// waiters list.List // } // type want struct { // } @@ -667,9 +667,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -691,9 +691,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // n:0, // }, // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -724,9 +724,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // checkFunc = defaultCheckFunc // } // s := &Weighted{ +// waiters: test.fields.waiters, // size: test.fields.size, // cur: test.fields.cur, -// waiters: test.fields.waiters, // } // // s.Resize(test.args.n) @@ -739,9 +739,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // // func TestWeighted_notifyWaiters(t *testing.T) { // type fields struct { +// waiters list.List // size int64 // cur int64 -// waiters list.List // } // type want struct { // } @@ -762,9 +762,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // { // name: "test_case_1", // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -783,9 +783,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // return test { // name: "test_case_2", // fields: fields { +// waiters:nil, // size:0, // cur:0, -// waiters:nil, // }, // want: want{}, // checkFunc: defaultCheckFunc, @@ -816,9 +816,9 @@ func TestAllocCancelDoesntStarve(t *testing.T) { // checkFunc = defaultCheckFunc // } // s := &Weighted{ +// waiters: test.fields.waiters, // size: test.fields.size, // cur: test.fields.cur, -// waiters: test.fields.waiters, // } // // s.notifyWaiters() diff --git a/internal/sync/singleflight/singleflight_test.go b/internal/sync/singleflight/singleflight_test.go index ca8f74cfc9..cd8df7f5e6 100644 --- a/internal/sync/singleflight/singleflight_test.go +++ b/internal/sync/singleflight/singleflight_test.go @@ -25,13 +25,13 @@ import ( "os/exec" "reflect" "runtime" - "strings" "sync/atomic" "testing" "time" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/info" + "github.com/vdaas/vald/internal/strings" "github.com/vdaas/vald/internal/sync" "github.com/vdaas/vald/internal/test/goleak" ) diff --git a/k8s/agent/configmap.yaml b/k8s/agent/configmap.yaml index 0e57796161..95c8d5db53 100644 --- a/k8s/agent/configmap.yaml +++ b/k8s/agent/configmap.yaml @@ -215,6 +215,7 @@ data: enable_copy_on_write: false enable_in_memory_mode: true enable_proactive_gc: false + error_buffer_limit: 10 index_path: "" initial_delay_max_duration: 3m kvsdb: diff --git a/k8s/operator/helm/crds/valdrelease.yaml b/k8s/operator/helm/crds/valdrelease.yaml index 46c151ab94..cb424153b8 100644 --- a/k8s/operator/helm/crds/valdrelease.yaml +++ b/k8s/operator/helm/crds/valdrelease.yaml @@ -250,6 +250,9 @@ spec: type: boolean enable_proactive_gc: type: boolean + error_buffer_limit: + type: integer + minimum: 1 index_path: type: string initial_delay_max_duration: diff --git a/pkg/agent/core/ngt/service/ngt.go b/pkg/agent/core/ngt/service/ngt.go index 3b598ceb7e..cdfe518702 100644 --- a/pkg/agent/core/ngt/service/ngt.go +++ b/pkg/agent/core/ngt/service/ngt.go @@ -192,6 +192,7 @@ func New(cfg *config.NGT, opts ...Option) (nn NGT, err error) { core.WithBulkInsertChunkSize(cfg.BulkInsertChunkSize), core.WithCreationEdgeSize(cfg.CreationEdgeSize), core.WithSearchEdgeSize(cfg.SearchEdgeSize), + core.WithErrorBufferLimit(cfg.ErrorBufferLimit), ) if err != nil { return nil, err diff --git a/pkg/agent/core/ngt/service/ngt_test.go b/pkg/agent/core/ngt/service/ngt_test.go index 1153d4308e..1ec884c64d 100644 --- a/pkg/agent/core/ngt/service/ngt_test.go +++ b/pkg/agent/core/ngt/service/ngt_test.go @@ -1553,8 +1553,8 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // historyLimit int // } // type want struct { -// want *payload.Search_Response -// err error +// wantRes *payload.Search_Response +// err error // } // type test struct { // name string @@ -1565,12 +1565,12 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // beforeFunc func(*testing.T, args) // afterFunc func(*testing.T, args) // } -// defaultCheckFunc := func(w want, got *payload.Search_Response, err error) error { +// defaultCheckFunc := func(w want, gotRes *payload.Search_Response, err error) error { // if !errors.Is(err, w.err) { // return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) // } -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) +// if !reflect.DeepEqual(gotRes, w.wantRes) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes) // } // return nil // } @@ -1752,8 +1752,8 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // historyLimit: test.fields.historyLimit, // } // -// got, err := n.Search(test.args.ctx, test.args.vec, test.args.size, test.args.epsilon, test.args.radius) -// if err := checkFunc(test.want, got, err); err != nil { +// gotRes, err := n.Search(test.args.ctx, test.args.vec, test.args.size, test.args.epsilon, test.args.radius) +// if err := checkFunc(test.want, gotRes, err); err != nil { // tt.Errorf("error = %v", err) // } // @@ -2022,6 +2022,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // // func Test_ngt_LinearSearch(t *testing.T) { // type args struct { +// ctx context.Context // vec []float32 // size uint32 // } @@ -2064,8 +2065,8 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // historyLimit int // } // type want struct { -// want *payload.Search_Response -// err error +// wantRes *payload.Search_Response +// err error // } // type test struct { // name string @@ -2076,12 +2077,12 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // beforeFunc func(*testing.T, args) // afterFunc func(*testing.T, args) // } -// defaultCheckFunc := func(w want, got *payload.Search_Response, err error) error { +// defaultCheckFunc := func(w want, gotRes *payload.Search_Response, err error) error { // if !errors.Is(err, w.err) { // return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) // } -// if !reflect.DeepEqual(got, w.want) { -// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) +// if !reflect.DeepEqual(gotRes, w.wantRes) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotRes, w.wantRes) // } // return nil // } @@ -2091,6 +2092,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // { // name: "test_case_1", // args: args { +// ctx:nil, // vec:nil, // size:0, // }, @@ -2149,6 +2151,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // return test { // name: "test_case_2", // args: args { +// ctx:nil, // vec:nil, // size:0, // }, @@ -2257,8 +2260,8 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // historyLimit: test.fields.historyLimit, // } // -// got, err := n.LinearSearch(test.args.vec, test.args.size) -// if err := checkFunc(test.want, got, err); err != nil { +// gotRes, err := n.LinearSearch(test.args.ctx, test.args.vec, test.args.size) +// if err := checkFunc(test.want, gotRes, err); err != nil { // tt.Errorf("error = %v", err) // } // @@ -2268,6 +2271,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // // func Test_ngt_LinearSearchByID(t *testing.T) { // type args struct { +// ctx context.Context // uuid string // size uint32 // } @@ -2341,6 +2345,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // { // name: "test_case_1", // args: args { +// ctx:nil, // uuid:"", // size:0, // }, @@ -2399,6 +2404,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // return test { // name: "test_case_2", // args: args { +// ctx:nil, // uuid:"", // size:0, // }, @@ -2507,7 +2513,7 @@ func createRandomData(num int, cfg *createRandomDataConfig) []index { // historyLimit: test.fields.historyLimit, // } // -// gotVec, gotDst, err := n.LinearSearchByID(test.args.uuid, test.args.size) +// gotVec, gotDst, err := n.LinearSearchByID(test.args.ctx, test.args.uuid, test.args.size) // if err := checkFunc(test.want, gotVec, gotDst, err); err != nil { // tt.Errorf("error = %v", err) // } diff --git a/pkg/agent/core/ngt/service/vqueue/queue_test.go b/pkg/agent/core/ngt/service/vqueue/queue_test.go index a1dca0d2c5..4f95baca22 100644 --- a/pkg/agent/core/ngt/service/vqueue/queue_test.go +++ b/pkg/agent/core/ngt/service/vqueue/queue_test.go @@ -967,6 +967,115 @@ func TestGetVector(t *testing.T) { // } // } // +// func Test_vqueue_Range(t *testing.T) { +// type args struct { +// ctx context.Context +// f func(uuid string, vector []float32, ts int64) bool +// } +// type fields struct { +// il sync.Map[string, *index] +// dl sync.Map[string, *index] +// ic uint64 +// dc uint64 +// } +// type want struct { +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want) error { +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// ctx:nil, +// f:nil, +// }, +// fields: fields { +// il:nil, +// dl:nil, +// ic:0, +// dc:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// ctx:nil, +// f:nil, +// }, +// fields: fields { +// il:nil, +// dl:nil, +// ic:0, +// dc:0, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// v := &vqueue{ +// il: test.fields.il, +// dl: test.fields.dl, +// ic: test.fields.ic, +// dc: test.fields.dc, +// } +// +// v.Range(test.args.ctx, test.args.f) +// if err := checkFunc(test.want); err != nil { +// tt.Errorf("error = %v", err) +// } +// }) +// } +// } +// // func Test_vqueue_IVQLen(t *testing.T) { // type fields struct { // il sync.Map[string, *index] diff --git a/pkg/gateway/filter/handler/grpc/handler_test.go b/pkg/gateway/filter/handler/grpc/handler_test.go index 0538955db6..cb78dcc7e4 100644 --- a/pkg/gateway/filter/handler/grpc/handler_test.go +++ b/pkg/gateway/filter/handler/grpc/handler_test.go @@ -6974,6 +6974,180 @@ package grpc // } // } // +// func Test_server_RemoveByTimestamp(t *testing.T) { +// type args struct { +// ctx context.Context +// req *payload.Remove_TimestampRequest +// } +// type fields struct { +// eg errgroup.Group +// defaultVectorizer string +// defaultFilters []string +// name string +// ip string +// ingress ingress.Client +// egress egress.Client +// gateway client.Client +// copts []grpc.CallOption +// streamConcurrency int +// Vectorizer string +// DistanceFilters []string +// ObjectFilters []string +// SearchFilters []string +// InsertFilters []string +// UpdateFilters []string +// UpsertFilters []string +// UnimplementedValdServerWithFilter vald.UnimplementedValdServerWithFilter +// } +// type want struct { +// want *payload.Object_Locations +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, *payload.Object_Locations, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, got *payload.Object_Locations, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(got, w.want) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", got, w.want) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// ctx:nil, +// req:nil, +// }, +// fields: fields { +// eg:nil, +// defaultVectorizer:"", +// defaultFilters:nil, +// name:"", +// ip:"", +// ingress:nil, +// egress:nil, +// gateway:nil, +// copts:nil, +// streamConcurrency:0, +// Vectorizer:"", +// DistanceFilters:nil, +// ObjectFilters:nil, +// SearchFilters:nil, +// InsertFilters:nil, +// UpdateFilters:nil, +// UpsertFilters:nil, +// UnimplementedValdServerWithFilter:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// ctx:nil, +// req:nil, +// }, +// fields: fields { +// eg:nil, +// defaultVectorizer:"", +// defaultFilters:nil, +// name:"", +// ip:"", +// ingress:nil, +// egress:nil, +// gateway:nil, +// copts:nil, +// streamConcurrency:0, +// Vectorizer:"", +// DistanceFilters:nil, +// ObjectFilters:nil, +// SearchFilters:nil, +// InsertFilters:nil, +// UpdateFilters:nil, +// UpsertFilters:nil, +// UnimplementedValdServerWithFilter:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// s := &server{ +// eg: test.fields.eg, +// defaultVectorizer: test.fields.defaultVectorizer, +// defaultFilters: test.fields.defaultFilters, +// name: test.fields.name, +// ip: test.fields.ip, +// ingress: test.fields.ingress, +// egress: test.fields.egress, +// gateway: test.fields.gateway, +// copts: test.fields.copts, +// streamConcurrency: test.fields.streamConcurrency, +// Vectorizer: test.fields.Vectorizer, +// DistanceFilters: test.fields.DistanceFilters, +// ObjectFilters: test.fields.ObjectFilters, +// SearchFilters: test.fields.SearchFilters, +// InsertFilters: test.fields.InsertFilters, +// UpdateFilters: test.fields.UpdateFilters, +// UpsertFilters: test.fields.UpsertFilters, +// UnimplementedValdServerWithFilter: test.fields.UnimplementedValdServerWithFilter, +// } +// +// got, err := s.RemoveByTimestamp(test.args.ctx, test.args.req) +// if err := checkFunc(test.want, got, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// // func Test_server_GetObject(t *testing.T) { // type args struct { // ctx context.Context diff --git a/pkg/gateway/lb/handler/grpc/handler_test.go b/pkg/gateway/lb/handler/grpc/handler_test.go index 77afaa590c..928adb73e0 100644 --- a/pkg/gateway/lb/handler/grpc/handler_test.go +++ b/pkg/gateway/lb/handler/grpc/handler_test.go @@ -3495,6 +3495,144 @@ package grpc // } // } // +// func Test_server_RemoveByTimestamp(t *testing.T) { +// type args struct { +// ctx context.Context +// req *payload.Remove_TimestampRequest +// } +// type fields struct { +// eg errgroup.Group +// gateway service.Gateway +// timeout time.Duration +// replica int +// streamConcurrency int +// multiConcurrency int +// name string +// ip string +// UnimplementedValdServer vald.UnimplementedValdServer +// } +// type want struct { +// wantLocs *payload.Object_Locations +// err error +// } +// type test struct { +// name string +// args args +// fields fields +// want want +// checkFunc func(want, *payload.Object_Locations, error) error +// beforeFunc func(*testing.T, args) +// afterFunc func(*testing.T, args) +// } +// defaultCheckFunc := func(w want, gotLocs *payload.Object_Locations, err error) error { +// if !errors.Is(err, w.err) { +// return errors.Errorf("got_error: \"%#v\",\n\t\t\t\twant: \"%#v\"", err, w.err) +// } +// if !reflect.DeepEqual(gotLocs, w.wantLocs) { +// return errors.Errorf("got: \"%#v\",\n\t\t\t\twant: \"%#v\"", gotLocs, w.wantLocs) +// } +// return nil +// } +// tests := []test{ +// // TODO test cases +// /* +// { +// name: "test_case_1", +// args: args { +// ctx:nil, +// req:nil, +// }, +// fields: fields { +// eg:nil, +// gateway:nil, +// timeout:nil, +// replica:0, +// streamConcurrency:0, +// multiConcurrency:0, +// name:"", +// ip:"", +// UnimplementedValdServer:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// }, +// */ +// +// // TODO test cases +// /* +// func() test { +// return test { +// name: "test_case_2", +// args: args { +// ctx:nil, +// req:nil, +// }, +// fields: fields { +// eg:nil, +// gateway:nil, +// timeout:nil, +// replica:0, +// streamConcurrency:0, +// multiConcurrency:0, +// name:"", +// ip:"", +// UnimplementedValdServer:nil, +// }, +// want: want{}, +// checkFunc: defaultCheckFunc, +// beforeFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// afterFunc: func(t *testing.T, args args) { +// t.Helper() +// }, +// } +// }(), +// */ +// } +// +// for _, tc := range tests { +// test := tc +// t.Run(test.name, func(tt *testing.T) { +// tt.Parallel() +// defer goleak.VerifyNone(tt, goleak.IgnoreCurrent()) +// if test.beforeFunc != nil { +// test.beforeFunc(tt, test.args) +// } +// if test.afterFunc != nil { +// defer test.afterFunc(tt, test.args) +// } +// checkFunc := test.checkFunc +// if test.checkFunc == nil { +// checkFunc = defaultCheckFunc +// } +// s := &server{ +// eg: test.fields.eg, +// gateway: test.fields.gateway, +// timeout: test.fields.timeout, +// replica: test.fields.replica, +// streamConcurrency: test.fields.streamConcurrency, +// multiConcurrency: test.fields.multiConcurrency, +// name: test.fields.name, +// ip: test.fields.ip, +// UnimplementedValdServer: test.fields.UnimplementedValdServer, +// } +// +// gotLocs, err := s.RemoveByTimestamp(test.args.ctx, test.args.req) +// if err := checkFunc(test.want, gotLocs, err); err != nil { +// tt.Errorf("error = %v", err) +// } +// +// }) +// } +// } +// // func Test_server_GetObject(t *testing.T) { // type args struct { // ctx context.Context diff --git a/tests/chaos/chart/README.md b/tests/chaos/chart/README.md index 0a5dbdc2cb..9cd7930487 100644 --- a/tests/chaos/chart/README.md +++ b/tests/chaos/chart/README.md @@ -41,4 +41,4 @@ A Helm chart for testing Vald using Chaos Mesh. --- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) +Autogenerated from chart metadata using [helm-docs v1.11.2](https://github.com/norwoodj/helm-docs/releases/v1.11.2) diff --git a/versions/HELM_DOCS_VERSION b/versions/HELM_DOCS_VERSION index 1cac385c6c..ca7176690d 100644 --- a/versions/HELM_DOCS_VERSION +++ b/versions/HELM_DOCS_VERSION @@ -1 +1 @@ -1.11.0 +1.11.2 diff --git a/versions/JAEGER_OPERATOR_VERSION b/versions/JAEGER_OPERATOR_VERSION index 64f878193d..bb13a7e354 100644 --- a/versions/JAEGER_OPERATOR_VERSION +++ b/versions/JAEGER_OPERATOR_VERSION @@ -1 +1 @@ -2.46.2 +2.47.0 diff --git a/versions/PROMETHEUS_STACK_VERSION b/versions/PROMETHEUS_STACK_VERSION index 4319c95d06..5412f0015a 100644 --- a/versions/PROMETHEUS_STACK_VERSION +++ b/versions/PROMETHEUS_STACK_VERSION @@ -1 +1 @@ -51.0.3 +51.2.0 diff --git a/versions/VALDCLI_VERSION b/versions/VALDCLI_VERSION index 5e6f203084..257d138aae 100644 --- a/versions/VALDCLI_VERSION +++ b/versions/VALDCLI_VERSION @@ -1 +1 @@ -v1.7.6.Rev2 +v1.7.8