From 376857c524f6d4fb68e2088f9603937ca8c41111 Mon Sep 17 00:00:00 2001 From: kpango Date: Mon, 25 May 2020 16:51:43 +0900 Subject: [PATCH 1/4] add agent sidecar Signed-off-by: kpango --- .github/labeler.yml | 16 +- .github/workflows/dockers-agent-ngt-image.yml | 12 +- .github/workflows/e2e-bench-agent.yml | 8 +- Makefile.d/bench.mk | 28 +- Makefile.d/docker.mk | 2 +- apis/docs/agent/{ => core}/docs.md | 10 +- apis/docs/agent/sidecar/docs.md | 57 + apis/grpc/agent/{ => core}/agent.pb.go | 158 +-- apis/grpc/agent/sidecar/sidecar.pb.go | 100 ++ apis/proto/agent/{ => core}/agent.proto | 6 +- apis/proto/agent/sidecar/sidecar.proto | 31 + .../agent/{ => core/core}/agent.swagger.json | 2 +- .../sidecar/sidecar/sidecar.swagger.json | 49 + cmd/agent/{ => core}/ngt/main.go | 4 +- cmd/agent/{ => core}/ngt/main_test.go | 0 cmd/agent/{ => core}/ngt/sample.yaml | 0 cmd/agent/{ => core}/sptag/.gitkeep | 0 cmd/agent/sidecar/main.go | 58 + cmd/agent/sidecar/main_test.go | 80 ++ dockers/agent/{ => core}/ngt/Dockerfile | 2 +- dockers/agent/sidecar/Dockerfile | 82 ++ go.mod | 1 + .../agent/{ => core}/ngt/ngt_bench_test.go | 2 +- .../starter/agent/{ => core}/ngt/ngt.go | 4 +- .../starter/agent/{ => core}/ngt/ngt_test.go | 2 +- .../starter/agent/{ => core}/ngt/option.go | 2 +- .../agent/{ => core}/ngt/option_test.go | 2 +- .../tools/config/agent/{ => core}/ngt/main.go | 2 +- .../config/agent/{ => core}/ngt/main_test.go | 0 .../config/agent/{ => core}/ngt/sample.yaml | 0 internal/client/agent/grpc/client.go | 2 +- internal/config/blob_test.go | 335 +++++ internal/config/sidecar.go | 38 + internal/config/sidecar_test.go | 108 ++ internal/db/storage/blob/blob_test.go | 452 +++++++ internal/db/storage/blob/option_test.go | 249 ++++ internal/db/storage/blob/s3/option_test.go | 701 ++++++++++ internal/db/storage/blob/s3/s3_test.go | 194 +++ internal/errors/file.go | 22 + internal/file/watch/option.go | 128 ++ internal/file/watch/option_test.go | 1155 +++++++++++++++++ internal/file/watch/watch.go | 188 +++ internal/file/watch/watch_test.go | 701 ++++++++++ .../metrics/agent/{ => core}/ngt/ngt.go | 2 +- .../metrics/agent/{ => core}/ngt/ngt_test.go | 2 +- pkg/agent/{ => core}/ngt/README.md | 0 pkg/agent/{ => core}/ngt/config/config.go | 0 .../{ => core}/ngt/config/config_test.go | 0 pkg/agent/{ => core}/ngt/handler/doc.go | 0 .../{ => core}/ngt/handler/grpc/handler.go | 6 +- .../ngt/handler/grpc/handler_test.go | 6 +- .../{ => core}/ngt/handler/grpc/option.go | 2 +- .../ngt/handler/grpc/option_test.go | 2 +- .../{ => core}/ngt/handler/rest/handler.go | 2 +- .../ngt/handler/rest/handler_test.go | 2 +- .../{ => core}/ngt/handler/rest/option.go | 2 +- .../ngt/handler/rest/option_test.go | 2 +- pkg/agent/{ => core}/ngt/model/ngt.go | 0 pkg/agent/{ => core}/ngt/router/option.go | 2 +- .../{ => core}/ngt/router/option_test.go | 2 +- pkg/agent/{ => core}/ngt/router/router.go | 2 +- .../{ => core}/ngt/router/router_test.go | 0 pkg/agent/{ => core}/ngt/service/doc.go | 0 pkg/agent/{ => core}/ngt/service/kvs/kvs.go | 0 .../{ => core}/ngt/service/kvs/kvs_test.go | 0 pkg/agent/{ => core}/ngt/service/kvs/ou.go | 0 .../{ => core}/ngt/service/kvs/ou_test.go | 0 pkg/agent/{ => core}/ngt/service/kvs/uo.go | 0 .../{ => core}/ngt/service/kvs/uo_test.go | 0 pkg/agent/{ => core}/ngt/service/ngt.go | 4 +- pkg/agent/{ => core}/ngt/service/ngt_test.go | 4 +- pkg/agent/{ => core}/ngt/service/vcaches.go | 0 .../{ => core}/ngt/service/vcaches_test.go | 0 pkg/agent/{ => core}/ngt/usecase/agentd.go | 14 +- .../{ => core}/ngt/usecase/agentd_test.go | 4 +- pkg/agent/{ => core}/sptag/.gitkeep | 0 pkg/agent/sidecar/README.md | 1 + pkg/agent/sidecar/config/config.go | 147 +++ pkg/agent/sidecar/config/config_test.go | 101 ++ pkg/agent/sidecar/handler/doc.go | 17 + pkg/agent/sidecar/handler/grpc/handler.go | 36 + .../sidecar/handler/grpc/handler_test.go | 98 ++ pkg/agent/sidecar/handler/grpc/option.go | 36 + pkg/agent/sidecar/handler/grpc/option_test.go | 138 ++ pkg/agent/sidecar/handler/rest/handler.go | 50 + .../sidecar/handler/rest/handler_test.go | 190 +++ pkg/agent/sidecar/handler/rest/option.go | 34 + pkg/agent/sidecar/handler/rest/option_test.go | 138 ++ pkg/agent/sidecar/router/option.go | 42 + pkg/agent/sidecar/router/option_test.go | 252 ++++ pkg/agent/sidecar/router/router.go | 52 + pkg/agent/sidecar/router/router_test.go | 96 ++ pkg/agent/sidecar/service/doc.go | 18 + pkg/agent/sidecar/service/option.go | 100 ++ pkg/agent/sidecar/service/option_test.go | 590 +++++++++ pkg/agent/sidecar/service/storage_observer.go | 143 ++ .../sidecar/service/storage_observer_test.go | 309 +++++ pkg/agent/sidecar/usecase/sidecard.go | 183 +++ pkg/agent/sidecar/usecase/sidecard_test.go | 611 +++++++++ pkg/gateway/vald/handler/grpc/handler.go | 2 +- pkg/gateway/vald/handler/grpc/handler_test.go | 2 +- pkg/gateway/vald/service/gateway.go | 2 +- pkg/gateway/vald/service/gateway_test.go | 2 +- pkg/manager/index/service/indexer.go | 2 +- pkg/tools/cli/loadtest/usecase/load.go | 2 +- pkg/tools/cli/loadtest/usecase/load_test.go | 2 +- 106 files changed, 8283 insertions(+), 166 deletions(-) rename apis/docs/agent/{ => core}/docs.md (97%) create mode 100644 apis/docs/agent/sidecar/docs.md rename apis/grpc/agent/{ => core}/agent.pb.go (85%) create mode 100644 apis/grpc/agent/sidecar/sidecar.pb.go rename apis/proto/agent/{ => core}/agent.proto (96%) create mode 100644 apis/proto/agent/sidecar/sidecar.proto rename apis/swagger/agent/{ => core/core}/agent.swagger.json (99%) create mode 100644 apis/swagger/agent/sidecar/sidecar/sidecar.swagger.json rename cmd/agent/{ => core}/ngt/main.go (93%) rename cmd/agent/{ => core}/ngt/main_test.go (100%) rename cmd/agent/{ => core}/ngt/sample.yaml (100%) rename cmd/agent/{ => core}/sptag/.gitkeep (100%) mode change 100755 => 100644 create mode 100644 cmd/agent/sidecar/main.go create mode 100644 cmd/agent/sidecar/main_test.go rename dockers/agent/{ => core}/ngt/Dockerfile (99%) create mode 100644 dockers/agent/sidecar/Dockerfile rename hack/benchmark/e2e/agent/{ => core}/ngt/ngt_bench_test.go (97%) rename hack/benchmark/internal/starter/agent/{ => core}/ngt/ngt.go (93%) rename hack/benchmark/internal/starter/agent/{ => core}/ngt/ngt_test.go (98%) rename hack/benchmark/internal/starter/agent/{ => core}/ngt/option.go (98%) rename hack/benchmark/internal/starter/agent/{ => core}/ngt/option_test.go (99%) rename hack/tools/config/agent/{ => core}/ngt/main.go (94%) rename hack/tools/config/agent/{ => core}/ngt/main_test.go (100%) rename hack/tools/config/agent/{ => core}/ngt/sample.yaml (100%) create mode 100644 internal/config/blob_test.go create mode 100644 internal/config/sidecar.go create mode 100644 internal/config/sidecar_test.go create mode 100644 internal/db/storage/blob/option_test.go create mode 100644 internal/db/storage/blob/s3/option_test.go create mode 100644 internal/db/storage/blob/s3/s3_test.go create mode 100644 internal/errors/file.go create mode 100644 internal/file/watch/option.go create mode 100644 internal/file/watch/option_test.go create mode 100644 internal/file/watch/watch.go create mode 100644 internal/file/watch/watch_test.go rename internal/observability/metrics/agent/{ => core}/ngt/ngt.go (98%) rename internal/observability/metrics/agent/{ => core}/ngt/ngt_test.go (99%) rename pkg/agent/{ => core}/ngt/README.md (100%) mode change 100755 => 100644 rename pkg/agent/{ => core}/ngt/config/config.go (100%) rename pkg/agent/{ => core}/ngt/config/config_test.go (100%) rename pkg/agent/{ => core}/ngt/handler/doc.go (100%) rename pkg/agent/{ => core}/ngt/handler/grpc/handler.go (98%) rename pkg/agent/{ => core}/ngt/handler/grpc/handler_test.go (99%) rename pkg/agent/{ => core}/ngt/handler/grpc/option.go (94%) rename pkg/agent/{ => core}/ngt/handler/grpc/option_test.go (99%) rename pkg/agent/{ => core}/ngt/handler/rest/handler.go (99%) rename pkg/agent/{ => core}/ngt/handler/rest/handler_test.go (99%) rename pkg/agent/{ => core}/ngt/handler/rest/option.go (93%) rename pkg/agent/{ => core}/ngt/handler/rest/option_test.go (98%) rename pkg/agent/{ => core}/ngt/model/ngt.go (100%) rename pkg/agent/{ => core}/ngt/router/option.go (95%) rename pkg/agent/{ => core}/ngt/router/option_test.go (99%) rename pkg/agent/{ => core}/ngt/router/router.go (98%) rename pkg/agent/{ => core}/ngt/router/router_test.go (100%) rename pkg/agent/{ => core}/ngt/service/doc.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/kvs.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/kvs_test.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/ou.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/ou_test.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/uo.go (100%) rename pkg/agent/{ => core}/ngt/service/kvs/uo_test.go (100%) rename pkg/agent/{ => core}/ngt/service/ngt.go (99%) rename pkg/agent/{ => core}/ngt/service/ngt_test.go (99%) rename pkg/agent/{ => core}/ngt/service/vcaches.go (100%) rename pkg/agent/{ => core}/ngt/service/vcaches_test.go (100%) rename pkg/agent/{ => core}/ngt/usecase/agentd.go (92%) rename pkg/agent/{ => core}/ngt/usecase/agentd_test.go (99%) rename pkg/agent/{ => core}/sptag/.gitkeep (100%) mode change 100755 => 100644 create mode 100644 pkg/agent/sidecar/README.md create mode 100644 pkg/agent/sidecar/config/config.go create mode 100644 pkg/agent/sidecar/config/config_test.go create mode 100644 pkg/agent/sidecar/handler/doc.go create mode 100644 pkg/agent/sidecar/handler/grpc/handler.go create mode 100644 pkg/agent/sidecar/handler/grpc/handler_test.go create mode 100644 pkg/agent/sidecar/handler/grpc/option.go create mode 100644 pkg/agent/sidecar/handler/grpc/option_test.go create mode 100644 pkg/agent/sidecar/handler/rest/handler.go create mode 100644 pkg/agent/sidecar/handler/rest/handler_test.go create mode 100644 pkg/agent/sidecar/handler/rest/option.go create mode 100644 pkg/agent/sidecar/handler/rest/option_test.go create mode 100644 pkg/agent/sidecar/router/option.go create mode 100644 pkg/agent/sidecar/router/option_test.go create mode 100644 pkg/agent/sidecar/router/router.go create mode 100644 pkg/agent/sidecar/router/router_test.go create mode 100644 pkg/agent/sidecar/service/doc.go create mode 100644 pkg/agent/sidecar/service/option.go create mode 100644 pkg/agent/sidecar/service/option_test.go create mode 100644 pkg/agent/sidecar/service/storage_observer.go create mode 100644 pkg/agent/sidecar/service/storage_observer_test.go create mode 100644 pkg/agent/sidecar/usecase/sidecard.go create mode 100644 pkg/agent/sidecar/usecase/sidecard_test.go diff --git a/.github/labeler.yml b/.github/labeler.yml index a1bb269f85..8c1fe4f425 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,8 +1,14 @@ -area/agent: - - apis/proto/agent/**/* - - apis/grpc/agent/**/* - - cmd/agent/**/* - - pkg/agent/**/* +area/agent/core: + - apis/proto/agent/core/**/* + - apis/grpc/agent/core/**/* + - cmd/agent/core/**/* + - pkg/agent/core/**/* + +area/agent/sidecar: + - apis/proto/agent/sidecar/**/* + - apis/grpc/agent/sidecar/**/* + - cmd/agent/sidecar/**/* + - pkg/agent/sidecar/**/* area/discoverer: - apis/proto/discoverer/**/* diff --git a/.github/workflows/dockers-agent-ngt-image.yml b/.github/workflows/dockers-agent-ngt-image.yml index d827402d4c..54ac7bc631 100755 --- a/.github/workflows/dockers-agent-ngt-image.yml +++ b/.github/workflows/dockers-agent-ngt-image.yml @@ -13,10 +13,10 @@ on: - '!internal/db/**' - '!internal/k8s/**' - 'apis/grpc/**' - - 'pkg/agent/ngt/**' - - 'cmd/agent/ngt/**' + - 'pkg/agent/core/ngt/**' + - 'cmd/agent/core/ngt/**' - 'dockers/base/Dockerfile' - - 'dockers/agent/ngt/Dockerfile' + - 'dockers/agent/core/ngt/Dockerfile' - 'versions/GO_VERSION' - 'versions/NGT_VERSION' pull_request: @@ -25,10 +25,10 @@ on: - '!internal/db/**' - '!internal/k8s/**' - 'apis/grpc/**' - - 'pkg/agent/ngt/**' - - 'cmd/agent/ngt/**' + - 'pkg/agent/core/ngt/**' + - 'cmd/agent/core/ngt/**' - 'dockers/base/Dockerfile' - - 'dockers/agent/ngt/Dockerfile' + - 'dockers/agent/core/ngt/Dockerfile' - 'versions/GO_VERSION' - 'versions/NGT_VERSION' diff --git a/.github/workflows/e2e-bench-agent.yml b/.github/workflows/e2e-bench-agent.yml index 8269f26f78..bcab8a867a 100644 --- a/.github/workflows/e2e-bench-agent.yml +++ b/.github/workflows/e2e-bench-agent.yml @@ -7,8 +7,8 @@ on: - '.github/workflows/e2e-bench-agent.yml' - 'internal/**' - 'apis/grpc/**' - - 'pkg/agent/ngt/**' - - 'cmd/agent/ngt/**' + - 'pkg/agent/core/ngt/**' + - 'cmd/agent/core/ngt/**' - 'hack/benchmark/**' - 'versions/GO_VERSION' - 'versions/NGT_VERSION' @@ -17,8 +17,8 @@ on: - '.github/workflows/e2e-bench-agent.yml' - 'internal/**' - 'apis/grpc/**' - - 'pkg/agent/ngt/**' - - 'cmd/agent/ngt/**' + - 'pkg/agent/core/ngt/**' + - 'cmd/agent/core/ngt/**' - 'hack/benchmark/**' - 'versions/GO_VERSION' - 'versions/NGT_VERSION' diff --git a/Makefile.d/bench.mk b/Makefile.d/bench.mk index 8b65aee14f..da6113f1f8 100644 --- a/Makefile.d/bench.mk +++ b/Makefile.d/bench.mk @@ -110,24 +110,24 @@ bench/agent: \ ## run benchmark for agent gRPC stream bench/agent/stream: \ ngt/install - $(call bench-pprof,pprof/agent/ngt,agent,gRPC_Stream,stream,\ - ./hack/benchmark/e2e/agent/ngt/ngt_bench_test.go \ + $(call bench-pprof,pprof/agent/core/ngt,agent,gRPC_Stream,stream,\ + ./hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go \ -dataset=$(DATASET_ARGS)) .PHONY: bench/agent/sequential/grpc ## run benchmark for agent gRPC sequential bench/agent/sequential/grpc: \ ngt/install - $(call bench-pprof,pprof/agent/ngt,agent,gRPC_Sequential,sequential-grpc,\ - ./hack/benchmark/e2e/agent/ngt/ngt_bench_test.go \ + $(call bench-pprof,pprof/agent/core/ngt,agent,gRPC_Sequential,sequential-grpc,\ + ./hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go \ -dataset=$(DATASET_ARGS)) .PHONY: bench/agent/sequential/rest ## run benchmark for agent REST bench/agent/sequential/rest: \ ngt/install - $(call bench-pprof,pprof/agent/ngt,agent,REST_Sequential,sequential-rest,\ - ./hack/benchmark/e2e/agent/ngt/ngt_bench_test.go \ + $(call bench-pprof,pprof/agent/core/ngt,agent,REST_Sequential,sequential-rest,\ + ./hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go \ -dataset=$(DATASET_ARGS)) .PHONY: bench/ngtd @@ -186,15 +186,15 @@ profile: \ .PHONY: profile/agent/stream profile/agent/stream: - $(call profile-web,pprof/agent/ngt,agent,stream,":6061",":6062",":6063") + $(call profile-web,pprof/agent/core/ngt,agent,stream,":6061",":6062",":6063") .PHONY: profile/agent/sequential/grpc profile/agent/sequential/grpc: - $(call profile-web,pprof/agent/ngt,agent,sequential-grpc,":6061",":6062",":6063") + $(call profile-web,pprof/agent/core/ngt,agent,sequential-grpc,":6061",":6062",":6063") .PHONY: profile/agent/sequential/rest profile/agent/sequential/rest: - $(call profile-web,pprof/agent/ngt,agent,sequential-rest,":6061",":6062",":6063") + $(call profile-web,pprof/agent/core/ngt,agent,sequential-rest,":6061",":6062",":6063") .PHONY: profile/ngtd/stream profile/ngtd/stream: @@ -216,14 +216,14 @@ metrics: \ .PHONY: metrics/agent ## calculate agent metrics metrics/agent: \ - metrics/agent/ngt + metrics/agent/core/ngt -.PHONY: metrics/agent/ngt -## calculate agent/ngt metrics -metrics/agent/ngt: $(ROOTDIR)/metrics.gob +.PHONY: metrics/agent/core/ngt +## calculate agent/core/ngt metrics +metrics/agent/core/ngt: $(ROOTDIR)/metrics.gob $(ROOTDIR)/metrics.gob: - go test -v --timeout=1h ./hack/benchmark/e2e/agent/ngt/... -output=$(ROOTDIR)/metrics.gob + go test -v --timeout=1h ./hack/benchmark/e2e/agent/core/ngt/... -output=$(ROOTDIR)/metrics.gob .PHONY: metrics/chart ## create metrics chart diff --git a/Makefile.d/docker.mk b/Makefile.d/docker.mk index 03c02da24a..2d9517b3c3 100644 --- a/Makefile.d/docker.mk +++ b/Makefile.d/docker.mk @@ -44,7 +44,7 @@ docker/name/agent-ngt: .PHONY: docker/build/agent-ngt ## build agent-ngt image docker/build/agent-ngt: docker/build/base - docker build -f dockers/agent/ngt/Dockerfile -t $(REPO)/$(AGENT_IMAGE) . + docker build -f dockers/agent/core/ngt/Dockerfile -t $(REPO)/$(AGENT_IMAGE) . .PHONY: docker/name/discoverer-k8s docker/name/discoverer-k8s: diff --git a/apis/docs/agent/docs.md b/apis/docs/agent/core/docs.md similarity index 97% rename from apis/docs/agent/docs.md rename to apis/docs/agent/core/docs.md index a805b95857..f06f2ce893 100644 --- a/apis/docs/agent/docs.md +++ b/apis/docs/agent/core/docs.md @@ -3,17 +3,17 @@ ## Table of Contents -- [agent.proto](#agent.proto) - - [Agent](#agent.Agent) +- [core/agent.proto](#core/agent.proto) + - [Agent](#core.Agent) - [Scalar Value Types](#scalar-value-types) - +

Top

-## agent.proto +## core/agent.proto @@ -23,7 +23,7 @@ - + ### Agent diff --git a/apis/docs/agent/sidecar/docs.md b/apis/docs/agent/sidecar/docs.md new file mode 100644 index 0000000000..1994bfd4bd --- /dev/null +++ b/apis/docs/agent/sidecar/docs.md @@ -0,0 +1,57 @@ +# Protocol Documentation + + +## Table of Contents + +- [sidecar/sidecar.proto](#sidecar/sidecar.proto) + - [Sidecar](#sidecar.Sidecar) + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## sidecar/sidecar.proto + + + + + + + + + + + +### Sidecar + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | +| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | +| double | | double | double | float | float64 | double | float | Float | +| float | | float | float | float | float32 | float | float | Float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | +| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | + diff --git a/apis/grpc/agent/agent.pb.go b/apis/grpc/agent/core/agent.pb.go similarity index 85% rename from apis/grpc/agent/agent.pb.go rename to apis/grpc/agent/core/agent.pb.go index 7ebd49db1c..1f69fbcaae 100644 --- a/apis/grpc/agent/agent.pb.go +++ b/apis/grpc/agent/core/agent.pb.go @@ -14,7 +14,7 @@ // limitations under the License. // -package agent +package core import ( context "context" @@ -41,48 +41,48 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) } - -var fileDescriptor_56ede974c0020f77 = []byte{ - // 595 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x95, 0xdf, 0x6a, 0x13, 0x41, - 0x14, 0xc6, 0xdd, 0x62, 0x23, 0x99, 0xfc, 0xa9, 0x4c, 0x63, 0x5a, 0x97, 0x92, 0x42, 0x44, 0x90, - 0x5e, 0xcc, 0x88, 0x7a, 0x51, 0xc4, 0x0b, 0x9b, 0xa4, 0xad, 0x8b, 0x84, 0x4a, 0x83, 0x41, 0xbd, - 0x9b, 0xec, 0x4e, 0xb7, 0x2b, 0x9b, 0x99, 0xed, 0xcc, 0x24, 0x34, 0x88, 0x37, 0xbe, 0x82, 0x2f, - 0xd2, 0x7b, 0x5f, 0xc0, 0x4b, 0xc1, 0x17, 0x08, 0xc1, 0x07, 0x91, 0x9d, 0xd9, 0xa4, 0x49, 0x36, - 0x22, 0xd9, 0xcb, 0x3d, 0xe7, 0x7c, 0xbf, 0xf9, 0xbe, 0x81, 0xb3, 0x03, 0x0a, 0xc4, 0xa7, 0x4c, - 0xa1, 0x48, 0x70, 0xc5, 0xe1, 0xa6, 0xfe, 0xb0, 0x4b, 0x11, 0x19, 0x85, 0x9c, 0x78, 0xa6, 0x6a, - 0xef, 0xf9, 0x9c, 0xfb, 0x21, 0xc5, 0x24, 0x0a, 0x30, 0x61, 0x8c, 0x2b, 0xa2, 0x02, 0xce, 0x64, - 0xd2, 0x2d, 0x46, 0x3d, 0xec, 0x5f, 0x85, 0xe6, 0xeb, 0xd9, 0x8f, 0x02, 0xd8, 0x3c, 0x8a, 0x21, - 0xf0, 0x04, 0xe4, 0x8e, 0xaf, 0x03, 0xa9, 0x24, 0x84, 0x68, 0xca, 0x3b, 0xeb, 0x7d, 0xa6, 0xae, - 0x42, 0x4e, 0xcb, 0x5e, 0x51, 0xab, 0x57, 0xbe, 0xfd, 0xfe, 0xf3, 0x7d, 0xa3, 0x0c, 0x8b, 0x98, - 0x6a, 0x21, 0xfe, 0x12, 0x78, 0x5f, 0xe1, 0x19, 0xc8, 0x75, 0x28, 0x11, 0xee, 0x25, 0xdc, 0x99, - 0x69, 0x4c, 0x01, 0x9d, 0xd3, 0xab, 0x01, 0x95, 0xca, 0xde, 0x4d, 0x37, 0x64, 0xc4, 0x99, 0xa4, - 0x75, 0xa8, 0x91, 0xc5, 0xfa, 0x3d, 0x2c, 0x75, 0xe7, 0xa5, 0x75, 0x00, 0x3f, 0x00, 0x60, 0xc6, - 0x1a, 0x23, 0xa7, 0x05, 0x1f, 0x2e, 0x6b, 0x9d, 0xd6, 0xff, 0xb1, 0x0f, 0x34, 0x76, 0xab, 0x0e, - 0x12, 0x2c, 0x0e, 0xbc, 0x98, 0x7c, 0x0a, 0x8a, 0x1d, 0x25, 0x28, 0xe9, 0x67, 0x37, 0x7c, 0xe7, - 0x89, 0xf5, 0xd4, 0x82, 0x6d, 0x70, 0x7f, 0x1e, 0x94, 0xdd, 0xa8, 0xc1, 0xbd, 0x01, 0x39, 0x87, - 0x49, 0x2a, 0x14, 0xac, 0x2e, 0x5f, 0x7b, 0x97, 0xba, 0x8a, 0x0b, 0xbb, 0x3c, 0xab, 0x1f, 0xf7, - 0x23, 0x35, 0xaa, 0x57, 0x6f, 0xc6, 0xfb, 0xd6, 0xec, 0xee, 0x02, 0x2d, 0x8e, 0x13, 0xbe, 0x9a, - 0x26, 0x5c, 0x93, 0x67, 0x7c, 0x1c, 0x82, 0x42, 0x7b, 0x10, 0xaa, 0x20, 0x11, 0xef, 0xac, 0x16, - 0xcb, 0xb4, 0x3a, 0x4e, 0xf0, 0x3e, 0xf2, 0x88, 0xa2, 0x19, 0x13, 0x0c, 0xb4, 0x78, 0x21, 0xc1, - 0x9a, 0xbc, 0xc5, 0x04, 0x89, 0x78, 0x8d, 0x04, 0x27, 0x20, 0x77, 0x4e, 0xfb, 0x7c, 0x48, 0x57, - 0xae, 0xc3, 0xf2, 0xfc, 0xee, 0xcc, 0x7d, 0xf9, 0xa0, 0x88, 0x85, 0x16, 0x9a, 0x75, 0x38, 0x9c, - 0xfa, 0x5f, 0x83, 0x66, 0xbc, 0xbf, 0x48, 0xbc, 0x27, 0xc2, 0xed, 0xb4, 0x70, 0x95, 0xef, 0x36, - 0xc8, 0x9f, 0x52, 0x65, 0x46, 0x56, 0x1e, 0xf6, 0x8f, 0x0b, 0x9c, 0xdb, 0x66, 0xae, 0xeb, 0xc6, - 0x7e, 0x13, 0x6c, 0x19, 0xfb, 0xd9, 0xa0, 0x26, 0xc9, 0x47, 0x50, 0x68, 0x0a, 0x4a, 0x14, 0x75, - 0x98, 0x47, 0xaf, 0xe1, 0xa3, 0xd9, 0x70, 0x93, 0x33, 0x25, 0x78, 0x88, 0xe6, 0xba, 0xd3, 0x1d, - 0x59, 0x4e, 0x96, 0xac, 0x30, 0x2c, 0xe1, 0x20, 0x1e, 0xc3, 0xae, 0x96, 0xc0, 0xd7, 0x20, 0xdf, - 0x21, 0xc3, 0x04, 0xbc, 0xa4, 0x49, 0x31, 0xb6, 0x35, 0xa3, 0x04, 0x0b, 0x09, 0x43, 0x92, 0x21, - 0x85, 0x3e, 0x80, 0xe6, 0xf8, 0x23, 0xe6, 0xdd, 0xa2, 0x32, 0x79, 0xdc, 0xd3, 0xfc, 0x2a, 0xac, - 0x2c, 0x78, 0x24, 0xcc, 0xd3, 0x07, 0xbd, 0x05, 0x79, 0xad, 0x76, 0xd8, 0x05, 0x4f, 0x59, 0xbd, - 0xfd, 0x5b, 0xc4, 0x6d, 0xa4, 0x07, 0x51, 0x93, 0x0f, 0x98, 0x4a, 0xb9, 0x0e, 0xd8, 0x05, 0xb7, - 0xef, 0xde, 0x8c, 0xf7, 0x37, 0x1a, 0xdd, 0x9f, 0x93, 0x9a, 0xf5, 0x6b, 0x52, 0xb3, 0xc6, 0x93, - 0x9a, 0x05, 0x2a, 0x5c, 0xf8, 0x68, 0xe8, 0x11, 0x22, 0xd1, 0x90, 0x84, 0x1e, 0xd2, 0x8f, 0x43, - 0x23, 0xdf, 0x25, 0xa1, 0xa7, 0x7f, 0xf1, 0xef, 0xac, 0x4f, 0x8f, 0xfd, 0x40, 0x5d, 0x0e, 0x7a, - 0xc8, 0xe5, 0x7d, 0xac, 0x27, 0x71, 0x3c, 0x19, 0xbf, 0x14, 0x12, 0xfb, 0x22, 0x72, 0xb1, 0xd6, - 0xf4, 0x72, 0xfa, 0x71, 0x78, 0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xf1, 0x4d, 0xcf, 0x6d, - 0x06, 0x00, 0x00, +func init() { proto.RegisterFile("core/agent.proto", fileDescriptor_30864f15308ac822) } + +var fileDescriptor_30864f15308ac822 = []byte{ + // 604 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x95, 0x4f, 0x6e, 0x13, 0x31, + 0x14, 0xc6, 0x99, 0xaa, 0x04, 0xc5, 0x49, 0xff, 0xc8, 0x2d, 0x69, 0x3b, 0xaa, 0x52, 0x29, 0x6c, + 0x50, 0x16, 0x36, 0x02, 0x16, 0x15, 0x62, 0x41, 0x93, 0xb4, 0x65, 0x84, 0xa2, 0xa2, 0x46, 0x54, + 0xc0, 0x0a, 0x67, 0xc6, 0x9d, 0x0e, 0x9a, 0xd8, 0x53, 0xdb, 0x89, 0x1a, 0x21, 0x36, 0x5c, 0x81, + 0x8b, 0x74, 0xcf, 0x05, 0x58, 0x22, 0x71, 0x81, 0x28, 0xe2, 0x20, 0xc8, 0xf6, 0x24, 0x4d, 0x32, + 0x41, 0x28, 0x59, 0xce, 0xf3, 0xfb, 0x7e, 0xfe, 0x3e, 0x4b, 0x6f, 0x1e, 0xd8, 0xf4, 0xb9, 0xa0, + 0x98, 0x84, 0x94, 0x29, 0x94, 0x08, 0xae, 0x38, 0x5c, 0xd5, 0x15, 0x77, 0x2d, 0x21, 0xfd, 0x98, + 0x93, 0xc0, 0x16, 0xdd, 0xfd, 0x90, 0xf3, 0x30, 0xa6, 0x98, 0x24, 0x11, 0x26, 0x8c, 0x71, 0x45, + 0x54, 0xc4, 0x99, 0x4c, 0x4f, 0x8b, 0x49, 0x1b, 0x87, 0xd7, 0xb1, 0xfd, 0x7a, 0xfa, 0xa3, 0x00, + 0xee, 0x1f, 0x69, 0x20, 0x3c, 0x01, 0xb9, 0xe3, 0x9b, 0x48, 0x2a, 0x09, 0x21, 0x1a, 0xf1, 0xce, + 0xda, 0x9f, 0xa9, 0xaf, 0x90, 0xd7, 0x70, 0xe7, 0xd4, 0x2a, 0xdb, 0xdf, 0x7e, 0xff, 0xf9, 0xbe, + 0xb2, 0x0e, 0x8b, 0x98, 0x1a, 0x21, 0xfe, 0x12, 0x05, 0x5f, 0xe1, 0x19, 0xc8, 0xb5, 0x28, 0x11, + 0xfe, 0x15, 0xdc, 0x19, 0x6b, 0x6c, 0x01, 0x9d, 0xd3, 0xeb, 0x2e, 0x95, 0xca, 0xdd, 0xcd, 0x1e, + 0xc8, 0x84, 0x33, 0x49, 0x2b, 0xd0, 0x20, 0x8b, 0x95, 0x07, 0x58, 0x9a, 0x93, 0x17, 0x4e, 0x15, + 0xbe, 0x07, 0xc0, 0xb6, 0xd5, 0xfa, 0x5e, 0x03, 0xee, 0xcd, 0x6a, 0xbd, 0xc6, 0xff, 0xb1, 0x0f, + 0x0d, 0x76, 0xa3, 0x02, 0x52, 0x2c, 0x8e, 0x02, 0x4d, 0x3e, 0x05, 0xc5, 0x96, 0x12, 0x94, 0x74, + 0x96, 0x37, 0x7c, 0xef, 0xb1, 0xf3, 0xc4, 0x81, 0x4d, 0xb0, 0x39, 0x09, 0x5a, 0xde, 0xa8, 0xc5, + 0xbd, 0x06, 0x39, 0x8f, 0x49, 0x2a, 0x14, 0x2c, 0xcd, 0x3e, 0xfb, 0x05, 0xf5, 0x15, 0x17, 0xee, + 0xfa, 0xb8, 0x7e, 0xdc, 0x49, 0x54, 0xbf, 0x52, 0xba, 0x1d, 0x1c, 0x38, 0xe3, 0xb7, 0x8b, 0x8c, + 0x58, 0x27, 0x7c, 0x39, 0x4a, 0xb8, 0x20, 0xcf, 0xfa, 0x38, 0x04, 0x85, 0x66, 0x37, 0x56, 0x51, + 0x2a, 0xde, 0x99, 0x2f, 0x96, 0x59, 0xb5, 0x4e, 0xf0, 0x2e, 0x09, 0x88, 0xa2, 0x4b, 0x26, 0xe8, + 0x1a, 0xf1, 0x54, 0x82, 0x05, 0x79, 0xd3, 0x09, 0x52, 0xf1, 0x02, 0x09, 0x4e, 0x40, 0xee, 0x9c, + 0x76, 0x78, 0x8f, 0xce, 0x1d, 0x87, 0xd9, 0xfe, 0xdd, 0xb1, 0xfb, 0xf5, 0x6a, 0x11, 0x0b, 0x23, + 0xb4, 0xe3, 0x70, 0x38, 0xf2, 0xbf, 0x00, 0xcd, 0x7a, 0x7f, 0x9e, 0x7a, 0x4f, 0x85, 0x5b, 0x59, + 0xe1, 0x3c, 0xdf, 0x4d, 0x90, 0x3f, 0xa5, 0xca, 0xb6, 0xcc, 0xbd, 0xec, 0x1f, 0x0f, 0x38, 0x31, + 0xcd, 0xdc, 0xd4, 0xad, 0xfd, 0x3a, 0xd8, 0xb0, 0xf6, 0x97, 0x83, 0xda, 0x24, 0x1f, 0x40, 0xa1, + 0x2e, 0x28, 0x51, 0xd4, 0x63, 0x01, 0xbd, 0x81, 0x8f, 0xc6, 0xcd, 0x75, 0xce, 0x94, 0xe0, 0x31, + 0x9a, 0x38, 0x1d, 0xcd, 0xc8, 0x6c, 0xb2, 0x74, 0x84, 0xe1, 0x1a, 0x8e, 0x74, 0x1b, 0xf6, 0x8d, + 0x04, 0xbe, 0x02, 0xf9, 0x16, 0xe9, 0xa5, 0xe0, 0x19, 0x4d, 0x86, 0xb1, 0x65, 0x18, 0x6b, 0xb0, + 0x90, 0x32, 0x24, 0xe9, 0x51, 0x18, 0x02, 0x68, 0xaf, 0x3f, 0x62, 0xc1, 0x1d, 0x6a, 0x29, 0x8f, + 0xfb, 0x86, 0x5f, 0x82, 0xdb, 0x53, 0x1e, 0x09, 0x0b, 0xcc, 0x45, 0x6f, 0x40, 0xde, 0xa8, 0x3d, + 0x76, 0xc9, 0x33, 0x56, 0xef, 0xfe, 0x16, 0xfa, 0x18, 0x99, 0x46, 0x54, 0xe7, 0x5d, 0xa6, 0x32, + 0xae, 0x23, 0x76, 0xc9, 0xdd, 0xd5, 0xdb, 0xc1, 0xc1, 0x4a, 0xed, 0xd3, 0xcf, 0x61, 0xd9, 0xf9, + 0x35, 0x2c, 0x3b, 0x83, 0x61, 0xd9, 0x01, 0x7b, 0x5c, 0x84, 0xa8, 0x17, 0x10, 0x22, 0x51, 0x8f, + 0xc4, 0x01, 0xb2, 0x8b, 0x42, 0x6f, 0x88, 0x5a, 0xfe, 0x82, 0xc4, 0x81, 0xf9, 0xcf, 0xbf, 0x75, + 0x3e, 0x56, 0xc3, 0x48, 0x5d, 0x75, 0xdb, 0xc8, 0xe7, 0x1d, 0x6c, 0xda, 0xb1, 0x6e, 0xd7, 0xeb, + 0x42, 0xe2, 0x50, 0x24, 0xbe, 0xdd, 0x30, 0x58, 0x0b, 0xdb, 0x39, 0xb3, 0x26, 0x9e, 0xfd, 0x0d, + 0x00, 0x00, 0xff, 0xff, 0x1b, 0x3e, 0x24, 0x30, 0x7b, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -129,7 +129,7 @@ func NewAgentClient(cc *grpc.ClientConn) AgentClient { func (c *agentClient) Exists(ctx context.Context, in *payload.Object_ID, opts ...grpc.CallOption) (*payload.Object_ID, error) { out := new(payload.Object_ID) - err := c.cc.Invoke(ctx, "/agent.Agent/Exists", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/Exists", in, out, opts...) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (c *agentClient) Exists(ctx context.Context, in *payload.Object_ID, opts .. func (c *agentClient) Search(ctx context.Context, in *payload.Search_Request, opts ...grpc.CallOption) (*payload.Search_Response, error) { out := new(payload.Search_Response) - err := c.cc.Invoke(ctx, "/agent.Agent/Search", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/Search", in, out, opts...) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (c *agentClient) Search(ctx context.Context, in *payload.Search_Request, op func (c *agentClient) SearchByID(ctx context.Context, in *payload.Search_IDRequest, opts ...grpc.CallOption) (*payload.Search_Response, error) { out := new(payload.Search_Response) - err := c.cc.Invoke(ctx, "/agent.Agent/SearchByID", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/SearchByID", in, out, opts...) if err != nil { return nil, err } @@ -155,7 +155,7 @@ func (c *agentClient) SearchByID(ctx context.Context, in *payload.Search_IDReque } func (c *agentClient) StreamSearch(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamSearchClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[0], "/agent.Agent/StreamSearch", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[0], "/core.Agent/StreamSearch", opts...) if err != nil { return nil, err } @@ -186,7 +186,7 @@ func (x *agentStreamSearchClient) Recv() (*payload.Search_Response, error) { } func (c *agentClient) StreamSearchByID(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamSearchByIDClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[1], "/agent.Agent/StreamSearchByID", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[1], "/core.Agent/StreamSearchByID", opts...) if err != nil { return nil, err } @@ -218,7 +218,7 @@ func (x *agentStreamSearchByIDClient) Recv() (*payload.Search_Response, error) { func (c *agentClient) Insert(ctx context.Context, in *payload.Object_Vector, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/Insert", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/Insert", in, out, opts...) if err != nil { return nil, err } @@ -226,7 +226,7 @@ func (c *agentClient) Insert(ctx context.Context, in *payload.Object_Vector, opt } func (c *agentClient) StreamInsert(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamInsertClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[2], "/agent.Agent/StreamInsert", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[2], "/core.Agent/StreamInsert", opts...) if err != nil { return nil, err } @@ -258,7 +258,7 @@ func (x *agentStreamInsertClient) Recv() (*payload.Empty, error) { func (c *agentClient) MultiInsert(ctx context.Context, in *payload.Object_Vectors, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/MultiInsert", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/MultiInsert", in, out, opts...) if err != nil { return nil, err } @@ -267,7 +267,7 @@ func (c *agentClient) MultiInsert(ctx context.Context, in *payload.Object_Vector func (c *agentClient) Update(ctx context.Context, in *payload.Object_Vector, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/Update", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/Update", in, out, opts...) if err != nil { return nil, err } @@ -275,7 +275,7 @@ func (c *agentClient) Update(ctx context.Context, in *payload.Object_Vector, opt } func (c *agentClient) StreamUpdate(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamUpdateClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[3], "/agent.Agent/StreamUpdate", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[3], "/core.Agent/StreamUpdate", opts...) if err != nil { return nil, err } @@ -307,7 +307,7 @@ func (x *agentStreamUpdateClient) Recv() (*payload.Empty, error) { func (c *agentClient) MultiUpdate(ctx context.Context, in *payload.Object_Vectors, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/MultiUpdate", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/MultiUpdate", in, out, opts...) if err != nil { return nil, err } @@ -316,7 +316,7 @@ func (c *agentClient) MultiUpdate(ctx context.Context, in *payload.Object_Vector func (c *agentClient) Remove(ctx context.Context, in *payload.Object_ID, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/Remove", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/Remove", in, out, opts...) if err != nil { return nil, err } @@ -324,7 +324,7 @@ func (c *agentClient) Remove(ctx context.Context, in *payload.Object_ID, opts .. } func (c *agentClient) StreamRemove(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamRemoveClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[4], "/agent.Agent/StreamRemove", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[4], "/core.Agent/StreamRemove", opts...) if err != nil { return nil, err } @@ -356,7 +356,7 @@ func (x *agentStreamRemoveClient) Recv() (*payload.Empty, error) { func (c *agentClient) MultiRemove(ctx context.Context, in *payload.Object_IDs, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/MultiRemove", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/MultiRemove", in, out, opts...) if err != nil { return nil, err } @@ -365,7 +365,7 @@ func (c *agentClient) MultiRemove(ctx context.Context, in *payload.Object_IDs, o func (c *agentClient) GetObject(ctx context.Context, in *payload.Object_ID, opts ...grpc.CallOption) (*payload.Object_Vector, error) { out := new(payload.Object_Vector) - err := c.cc.Invoke(ctx, "/agent.Agent/GetObject", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/GetObject", in, out, opts...) if err != nil { return nil, err } @@ -373,7 +373,7 @@ func (c *agentClient) GetObject(ctx context.Context, in *payload.Object_ID, opts } func (c *agentClient) StreamGetObject(ctx context.Context, opts ...grpc.CallOption) (Agent_StreamGetObjectClient, error) { - stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[5], "/agent.Agent/StreamGetObject", opts...) + stream, err := c.cc.NewStream(ctx, &_Agent_serviceDesc.Streams[5], "/core.Agent/StreamGetObject", opts...) if err != nil { return nil, err } @@ -405,7 +405,7 @@ func (x *agentStreamGetObjectClient) Recv() (*payload.Object_Vector, error) { func (c *agentClient) CreateIndex(ctx context.Context, in *payload.Control_CreateIndexRequest, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/CreateIndex", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/CreateIndex", in, out, opts...) if err != nil { return nil, err } @@ -414,7 +414,7 @@ func (c *agentClient) CreateIndex(ctx context.Context, in *payload.Control_Creat func (c *agentClient) SaveIndex(ctx context.Context, in *payload.Empty, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/SaveIndex", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/SaveIndex", in, out, opts...) if err != nil { return nil, err } @@ -423,7 +423,7 @@ func (c *agentClient) SaveIndex(ctx context.Context, in *payload.Empty, opts ... func (c *agentClient) CreateAndSaveIndex(ctx context.Context, in *payload.Control_CreateIndexRequest, opts ...grpc.CallOption) (*payload.Empty, error) { out := new(payload.Empty) - err := c.cc.Invoke(ctx, "/agent.Agent/CreateAndSaveIndex", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/CreateAndSaveIndex", in, out, opts...) if err != nil { return nil, err } @@ -432,7 +432,7 @@ func (c *agentClient) CreateAndSaveIndex(ctx context.Context, in *payload.Contro func (c *agentClient) IndexInfo(ctx context.Context, in *payload.Empty, opts ...grpc.CallOption) (*payload.Info_Index_Count, error) { out := new(payload.Info_Index_Count) - err := c.cc.Invoke(ctx, "/agent.Agent/IndexInfo", in, out, opts...) + err := c.cc.Invoke(ctx, "/core.Agent/IndexInfo", in, out, opts...) if err != nil { return nil, err } @@ -542,7 +542,7 @@ func _Agent_Exists_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/Exists", + FullMethod: "/core.Agent/Exists", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).Exists(ctx, req.(*payload.Object_ID)) @@ -560,7 +560,7 @@ func _Agent_Search_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/Search", + FullMethod: "/core.Agent/Search", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).Search(ctx, req.(*payload.Search_Request)) @@ -578,7 +578,7 @@ func _Agent_SearchByID_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/SearchByID", + FullMethod: "/core.Agent/SearchByID", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).SearchByID(ctx, req.(*payload.Search_IDRequest)) @@ -648,7 +648,7 @@ func _Agent_Insert_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/Insert", + FullMethod: "/core.Agent/Insert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).Insert(ctx, req.(*payload.Object_Vector)) @@ -692,7 +692,7 @@ func _Agent_MultiInsert_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/MultiInsert", + FullMethod: "/core.Agent/MultiInsert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).MultiInsert(ctx, req.(*payload.Object_Vectors)) @@ -710,7 +710,7 @@ func _Agent_Update_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/Update", + FullMethod: "/core.Agent/Update", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).Update(ctx, req.(*payload.Object_Vector)) @@ -754,7 +754,7 @@ func _Agent_MultiUpdate_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/MultiUpdate", + FullMethod: "/core.Agent/MultiUpdate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).MultiUpdate(ctx, req.(*payload.Object_Vectors)) @@ -772,7 +772,7 @@ func _Agent_Remove_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/Remove", + FullMethod: "/core.Agent/Remove", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).Remove(ctx, req.(*payload.Object_ID)) @@ -816,7 +816,7 @@ func _Agent_MultiRemove_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/MultiRemove", + FullMethod: "/core.Agent/MultiRemove", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).MultiRemove(ctx, req.(*payload.Object_IDs)) @@ -834,7 +834,7 @@ func _Agent_GetObject_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/GetObject", + FullMethod: "/core.Agent/GetObject", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).GetObject(ctx, req.(*payload.Object_ID)) @@ -878,7 +878,7 @@ func _Agent_CreateIndex_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/CreateIndex", + FullMethod: "/core.Agent/CreateIndex", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).CreateIndex(ctx, req.(*payload.Control_CreateIndexRequest)) @@ -896,7 +896,7 @@ func _Agent_SaveIndex_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/SaveIndex", + FullMethod: "/core.Agent/SaveIndex", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).SaveIndex(ctx, req.(*payload.Empty)) @@ -914,7 +914,7 @@ func _Agent_CreateAndSaveIndex_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/CreateAndSaveIndex", + FullMethod: "/core.Agent/CreateAndSaveIndex", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).CreateAndSaveIndex(ctx, req.(*payload.Control_CreateIndexRequest)) @@ -932,7 +932,7 @@ func _Agent_IndexInfo_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/agent.Agent/IndexInfo", + FullMethod: "/core.Agent/IndexInfo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(AgentServer).IndexInfo(ctx, req.(*payload.Empty)) @@ -941,7 +941,7 @@ func _Agent_IndexInfo_Handler(srv interface{}, ctx context.Context, dec func(int } var _Agent_serviceDesc = grpc.ServiceDesc{ - ServiceName: "agent.Agent", + ServiceName: "core.Agent", HandlerType: (*AgentServer)(nil), Methods: []grpc.MethodDesc{ { @@ -1039,5 +1039,5 @@ var _Agent_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: "agent.proto", + Metadata: "core/agent.proto", } diff --git a/apis/grpc/agent/sidecar/sidecar.pb.go b/apis/grpc/agent/sidecar/sidecar.pb.go new file mode 100644 index 0000000000..08e363b775 --- /dev/null +++ b/apis/grpc/agent/sidecar/sidecar.pb.go @@ -0,0 +1,100 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 sidecar + +import ( + context "context" + fmt "fmt" + math "math" + + _ "github.com/danielvladco/go-proto-gql/pb" + proto "github.com/gogo/protobuf/proto" + _ "github.com/vdaas/vald/apis/grpc/payload" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("sidecar/sidecar.proto", fileDescriptor_a79f12d5eccb8a6a) } + +var fileDescriptor_a79f12d5eccb8a6a = []byte{ + // 188 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2d, 0xce, 0x4c, 0x49, + 0x4d, 0x4e, 0x2c, 0xd2, 0x87, 0xd2, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xec, 0x50, 0xae, + 0x14, 0x6f, 0x41, 0x62, 0x65, 0x4e, 0x7e, 0x62, 0x0a, 0x44, 0x5c, 0x4a, 0x26, 0x3d, 0x3f, 0x3f, + 0x3d, 0x27, 0x55, 0x3f, 0xb1, 0x20, 0x53, 0x3f, 0x31, 0x2f, 0x2f, 0xbf, 0x24, 0xb1, 0x24, 0x33, + 0x3f, 0xaf, 0x18, 0x2a, 0xcb, 0x53, 0x90, 0xa4, 0x9f, 0x5e, 0x98, 0x03, 0xe1, 0x19, 0x71, 0x72, + 0xb1, 0x07, 0x43, 0x4c, 0x71, 0xca, 0x3d, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, + 0x8f, 0xe4, 0x18, 0xb9, 0x64, 0xf2, 0x8b, 0xd2, 0xf5, 0xca, 0x52, 0x12, 0x13, 0x8b, 0xf5, 0xca, + 0x12, 0x73, 0x52, 0xf4, 0x12, 0xd3, 0x53, 0xf3, 0x4a, 0xf4, 0xa0, 0x36, 0x3a, 0x09, 0x84, 0x25, + 0xe6, 0xa4, 0x38, 0x82, 0x84, 0xa0, 0xba, 0x03, 0x18, 0xa3, 0x74, 0xd3, 0x33, 0x4b, 0x32, 0x4a, + 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xc1, 0x1a, 0xf5, 0x41, 0x1a, 0x41, 0xae, 0x28, 0xd6, 0x4f, + 0x2f, 0x2a, 0x48, 0xd6, 0x07, 0x1b, 0x01, 0xf3, 0x43, 0x12, 0x1b, 0xd8, 0x01, 0xc6, 0x80, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x1c, 0x2f, 0x76, 0x1a, 0xdd, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// SidecarClient is the client API for Sidecar service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SidecarClient interface { +} + +type sidecarClient struct { + cc *grpc.ClientConn +} + +func NewSidecarClient(cc *grpc.ClientConn) SidecarClient { + return &sidecarClient{cc} +} + +// SidecarServer is the server API for Sidecar service. +type SidecarServer interface { +} + +// UnimplementedSidecarServer can be embedded to have forward compatible implementations. +type UnimplementedSidecarServer struct { +} + +func RegisterSidecarServer(s *grpc.Server, srv SidecarServer) { + s.RegisterService(&_Sidecar_serviceDesc, srv) +} + +var _Sidecar_serviceDesc = grpc.ServiceDesc{ + ServiceName: "sidecar.Sidecar", + HandlerType: (*SidecarServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "sidecar/sidecar.proto", +} diff --git a/apis/proto/agent/agent.proto b/apis/proto/agent/core/agent.proto similarity index 96% rename from apis/proto/agent/agent.proto rename to apis/proto/agent/core/agent.proto index 7b54efeced..101b2b2d17 100644 --- a/apis/proto/agent/agent.proto +++ b/apis/proto/agent/core/agent.proto @@ -16,11 +16,11 @@ syntax = "proto3"; -package agent; +package core; -option go_package = "github.com/vdaas/vald/apis/grpc/agent"; +option go_package = "github.com/vdaas/vald/apis/grpc/agent/core"; option java_multiple_files = true; -option java_package = "org.vdaas.vald.agent"; +option java_package = "org.vdaas.vald.agent.core"; option java_outer_classname = "ValdAgent"; import "payload.proto"; diff --git a/apis/proto/agent/sidecar/sidecar.proto b/apis/proto/agent/sidecar/sidecar.proto new file mode 100644 index 0000000000..dc6ebf4ed9 --- /dev/null +++ b/apis/proto/agent/sidecar/sidecar.proto @@ -0,0 +1,31 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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. +// + +syntax = "proto3"; + +package sidecar; + +option go_package = "github.com/vdaas/vald/apis/grpc/agent/sidecar"; +option java_multiple_files = true; +option java_package = "org.vdaas.vald.agent.sidecar"; +option java_outer_classname = "ValdAgentSidecar"; + +import "payload.proto"; +import "google/api/annotations.proto"; +import "pb/gql.proto"; + +service Sidecar { +} diff --git a/apis/swagger/agent/agent.swagger.json b/apis/swagger/agent/core/core/agent.swagger.json similarity index 99% rename from apis/swagger/agent/agent.swagger.json rename to apis/swagger/agent/core/core/agent.swagger.json index db9d54f190..5b43cba8a2 100644 --- a/apis/swagger/agent/agent.swagger.json +++ b/apis/swagger/agent/core/core/agent.swagger.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "title": "agent.proto", + "title": "core/agent.proto", "version": "version not set" }, "consumes": [ diff --git a/apis/swagger/agent/sidecar/sidecar/sidecar.swagger.json b/apis/swagger/agent/sidecar/sidecar/sidecar.swagger.json new file mode 100644 index 0000000000..a4e536e2ba --- /dev/null +++ b/apis/swagger/agent/sidecar/sidecar/sidecar.swagger.json @@ -0,0 +1,49 @@ +{ + "swagger": "2.0", + "info": { + "title": "sidecar/sidecar.proto", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "typeUrl": { + "type": "string" + }, + "value": { + "type": "string", + "format": "byte" + } + } + }, + "runtimeError": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/cmd/agent/ngt/main.go b/cmd/agent/core/ngt/main.go similarity index 93% rename from cmd/agent/ngt/main.go rename to cmd/agent/core/ngt/main.go index 67abef000c..9081670efc 100644 --- a/cmd/agent/ngt/main.go +++ b/cmd/agent/core/ngt/main.go @@ -24,8 +24,8 @@ import ( "github.com/vdaas/vald/internal/log" "github.com/vdaas/vald/internal/runner" "github.com/vdaas/vald/internal/safety" - "github.com/vdaas/vald/pkg/agent/ngt/config" - "github.com/vdaas/vald/pkg/agent/ngt/usecase" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/usecase" ) const ( diff --git a/cmd/agent/ngt/main_test.go b/cmd/agent/core/ngt/main_test.go similarity index 100% rename from cmd/agent/ngt/main_test.go rename to cmd/agent/core/ngt/main_test.go diff --git a/cmd/agent/ngt/sample.yaml b/cmd/agent/core/ngt/sample.yaml similarity index 100% rename from cmd/agent/ngt/sample.yaml rename to cmd/agent/core/ngt/sample.yaml diff --git a/cmd/agent/sptag/.gitkeep b/cmd/agent/core/sptag/.gitkeep old mode 100755 new mode 100644 similarity index 100% rename from cmd/agent/sptag/.gitkeep rename to cmd/agent/core/sptag/.gitkeep diff --git a/cmd/agent/sidecar/main.go b/cmd/agent/sidecar/main.go new file mode 100644 index 0000000000..69598ab141 --- /dev/null +++ b/cmd/agent/sidecar/main.go @@ -0,0 +1,58 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 main provides program main +package main + +import ( + "context" + + "github.com/vdaas/vald/internal/info" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/runner" + "github.com/vdaas/vald/internal/safety" + "github.com/vdaas/vald/pkg/agent/sidecar/config" + "github.com/vdaas/vald/pkg/agent/sidecar/usecase" +) + +const ( + maxVersion = "v0.0.10" + minVersion = "v0.0.0" + name = "agent sidecar" +) + +func main() { + if err := safety.RecoverFunc(func() error { + return runner.Do( + context.Background(), + runner.WithName(name), + runner.WithVersion(info.Version, maxVersion, minVersion), + runner.WithConfigLoader(func(path string) (interface{}, *config.GlobalConfig, error) { + cfg, err := config.NewConfig(path) + if err != nil { + return nil, nil, err + } + return cfg, &cfg.GlobalConfig, nil + }), + runner.WithDaemonInitializer(func(cfg interface{}) (runner.Runner, error) { + return usecase.New(cfg.(*config.Data)) + }), + ) + })(); err != nil { + log.Fatal(err, info.Get()) + return + } +} diff --git a/cmd/agent/sidecar/main_test.go b/cmd/agent/sidecar/main_test.go new file mode 100644 index 0000000000..77175e6295 --- /dev/null +++ b/cmd/agent/sidecar/main_test.go @@ -0,0 +1,80 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 main provides program main +package main + +import ( + "testing" + + "go.uber.org/goleak" +) + +func Test_main(t *testing.T) { + type want struct { + } + type test struct { + name string + want want + checkFunc func(want) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want) error { + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + main() + if err := test.checkFunc(test.want); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} diff --git a/dockers/agent/ngt/Dockerfile b/dockers/agent/core/ngt/Dockerfile similarity index 99% rename from dockers/agent/ngt/Dockerfile rename to dockers/agent/core/ngt/Dockerfile index 2c82d0921a..bfb0723705 100644 --- a/dockers/agent/ngt/Dockerfile +++ b/dockers/agent/core/ngt/Dockerfile @@ -18,7 +18,7 @@ FROM vdaas/vald-base:latest AS builder ENV ORG vdaas ENV REPO vald -ENV PKG agent/ngt +ENV PKG agent/core/ngt ENV APP_NAME ngt WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal diff --git a/dockers/agent/sidecar/Dockerfile b/dockers/agent/sidecar/Dockerfile new file mode 100644 index 0000000000..af2361071b --- /dev/null +++ b/dockers/agent/sidecar/Dockerfile @@ -0,0 +1,82 @@ +# +# Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +# +# 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. +# + +FROM vdaas/vald-base:latest AS builder + +ENV ORG vdaas +ENV REPO vald +ENV PKG agent/sidecar +ENV APP_NAME sidecar + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/internal +COPY internal . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/apis/grpc +COPY apis/grpc . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/pkg/${PKG} +COPY pkg/${PKG} . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO}/cmd/${PKG} +COPY cmd/${PKG} . + +WORKDIR ${GOPATH}/src/github.com/${ORG}/${REPO} +COPY versions/GO_VERSION . +COPY versions/VALD_VERSION . +COPY .git . +RUN GO_VERSION="$(cat GO_VERSION)" \ + && VALD_VERSION="$(cat VALD_VERSION)" \ + && GIT_COMMIT="$(git rev-list -1 HEAD)" \ + && CPU_INFO_FLAGS="$(cat /proc/cpuinfo | grep flags | cut -d " " -f 2- | head -1)" \ + && GOOS="$(go env GOOS)" \ + && GOARCH="$(go env GOARCH)" \ + && CGO_ENABLED=0 \ + && GO111MODULE=on \ + go build \ + --ldflags "-s -w -linkmode 'external' \ + -extldflags '-static' \ + -X 'github.com/${ORG}/${REPO}/internal/info.Version=${VALD_VERSION}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.GitCommit=${GIT_COMMIT}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.GoVersion=${GO_VERSION}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.GoOS=${GOOS}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.GoArch=${GOARCH}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.CGOEnabled=${CGO_ENABLED}' \ + -X 'github.com/${ORG}/${REPO}/internal/info.BuildCPUInfoFlags=${CPU_INFO_FLAGS}'" \ + -a \ + -tags netgo \ + -trimpath \ + -installsuffix netgo \ + -o "${APP_NAME}" \ + "cmd/${PKG}/main.go" \ + && upx -9 -o "/usr/bin/${APP_NAME}" "${APP_NAME}" + +# Start From Scratch For Running Environment +FROM scratch +# Start From Alpine For Debug Environment +# FROM alpine:latest +LABEL maintainer "kpango " + +ENV APP_NAME sidecar + +# Copy certificates for SSL/TLS +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +# Copy permissions +COPY --from=builder /etc/passwd /etc/passwd +# Copy our static executable +COPY --from=builder /usr/bin/${APP_NAME} /go/bin/${APP_NAME} +COPY --from=builder /tmp/config.yaml /etc/server/config.yaml + +ENTRYPOINT ["/go/bin/sidecar"] diff --git a/go.mod b/go.mod index f33116f730..1f97f06c0e 100755 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/cockroachdb/errors v0.0.0-00010101000000-000000000000 github.com/danielvladco/go-proto-gql/pb v0.6.1 github.com/envoyproxy/protoc-gen-validate v0.1.0 + github.com/fsnotify/fsnotify v1.4.7 github.com/go-redis/redis/v7 v7.3.0 github.com/go-sql-driver/mysql v1.5.0 github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 diff --git a/hack/benchmark/e2e/agent/ngt/ngt_bench_test.go b/hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go similarity index 97% rename from hack/benchmark/e2e/agent/ngt/ngt_bench_test.go rename to hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go index 65a43d3eeb..9c7347487b 100644 --- a/hack/benchmark/e2e/agent/ngt/ngt_bench_test.go +++ b/hack/benchmark/e2e/agent/core/ngt/ngt_bench_test.go @@ -24,7 +24,7 @@ import ( "github.com/vdaas/vald/hack/benchmark/internal/assets" "github.com/vdaas/vald/hack/benchmark/internal/e2e" "github.com/vdaas/vald/hack/benchmark/internal/e2e/strategy" - "github.com/vdaas/vald/hack/benchmark/internal/starter/agent/ngt" + "github.com/vdaas/vald/hack/benchmark/internal/starter/agent/core/ngt" "github.com/vdaas/vald/internal/client/agent/grpc" "github.com/vdaas/vald/internal/client/agent/rest" "github.com/vdaas/vald/internal/log" diff --git a/hack/benchmark/internal/starter/agent/ngt/ngt.go b/hack/benchmark/internal/starter/agent/core/ngt/ngt.go similarity index 93% rename from hack/benchmark/internal/starter/agent/ngt/ngt.go rename to hack/benchmark/internal/starter/agent/core/ngt/ngt.go index 66624814a9..50f648b242 100644 --- a/hack/benchmark/internal/starter/agent/ngt/ngt.go +++ b/hack/benchmark/internal/starter/agent/core/ngt/ngt.go @@ -25,8 +25,8 @@ import ( "github.com/vdaas/vald/hack/benchmark/internal/starter" "github.com/vdaas/vald/internal/log" "github.com/vdaas/vald/internal/runner" - "github.com/vdaas/vald/pkg/agent/ngt/config" - "github.com/vdaas/vald/pkg/agent/ngt/usecase" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/usecase" ) const name = "agent-ngt" diff --git a/hack/benchmark/internal/starter/agent/ngt/ngt_test.go b/hack/benchmark/internal/starter/agent/core/ngt/ngt_test.go similarity index 98% rename from hack/benchmark/internal/starter/agent/ngt/ngt_test.go rename to hack/benchmark/internal/starter/agent/core/ngt/ngt_test.go index 15e95c8a96..6c10f201a8 100644 --- a/hack/benchmark/internal/starter/agent/ngt/ngt_test.go +++ b/hack/benchmark/internal/starter/agent/core/ngt/ngt_test.go @@ -24,7 +24,7 @@ import ( "github.com/vdaas/vald/hack/benchmark/internal/starter" "github.com/vdaas/vald/internal/errors" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" "go.uber.org/goleak" ) diff --git a/hack/benchmark/internal/starter/agent/ngt/option.go b/hack/benchmark/internal/starter/agent/core/ngt/option.go similarity index 98% rename from hack/benchmark/internal/starter/agent/ngt/option.go rename to hack/benchmark/internal/starter/agent/core/ngt/option.go index 3b4d4fdf1a..defe1319ff 100644 --- a/hack/benchmark/internal/starter/agent/ngt/option.go +++ b/hack/benchmark/internal/starter/agent/core/ngt/option.go @@ -19,7 +19,7 @@ package ngt import ( iconfig "github.com/vdaas/vald/internal/config" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" ) type Option func(*server) diff --git a/hack/benchmark/internal/starter/agent/ngt/option_test.go b/hack/benchmark/internal/starter/agent/core/ngt/option_test.go similarity index 99% rename from hack/benchmark/internal/starter/agent/ngt/option_test.go rename to hack/benchmark/internal/starter/agent/core/ngt/option_test.go index 415724a9ca..40363d0918 100644 --- a/hack/benchmark/internal/starter/agent/ngt/option_test.go +++ b/hack/benchmark/internal/starter/agent/core/ngt/option_test.go @@ -20,7 +20,7 @@ package ngt import ( "testing" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" "go.uber.org/goleak" ) diff --git a/hack/tools/config/agent/ngt/main.go b/hack/tools/config/agent/core/ngt/main.go similarity index 94% rename from hack/tools/config/agent/ngt/main.go rename to hack/tools/config/agent/core/ngt/main.go index 7e157eefaf..267c59d5e3 100644 --- a/hack/tools/config/agent/ngt/main.go +++ b/hack/tools/config/agent/core/ngt/main.go @@ -21,7 +21,7 @@ import ( fuzz "github.com/google/gofuzz" conf "github.com/vdaas/vald/internal/config" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" ) func main() { diff --git a/hack/tools/config/agent/ngt/main_test.go b/hack/tools/config/agent/core/ngt/main_test.go similarity index 100% rename from hack/tools/config/agent/ngt/main_test.go rename to hack/tools/config/agent/core/ngt/main_test.go diff --git a/hack/tools/config/agent/ngt/sample.yaml b/hack/tools/config/agent/core/ngt/sample.yaml similarity index 100% rename from hack/tools/config/agent/ngt/sample.yaml rename to hack/tools/config/agent/core/ngt/sample.yaml diff --git a/internal/client/agent/grpc/client.go b/internal/client/agent/grpc/client.go index 2fb029341c..0b1adfce04 100644 --- a/internal/client/agent/grpc/client.go +++ b/internal/client/agent/grpc/client.go @@ -20,7 +20,7 @@ package grpc import ( "context" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/internal/client" "github.com/vdaas/vald/internal/net/grpc" ) diff --git a/internal/config/blob_test.go b/internal/config/blob_test.go new file mode 100644 index 0000000000..c196e65f31 --- /dev/null +++ b/internal/config/blob_test.go @@ -0,0 +1,335 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 config providers configuration type and load configuration logic +package config + +import ( + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestBlobStorageType_String(t *testing.T) { + type want struct { + want string + } + type test struct { + name string + bst BlobStorageType + want want + checkFunc func(want, string) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got string) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := test.bst.String() + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func TestAtoBST(t *testing.T) { + type args struct { + bst string + } + type want struct { + want BlobStorageType + } + type test struct { + name string + args args + want want + checkFunc func(want, BlobStorageType) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got BlobStorageType) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + bst: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + bst: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := AtoBST(test.args.bst) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func TestBlob_Bind(t *testing.T) { + type fields struct { + StorageType string + BucketURL string + S3 *S3Config + } + type want struct { + want *Blob + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *Blob) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *Blob) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + StorageType: "", + BucketURL: "", + S3: S3Config{}, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + StorageType: "", + BucketURL: "", + S3: S3Config{}, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + b := &Blob{ + StorageType: test.fields.StorageType, + BucketURL: test.fields.BucketURL, + S3: test.fields.S3, + } + + got := b.Bind() + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func TestS3Config_Bind(t *testing.T) { + type fields struct { + Endpoint string + Region string + AccessKey string + SecretAccessKey string + Token string + UseLegacyList bool + } + type want struct { + want *S3Config + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *S3Config) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *S3Config) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + Endpoint: "", + Region: "", + AccessKey: "", + SecretAccessKey: "", + Token: "", + UseLegacyList: false, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + Endpoint: "", + Region: "", + AccessKey: "", + SecretAccessKey: "", + Token: "", + UseLegacyList: false, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + s := &S3Config{ + Endpoint: test.fields.Endpoint, + Region: test.fields.Region, + AccessKey: test.fields.AccessKey, + SecretAccessKey: test.fields.SecretAccessKey, + Token: test.fields.Token, + UseLegacyList: test.fields.UseLegacyList, + } + + got := s.Bind() + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/config/sidecar.go b/internal/config/sidecar.go new file mode 100644 index 0000000000..aaf5a7cf0b --- /dev/null +++ b/internal/config/sidecar.go @@ -0,0 +1,38 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 config providers configuration type and load configuration logic +package config + +type Sidecar struct { + // Name string `yaml:"name" json:"name"` + + // WatchPaths represents watch path list for backup + WatchPaths []string `yaml:"watch_paths" json:"watch_paths"` + + // AutoBackupDurationLimit represents auto backup duration limit + AutoBackupDurationLimit string `yaml:"auto_backup_duration_limit" json:"auto_backup_duration_limit"` + + // AutoBackupDuration represent checking loop duration for auto backup execution + AutoBackupDuration string `yaml:"auto_backup_duration" json:"auto_backup_duration"` +} + +func (s *Sidecar) Bind() *Sidecar { + s.WatchPaths = GetActualValues(s.WatchPaths) + s.AutoBackupDuration = GetActualValue(s.AutoBackupDuration) + s.AutoBackupDurationLimit = GetActualValue(s.AutoBackupDurationLimit) + return s +} diff --git a/internal/config/sidecar_test.go b/internal/config/sidecar_test.go new file mode 100644 index 0000000000..be15a480e2 --- /dev/null +++ b/internal/config/sidecar_test.go @@ -0,0 +1,108 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 config providers configuration type and load configuration logic +package config + +import ( + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestSidecar_Bind(t *testing.T) { + type fields struct { + WatchPaths []string + AutoBackupDurationLimit string + AutoBackupDuration string + } + type want struct { + want *Sidecar + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *Sidecar) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *Sidecar) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + WatchPaths: nil, + AutoBackupDurationLimit: "", + AutoBackupDuration: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + WatchPaths: nil, + AutoBackupDurationLimit: "", + AutoBackupDuration: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + s := &Sidecar{ + WatchPaths: test.fields.WatchPaths, + AutoBackupDurationLimit: test.fields.AutoBackupDurationLimit, + AutoBackupDuration: test.fields.AutoBackupDuration, + } + + got := s.Bind() + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/db/storage/blob/blob_test.go b/internal/db/storage/blob/blob_test.go index 0a14e94c8b..e3cd979b89 100644 --- a/internal/db/storage/blob/blob_test.go +++ b/internal/db/storage/blob/blob_test.go @@ -18,9 +18,14 @@ package blob import ( "context" + "io" + "reflect" "testing" "github.com/vdaas/vald/internal/db/storage/blob/s3" + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" + "gocloud.dev/blob" ) const ( @@ -133,3 +138,450 @@ func TestS3Read(t *testing.T) { t.Logf("read: %s", string(rbuf)) } + +func TestNewBucket(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want Bucket + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, Bucket, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got Bucket, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got, err := NewBucket(test.args.opts...) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_bucket_Open(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + opener BucketURLOpener + url string + bucket *blob.Bucket + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + b := &bucket{ + opener: test.fields.opener, + url: test.fields.url, + bucket: test.fields.bucket, + } + + err := b.Open(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_bucket_Close(t *testing.T) { + type fields struct { + opener BucketURLOpener + url string + bucket *blob.Bucket + } + type want struct { + err error + } + type test struct { + name string + fields fields + want want + checkFunc func(want, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + b := &bucket{ + opener: test.fields.opener, + url: test.fields.url, + bucket: test.fields.bucket, + } + + err := b.Close() + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_bucket_Reader(t *testing.T) { + type args struct { + ctx context.Context + key string + } + type fields struct { + opener BucketURLOpener + url string + bucket *blob.Bucket + } + type want struct { + want io.ReadCloser + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, io.ReadCloser, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got io.ReadCloser, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + key: "", + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + key: "", + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + b := &bucket{ + opener: test.fields.opener, + url: test.fields.url, + bucket: test.fields.bucket, + } + + got, err := b.Reader(test.args.ctx, test.args.key) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_bucket_Writer(t *testing.T) { + type args struct { + ctx context.Context + key string + } + type fields struct { + opener BucketURLOpener + url string + bucket *blob.Bucket + } + type want struct { + want io.WriteCloser + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, io.WriteCloser, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got io.WriteCloser, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + key: "", + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + key: "", + }, + fields: fields { + opener: nil, + url: "", + bucket: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + b := &bucket{ + opener: test.fields.opener, + url: test.fields.url, + bucket: test.fields.bucket, + } + + got, err := b.Writer(test.args.ctx, test.args.key) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/db/storage/blob/option_test.go b/internal/db/storage/blob/option_test.go new file mode 100644 index 0000000000..08efc74347 --- /dev/null +++ b/internal/db/storage/blob/option_test.go @@ -0,0 +1,249 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 blob + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestWithBucketURLOpener(t *testing.T) { + type T = interface{} + type args struct { + bo BucketURLOpener + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + bo: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + bo: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBucketURLOpener(test.args.bo) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBucketURLOpener(test.args.bo) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithBucketURL(t *testing.T) { + type T = interface{} + type args struct { + url string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + url: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + url: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBucketURL(test.args.url) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBucketURL(test.args.url) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/internal/db/storage/blob/s3/option_test.go b/internal/db/storage/blob/s3/option_test.go new file mode 100644 index 0000000000..c9f80664d2 --- /dev/null +++ b/internal/db/storage/blob/s3/option_test.go @@ -0,0 +1,701 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 s3 + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestWithEndpoint(t *testing.T) { + type T = interface{} + type args struct { + ep string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ep: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ep: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithEndpoint(test.args.ep) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithEndpoint(test.args.ep) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithRegion(t *testing.T) { + type T = interface{} + type args struct { + rg string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + rg: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + rg: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithRegion(test.args.rg) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithRegion(test.args.rg) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithAccessKey(t *testing.T) { + type T = interface{} + type args struct { + ak string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ak: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ak: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithAccessKey(test.args.ak) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithAccessKey(test.args.ak) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithSecretAccessKey(t *testing.T) { + type T = interface{} + type args struct { + sak string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + sak: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + sak: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithSecretAccessKey(test.args.sak) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithSecretAccessKey(test.args.sak) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithToken(t *testing.T) { + type T = interface{} + type args struct { + tk string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + tk: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + tk: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithToken(test.args.tk) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithToken(test.args.tk) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithUseLegacyList(t *testing.T) { + type T = interface{} + type args struct { + flg bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + flg: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + flg: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithUseLegacyList(test.args.flg) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithUseLegacyList(test.args.flg) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/internal/db/storage/blob/s3/s3_test.go b/internal/db/storage/blob/s3/s3_test.go new file mode 100644 index 0000000000..893316c8af --- /dev/null +++ b/internal/db/storage/blob/s3/s3_test.go @@ -0,0 +1,194 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 s3 + +import ( + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestNewSession(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want Session + } + type test struct { + name string + args args + want want + checkFunc func(want, Session) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got Session) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := NewSession(test.args.opts...) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_sess_URLOpener(t *testing.T) { + type fields struct { + endpoint string + region string + accessKey string + secretAccessKey string + token string + useLegacyList bool + } + type want struct { + want *URLOpener + err error + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *URLOpener, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *URLOpener, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + endpoint: "", + region: "", + accessKey: "", + secretAccessKey: "", + token: "", + useLegacyList: false, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + endpoint: "", + region: "", + accessKey: "", + secretAccessKey: "", + token: "", + useLegacyList: false, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + s := &sess{ + endpoint: test.fields.endpoint, + region: test.fields.region, + accessKey: test.fields.accessKey, + secretAccessKey: test.fields.secretAccessKey, + token: test.fields.token, + useLegacyList: test.fields.useLegacyList, + } + + got, err := s.URLOpener() + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/errors/file.go b/internal/errors/file.go new file mode 100644 index 0000000000..e0a77cb18e --- /dev/null +++ b/internal/errors/file.go @@ -0,0 +1,22 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 errors provides error types and function +package errors + +var ( + ErrWatchDirNotFound = New("fs watcher watch dir not found") +) diff --git a/internal/file/watch/option.go b/internal/file/watch/option.go new file mode 100644 index 0000000000..8b7cdfec6b --- /dev/null +++ b/internal/file/watch/option.go @@ -0,0 +1,128 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 watch + +import ( + "context" + + "github.com/vdaas/vald/internal/errgroup" +) + +type Option func(w *watch) error + +var ( + defaultOpts = []Option{} +) + +func WithErrGroup(eg errgroup.Group) Option { + return func(w *watch) error { + if eg != nil { + w.eg = eg + } + return nil + } +} + +func WithDirs(dirs ...string) Option { + return func(w *watch) error { + if len(dirs) == 0 { + return nil + } + if w.dirs != nil { + w.dirs = append(w.dirs, dirs...) + } else { + w.dirs = dirs + } + return nil + } +} + +func WithDir(dir string) Option { + return func(w *watch) error { + if len(dir) == 0 { + return nil + } + if w.dirs != nil { + w.dirs = append(w.dirs, dir) + } else { + w.dirs = []string{dir} + } + return nil + } +} + +func WithOnChange(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onChange = f + } + return nil + } +} + +func WithOnCreate(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onCreate = f + } + return nil + } +} + +func WithOnChmod(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onChmod = f + } + return nil + } +} + +func WithOnRename(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onRename = f + } + return nil + } +} + +func WithOnDelete(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onDelete = f + } + return nil + } +} +func WithOnWrite(f func(ctx context.Context, name string) error) Option { + return func(w *watch) error { + if f != nil { + w.onWrite = f + } + return nil + } +} + +func WithOnError(f func(ctx context.Context, err error) error) Option { + return func(w *watch) error { + if f != nil { + w.onError = f + } + return nil + } +} diff --git a/internal/file/watch/option_test.go b/internal/file/watch/option_test.go new file mode 100644 index 0000000000..de90aa6d23 --- /dev/null +++ b/internal/file/watch/option_test.go @@ -0,0 +1,1155 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 watch + +import ( + "context" + "testing" + + "github.com/vdaas/vald/internal/errgroup" + "go.uber.org/goleak" +) + +func TestWithErrGroup(t *testing.T) { + type T = interface{} + type args struct { + eg errgroup.Group + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + eg: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + eg: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithErrGroup(test.args.eg) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithErrGroup(test.args.eg) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDirs(t *testing.T) { + type T = interface{} + type args struct { + dirs []string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dirs: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dirs: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDirs(test.args.dirs...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDirs(test.args.dirs...) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDir(t *testing.T) { + type T = interface{} + type args struct { + dir string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dir: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dir: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDir(test.args.dir) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDir(test.args.dir) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnChange(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnChange(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnChange(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnCreate(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnCreate(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnCreate(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnChmod(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnChmod(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnChmod(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnRename(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnRename(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnRename(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnDelete(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnDelete(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnDelete(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnWrite(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, name string) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnWrite(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnWrite(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnError(t *testing.T) { + type T = interface{} + type args struct { + f func(ctx context.Context, err error) error + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnError(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnError(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/internal/file/watch/watch.go b/internal/file/watch/watch.go new file mode 100644 index 0000000000..2683fd98bf --- /dev/null +++ b/internal/file/watch/watch.go @@ -0,0 +1,188 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 watch + +import ( + "context" + "reflect" + + "github.com/fsnotify/fsnotify" + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/safety" +) + +type Watcher interface { + Start(ctx context.Context) (<-chan error, error) + Add(dir string) error + Remove(dir string) error + Stop(ctx context.Context) error +} + +type watch struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error +} + +func New(opts ...Option) (Watcher, error) { + w := new(watch) + for _, opt := range append(defaultOpts, opts...) { + if err := opt(w); err != nil { + return nil, errors.ErrOptionFailed(err, reflect.ValueOf(opt)) + } + } + + if len(w.dirs) == 0 { + return nil, errors.ErrWatchDirNotFound + } + return w.init() +} + +func (w *watch) init() (*watch, error) { + watcher, err := fsnotify.NewWatcher() + if err != nil { + return nil, err + } + if w.w != nil { + err = w.w.Close() + if err != nil { + return nil, err + } + } + w.w = watcher + + for _, dir := range w.dirs { + err = w.w.Add(dir) + if err != nil { + return nil, err + } + } + return w, nil +} + +func (w *watch) Start(ctx context.Context) (<-chan error, error) { + ech := make(chan error, 10) + w.eg.Go(safety.RecoverFunc(func() (err error) { + defer close(ech) + var ( + event fsnotify.Event + ok bool + ) + handleErr := func(ctx context.Context, err error) { + log.Error(err) + select { + case <-ctx.Done(): + case ech <- err: + } + } + for { + ok = true + err = nil + select { + case <-ctx.Done(): + return ctx.Err() + case event, ok = <-w.w.Events: + if ok { + log.Debug("change detected file: ", event.Name) + if w.onChange != nil { + err = w.onChange(ctx, event.Name) + if err != nil { + handleErr(ctx, err) + } + err = nil + } + switch { + case event.Op&fsnotify.Write == fsnotify.Write && w.onWrite != nil: + log.Debug("Modified file: ", event.Name) + err = w.onWrite(ctx, event.Name) + case event.Op&fsnotify.Create == fsnotify.Create && w.onCreate != nil: + log.Debug("Created file: ", event.Name) + err = w.onCreate(ctx, event.Name) + case event.Op&fsnotify.Remove == fsnotify.Remove && w.onDelete != nil: + log.Debug("Removed file: ", event.Name) + err = w.onDelete(ctx, event.Name) + case event.Op&fsnotify.Rename == fsnotify.Rename && w.onRename != nil: + log.Debug("Renamed file: ", event.Name) + err = w.onRename(ctx, event.Name) + case event.Op&fsnotify.Chmod == fsnotify.Chmod && w.onChmod != nil: + log.Debug("File changed permission: ", event.Name) + err = w.onChmod(ctx, event.Name) + } + } + } + if !ok { + w, err = w.init() + } + if err != nil { + handleErr(ctx, err) + } + } + return nil + })) + w.eg.Go(safety.RecoverFunc(func() (err error) { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err, ok := <-w.w.Errors: + if !ok { + w, err = w.init() + } else { + err = w.onError(ctx, err) + } + if err != nil { + log.Error(err) + select { + case <-ctx.Done(): + case ech <- err: + } + } + } + } + return nil + })) + return ech, nil +} +func (w *watch) Add(dir string) error { + if w.w != nil { + return w.w.Add(dir) + } + return nil +} + +func (w *watch) Remove(dir string) error { + if w.w != nil { + return w.w.Remove(dir) + } + return nil +} + +func (w *watch) Stop(ctx context.Context) error { + if w.w != nil { + return w.w.Close() + } + return nil +} diff --git a/internal/file/watch/watch_test.go b/internal/file/watch/watch_test.go new file mode 100644 index 0000000000..8974df0474 --- /dev/null +++ b/internal/file/watch/watch_test.go @@ -0,0 +1,701 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 watch + +import ( + "context" + "reflect" + "testing" + + "github.com/fsnotify/fsnotify" + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want Watcher + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, Watcher, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got Watcher, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got, err := New(test.args.opts...) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_watch_init(t *testing.T) { + type fields struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error + } + type want struct { + want *watch + err error + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *watch, error) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *watch, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + w := &watch{ + w: test.fields.w, + eg: test.fields.eg, + dirs: test.fields.dirs, + onChange: test.fields.onChange, + onCreate: test.fields.onCreate, + onRename: test.fields.onRename, + onDelete: test.fields.onDelete, + onWrite: test.fields.onWrite, + onChmod: test.fields.onChmod, + onError: test.fields.onError, + } + + got, err := w.init() + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_watch_Start(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error + } + type want struct { + want <-chan error + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, <-chan error, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got <-chan error, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + w := &watch{ + w: test.fields.w, + eg: test.fields.eg, + dirs: test.fields.dirs, + onChange: test.fields.onChange, + onCreate: test.fields.onCreate, + onRename: test.fields.onRename, + onDelete: test.fields.onDelete, + onWrite: test.fields.onWrite, + onChmod: test.fields.onChmod, + onError: test.fields.onError, + } + + got, err := w.Start(test.args.ctx) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_watch_Add(t *testing.T) { + type args struct { + dir string + } + type fields struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dir: "", + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dir: "", + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + w := &watch{ + w: test.fields.w, + eg: test.fields.eg, + dirs: test.fields.dirs, + onChange: test.fields.onChange, + onCreate: test.fields.onCreate, + onRename: test.fields.onRename, + onDelete: test.fields.onDelete, + onWrite: test.fields.onWrite, + onChmod: test.fields.onChmod, + onError: test.fields.onError, + } + + err := w.Add(test.args.dir) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_watch_Remove(t *testing.T) { + type args struct { + dir string + } + type fields struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dir: "", + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dir: "", + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + w := &watch{ + w: test.fields.w, + eg: test.fields.eg, + dirs: test.fields.dirs, + onChange: test.fields.onChange, + onCreate: test.fields.onCreate, + onRename: test.fields.onRename, + onDelete: test.fields.onDelete, + onWrite: test.fields.onWrite, + onChmod: test.fields.onChmod, + onError: test.fields.onError, + } + + err := w.Remove(test.args.dir) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_watch_Stop(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + w *fsnotify.Watcher + eg errgroup.Group + dirs []string + onChange func(ctx context.Context, name string) error + onCreate func(ctx context.Context, name string) error + onRename func(ctx context.Context, name string) error + onDelete func(ctx context.Context, name string) error + onWrite func(ctx context.Context, name string) error + onChmod func(ctx context.Context, name string) error + onError func(ctx context.Context, err error) error + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + eg: nil, + dirs: nil, + onChange: nil, + onCreate: nil, + onRename: nil, + onDelete: nil, + onWrite: nil, + onChmod: nil, + onError: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + w := &watch{ + w: test.fields.w, + eg: test.fields.eg, + dirs: test.fields.dirs, + onChange: test.fields.onChange, + onCreate: test.fields.onCreate, + onRename: test.fields.onRename, + onDelete: test.fields.onDelete, + onWrite: test.fields.onWrite, + onChmod: test.fields.onChmod, + onError: test.fields.onError, + } + + err := w.Stop(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/observability/metrics/agent/ngt/ngt.go b/internal/observability/metrics/agent/core/ngt/ngt.go similarity index 98% rename from internal/observability/metrics/agent/ngt/ngt.go rename to internal/observability/metrics/agent/core/ngt/ngt.go index 3009af5a6f..b008ab5416 100644 --- a/internal/observability/metrics/agent/ngt/ngt.go +++ b/internal/observability/metrics/agent/core/ngt/ngt.go @@ -21,7 +21,7 @@ import ( "context" "github.com/vdaas/vald/internal/observability/metrics" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" ) type ngtMetrics struct { diff --git a/internal/observability/metrics/agent/ngt/ngt_test.go b/internal/observability/metrics/agent/core/ngt/ngt_test.go similarity index 99% rename from internal/observability/metrics/agent/ngt/ngt_test.go rename to internal/observability/metrics/agent/core/ngt/ngt_test.go index e5aed2d095..cd4bf71f8f 100644 --- a/internal/observability/metrics/agent/ngt/ngt_test.go +++ b/internal/observability/metrics/agent/core/ngt/ngt_test.go @@ -24,7 +24,7 @@ import ( "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/observability/metrics" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/README.md b/pkg/agent/core/ngt/README.md old mode 100755 new mode 100644 similarity index 100% rename from pkg/agent/ngt/README.md rename to pkg/agent/core/ngt/README.md diff --git a/pkg/agent/ngt/config/config.go b/pkg/agent/core/ngt/config/config.go similarity index 100% rename from pkg/agent/ngt/config/config.go rename to pkg/agent/core/ngt/config/config.go diff --git a/pkg/agent/ngt/config/config_test.go b/pkg/agent/core/ngt/config/config_test.go similarity index 100% rename from pkg/agent/ngt/config/config_test.go rename to pkg/agent/core/ngt/config/config_test.go diff --git a/pkg/agent/ngt/handler/doc.go b/pkg/agent/core/ngt/handler/doc.go similarity index 100% rename from pkg/agent/ngt/handler/doc.go rename to pkg/agent/core/ngt/handler/doc.go diff --git a/pkg/agent/ngt/handler/grpc/handler.go b/pkg/agent/core/ngt/handler/grpc/handler.go similarity index 98% rename from pkg/agent/ngt/handler/grpc/handler.go rename to pkg/agent/core/ngt/handler/grpc/handler.go index 51b5430927..63b05769a8 100644 --- a/pkg/agent/ngt/handler/grpc/handler.go +++ b/pkg/agent/core/ngt/handler/grpc/handler.go @@ -22,7 +22,7 @@ import ( "fmt" "strconv" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/info" @@ -30,8 +30,8 @@ import ( "github.com/vdaas/vald/internal/net/grpc" "github.com/vdaas/vald/internal/net/grpc/status" "github.com/vdaas/vald/internal/observability/trace" - "github.com/vdaas/vald/pkg/agent/ngt/model" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/model" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" ) type Server agent.AgentServer diff --git a/pkg/agent/ngt/handler/grpc/handler_test.go b/pkg/agent/core/ngt/handler/grpc/handler_test.go similarity index 99% rename from pkg/agent/ngt/handler/grpc/handler_test.go rename to pkg/agent/core/ngt/handler/grpc/handler_test.go index 339d15a56d..cff96d42ab 100644 --- a/pkg/agent/ngt/handler/grpc/handler_test.go +++ b/pkg/agent/core/ngt/handler/grpc/handler_test.go @@ -22,11 +22,11 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/errors" - "github.com/vdaas/vald/pkg/agent/ngt/model" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/model" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/handler/grpc/option.go b/pkg/agent/core/ngt/handler/grpc/option.go similarity index 94% rename from pkg/agent/ngt/handler/grpc/option.go rename to pkg/agent/core/ngt/handler/grpc/option.go index 4db76aba22..3d8c270c9f 100644 --- a/pkg/agent/ngt/handler/grpc/option.go +++ b/pkg/agent/core/ngt/handler/grpc/option.go @@ -17,7 +17,7 @@ // Package grpc provides grpc server logic package grpc -import "github.com/vdaas/vald/pkg/agent/ngt/service" +import "github.com/vdaas/vald/pkg/agent/core/ngt/service" type Option func(*server) diff --git a/pkg/agent/ngt/handler/grpc/option_test.go b/pkg/agent/core/ngt/handler/grpc/option_test.go similarity index 99% rename from pkg/agent/ngt/handler/grpc/option_test.go rename to pkg/agent/core/ngt/handler/grpc/option_test.go index bed6bb771d..169f3a072e 100644 --- a/pkg/agent/ngt/handler/grpc/option_test.go +++ b/pkg/agent/core/ngt/handler/grpc/option_test.go @@ -20,7 +20,7 @@ package grpc import ( "testing" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/handler/rest/handler.go b/pkg/agent/core/ngt/handler/rest/handler.go similarity index 99% rename from pkg/agent/ngt/handler/rest/handler.go rename to pkg/agent/core/ngt/handler/rest/handler.go index e6e57354ba..25bb1c4a2b 100644 --- a/pkg/agent/ngt/handler/rest/handler.go +++ b/pkg/agent/core/ngt/handler/rest/handler.go @@ -22,7 +22,7 @@ import ( "io/ioutil" "net/http" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/net/http/dump" "github.com/vdaas/vald/internal/net/http/json" diff --git a/pkg/agent/ngt/handler/rest/handler_test.go b/pkg/agent/core/ngt/handler/rest/handler_test.go similarity index 99% rename from pkg/agent/ngt/handler/rest/handler_test.go rename to pkg/agent/core/ngt/handler/rest/handler_test.go index 2246525d1b..980e2e360f 100644 --- a/pkg/agent/ngt/handler/rest/handler_test.go +++ b/pkg/agent/core/ngt/handler/rest/handler_test.go @@ -22,7 +22,7 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/internal/errors" "go.uber.org/goleak" diff --git a/pkg/agent/ngt/handler/rest/option.go b/pkg/agent/core/ngt/handler/rest/option.go similarity index 93% rename from pkg/agent/ngt/handler/rest/option.go rename to pkg/agent/core/ngt/handler/rest/option.go index f35276618d..c7cfd0fd66 100644 --- a/pkg/agent/ngt/handler/rest/option.go +++ b/pkg/agent/core/ngt/handler/rest/option.go @@ -17,7 +17,7 @@ // Package rest provides rest api logic package rest -import "github.com/vdaas/vald/apis/grpc/agent" +import agent "github.com/vdaas/vald/apis/grpc/agent/core" type Option func(*handler) diff --git a/pkg/agent/ngt/handler/rest/option_test.go b/pkg/agent/core/ngt/handler/rest/option_test.go similarity index 98% rename from pkg/agent/ngt/handler/rest/option_test.go rename to pkg/agent/core/ngt/handler/rest/option_test.go index 9f4f8d0587..32d808a5d6 100644 --- a/pkg/agent/ngt/handler/rest/option_test.go +++ b/pkg/agent/core/ngt/handler/rest/option_test.go @@ -20,7 +20,7 @@ package rest import ( "testing" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/model/ngt.go b/pkg/agent/core/ngt/model/ngt.go similarity index 100% rename from pkg/agent/ngt/model/ngt.go rename to pkg/agent/core/ngt/model/ngt.go diff --git a/pkg/agent/ngt/router/option.go b/pkg/agent/core/ngt/router/option.go similarity index 95% rename from pkg/agent/ngt/router/option.go rename to pkg/agent/core/ngt/router/option.go index 133134507d..0b2567351e 100644 --- a/pkg/agent/ngt/router/option.go +++ b/pkg/agent/core/ngt/router/option.go @@ -19,7 +19,7 @@ package router import ( "github.com/vdaas/vald/internal/errgroup" - "github.com/vdaas/vald/pkg/agent/ngt/handler/rest" + "github.com/vdaas/vald/pkg/agent/core/ngt/handler/rest" ) type Option func(*router) diff --git a/pkg/agent/ngt/router/option_test.go b/pkg/agent/core/ngt/router/option_test.go similarity index 99% rename from pkg/agent/ngt/router/option_test.go rename to pkg/agent/core/ngt/router/option_test.go index 2b60aef4a4..29b650563e 100644 --- a/pkg/agent/ngt/router/option_test.go +++ b/pkg/agent/core/ngt/router/option_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/vdaas/vald/internal/errgroup" - "github.com/vdaas/vald/pkg/agent/ngt/handler/rest" + "github.com/vdaas/vald/pkg/agent/core/ngt/handler/rest" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/router/router.go b/pkg/agent/core/ngt/router/router.go similarity index 98% rename from pkg/agent/ngt/router/router.go rename to pkg/agent/core/ngt/router/router.go index 518cefd096..e3325b7622 100644 --- a/pkg/agent/ngt/router/router.go +++ b/pkg/agent/core/ngt/router/router.go @@ -23,7 +23,7 @@ import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/net/http/middleware" "github.com/vdaas/vald/internal/net/http/routing" - "github.com/vdaas/vald/pkg/agent/ngt/handler/rest" + "github.com/vdaas/vald/pkg/agent/core/ngt/handler/rest" ) type router struct { diff --git a/pkg/agent/ngt/router/router_test.go b/pkg/agent/core/ngt/router/router_test.go similarity index 100% rename from pkg/agent/ngt/router/router_test.go rename to pkg/agent/core/ngt/router/router_test.go diff --git a/pkg/agent/ngt/service/doc.go b/pkg/agent/core/ngt/service/doc.go similarity index 100% rename from pkg/agent/ngt/service/doc.go rename to pkg/agent/core/ngt/service/doc.go diff --git a/pkg/agent/ngt/service/kvs/kvs.go b/pkg/agent/core/ngt/service/kvs/kvs.go similarity index 100% rename from pkg/agent/ngt/service/kvs/kvs.go rename to pkg/agent/core/ngt/service/kvs/kvs.go diff --git a/pkg/agent/ngt/service/kvs/kvs_test.go b/pkg/agent/core/ngt/service/kvs/kvs_test.go similarity index 100% rename from pkg/agent/ngt/service/kvs/kvs_test.go rename to pkg/agent/core/ngt/service/kvs/kvs_test.go diff --git a/pkg/agent/ngt/service/kvs/ou.go b/pkg/agent/core/ngt/service/kvs/ou.go similarity index 100% rename from pkg/agent/ngt/service/kvs/ou.go rename to pkg/agent/core/ngt/service/kvs/ou.go diff --git a/pkg/agent/ngt/service/kvs/ou_test.go b/pkg/agent/core/ngt/service/kvs/ou_test.go similarity index 100% rename from pkg/agent/ngt/service/kvs/ou_test.go rename to pkg/agent/core/ngt/service/kvs/ou_test.go diff --git a/pkg/agent/ngt/service/kvs/uo.go b/pkg/agent/core/ngt/service/kvs/uo.go similarity index 100% rename from pkg/agent/ngt/service/kvs/uo.go rename to pkg/agent/core/ngt/service/kvs/uo.go diff --git a/pkg/agent/ngt/service/kvs/uo_test.go b/pkg/agent/core/ngt/service/kvs/uo_test.go similarity index 100% rename from pkg/agent/ngt/service/kvs/uo_test.go rename to pkg/agent/core/ngt/service/kvs/uo_test.go diff --git a/pkg/agent/ngt/service/ngt.go b/pkg/agent/core/ngt/service/ngt.go similarity index 99% rename from pkg/agent/ngt/service/ngt.go rename to pkg/agent/core/ngt/service/ngt.go index 2389c21306..3b09976b0d 100644 --- a/pkg/agent/ngt/service/ngt.go +++ b/pkg/agent/core/ngt/service/ngt.go @@ -37,8 +37,8 @@ import ( "github.com/vdaas/vald/internal/rand" "github.com/vdaas/vald/internal/safety" "github.com/vdaas/vald/internal/timeutil" - "github.com/vdaas/vald/pkg/agent/ngt/model" - "github.com/vdaas/vald/pkg/agent/ngt/service/kvs" + "github.com/vdaas/vald/pkg/agent/core/ngt/model" + "github.com/vdaas/vald/pkg/agent/core/ngt/service/kvs" ) type NGT interface { diff --git a/pkg/agent/ngt/service/ngt_test.go b/pkg/agent/core/ngt/service/ngt_test.go similarity index 99% rename from pkg/agent/ngt/service/ngt_test.go rename to pkg/agent/core/ngt/service/ngt_test.go index 91b888abbe..8cc5c4af7b 100644 --- a/pkg/agent/ngt/service/ngt_test.go +++ b/pkg/agent/core/ngt/service/ngt_test.go @@ -28,8 +28,8 @@ import ( core "github.com/vdaas/vald/internal/core/ngt" "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" - "github.com/vdaas/vald/pkg/agent/ngt/model" - "github.com/vdaas/vald/pkg/agent/ngt/service/kvs" + "github.com/vdaas/vald/pkg/agent/core/ngt/model" + "github.com/vdaas/vald/pkg/agent/core/ngt/service/kvs" "go.uber.org/goleak" ) diff --git a/pkg/agent/ngt/service/vcaches.go b/pkg/agent/core/ngt/service/vcaches.go similarity index 100% rename from pkg/agent/ngt/service/vcaches.go rename to pkg/agent/core/ngt/service/vcaches.go diff --git a/pkg/agent/ngt/service/vcaches_test.go b/pkg/agent/core/ngt/service/vcaches_test.go similarity index 100% rename from pkg/agent/ngt/service/vcaches_test.go rename to pkg/agent/core/ngt/service/vcaches_test.go diff --git a/pkg/agent/ngt/usecase/agentd.go b/pkg/agent/core/ngt/usecase/agentd.go similarity index 92% rename from pkg/agent/ngt/usecase/agentd.go rename to pkg/agent/core/ngt/usecase/agentd.go index a89b55a252..dae6aa483d 100644 --- a/pkg/agent/ngt/usecase/agentd.go +++ b/pkg/agent/core/ngt/usecase/agentd.go @@ -19,23 +19,23 @@ package usecase import ( "context" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" iconf "github.com/vdaas/vald/internal/config" "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/log" "github.com/vdaas/vald/internal/net/grpc" "github.com/vdaas/vald/internal/net/grpc/metric" "github.com/vdaas/vald/internal/observability" - ngtmetrics "github.com/vdaas/vald/internal/observability/metrics/agent/ngt" + ngtmetrics "github.com/vdaas/vald/internal/observability/metrics/agent/core/ngt" "github.com/vdaas/vald/internal/runner" "github.com/vdaas/vald/internal/safety" "github.com/vdaas/vald/internal/servers/server" "github.com/vdaas/vald/internal/servers/starter" - "github.com/vdaas/vald/pkg/agent/ngt/config" - handler "github.com/vdaas/vald/pkg/agent/ngt/handler/grpc" - "github.com/vdaas/vald/pkg/agent/ngt/handler/rest" - "github.com/vdaas/vald/pkg/agent/ngt/router" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" + handler "github.com/vdaas/vald/pkg/agent/core/ngt/handler/grpc" + "github.com/vdaas/vald/pkg/agent/core/ngt/handler/rest" + "github.com/vdaas/vald/pkg/agent/core/ngt/router" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" ) type run struct { diff --git a/pkg/agent/ngt/usecase/agentd_test.go b/pkg/agent/core/ngt/usecase/agentd_test.go similarity index 99% rename from pkg/agent/ngt/usecase/agentd_test.go rename to pkg/agent/core/ngt/usecase/agentd_test.go index 4e609e9f8d..8f2da9be5c 100644 --- a/pkg/agent/ngt/usecase/agentd_test.go +++ b/pkg/agent/core/ngt/usecase/agentd_test.go @@ -26,8 +26,8 @@ import ( "github.com/vdaas/vald/internal/observability" "github.com/vdaas/vald/internal/runner" "github.com/vdaas/vald/internal/servers/starter" - "github.com/vdaas/vald/pkg/agent/ngt/config" - "github.com/vdaas/vald/pkg/agent/ngt/service" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/service" "go.uber.org/goleak" ) diff --git a/pkg/agent/sptag/.gitkeep b/pkg/agent/core/sptag/.gitkeep old mode 100755 new mode 100644 similarity index 100% rename from pkg/agent/sptag/.gitkeep rename to pkg/agent/core/sptag/.gitkeep diff --git a/pkg/agent/sidecar/README.md b/pkg/agent/sidecar/README.md new file mode 100644 index 0000000000..9b8d2e1af5 --- /dev/null +++ b/pkg/agent/sidecar/README.md @@ -0,0 +1 @@ +# server sample diff --git a/pkg/agent/sidecar/config/config.go b/pkg/agent/sidecar/config/config.go new file mode 100644 index 0000000000..c13dfed6ad --- /dev/null +++ b/pkg/agent/sidecar/config/config.go @@ -0,0 +1,147 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 setting stores all server application settings +package config + +import ( + "github.com/vdaas/vald/internal/config" +) + +type GlobalConfig = config.GlobalConfig + +// Config represent a application setting data content (config.yaml). +// In K8s environment, this configuration is stored in K8s ConfigMap. +type Data struct { + config.GlobalConfig `json:",inline" yaml:",inline"` + + // Server represent all server configurations + Server *config.Servers `json:"server_config" yaml:"server_config"` + + // Observability represent observability configurations + Observability *config.Observability `json:"observability" yaml:"observability"` + + // Sidecar represent agent storage sync sidecar service configuration + Sidecar *config.Sidecar `json:"sidecar" yaml:"sidecar"` +} + +func NewConfig(path string) (cfg *Data, err error) { + err = config.Read(path, &cfg) + + if err != nil { + return nil, err + } + + if cfg != nil { + cfg.Bind() + } + + if cfg.Server != nil { + cfg.Server = cfg.Server.Bind() + } + + if cfg.Observability != nil { + cfg.Observability = cfg.Observability.Bind() + } + + if cfg.Sidecar != nil { + cfg.Sidecar = cfg.Sidecar.Bind() + } + return cfg, nil +} + +// func FakeData() { +// d := Data{ +// Version: "v0.0.1", +// Server: &config.Servers{ +// Servers: []*config.Server{ +// { +// Name: "agent-rest", +// Host: "127.0.0.1", +// Port: 8080, +// Mode: "REST", +// ProbeWaitTime: "3s", +// ShutdownDuration: "5s", +// HandlerTimeout: "5s", +// IdleTimeout: "2s", +// ReadHeaderTimeout: "1s", +// ReadTimeout: "1s", +// WriteTimeout: "1s", +// }, +// { +// Name: "agent-grpc", +// Host: "127.0.0.1", +// Port: 8082, +// Mode: "GRPC", +// }, +// }, +// MetricsServers: []*config.Server{ +// { +// Name: "pprof", +// Host: "127.0.0.1", +// Port: 6060, +// Mode: "REST", +// ProbeWaitTime: "3s", +// ShutdownDuration: "5s", +// HandlerTimeout: "5s", +// IdleTimeout: "2s", +// ReadHeaderTimeout: "1s", +// ReadTimeout: "1s", +// WriteTimeout: "1s", +// }, +// }, +// HealthCheckServers: []*config.Server{ +// { +// Name: "livenesss", +// Host: "127.0.0.1", +// Port: 3000, +// }, +// { +// Name: "readiness", +// Host: "127.0.0.1", +// Port: 3001, +// }, +// }, +// StartUpStrategy: []string{ +// "livenesss", +// "pprof", +// "agent-grpc", +// "agent-rest", +// "readiness", +// }, +// ShutdownStrategy: []string{ +// "readiness", +// "agent-rest", +// "agent-grpc", +// "pprof", +// "livenesss", +// }, +// FullShutdownDuration: "30s", +// TLS: &config.TLS{ +// Enabled: false, +// Cert: "/path/to/cert", +// Key: "/path/to/key", +// CA: "/path/to/ca", +// }, +// }, +// Gateway: &config.Gateway{ +// AgentPort: 8080, +// AgentName: "vald-agent", +// BackoffEnabled: false,, +// }, +// } +// fmt.Println(config.ToRawYaml(d)) +// } diff --git a/pkg/agent/sidecar/config/config_test.go b/pkg/agent/sidecar/config/config_test.go new file mode 100644 index 0000000000..e8090717ea --- /dev/null +++ b/pkg/agent/sidecar/config/config_test.go @@ -0,0 +1,101 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 setting stores all server application settings +package config + +import ( + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestNewConfig(t *testing.T) { + type args struct { + path string + } + type want struct { + wantCfg *Data + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, *Data, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, gotCfg *Data, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(gotCfg, w.wantCfg) { + return errors.Errorf("got = %v, want %v", gotCfg, w.wantCfg) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + path: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + path: "", + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + gotCfg, err := NewConfig(test.args.path) + if err := test.checkFunc(test.want, gotCfg, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/agent/sidecar/handler/doc.go b/pkg/agent/sidecar/handler/doc.go new file mode 100644 index 0000000000..86b6d1869d --- /dev/null +++ b/pkg/agent/sidecar/handler/doc.go @@ -0,0 +1,17 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 handler diff --git a/pkg/agent/sidecar/handler/grpc/handler.go b/pkg/agent/sidecar/handler/grpc/handler.go new file mode 100644 index 0000000000..5b16c4ce4b --- /dev/null +++ b/pkg/agent/sidecar/handler/grpc/handler.go @@ -0,0 +1,36 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 grpc server logic +package grpc + +import ( + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "github.com/vdaas/vald/pkg/agent/sidecar/service" +) + +type server struct { + so service.StorageObserver +} + +func New(opts ...Option) sidecar.SidecarServer { + s := new(server) + + for _, opt := range append(defaultOpts, opts...) { + opt(s) + } + return s +} diff --git a/pkg/agent/sidecar/handler/grpc/handler_test.go b/pkg/agent/sidecar/handler/grpc/handler_test.go new file mode 100644 index 0000000000..198c039939 --- /dev/null +++ b/pkg/agent/sidecar/handler/grpc/handler_test.go @@ -0,0 +1,98 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 grpc server logic +package grpc + +import ( + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want sidecar.SidecarServer + } + type test struct { + name string + args args + want want + checkFunc func(want, sidecar.SidecarServer) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got sidecar.SidecarServer) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := New(test.args.opts...) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/agent/sidecar/handler/grpc/option.go b/pkg/agent/sidecar/handler/grpc/option.go new file mode 100644 index 0000000000..0ea18a48ea --- /dev/null +++ b/pkg/agent/sidecar/handler/grpc/option.go @@ -0,0 +1,36 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 grpc server logic +package grpc + +import ( + "github.com/vdaas/vald/pkg/agent/sidecar/service" +) + +type Option func(*server) + +var ( + defaultOpts = []Option{} +) + +func WithStorageObserver(so service.StorageObserver) Option { + return func(s *server) { + if i != nil { + s.so = so + } + } +} diff --git a/pkg/agent/sidecar/handler/grpc/option_test.go b/pkg/agent/sidecar/handler/grpc/option_test.go new file mode 100644 index 0000000000..de873662b0 --- /dev/null +++ b/pkg/agent/sidecar/handler/grpc/option_test.go @@ -0,0 +1,138 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 grpc server logic +package grpc + +import ( + "testing" + + "github.com/vdaas/vald/pkg/agent/sidecar/service" + "go.uber.org/goleak" +) + +func TestWithStorageObserver(t *testing.T) { + type T = interface{} + type args struct { + so service.StorageObserver + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + so: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + so: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithStorageObserver(test.args.so) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithStorageObserver(test.args.so) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/pkg/agent/sidecar/handler/rest/handler.go b/pkg/agent/sidecar/handler/rest/handler.go new file mode 100644 index 0000000000..5fb6c20df2 --- /dev/null +++ b/pkg/agent/sidecar/handler/rest/handler.go @@ -0,0 +1,50 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 rest provides rest api logic +package rest + +import ( + "net/http" + + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "github.com/vdaas/vald/internal/net/http/dump" + "github.com/vdaas/vald/internal/net/http/json" +) + +type Handler interface { + Index(w http.ResponseWriter, r *http.Request) (int, error) +} + +type handler struct { + sc sidecar.SidecarServer +} + +func New(opts ...Option) Handler { + h := new(handler) + + for _, opt := range append(defaultOpts, opts...) { + opt(h) + } + return h +} + +func (h *handler) Index(w http.ResponseWriter, r *http.Request) (int, error) { + data := make(map[string]interface{}) + return json.Handler(w, r, &data, func() (interface{}, error) { + return dump.Request(nil, data, r) + }) +} diff --git a/pkg/agent/sidecar/handler/rest/handler_test.go b/pkg/agent/sidecar/handler/rest/handler_test.go new file mode 100644 index 0000000000..8e6e06f42b --- /dev/null +++ b/pkg/agent/sidecar/handler/rest/handler_test.go @@ -0,0 +1,190 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 rest provides rest api logic +package rest + +import ( + "net/http" + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want Handler + } + type test struct { + name string + args args + want want + checkFunc func(want, Handler) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got Handler) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := New(test.args.opts...) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_handler_Index(t *testing.T) { + type args struct { + w http.ResponseWriter + r *http.Request + } + type fields struct { + sc sidecar.SidecarServer + } + type want struct { + want int + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, int, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got int, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + w: nil, + r: nil, + }, + fields: fields { + sc: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + w: nil, + r: nil, + }, + fields: fields { + sc: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + h := &handler{ + sc: test.fields.sc, + } + + got, err := h.Index(test.args.w, test.args.r) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/agent/sidecar/handler/rest/option.go b/pkg/agent/sidecar/handler/rest/option.go new file mode 100644 index 0000000000..00d34db91e --- /dev/null +++ b/pkg/agent/sidecar/handler/rest/option.go @@ -0,0 +1,34 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 rest provides rest api logic +package rest + +import ( + "github.com/vdaas/vald/apis/grpc/agent/sidecar" +) + +type Option func(*handler) + +var ( + defaultOpts = []Option{} +) + +func WithSidecar(sc sidecar.SidecarServer) Option { + return func(h *handler) { + h.sc = sc + } +} diff --git a/pkg/agent/sidecar/handler/rest/option_test.go b/pkg/agent/sidecar/handler/rest/option_test.go new file mode 100644 index 0000000000..17c17ecd99 --- /dev/null +++ b/pkg/agent/sidecar/handler/rest/option_test.go @@ -0,0 +1,138 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 rest provides rest api logic +package rest + +import ( + "testing" + + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "go.uber.org/goleak" +) + +func TestWithSidecar(t *testing.T) { + type T = interface{} + type args struct { + sc sidecar.SidecarServer + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + sc: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + sc: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithSidecar(test.args.sc) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithSidecar(test.args.sc) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/pkg/agent/sidecar/router/option.go b/pkg/agent/sidecar/router/option.go new file mode 100644 index 0000000000..2ca5928d0c --- /dev/null +++ b/pkg/agent/sidecar/router/option.go @@ -0,0 +1,42 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 router provides implementation of Go API for routing http Handler wrapped by rest.Func +package router + +import ( + "github.com/vdaas/vald/pkg/agent/sidecar/handler/rest" +) + +type Option func(*router) + +var ( + defaultOpts = []Option{ + WithTimeout("3s"), + } +) + +func WithHandler(h rest.Handler) Option { + return func(r *router) { + r.handler = h + } +} + +func WithTimeout(timeout string) Option { + return func(r *router) { + r.timeout = timeout + } +} diff --git a/pkg/agent/sidecar/router/option_test.go b/pkg/agent/sidecar/router/option_test.go new file mode 100644 index 0000000000..2edd4edb86 --- /dev/null +++ b/pkg/agent/sidecar/router/option_test.go @@ -0,0 +1,252 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 router provides implementation of Go API for routing http Handler wrapped by rest.Func +package router + +import ( + "testing" + + "github.com/vdaas/vald/pkg/agent/sidecar/handler/rest" + + "go.uber.org/goleak" +) + +func TestWithHandler(t *testing.T) { + type T = interface{} + type args struct { + h rest.Handler + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + h: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + h: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithHandler(test.args.h) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithHandler(test.args.h) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithTimeout(t *testing.T) { + type T = interface{} + type args struct { + timeout string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + timeout: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + timeout: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTimeout(test.args.timeout) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithTimeout(test.args.timeout) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/pkg/agent/sidecar/router/router.go b/pkg/agent/sidecar/router/router.go new file mode 100644 index 0000000000..a0a876b575 --- /dev/null +++ b/pkg/agent/sidecar/router/router.go @@ -0,0 +1,52 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 router provides implementation of Go API for routing http Handler wrapped by rest.Func +package router + +import ( + "net/http" + + "github.com/vdaas/vald/internal/net/http/routing" + "github.com/vdaas/vald/pkg/agent/sidecar/handler/rest" +) + +type router struct { + handler rest.Handler + timeout string +} + +// New returns REST route&method information from handler interface +func New(opts ...Option) http.Handler { + r := new(router) + + for _, opt := range append(defaultOpts, opts...) { + opt(r) + } + + h := r.handler + + return routing.New( + routing.WithRoutes([]routing.Route{ + { + "Index", + []string{ + http.MethodGet, + }, + "/", + h.Index, + }}...)) +} diff --git a/pkg/agent/sidecar/router/router_test.go b/pkg/agent/sidecar/router/router_test.go new file mode 100644 index 0000000000..876b9574c4 --- /dev/null +++ b/pkg/agent/sidecar/router/router_test.go @@ -0,0 +1,96 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 router provides implementation of Go API for routing http Handler wrapped by rest.Func +package router + +import ( + "net/http" + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + want http.Handler + } + type test struct { + name string + args args + want want + checkFunc func(want, http.Handler) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got http.Handler) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := New(test.args.opts...) + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/agent/sidecar/service/doc.go b/pkg/agent/sidecar/service/doc.go new file mode 100644 index 0000000000..c13956cbbe --- /dev/null +++ b/pkg/agent/sidecar/service/doc.go @@ -0,0 +1,18 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 service manages the main logic of server. +package service diff --git a/pkg/agent/sidecar/service/option.go b/pkg/agent/sidecar/service/option.go new file mode 100644 index 0000000000..c0d8f9470e --- /dev/null +++ b/pkg/agent/sidecar/service/option.go @@ -0,0 +1,100 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 service +package service + +import ( + "time" + + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/timeutil" +) + +type Option func(o *observer) error + +var ( + defaultOpts = []Option{ + WithErrGroup(errgroup.Get()), + WithBackupDuration("5m"), + WithBackupDurationLimit("1h"), + } +) + +func WithBackupDuration(dur string) Option { + return func(o *observer) error { + if dur == "" { + return nil + } + d, err := timeutil.Parse(dur) + if err != nil { + d = time.Minute * 5 + } + o.checkDuration = d + return nil + } +} + +func WithBackupDurationLimit(dur string) Option { + return func(o *observer) error { + if dur == "" { + return nil + } + d, err := timeutil.Parse(dur) + if err != nil { + d = time.Hour + } + o.longestCheckDuration = d + return nil + } +} + +func WithErrGroup(eg errgroup.Group) Option { + return func(o *observer) error { + if eg != nil { + o.eg = eg + } + return nil + } +} + +func WithDirs(dirs ...string) Option { + return func(o *observer) error { + if len(dirs) == 0 { + return nil + } + if o.dirs != nil { + o.dirs = append(o.dirs, dirs...) + } else { + o.dirs = dirs + } + return nil + } +} + +func WithDir(dir string) Option { + return func(o *observer) error { + if len(dir) == 0 { + return nil + } + if o.dirs != nil { + o.dirs = append(o.dirs, dir) + } else { + o.dirs = []string{dir} + } + return nil + } +} diff --git a/pkg/agent/sidecar/service/option_test.go b/pkg/agent/sidecar/service/option_test.go new file mode 100644 index 0000000000..d6aea6a7ed --- /dev/null +++ b/pkg/agent/sidecar/service/option_test.go @@ -0,0 +1,590 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 service +package service + +import ( + "testing" + + "github.com/vdaas/vald/internal/errgroup" + "go.uber.org/goleak" +) + +func TestWithBackupDuration(t *testing.T) { + type T = interface{} + type args struct { + dur string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBackupDuration(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBackupDuration(test.args.dur) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithBackupDurationLimit(t *testing.T) { + type T = interface{} + type args struct { + dur string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBackupDurationLimit(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBackupDurationLimit(test.args.dur) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithErrGroup(t *testing.T) { + type T = interface{} + type args struct { + eg errgroup.Group + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + eg: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + eg: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithErrGroup(test.args.eg) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithErrGroup(test.args.eg) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDirs(t *testing.T) { + type T = interface{} + type args struct { + dirs []string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dirs: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dirs: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDirs(test.args.dirs...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDirs(test.args.dirs...) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDir(t *testing.T) { + type T = interface{} + type args struct { + dir string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.c) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dir: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dir: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDir(test.args.dir) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDir(test.args.dir) + obj := new(T) + got(obj) + if err := test.checkFunc(tt.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/pkg/agent/sidecar/service/storage_observer.go b/pkg/agent/sidecar/service/storage_observer.go new file mode 100644 index 0000000000..f025951ef8 --- /dev/null +++ b/pkg/agent/sidecar/service/storage_observer.go @@ -0,0 +1,143 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 service +package service + +import ( + "context" + "reflect" + "time" + + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/file/watch" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/observability/trace" + "github.com/vdaas/vald/internal/safety" +) + +type StorageObserver interface { + Start(ctx context.Context) (<-chan error, error) +} + +type observer struct { + w watch.Watcher + dirs []string + eg errgroup.Group + checkDuration time.Duration + longestCheckDuration time.Duration +} + +func New(opts ...Option) (so StorageObserver, err error) { + o := new(observer) + for _, opt := range append(defaultOpts, opts...) { + if err := opt(o); err != nil { + return nil, errors.ErrOptionFailed(err, reflect.ValueOf(opt)) + } + } + o.w, err = watch.New( + watch.WithDirs(o.dirs...), + watch.WithErrGroup(o.eg), + watch.WithOnWrite(func(ctx context.Context, name string) error { + ctx, span := trace.StartSpan(ctx, "vald/agent-sidecar/service/StorageObserver.watcher.OnWrite") + defer func() { + if span != nil { + span.End() + } + }() + return o.backup(ctx) + }), + watch.WithOnCreate(func(ctx context.Context, name string) error { + ctx, span := trace.StartSpan(ctx, "vald/agent-sidecar/service/StorageObserver.watcher.OnCreate") + defer func() { + if span != nil { + span.End() + } + }() + return o.backup(ctx) + }), + ) + if err != nil { + return nil, err + } + + return o, nil +} + +func (o *observer) Start(ctx context.Context) (<-chan error, error) { + wech, err := o.w.Start(ctx) + if err != nil { + return nil, err + } + ech := make(chan error, 100) + o.eg.Go(safety.RecoverFunc(func() (err error) { + defer close(ech) + ct := time.NewTicker(o.checkDuration) + defer ct.Stop() + lct := time.NewTicker(o.longestCheckDuration) + defer lct.Stop() + finalize := func() (err error) { + err = ctx.Err() + if err != nil && err != context.Canceled { + return err + } + return nil + } + for { + select { + case <-ctx.Done(): + return finalize() + case <-ct.C: + err = o.backup(ctx) + if err != nil { + ech <- err + log.Error(err) + err = nil + } + case <-lct.C: + err = o.backup(ctx) + if err != nil { + ech <- err + log.Error(err) + err = nil + } + case err = <-wech: + } + if err != nil { + log.Error(err) + select { + case <-ctx.Done(): + return finalize() + case ech <- err: + } + } + } + })) + return ech, nil +} + +func (o *observer) backup(ctx context.Context) (err error) { + ctx, span := trace.StartSpan(ctx, "vald/agent-sidecar/service/StorageObserver.backup") + defer func() { + if span != nil { + span.End() + } + }() + // TODO implement backup logic here + + return nil +} diff --git a/pkg/agent/sidecar/service/storage_observer_test.go b/pkg/agent/sidecar/service/storage_observer_test.go new file mode 100644 index 0000000000..3e143faad1 --- /dev/null +++ b/pkg/agent/sidecar/service/storage_observer_test.go @@ -0,0 +1,309 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 service +package service + +import ( + "context" + "reflect" + "testing" + "time" + + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/file/watch" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + wantSo StorageObserver + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, StorageObserver, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, gotSo StorageObserver, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(gotSo, w.wantSo) { + return errors.Errorf("got = %v, want %v", gotSo, w.wantSo) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + gotSo, err := New(test.args.opts...) + if err := test.checkFunc(test.want, gotSo, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_observer_Start(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + w watch.Watcher + dirs []string + eg errgroup.Group + checkDuration time.Duration + longestCheckDuration time.Duration + } + type want struct { + want <-chan error + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, <-chan error, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got <-chan error, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + dirs: nil, + eg: nil, + checkDuration: nil, + longestCheckDuration: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + dirs: nil, + eg: nil, + checkDuration: nil, + longestCheckDuration: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + o := &observer{ + w: test.fields.w, + dirs: test.fields.dirs, + eg: test.fields.eg, + checkDuration: test.fields.checkDuration, + longestCheckDuration: test.fields.longestCheckDuration, + } + + got, err := o.Start(test.args.ctx) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_observer_backup(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + w watch.Watcher + dirs []string + eg errgroup.Group + checkDuration time.Duration + longestCheckDuration time.Duration + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + dirs: nil, + eg: nil, + checkDuration: nil, + longestCheckDuration: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + w: nil, + dirs: nil, + eg: nil, + checkDuration: nil, + longestCheckDuration: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + o := &observer{ + w: test.fields.w, + dirs: test.fields.dirs, + eg: test.fields.eg, + checkDuration: test.fields.checkDuration, + longestCheckDuration: test.fields.longestCheckDuration, + } + + err := o.backup(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/agent/sidecar/usecase/sidecard.go b/pkg/agent/sidecar/usecase/sidecard.go new file mode 100644 index 0000000000..a39b1578d2 --- /dev/null +++ b/pkg/agent/sidecar/usecase/sidecard.go @@ -0,0 +1,183 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 usecase + +import ( + "context" + + "github.com/vdaas/vald/apis/grpc/agent/sidecar" + iconf "github.com/vdaas/vald/internal/config" + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/net/grpc" + "github.com/vdaas/vald/internal/net/grpc/metric" + "github.com/vdaas/vald/internal/observability" + "github.com/vdaas/vald/internal/runner" + "github.com/vdaas/vald/internal/safety" + "github.com/vdaas/vald/internal/servers/server" + "github.com/vdaas/vald/internal/servers/starter" + "github.com/vdaas/vald/pkg/agent/sidecar/config" + handler "github.com/vdaas/vald/pkg/agent/sidecar/handler/grpc" + "github.com/vdaas/vald/pkg/agent/sidecar/handler/rest" + "github.com/vdaas/vald/pkg/agent/sidecar/router" + "github.com/vdaas/vald/pkg/agent/sidecar/service" +) + +type run struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver +} + +func New(cfg *config.Data) (r runner.Runner, err error) { + eg := errgroup.Get() + + var ( + so service.StorageObserver + ) + + var obs observability.Observability + if cfg.Observability.Enabled { + obs, err = observability.NewWithConfig(cfg.Observability) + if err != nil { + return nil, err + } + // TODO observe something + _ = obs + } + so, err = service.New( + service.WithErrGroup(eg), + service.WithBackupDuration(cfg.Sidecar.AutoBackupDuration), + service.WithBackupDurationLimit(cfg.Sidecar.AutoBackupDurationLimit), + service.WithDirs(cfg.Sidecar.WatchPaths...), + ) + if err != nil { + return nil, err + } + g := handler.New(handler.WithStorageObserver(so)) + + grpcServerOptions := []server.Option{ + server.WithGRPCRegistFunc(func(srv *grpc.Server) { + sidecar.RegisterSidecarServer(srv, g) + }), + server.WithPreStopFunction(func() error { + // TODO notify another gateway and scheduler + return nil + }), + } + + if cfg.Observability.Enabled { + grpcServerOptions = append( + grpcServerOptions, + server.WithGRPCOption( + grpc.StatsHandler(metric.NewServerHandler()), + ), + ) + } + + srv, err := starter.New( + starter.WithConfig(cfg.Server), + starter.WithREST(func(sc *iconf.Server) []server.Option { + return []server.Option{ + server.WithHTTPHandler( + router.New( + router.WithHandler( + rest.New( + rest.WithSidecar(g), + ), + ), + ), + ), + } + }), + starter.WithGRPC(func(sc *iconf.Server) []server.Option { + return grpcServerOptions + }), + // TODO add GraphQL handler + ) + if err != nil { + return nil, err + } + + return &run{ + eg: eg, + cfg: cfg, + server: srv, + observability: obs, + so: so, + }, nil +} + +func (r *run) PreStart(ctx context.Context) error { + if r.observability != nil { + return r.observability.PreStart(ctx) + } + return nil +} + +func (r *run) Start(ctx context.Context) (<-chan error, error) { + ech := make(chan error, 5) + var soech, sech, oech <-chan error + var err error + if r.observability != nil { + oech = r.observability.Start(ctx) + } + if r.so != nil { + soech, err = r.so.Start(ctx) + if err != nil { + close(ech) + return nil, err + } + } + sech = r.server.ListenAndServe(ctx) + r.eg.Go(safety.RecoverFunc(func() (err error) { + defer close(ech) + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err = <-oech: + case err = <-soech: + case err = <-sech: + } + if err != nil { + select { + case <-ctx.Done(): + return ctx.Err() + case ech <- err: + } + } + } + })) + return ech, nil +} + +func (r *run) PreStop(ctx context.Context) error { + return nil +} + +func (r *run) Stop(ctx context.Context) error { + if r.observability != nil { + r.observability.Stop(ctx) + } + return r.server.Shutdown(ctx) +} + +func (r *run) PostStop(ctx context.Context) error { + return nil +} diff --git a/pkg/agent/sidecar/usecase/sidecard_test.go b/pkg/agent/sidecar/usecase/sidecard_test.go new file mode 100644 index 0000000000..c41611085a --- /dev/null +++ b/pkg/agent/sidecar/usecase/sidecard_test.go @@ -0,0 +1,611 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// 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 usecase + +import ( + "context" + "reflect" + "testing" + + "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/observability" + "github.com/vdaas/vald/internal/runner" + "github.com/vdaas/vald/internal/servers/starter" + "github.com/vdaas/vald/pkg/agent/sidecar/config" + "github.com/vdaas/vald/pkg/agent/sidecar/service" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + cfg *config.Data + } + type want struct { + wantR runner.Runner + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, runner.Runner, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, gotR runner.Runner, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(gotR, w.wantR) { + return errors.Errorf("got = %v, want %v", gotR, w.wantR) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + cfg: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + cfg: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + gotR, err := New(test.args.cfg) + if err := test.checkFunc(test.want, gotR, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_run_PreStart(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + r := &run{ + eg: test.fields.eg, + cfg: test.fields.cfg, + server: test.fields.server, + observability: test.fields.observability, + so: test.fields.so, + } + + err := r.PreStart(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_run_Start(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver + } + type want struct { + want <-chan error + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, <-chan error, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, got <-chan error, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + r := &run{ + eg: test.fields.eg, + cfg: test.fields.cfg, + server: test.fields.server, + observability: test.fields.observability, + so: test.fields.so, + } + + got, err := r.Start(test.args.ctx) + if err := test.checkFunc(test.want, got, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_run_PreStop(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + r := &run{ + eg: test.fields.eg, + cfg: test.fields.cfg, + server: test.fields.server, + observability: test.fields.observability, + so: test.fields.so, + } + + err := r.PreStop(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_run_Stop(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + r := &run{ + eg: test.fields.eg, + cfg: test.fields.cfg, + server: test.fields.server, + observability: test.fields.observability, + so: test.fields.so, + } + + err := r.Stop(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_run_PostStop(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + eg errgroup.Group + cfg *config.Data + server starter.Server + observability observability.Observability + so service.StorageObserver + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + eg: nil, + cfg: nil, + server: nil, + observability: nil, + so: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(t) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + r := &run{ + eg: test.fields.eg, + cfg: test.fields.cfg, + server: test.fields.server, + observability: test.fields.observability, + so: test.fields.so, + } + + err := r.PostStop(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/pkg/gateway/vald/handler/grpc/handler.go b/pkg/gateway/vald/handler/grpc/handler.go index 3fe736b682..7dac4a2f01 100644 --- a/pkg/gateway/vald/handler/grpc/handler.go +++ b/pkg/gateway/vald/handler/grpc/handler.go @@ -27,7 +27,7 @@ import ( "time" "github.com/kpango/fuid" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/gateway/vald" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/errgroup" diff --git a/pkg/gateway/vald/handler/grpc/handler_test.go b/pkg/gateway/vald/handler/grpc/handler_test.go index b811a0b3ca..b2d6bb9897 100644 --- a/pkg/gateway/vald/handler/grpc/handler_test.go +++ b/pkg/gateway/vald/handler/grpc/handler_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/gateway/vald" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/errgroup" diff --git a/pkg/gateway/vald/service/gateway.go b/pkg/gateway/vald/service/gateway.go index a67a383b1c..06469551ad 100644 --- a/pkg/gateway/vald/service/gateway.go +++ b/pkg/gateway/vald/service/gateway.go @@ -22,7 +22,7 @@ import ( "reflect" "sync/atomic" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/internal/client/discoverer" "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" diff --git a/pkg/gateway/vald/service/gateway_test.go b/pkg/gateway/vald/service/gateway_test.go index e1e87f6b32..b2592a62b0 100644 --- a/pkg/gateway/vald/service/gateway_test.go +++ b/pkg/gateway/vald/service/gateway_test.go @@ -22,7 +22,7 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/internal/client/discoverer" "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" diff --git a/pkg/manager/index/service/indexer.go b/pkg/manager/index/service/indexer.go index d47f91bf7a..e5f26e6ae7 100644 --- a/pkg/manager/index/service/indexer.go +++ b/pkg/manager/index/service/indexer.go @@ -23,7 +23,7 @@ import ( "sync/atomic" "time" - "github.com/vdaas/vald/apis/grpc/agent" + agent "github.com/vdaas/vald/apis/grpc/agent/core" "github.com/vdaas/vald/apis/grpc/payload" "github.com/vdaas/vald/internal/client/discoverer" "github.com/vdaas/vald/internal/errgroup" diff --git a/pkg/tools/cli/loadtest/usecase/load.go b/pkg/tools/cli/loadtest/usecase/load.go index 91bd969e80..c00d629298 100644 --- a/pkg/tools/cli/loadtest/usecase/load.go +++ b/pkg/tools/cli/loadtest/usecase/load.go @@ -21,7 +21,7 @@ import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/runner" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" ) type run struct { diff --git a/pkg/tools/cli/loadtest/usecase/load_test.go b/pkg/tools/cli/loadtest/usecase/load_test.go index 8b14dad49f..676a865022 100644 --- a/pkg/tools/cli/loadtest/usecase/load_test.go +++ b/pkg/tools/cli/loadtest/usecase/load_test.go @@ -24,7 +24,7 @@ import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/runner" - "github.com/vdaas/vald/pkg/agent/ngt/config" + "github.com/vdaas/vald/pkg/agent/core/ngt/config" "go.uber.org/goleak" ) From d3bcfb893693779152cf0522d1e154b10d71dd32 Mon Sep 17 00:00:00 2001 From: kpango Date: Tue, 26 May 2020 10:33:50 +0900 Subject: [PATCH 2/4] fix Signed-off-by: kpango --- go.mod | 4 +- go.sum | 8 +- internal/config/sidecar.go | 4 +- internal/config/sidecar_test.go | 10 +- internal/file/watch/option.go | 14 --- internal/file/watch/option_test.go | 113 ------------------ pkg/agent/sidecar/config/config.go | 6 +- .../sidecar/handler/grpc/handler_test.go | 2 +- pkg/agent/sidecar/handler/grpc/option.go | 2 +- .../sidecar/handler/rest/handler_test.go | 2 +- pkg/agent/sidecar/service/option.go | 14 --- pkg/agent/sidecar/service/option_test.go | 113 ------------------ pkg/agent/sidecar/usecase/sidecard.go | 6 +- pkg/agent/sidecar/usecase/sidecard_test.go | 2 +- 14 files changed, 24 insertions(+), 276 deletions(-) diff --git a/go.mod b/go.mod index 1f97f06c0e..d5c33df82e 100755 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ replace ( github.com/coreos/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200425165423-262c93980547 github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.3.0-java - github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.5.1-0.20200521132419-128a6737a202 + github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.5.1-0.20200525102840-8c3a2d9049b4 github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20200519160334-799061058e31 github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.1 github.com/gophercloud/gophercloud => github.com/gophercloud/gophercloud v0.11.0 @@ -32,7 +32,7 @@ require ( github.com/cockroachdb/errors v0.0.0-00010101000000-000000000000 github.com/danielvladco/go-proto-gql/pb v0.6.1 github.com/envoyproxy/protoc-gen-validate v0.1.0 - github.com/fsnotify/fsnotify v1.4.7 + github.com/fsnotify/fsnotify v1.4.9 github.com/go-redis/redis/v7 v7.3.0 github.com/go-sql-driver/mysql v1.5.0 github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 diff --git a/go.sum b/go.sum index 56dddec0f1..245b2e78a5 100644 --- a/go.sum +++ b/go.sum @@ -151,8 +151,9 @@ github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.4.0 h1:rCSCih1FnSWJEel/eub9wclBSqpF2F/PuvxUWGWnbO8= github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -218,8 +219,8 @@ github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDA github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v7 v7.3.0 h1:3oHqd0W7f/VLKBxeYTEpqdMUsmMectngjM9OtoRoIgg= github.com/go-redis/redis/v7 v7.3.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= -github.com/go-sql-driver/mysql v1.5.1-0.20200521132419-128a6737a202 h1:MVqCQqO9Y9V3LM1TwbOGOuLqlBWiU+TjjMH/M/PfGiw= -github.com/go-sql-driver/mysql v1.5.1-0.20200521132419-128a6737a202/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.5.1-0.20200525102840-8c3a2d9049b4 h1:EwVyKWAXcaG1sJdJu+D7NlZ5WZdze/plTXEBHPrf2mk= +github.com/go-sql-driver/mysql v1.5.1-0.20200525102840-8c3a2d9049b4/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -681,6 +682,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/internal/config/sidecar.go b/internal/config/sidecar.go index aaf5a7cf0b..96519a6ddd 100644 --- a/internal/config/sidecar.go +++ b/internal/config/sidecar.go @@ -17,7 +17,7 @@ // Package config providers configuration type and load configuration logic package config -type Sidecar struct { +type AgentSidecar struct { // Name string `yaml:"name" json:"name"` // WatchPaths represents watch path list for backup @@ -30,7 +30,7 @@ type Sidecar struct { AutoBackupDuration string `yaml:"auto_backup_duration" json:"auto_backup_duration"` } -func (s *Sidecar) Bind() *Sidecar { +func (s *AgentSidecar) Bind() *AgentSidecar { s.WatchPaths = GetActualValues(s.WatchPaths) s.AutoBackupDuration = GetActualValue(s.AutoBackupDuration) s.AutoBackupDurationLimit = GetActualValue(s.AutoBackupDurationLimit) diff --git a/internal/config/sidecar_test.go b/internal/config/sidecar_test.go index be15a480e2..ce7d1e9d5c 100644 --- a/internal/config/sidecar_test.go +++ b/internal/config/sidecar_test.go @@ -25,24 +25,24 @@ import ( "go.uber.org/goleak" ) -func TestSidecar_Bind(t *testing.T) { +func TestAgentSidecar_Bind(t *testing.T) { type fields struct { WatchPaths []string AutoBackupDurationLimit string AutoBackupDuration string } type want struct { - want *Sidecar + want *AgentSidecar } type test struct { name string fields fields want want - checkFunc func(want, *Sidecar) error + checkFunc func(want, *AgentSidecar) error beforeFunc func() afterFunc func() } - defaultCheckFunc := func(w want, got *Sidecar) error { + defaultCheckFunc := func(w want, got *AgentSidecar) error { if !reflect.DeepEqual(got, w.want) { return errors.Errorf("got = %v, want %v", got, w.want) } @@ -92,7 +92,7 @@ func TestSidecar_Bind(t *testing.T) { if test.checkFunc == nil { test.checkFunc = defaultCheckFunc } - s := &Sidecar{ + s := &AgentSidecar{ WatchPaths: test.fields.WatchPaths, AutoBackupDurationLimit: test.fields.AutoBackupDurationLimit, AutoBackupDuration: test.fields.AutoBackupDuration, diff --git a/internal/file/watch/option.go b/internal/file/watch/option.go index 8b7cdfec6b..4b336b771d 100644 --- a/internal/file/watch/option.go +++ b/internal/file/watch/option.go @@ -51,20 +51,6 @@ func WithDirs(dirs ...string) Option { } } -func WithDir(dir string) Option { - return func(w *watch) error { - if len(dir) == 0 { - return nil - } - if w.dirs != nil { - w.dirs = append(w.dirs, dir) - } else { - w.dirs = []string{dir} - } - return nil - } -} - func WithOnChange(f func(ctx context.Context, name string) error) Option { return func(w *watch) error { if f != nil { diff --git a/internal/file/watch/option_test.go b/internal/file/watch/option_test.go index de90aa6d23..4e3288d29a 100644 --- a/internal/file/watch/option_test.go +++ b/internal/file/watch/option_test.go @@ -250,119 +250,6 @@ func TestWithDirs(t *testing.T) { } } -func TestWithDir(t *testing.T) { - type T = interface{} - type args struct { - dir string - } - type want struct { - obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error - } - type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error - beforeFunc func(args) - afterFunc func(args) - } - - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ - - tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - dir: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - dir: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ - } - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) - if test.beforeFunc != nil { - test.beforeFunc(test.args) - } - if test.afterFunc != nil { - defer test.afterFunc(test.args) - } - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithDir(test.args.dir) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithDir(test.args.dir) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ - }) - } -} - func TestWithOnChange(t *testing.T) { type T = interface{} type args struct { diff --git a/pkg/agent/sidecar/config/config.go b/pkg/agent/sidecar/config/config.go index c13dfed6ad..eb5d698055 100644 --- a/pkg/agent/sidecar/config/config.go +++ b/pkg/agent/sidecar/config/config.go @@ -35,7 +35,7 @@ type Data struct { Observability *config.Observability `json:"observability" yaml:"observability"` // Sidecar represent agent storage sync sidecar service configuration - Sidecar *config.Sidecar `json:"sidecar" yaml:"sidecar"` + AgentSidecar *config.AgentSidecar `json:"agent_sidecar" yaml:"agent_sidecar"` } func NewConfig(path string) (cfg *Data, err error) { @@ -57,8 +57,8 @@ func NewConfig(path string) (cfg *Data, err error) { cfg.Observability = cfg.Observability.Bind() } - if cfg.Sidecar != nil { - cfg.Sidecar = cfg.Sidecar.Bind() + if cfg.AgentSidecar != nil { + cfg.AgentSidecar = cfg.AgentSidecar.Bind() } return cfg, nil } diff --git a/pkg/agent/sidecar/handler/grpc/handler_test.go b/pkg/agent/sidecar/handler/grpc/handler_test.go index 198c039939..81ebd95bbe 100644 --- a/pkg/agent/sidecar/handler/grpc/handler_test.go +++ b/pkg/agent/sidecar/handler/grpc/handler_test.go @@ -21,8 +21,8 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "github.com/vdaas/vald/internal/errors" "go.uber.org/goleak" ) diff --git a/pkg/agent/sidecar/handler/grpc/option.go b/pkg/agent/sidecar/handler/grpc/option.go index 0ea18a48ea..1421fff34e 100644 --- a/pkg/agent/sidecar/handler/grpc/option.go +++ b/pkg/agent/sidecar/handler/grpc/option.go @@ -29,7 +29,7 @@ var ( func WithStorageObserver(so service.StorageObserver) Option { return func(s *server) { - if i != nil { + if so != nil { s.so = so } } diff --git a/pkg/agent/sidecar/handler/rest/handler_test.go b/pkg/agent/sidecar/handler/rest/handler_test.go index 8e6e06f42b..8fc6c65f7f 100644 --- a/pkg/agent/sidecar/handler/rest/handler_test.go +++ b/pkg/agent/sidecar/handler/rest/handler_test.go @@ -22,8 +22,8 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/apis/grpc/agent/sidecar" + "github.com/vdaas/vald/internal/errors" "go.uber.org/goleak" ) diff --git a/pkg/agent/sidecar/service/option.go b/pkg/agent/sidecar/service/option.go index c0d8f9470e..0440c2b51c 100644 --- a/pkg/agent/sidecar/service/option.go +++ b/pkg/agent/sidecar/service/option.go @@ -84,17 +84,3 @@ func WithDirs(dirs ...string) Option { return nil } } - -func WithDir(dir string) Option { - return func(o *observer) error { - if len(dir) == 0 { - return nil - } - if o.dirs != nil { - o.dirs = append(o.dirs, dir) - } else { - o.dirs = []string{dir} - } - return nil - } -} diff --git a/pkg/agent/sidecar/service/option_test.go b/pkg/agent/sidecar/service/option_test.go index d6aea6a7ed..a2c17d45ed 100644 --- a/pkg/agent/sidecar/service/option_test.go +++ b/pkg/agent/sidecar/service/option_test.go @@ -475,116 +475,3 @@ func TestWithDirs(t *testing.T) { }) } } - -func TestWithDir(t *testing.T) { - type T = interface{} - type args struct { - dir string - } - type want struct { - obj *T - // Uncomment this line if the option returns an error, otherwise delete it - // err error - } - type test struct { - name string - args args - want want - // Use the first line if the option returns an error. otherwise use the second line - // checkFunc func(want, *T, error) error - // checkFunc func(want, *T) error - beforeFunc func(args) - afterFunc func(args) - } - - // Uncomment this block if the option returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T, err error) error { - if !errors.Is(err, w.err) { - return errors.Errorf("got error = %v, want %v", err, w.err) - } - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.obj) - } - return nil - } - */ - - // Uncomment this block if the option do not returns an error, otherwise delete it - /* - defaultCheckFunc := func(w want, obj *T) error { - if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) - } - return nil - } - */ - - tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - args: args { - dir: "", - }, - want: want { - obj: new(T), - }, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - args: args { - dir: "", - }, - want: want { - obj: new(T), - }, - } - }(), - */ - } - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) - if test.beforeFunc != nil { - test.beforeFunc(test.args) - } - if test.afterFunc != nil { - defer test.afterFunc(test.args) - } - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - - got := WithDir(test.args.dir) - obj := new(T) - if err := test.checkFunc(test.want, obj, got(obj)); err != nil { - tt.Errorf("error = %v", err) - } - */ - - // Uncomment this block if the option returns an error, otherwise delete it - /* - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - got := WithDir(test.args.dir) - obj := new(T) - got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { - tt.Errorf("error = %v", err) - } - */ - }) - } -} diff --git a/pkg/agent/sidecar/usecase/sidecard.go b/pkg/agent/sidecar/usecase/sidecard.go index a39b1578d2..010d84ba60 100644 --- a/pkg/agent/sidecar/usecase/sidecard.go +++ b/pkg/agent/sidecar/usecase/sidecard.go @@ -62,9 +62,9 @@ func New(cfg *config.Data) (r runner.Runner, err error) { } so, err = service.New( service.WithErrGroup(eg), - service.WithBackupDuration(cfg.Sidecar.AutoBackupDuration), - service.WithBackupDurationLimit(cfg.Sidecar.AutoBackupDurationLimit), - service.WithDirs(cfg.Sidecar.WatchPaths...), + service.WithBackupDuration(cfg.AgentSidecar.AutoBackupDuration), + service.WithBackupDurationLimit(cfg.AgentSidecar.AutoBackupDurationLimit), + service.WithDirs(cfg.AgentSidecar.WatchPaths...), ) if err != nil { return nil, err diff --git a/pkg/agent/sidecar/usecase/sidecard_test.go b/pkg/agent/sidecar/usecase/sidecard_test.go index c41611085a..4d071c30f3 100644 --- a/pkg/agent/sidecar/usecase/sidecard_test.go +++ b/pkg/agent/sidecar/usecase/sidecard_test.go @@ -21,8 +21,8 @@ import ( "reflect" "testing" - "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/errgroup" + "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/observability" "github.com/vdaas/vald/internal/runner" "github.com/vdaas/vald/internal/servers/starter" From 02544ecc4dc32be1facdcaadb9de2aa0f9cb5008 Mon Sep 17 00:00:00 2001 From: kpango Date: Tue, 26 May 2020 11:29:26 +0900 Subject: [PATCH 3/4] fix Signed-off-by: kpango --- internal/file/watch/watch.go | 90 ++++++++++++++++++------------- internal/file/watch/watch_test.go | 47 +++++++++++----- 2 files changed, 86 insertions(+), 51 deletions(-) diff --git a/internal/file/watch/watch.go b/internal/file/watch/watch.go index 2683fd98bf..7c16f7fdce 100644 --- a/internal/file/watch/watch.go +++ b/internal/file/watch/watch.go @@ -19,6 +19,7 @@ package watch import ( "context" "reflect" + "sync" "github.com/fsnotify/fsnotify" "github.com/vdaas/vald/internal/errgroup" @@ -29,15 +30,16 @@ import ( type Watcher interface { Start(ctx context.Context) (<-chan error, error) - Add(dir string) error - Remove(dir string) error + Add(dirs ...string) error + Remove(dirs ...string) error Stop(ctx context.Context) error } type watch struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -66,20 +68,26 @@ func (w *watch) init() (*watch, error) { if err != nil { return nil, err } - if w.w != nil { - err = w.w.Close() + w.mu.RLock() + dirs := w.dirs + w.mu.RUnlock() + for dir := range dirs { + err = watcher.Add(dir) if err != nil { return nil, err } } - w.w = watcher - for _, dir := range w.dirs { - err = w.w.Add(dir) + w.mu.Lock() + defer w.mu.Unlock() + if w.w != nil { + err = w.w.Close() if err != nil { return nil, err } } + w.w = watcher + return w, nil } @@ -132,6 +140,7 @@ func (w *watch) Start(ctx context.Context) (<-chan error, error) { err = w.onChmod(ctx, event.Name) } } + case err, ok = <-w.w.Errors: } if !ok { w, err = w.init() @@ -140,47 +149,52 @@ func (w *watch) Start(ctx context.Context) (<-chan error, error) { handleErr(ctx, err) } } - return nil - })) - w.eg.Go(safety.RecoverFunc(func() (err error) { - for { - select { - case <-ctx.Done(): - return ctx.Err() - case err, ok := <-w.w.Errors: - if !ok { - w, err = w.init() - } else { - err = w.onError(ctx, err) - } - if err != nil { - log.Error(err) - select { - case <-ctx.Done(): - case ech <- err: - } - } - } - } - return nil })) return ech, nil } -func (w *watch) Add(dir string) error { - if w.w != nil { - return w.w.Add(dir) + +func (w *watch) Add(dirs ...string) (err error) { + w.mu.Lock() + defer w.mu.Unlock() + for _, dir := range dirs { + w.dirs[dir] = struct{}{} + if w.w != nil { + err = w.w.Add(dir) + if err != nil { + return err + } + } } return nil } -func (w *watch) Remove(dir string) error { - if w.w != nil { - return w.w.Remove(dir) +func (w *watch) Remove(dirs ...string) (err error) { + w.mu.Lock() + defer w.mu.Unlock() + for _, dir := range dirs { + delete(w.dirs, dir) + if w.w != nil { + err = w.w.Remove(dir) + if err != nil { + return err + } + } } return nil } -func (w *watch) Stop(ctx context.Context) error { +func (w *watch) Stop(ctx context.Context) (err error) { + w.mu.Lock() + defer w.mu.Unlock() + for dir := range w.dirs { + delete(w.dirs, dir) + if w.w != nil { + err = w.w.Remove(dir) + if err != nil { + return err + } + } + } if w.w != nil { return w.w.Close() } diff --git a/internal/file/watch/watch_test.go b/internal/file/watch/watch_test.go index 8974df0474..f233f42d00 100644 --- a/internal/file/watch/watch_test.go +++ b/internal/file/watch/watch_test.go @@ -19,6 +19,7 @@ package watch import ( "context" "reflect" + "sync" "testing" "github.com/fsnotify/fsnotify" @@ -106,7 +107,8 @@ func Test_watch_init(t *testing.T) { type fields struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -145,6 +147,7 @@ func Test_watch_init(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -167,6 +170,7 @@ func Test_watch_init(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -198,6 +202,7 @@ func Test_watch_init(t *testing.T) { w: test.fields.w, eg: test.fields.eg, dirs: test.fields.dirs, + mu: test.fields.mu, onChange: test.fields.onChange, onCreate: test.fields.onCreate, onRename: test.fields.onRename, @@ -223,7 +228,8 @@ func Test_watch_Start(t *testing.T) { type fields struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -266,6 +272,7 @@ func Test_watch_Start(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -291,6 +298,7 @@ func Test_watch_Start(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -322,6 +330,7 @@ func Test_watch_Start(t *testing.T) { w: test.fields.w, eg: test.fields.eg, dirs: test.fields.dirs, + mu: test.fields.mu, onChange: test.fields.onChange, onCreate: test.fields.onCreate, onRename: test.fields.onRename, @@ -342,12 +351,13 @@ func Test_watch_Start(t *testing.T) { func Test_watch_Add(t *testing.T) { type args struct { - dir string + dirs []string } type fields struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -380,12 +390,13 @@ func Test_watch_Add(t *testing.T) { { name: "test_case_1", args: args { - dir: "", + dirs: nil, }, fields: fields { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -405,12 +416,13 @@ func Test_watch_Add(t *testing.T) { return test { name: "test_case_2", args: args { - dir: "", + dirs: nil, }, fields: fields { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -442,6 +454,7 @@ func Test_watch_Add(t *testing.T) { w: test.fields.w, eg: test.fields.eg, dirs: test.fields.dirs, + mu: test.fields.mu, onChange: test.fields.onChange, onCreate: test.fields.onCreate, onRename: test.fields.onRename, @@ -451,7 +464,7 @@ func Test_watch_Add(t *testing.T) { onError: test.fields.onError, } - err := w.Add(test.args.dir) + err := w.Add(test.args.dirs...) if err := test.checkFunc(test.want, err); err != nil { tt.Errorf("error = %v", err) } @@ -462,12 +475,13 @@ func Test_watch_Add(t *testing.T) { func Test_watch_Remove(t *testing.T) { type args struct { - dir string + dirs []string } type fields struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -500,12 +514,13 @@ func Test_watch_Remove(t *testing.T) { { name: "test_case_1", args: args { - dir: "", + dirs: nil, }, fields: fields { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -525,12 +540,13 @@ func Test_watch_Remove(t *testing.T) { return test { name: "test_case_2", args: args { - dir: "", + dirs: nil, }, fields: fields { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -562,6 +578,7 @@ func Test_watch_Remove(t *testing.T) { w: test.fields.w, eg: test.fields.eg, dirs: test.fields.dirs, + mu: test.fields.mu, onChange: test.fields.onChange, onCreate: test.fields.onCreate, onRename: test.fields.onRename, @@ -571,7 +588,7 @@ func Test_watch_Remove(t *testing.T) { onError: test.fields.onError, } - err := w.Remove(test.args.dir) + err := w.Remove(test.args.dirs...) if err := test.checkFunc(test.want, err); err != nil { tt.Errorf("error = %v", err) } @@ -587,7 +604,8 @@ func Test_watch_Stop(t *testing.T) { type fields struct { w *fsnotify.Watcher eg errgroup.Group - dirs []string + dirs map[string]struct{} + mu sync.RWMutex onChange func(ctx context.Context, name string) error onCreate func(ctx context.Context, name string) error onRename func(ctx context.Context, name string) error @@ -626,6 +644,7 @@ func Test_watch_Stop(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -651,6 +670,7 @@ func Test_watch_Stop(t *testing.T) { w: nil, eg: nil, dirs: nil, + mu: sync.RWMutex{}, onChange: nil, onCreate: nil, onRename: nil, @@ -682,6 +702,7 @@ func Test_watch_Stop(t *testing.T) { w: test.fields.w, eg: test.fields.eg, dirs: test.fields.dirs, + mu: test.fields.mu, onChange: test.fields.onChange, onCreate: test.fields.onCreate, onRename: test.fields.onRename, From 06897f542618a34d23521d4b6c9cb15016ed2bb2 Mon Sep 17 00:00:00 2001 From: kpango Date: Tue, 26 May 2020 11:40:27 +0900 Subject: [PATCH 4/4] fix Signed-off-by: kpango --- internal/file/watch/option.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/file/watch/option.go b/internal/file/watch/option.go index 4b336b771d..38c4ca645c 100644 --- a/internal/file/watch/option.go +++ b/internal/file/watch/option.go @@ -42,10 +42,8 @@ func WithDirs(dirs ...string) Option { if len(dirs) == 0 { return nil } - if w.dirs != nil { - w.dirs = append(w.dirs, dirs...) - } else { - w.dirs = dirs + for _, dir := range dirs { + w.dirs[dir] = struct{}{} } return nil }