diff --git a/cmd/main/main.go b/cmd/main/main.go index 509a5c8..3e35f49 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -182,7 +182,6 @@ func main() { // Initialize Minio client minioClient, _ := minio.NewMinioClientAndInitBucket() - service := service.NewService(repository, minioClient, mgmtPrivateServiceClient, httpclient.NewRegistryClient(ctx)) publicGrpcS := grpc.NewServer(grpcServerOpts...) diff --git a/go.mod b/go.mod index fbaa3ec..bf17ada 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 github.com/influxdata/influxdb-client-go/v2 v2.12.3 - github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240620083254-e05817f35b4d + github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240624201244-e8a5b1dcc4a1 github.com/instill-ai/usage-client v0.3.0-alpha.0.20240319060111-4a3a39f2fd61 github.com/instill-ai/x v0.3.0-alpha.0.20231219052200-6230a89e386c github.com/knadh/koanf v1.5.0 diff --git a/go.sum b/go.sum index 57bd969..9cf2b97 100644 --- a/go.sum +++ b/go.sum @@ -286,8 +286,8 @@ github.com/influxdata/influxdb-client-go/v2 v2.12.3 h1:28nRlNMRIV4QbtIUvxhWqaxn0 github.com/influxdata/influxdb-client-go/v2 v2.12.3/go.mod h1:IrrLUbCjjfkmRuaCiGQg4m2GbkaeJDcuWoxiWdQEbA0= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240620083254-e05817f35b4d h1:gJqn9yDo+1vyL6I9In667Y8LM0iVRg0ExH7Kd97OZvw= -github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240620083254-e05817f35b4d/go.mod h1:2blmpUwiTwxIDnrjIqT6FhR5ewshZZF554wzjXFvKpQ= +github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240624201244-e8a5b1dcc4a1 h1:Vxg7WEXNqzI9sj13SdDQP3wQC/6rRJ8mW1KnAnYiaIQ= +github.com/instill-ai/protogen-go v0.3.3-alpha.0.20240624201244-e8a5b1dcc4a1/go.mod h1:2blmpUwiTwxIDnrjIqT6FhR5ewshZZF554wzjXFvKpQ= github.com/instill-ai/usage-client v0.3.0-alpha.0.20240319060111-4a3a39f2fd61 h1:smPTvmXDhn/QC7y/TPXyMTqbbRd0gvzmFgWBChwTfhE= github.com/instill-ai/usage-client v0.3.0-alpha.0.20240319060111-4a3a39f2fd61/go.mod h1:/TAHs4ybuylk5icuy+MQtHRc4XUnIyXzeNKxX9qDFhw= github.com/instill-ai/x v0.3.0-alpha.0.20231219052200-6230a89e386c h1:a2RVkpIV2QcrGnSHAou+t/L+vBsaIfFvk5inVg5Uh4s= diff --git a/pkg/client/http/registry.go b/pkg/client/http/registry.go index 33769af..85c8533 100644 --- a/pkg/client/http/registry.go +++ b/pkg/client/http/registry.go @@ -57,3 +57,30 @@ func (c *RegistryClient) ListTags(ctx context.Context, repository string) ([]str return resp.Tags, nil } + +// DeleteTag calls the DELETE /v2//manifests/ endpoint, where is a +// repository, and is the digest +func (c *RegistryClient) DeleteTag(ctx context.Context, repository string, digest string) error { + + deletePath := fmt.Sprintf("/v2/%s/manifests/%s", repository, digest) + r := c.R().SetContext(ctx) + if _, err := r.Delete(deletePath); err != nil { + return fmt.Errorf("couldn't delete the image with registry: %w", err) + } + + return nil +} + +// GetTagDigest calls the HEAD /v2//manifests/ endpoint, where is a +// repository, and is the tag +func (c *RegistryClient) GetTagDigest(ctx context.Context, repository string, tag string) (string, error) { + + digestPath := fmt.Sprintf("/v2/%s/manifests/%s", repository, tag) + r := c.R().SetContext(ctx).SetHeader("Accept", "application/vnd.docker.distribution.manifest.v2+json") + resp, err := r.Head(digestPath) + if err != nil { + return "", fmt.Errorf("couldn't get the image digest: %w", err) + } + + return resp.Header().Get("Docker-Content-Digest"), nil +} diff --git a/pkg/handler/private.go b/pkg/handler/private.go index ef0ab71..738ec1b 100644 --- a/pkg/handler/private.go +++ b/pkg/handler/private.go @@ -62,3 +62,20 @@ func (h *PrivateHandler) CreateRepositoryTag(ctx context.Context, req *pb.Create logger.Info("CreateRepositoryTag") return resp, nil } + +// DeleteRepositoryTag deletes the information of a repository tag in registry. +func (h *PrivateHandler) DeleteRepositoryTag(ctx context.Context, req *pb.DeleteRepositoryTagRequest) (*pb.DeleteRepositoryTagResponse, error) { + ctx, span := tracer.Start(ctx, "DeleteRepositoryTag", trace.WithSpanKind(trace.SpanKindServer)) + defer span.End() + + logger, _ := logger.GetZapLogger(ctx) + + resp, err := h.service.DeleteRepositoryTag(ctx, req) + if err != nil { + span.SetStatus(1, err.Error()) + return nil, err + } + + logger.Info("DeleteRepositoryTag") + return resp, nil +} diff --git a/pkg/mock/registry_client_mock.gen.go b/pkg/mock/registry_client_mock.gen.go index 445fcff..6c9851e 100644 --- a/pkg/mock/registry_client_mock.gen.go +++ b/pkg/mock/registry_client_mock.gen.go @@ -1,4 +1,4 @@ -// Code generated by http://github.com/gojuno/minimock (v3.3.9). DO NOT EDIT. +// Code generated by http://github.com/gojuno/minimock (v3.3.13). DO NOT EDIT. package mock @@ -16,6 +16,18 @@ type RegistryClientMock struct { t minimock.Tester finishOnce sync.Once + funcDeleteTag func(ctx context.Context, repository string, digest string) (err error) + inspectFuncDeleteTag func(ctx context.Context, repository string, digest string) + afterDeleteTagCounter uint64 + beforeDeleteTagCounter uint64 + DeleteTagMock mRegistryClientMockDeleteTag + + funcGetTagDigest func(ctx context.Context, repository string, tag string) (digest string, err error) + inspectFuncGetTagDigest func(ctx context.Context, repository string, tag string) + afterGetTagDigestCounter uint64 + beforeGetTagDigestCounter uint64 + GetTagDigestMock mRegistryClientMockGetTagDigest + funcListTags func(ctx context.Context, repository string) (tags []string, err error) inspectFuncListTags func(ctx context.Context, repository string) afterListTagsCounter uint64 @@ -31,6 +43,12 @@ func NewRegistryClientMock(t minimock.Tester) *RegistryClientMock { controller.RegisterMocker(m) } + m.DeleteTagMock = mRegistryClientMockDeleteTag{mock: m} + m.DeleteTagMock.callArgs = []*RegistryClientMockDeleteTagParams{} + + m.GetTagDigestMock = mRegistryClientMockGetTagDigest{mock: m} + m.GetTagDigestMock.callArgs = []*RegistryClientMockGetTagDigestParams{} + m.ListTagsMock = mRegistryClientMockListTags{mock: m} m.ListTagsMock.callArgs = []*RegistryClientMockListTagsParams{} @@ -39,7 +57,705 @@ func NewRegistryClientMock(t minimock.Tester) *RegistryClientMock { return m } +type mRegistryClientMockDeleteTag struct { + optional bool + mock *RegistryClientMock + defaultExpectation *RegistryClientMockDeleteTagExpectation + expectations []*RegistryClientMockDeleteTagExpectation + + callArgs []*RegistryClientMockDeleteTagParams + mutex sync.RWMutex + + expectedInvocations uint64 +} + +// RegistryClientMockDeleteTagExpectation specifies expectation struct of the RegistryClient.DeleteTag +type RegistryClientMockDeleteTagExpectation struct { + mock *RegistryClientMock + params *RegistryClientMockDeleteTagParams + paramPtrs *RegistryClientMockDeleteTagParamPtrs + results *RegistryClientMockDeleteTagResults + Counter uint64 +} + +// RegistryClientMockDeleteTagParams contains parameters of the RegistryClient.DeleteTag +type RegistryClientMockDeleteTagParams struct { + ctx context.Context + repository string + digest string +} + +// RegistryClientMockDeleteTagParamPtrs contains pointers to parameters of the RegistryClient.DeleteTag +type RegistryClientMockDeleteTagParamPtrs struct { + ctx *context.Context + repository *string + digest *string +} + +// RegistryClientMockDeleteTagResults contains results of the RegistryClient.DeleteTag +type RegistryClientMockDeleteTagResults struct { + err error +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmDeleteTag *mRegistryClientMockDeleteTag) Optional() *mRegistryClientMockDeleteTag { + mmDeleteTag.optional = true + return mmDeleteTag +} + +// Expect sets up expected params for RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) Expect(ctx context.Context, repository string, digest string) *mRegistryClientMockDeleteTag { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + if mmDeleteTag.defaultExpectation == nil { + mmDeleteTag.defaultExpectation = &RegistryClientMockDeleteTagExpectation{} + } + + if mmDeleteTag.defaultExpectation.paramPtrs != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by ExpectParams functions") + } + + mmDeleteTag.defaultExpectation.params = &RegistryClientMockDeleteTagParams{ctx, repository, digest} + for _, e := range mmDeleteTag.expectations { + if minimock.Equal(e.params, mmDeleteTag.defaultExpectation.params) { + mmDeleteTag.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmDeleteTag.defaultExpectation.params) + } + } + + return mmDeleteTag +} + +// ExpectCtxParam1 sets up expected param ctx for RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) ExpectCtxParam1(ctx context.Context) *mRegistryClientMockDeleteTag { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + if mmDeleteTag.defaultExpectation == nil { + mmDeleteTag.defaultExpectation = &RegistryClientMockDeleteTagExpectation{} + } + + if mmDeleteTag.defaultExpectation.params != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Expect") + } + + if mmDeleteTag.defaultExpectation.paramPtrs == nil { + mmDeleteTag.defaultExpectation.paramPtrs = &RegistryClientMockDeleteTagParamPtrs{} + } + mmDeleteTag.defaultExpectation.paramPtrs.ctx = &ctx + + return mmDeleteTag +} + +// ExpectRepositoryParam2 sets up expected param repository for RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) ExpectRepositoryParam2(repository string) *mRegistryClientMockDeleteTag { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + if mmDeleteTag.defaultExpectation == nil { + mmDeleteTag.defaultExpectation = &RegistryClientMockDeleteTagExpectation{} + } + + if mmDeleteTag.defaultExpectation.params != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Expect") + } + + if mmDeleteTag.defaultExpectation.paramPtrs == nil { + mmDeleteTag.defaultExpectation.paramPtrs = &RegistryClientMockDeleteTagParamPtrs{} + } + mmDeleteTag.defaultExpectation.paramPtrs.repository = &repository + + return mmDeleteTag +} + +// ExpectDigestParam3 sets up expected param digest for RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) ExpectDigestParam3(digest string) *mRegistryClientMockDeleteTag { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + if mmDeleteTag.defaultExpectation == nil { + mmDeleteTag.defaultExpectation = &RegistryClientMockDeleteTagExpectation{} + } + + if mmDeleteTag.defaultExpectation.params != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Expect") + } + + if mmDeleteTag.defaultExpectation.paramPtrs == nil { + mmDeleteTag.defaultExpectation.paramPtrs = &RegistryClientMockDeleteTagParamPtrs{} + } + mmDeleteTag.defaultExpectation.paramPtrs.digest = &digest + + return mmDeleteTag +} + +// Inspect accepts an inspector function that has same arguments as the RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) Inspect(f func(ctx context.Context, repository string, digest string)) *mRegistryClientMockDeleteTag { + if mmDeleteTag.mock.inspectFuncDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("Inspect function is already set for RegistryClientMock.DeleteTag") + } + + mmDeleteTag.mock.inspectFuncDeleteTag = f + + return mmDeleteTag +} + +// Return sets up results that will be returned by RegistryClient.DeleteTag +func (mmDeleteTag *mRegistryClientMockDeleteTag) Return(err error) *RegistryClientMock { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + if mmDeleteTag.defaultExpectation == nil { + mmDeleteTag.defaultExpectation = &RegistryClientMockDeleteTagExpectation{mock: mmDeleteTag.mock} + } + mmDeleteTag.defaultExpectation.results = &RegistryClientMockDeleteTagResults{err} + return mmDeleteTag.mock +} + +// Set uses given function f to mock the RegistryClient.DeleteTag method +func (mmDeleteTag *mRegistryClientMockDeleteTag) Set(f func(ctx context.Context, repository string, digest string) (err error)) *RegistryClientMock { + if mmDeleteTag.defaultExpectation != nil { + mmDeleteTag.mock.t.Fatalf("Default expectation is already set for the RegistryClient.DeleteTag method") + } + + if len(mmDeleteTag.expectations) > 0 { + mmDeleteTag.mock.t.Fatalf("Some expectations are already set for the RegistryClient.DeleteTag method") + } + + mmDeleteTag.mock.funcDeleteTag = f + return mmDeleteTag.mock +} + +// When sets expectation for the RegistryClient.DeleteTag which will trigger the result defined by the following +// Then helper +func (mmDeleteTag *mRegistryClientMockDeleteTag) When(ctx context.Context, repository string, digest string) *RegistryClientMockDeleteTagExpectation { + if mmDeleteTag.mock.funcDeleteTag != nil { + mmDeleteTag.mock.t.Fatalf("RegistryClientMock.DeleteTag mock is already set by Set") + } + + expectation := &RegistryClientMockDeleteTagExpectation{ + mock: mmDeleteTag.mock, + params: &RegistryClientMockDeleteTagParams{ctx, repository, digest}, + } + mmDeleteTag.expectations = append(mmDeleteTag.expectations, expectation) + return expectation +} + +// Then sets up RegistryClient.DeleteTag return parameters for the expectation previously defined by the When method +func (e *RegistryClientMockDeleteTagExpectation) Then(err error) *RegistryClientMock { + e.results = &RegistryClientMockDeleteTagResults{err} + return e.mock +} + +// Times sets number of times RegistryClient.DeleteTag should be invoked +func (mmDeleteTag *mRegistryClientMockDeleteTag) Times(n uint64) *mRegistryClientMockDeleteTag { + if n == 0 { + mmDeleteTag.mock.t.Fatalf("Times of RegistryClientMock.DeleteTag mock can not be zero") + } + mm_atomic.StoreUint64(&mmDeleteTag.expectedInvocations, n) + return mmDeleteTag +} + +func (mmDeleteTag *mRegistryClientMockDeleteTag) invocationsDone() bool { + if len(mmDeleteTag.expectations) == 0 && mmDeleteTag.defaultExpectation == nil && mmDeleteTag.mock.funcDeleteTag == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmDeleteTag.mock.afterDeleteTagCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmDeleteTag.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// DeleteTag implements service.RegistryClient +func (mmDeleteTag *RegistryClientMock) DeleteTag(ctx context.Context, repository string, digest string) (err error) { + mm_atomic.AddUint64(&mmDeleteTag.beforeDeleteTagCounter, 1) + defer mm_atomic.AddUint64(&mmDeleteTag.afterDeleteTagCounter, 1) + + if mmDeleteTag.inspectFuncDeleteTag != nil { + mmDeleteTag.inspectFuncDeleteTag(ctx, repository, digest) + } + + mm_params := RegistryClientMockDeleteTagParams{ctx, repository, digest} + + // Record call args + mmDeleteTag.DeleteTagMock.mutex.Lock() + mmDeleteTag.DeleteTagMock.callArgs = append(mmDeleteTag.DeleteTagMock.callArgs, &mm_params) + mmDeleteTag.DeleteTagMock.mutex.Unlock() + + for _, e := range mmDeleteTag.DeleteTagMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmDeleteTag.DeleteTagMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmDeleteTag.DeleteTagMock.defaultExpectation.Counter, 1) + mm_want := mmDeleteTag.DeleteTagMock.defaultExpectation.params + mm_want_ptrs := mmDeleteTag.DeleteTagMock.defaultExpectation.paramPtrs + + mm_got := RegistryClientMockDeleteTagParams{ctx, repository, digest} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmDeleteTag.t.Errorf("RegistryClientMock.DeleteTag got unexpected parameter ctx, want: %#v, got: %#v%s\n", *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.repository != nil && !minimock.Equal(*mm_want_ptrs.repository, mm_got.repository) { + mmDeleteTag.t.Errorf("RegistryClientMock.DeleteTag got unexpected parameter repository, want: %#v, got: %#v%s\n", *mm_want_ptrs.repository, mm_got.repository, minimock.Diff(*mm_want_ptrs.repository, mm_got.repository)) + } + + if mm_want_ptrs.digest != nil && !minimock.Equal(*mm_want_ptrs.digest, mm_got.digest) { + mmDeleteTag.t.Errorf("RegistryClientMock.DeleteTag got unexpected parameter digest, want: %#v, got: %#v%s\n", *mm_want_ptrs.digest, mm_got.digest, minimock.Diff(*mm_want_ptrs.digest, mm_got.digest)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmDeleteTag.t.Errorf("RegistryClientMock.DeleteTag got unexpected parameters, want: %#v, got: %#v%s\n", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmDeleteTag.DeleteTagMock.defaultExpectation.results + if mm_results == nil { + mmDeleteTag.t.Fatal("No results are set for the RegistryClientMock.DeleteTag") + } + return (*mm_results).err + } + if mmDeleteTag.funcDeleteTag != nil { + return mmDeleteTag.funcDeleteTag(ctx, repository, digest) + } + mmDeleteTag.t.Fatalf("Unexpected call to RegistryClientMock.DeleteTag. %v %v %v", ctx, repository, digest) + return +} + +// DeleteTagAfterCounter returns a count of finished RegistryClientMock.DeleteTag invocations +func (mmDeleteTag *RegistryClientMock) DeleteTagAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmDeleteTag.afterDeleteTagCounter) +} + +// DeleteTagBeforeCounter returns a count of RegistryClientMock.DeleteTag invocations +func (mmDeleteTag *RegistryClientMock) DeleteTagBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmDeleteTag.beforeDeleteTagCounter) +} + +// Calls returns a list of arguments used in each call to RegistryClientMock.DeleteTag. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmDeleteTag *mRegistryClientMockDeleteTag) Calls() []*RegistryClientMockDeleteTagParams { + mmDeleteTag.mutex.RLock() + + argCopy := make([]*RegistryClientMockDeleteTagParams, len(mmDeleteTag.callArgs)) + copy(argCopy, mmDeleteTag.callArgs) + + mmDeleteTag.mutex.RUnlock() + + return argCopy +} + +// MinimockDeleteTagDone returns true if the count of the DeleteTag invocations corresponds +// the number of defined expectations +func (m *RegistryClientMock) MinimockDeleteTagDone() bool { + if m.DeleteTagMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.DeleteTagMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.DeleteTagMock.invocationsDone() +} + +// MinimockDeleteTagInspect logs each unmet expectation +func (m *RegistryClientMock) MinimockDeleteTagInspect() { + for _, e := range m.DeleteTagMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to RegistryClientMock.DeleteTag with params: %#v", *e.params) + } + } + + afterDeleteTagCounter := mm_atomic.LoadUint64(&m.afterDeleteTagCounter) + // if default expectation was set then invocations count should be greater than zero + if m.DeleteTagMock.defaultExpectation != nil && afterDeleteTagCounter < 1 { + if m.DeleteTagMock.defaultExpectation.params == nil { + m.t.Error("Expected call to RegistryClientMock.DeleteTag") + } else { + m.t.Errorf("Expected call to RegistryClientMock.DeleteTag with params: %#v", *m.DeleteTagMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcDeleteTag != nil && afterDeleteTagCounter < 1 { + m.t.Error("Expected call to RegistryClientMock.DeleteTag") + } + + if !m.DeleteTagMock.invocationsDone() && afterDeleteTagCounter > 0 { + m.t.Errorf("Expected %d calls to RegistryClientMock.DeleteTag but found %d calls", + mm_atomic.LoadUint64(&m.DeleteTagMock.expectedInvocations), afterDeleteTagCounter) + } +} + +type mRegistryClientMockGetTagDigest struct { + optional bool + mock *RegistryClientMock + defaultExpectation *RegistryClientMockGetTagDigestExpectation + expectations []*RegistryClientMockGetTagDigestExpectation + + callArgs []*RegistryClientMockGetTagDigestParams + mutex sync.RWMutex + + expectedInvocations uint64 +} + +// RegistryClientMockGetTagDigestExpectation specifies expectation struct of the RegistryClient.GetTagDigest +type RegistryClientMockGetTagDigestExpectation struct { + mock *RegistryClientMock + params *RegistryClientMockGetTagDigestParams + paramPtrs *RegistryClientMockGetTagDigestParamPtrs + results *RegistryClientMockGetTagDigestResults + Counter uint64 +} + +// RegistryClientMockGetTagDigestParams contains parameters of the RegistryClient.GetTagDigest +type RegistryClientMockGetTagDigestParams struct { + ctx context.Context + repository string + tag string +} + +// RegistryClientMockGetTagDigestParamPtrs contains pointers to parameters of the RegistryClient.GetTagDigest +type RegistryClientMockGetTagDigestParamPtrs struct { + ctx *context.Context + repository *string + tag *string +} + +// RegistryClientMockGetTagDigestResults contains results of the RegistryClient.GetTagDigest +type RegistryClientMockGetTagDigestResults struct { + digest string + err error +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Optional() *mRegistryClientMockGetTagDigest { + mmGetTagDigest.optional = true + return mmGetTagDigest +} + +// Expect sets up expected params for RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Expect(ctx context.Context, repository string, tag string) *mRegistryClientMockGetTagDigest { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + if mmGetTagDigest.defaultExpectation == nil { + mmGetTagDigest.defaultExpectation = &RegistryClientMockGetTagDigestExpectation{} + } + + if mmGetTagDigest.defaultExpectation.paramPtrs != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by ExpectParams functions") + } + + mmGetTagDigest.defaultExpectation.params = &RegistryClientMockGetTagDigestParams{ctx, repository, tag} + for _, e := range mmGetTagDigest.expectations { + if minimock.Equal(e.params, mmGetTagDigest.defaultExpectation.params) { + mmGetTagDigest.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmGetTagDigest.defaultExpectation.params) + } + } + + return mmGetTagDigest +} + +// ExpectCtxParam1 sets up expected param ctx for RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) ExpectCtxParam1(ctx context.Context) *mRegistryClientMockGetTagDigest { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + if mmGetTagDigest.defaultExpectation == nil { + mmGetTagDigest.defaultExpectation = &RegistryClientMockGetTagDigestExpectation{} + } + + if mmGetTagDigest.defaultExpectation.params != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Expect") + } + + if mmGetTagDigest.defaultExpectation.paramPtrs == nil { + mmGetTagDigest.defaultExpectation.paramPtrs = &RegistryClientMockGetTagDigestParamPtrs{} + } + mmGetTagDigest.defaultExpectation.paramPtrs.ctx = &ctx + + return mmGetTagDigest +} + +// ExpectRepositoryParam2 sets up expected param repository for RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) ExpectRepositoryParam2(repository string) *mRegistryClientMockGetTagDigest { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + if mmGetTagDigest.defaultExpectation == nil { + mmGetTagDigest.defaultExpectation = &RegistryClientMockGetTagDigestExpectation{} + } + + if mmGetTagDigest.defaultExpectation.params != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Expect") + } + + if mmGetTagDigest.defaultExpectation.paramPtrs == nil { + mmGetTagDigest.defaultExpectation.paramPtrs = &RegistryClientMockGetTagDigestParamPtrs{} + } + mmGetTagDigest.defaultExpectation.paramPtrs.repository = &repository + + return mmGetTagDigest +} + +// ExpectTagParam3 sets up expected param tag for RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) ExpectTagParam3(tag string) *mRegistryClientMockGetTagDigest { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + if mmGetTagDigest.defaultExpectation == nil { + mmGetTagDigest.defaultExpectation = &RegistryClientMockGetTagDigestExpectation{} + } + + if mmGetTagDigest.defaultExpectation.params != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Expect") + } + + if mmGetTagDigest.defaultExpectation.paramPtrs == nil { + mmGetTagDigest.defaultExpectation.paramPtrs = &RegistryClientMockGetTagDigestParamPtrs{} + } + mmGetTagDigest.defaultExpectation.paramPtrs.tag = &tag + + return mmGetTagDigest +} + +// Inspect accepts an inspector function that has same arguments as the RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Inspect(f func(ctx context.Context, repository string, tag string)) *mRegistryClientMockGetTagDigest { + if mmGetTagDigest.mock.inspectFuncGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("Inspect function is already set for RegistryClientMock.GetTagDigest") + } + + mmGetTagDigest.mock.inspectFuncGetTagDigest = f + + return mmGetTagDigest +} + +// Return sets up results that will be returned by RegistryClient.GetTagDigest +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Return(digest string, err error) *RegistryClientMock { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + if mmGetTagDigest.defaultExpectation == nil { + mmGetTagDigest.defaultExpectation = &RegistryClientMockGetTagDigestExpectation{mock: mmGetTagDigest.mock} + } + mmGetTagDigest.defaultExpectation.results = &RegistryClientMockGetTagDigestResults{digest, err} + return mmGetTagDigest.mock +} + +// Set uses given function f to mock the RegistryClient.GetTagDigest method +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Set(f func(ctx context.Context, repository string, tag string) (digest string, err error)) *RegistryClientMock { + if mmGetTagDigest.defaultExpectation != nil { + mmGetTagDigest.mock.t.Fatalf("Default expectation is already set for the RegistryClient.GetTagDigest method") + } + + if len(mmGetTagDigest.expectations) > 0 { + mmGetTagDigest.mock.t.Fatalf("Some expectations are already set for the RegistryClient.GetTagDigest method") + } + + mmGetTagDigest.mock.funcGetTagDigest = f + return mmGetTagDigest.mock +} + +// When sets expectation for the RegistryClient.GetTagDigest which will trigger the result defined by the following +// Then helper +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) When(ctx context.Context, repository string, tag string) *RegistryClientMockGetTagDigestExpectation { + if mmGetTagDigest.mock.funcGetTagDigest != nil { + mmGetTagDigest.mock.t.Fatalf("RegistryClientMock.GetTagDigest mock is already set by Set") + } + + expectation := &RegistryClientMockGetTagDigestExpectation{ + mock: mmGetTagDigest.mock, + params: &RegistryClientMockGetTagDigestParams{ctx, repository, tag}, + } + mmGetTagDigest.expectations = append(mmGetTagDigest.expectations, expectation) + return expectation +} + +// Then sets up RegistryClient.GetTagDigest return parameters for the expectation previously defined by the When method +func (e *RegistryClientMockGetTagDigestExpectation) Then(digest string, err error) *RegistryClientMock { + e.results = &RegistryClientMockGetTagDigestResults{digest, err} + return e.mock +} + +// Times sets number of times RegistryClient.GetTagDigest should be invoked +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Times(n uint64) *mRegistryClientMockGetTagDigest { + if n == 0 { + mmGetTagDigest.mock.t.Fatalf("Times of RegistryClientMock.GetTagDigest mock can not be zero") + } + mm_atomic.StoreUint64(&mmGetTagDigest.expectedInvocations, n) + return mmGetTagDigest +} + +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) invocationsDone() bool { + if len(mmGetTagDigest.expectations) == 0 && mmGetTagDigest.defaultExpectation == nil && mmGetTagDigest.mock.funcGetTagDigest == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmGetTagDigest.mock.afterGetTagDigestCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmGetTagDigest.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// GetTagDigest implements service.RegistryClient +func (mmGetTagDigest *RegistryClientMock) GetTagDigest(ctx context.Context, repository string, tag string) (digest string, err error) { + mm_atomic.AddUint64(&mmGetTagDigest.beforeGetTagDigestCounter, 1) + defer mm_atomic.AddUint64(&mmGetTagDigest.afterGetTagDigestCounter, 1) + + if mmGetTagDigest.inspectFuncGetTagDigest != nil { + mmGetTagDigest.inspectFuncGetTagDigest(ctx, repository, tag) + } + + mm_params := RegistryClientMockGetTagDigestParams{ctx, repository, tag} + + // Record call args + mmGetTagDigest.GetTagDigestMock.mutex.Lock() + mmGetTagDigest.GetTagDigestMock.callArgs = append(mmGetTagDigest.GetTagDigestMock.callArgs, &mm_params) + mmGetTagDigest.GetTagDigestMock.mutex.Unlock() + + for _, e := range mmGetTagDigest.GetTagDigestMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.digest, e.results.err + } + } + + if mmGetTagDigest.GetTagDigestMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmGetTagDigest.GetTagDigestMock.defaultExpectation.Counter, 1) + mm_want := mmGetTagDigest.GetTagDigestMock.defaultExpectation.params + mm_want_ptrs := mmGetTagDigest.GetTagDigestMock.defaultExpectation.paramPtrs + + mm_got := RegistryClientMockGetTagDigestParams{ctx, repository, tag} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmGetTagDigest.t.Errorf("RegistryClientMock.GetTagDigest got unexpected parameter ctx, want: %#v, got: %#v%s\n", *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.repository != nil && !minimock.Equal(*mm_want_ptrs.repository, mm_got.repository) { + mmGetTagDigest.t.Errorf("RegistryClientMock.GetTagDigest got unexpected parameter repository, want: %#v, got: %#v%s\n", *mm_want_ptrs.repository, mm_got.repository, minimock.Diff(*mm_want_ptrs.repository, mm_got.repository)) + } + + if mm_want_ptrs.tag != nil && !minimock.Equal(*mm_want_ptrs.tag, mm_got.tag) { + mmGetTagDigest.t.Errorf("RegistryClientMock.GetTagDigest got unexpected parameter tag, want: %#v, got: %#v%s\n", *mm_want_ptrs.tag, mm_got.tag, minimock.Diff(*mm_want_ptrs.tag, mm_got.tag)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmGetTagDigest.t.Errorf("RegistryClientMock.GetTagDigest got unexpected parameters, want: %#v, got: %#v%s\n", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmGetTagDigest.GetTagDigestMock.defaultExpectation.results + if mm_results == nil { + mmGetTagDigest.t.Fatal("No results are set for the RegistryClientMock.GetTagDigest") + } + return (*mm_results).digest, (*mm_results).err + } + if mmGetTagDigest.funcGetTagDigest != nil { + return mmGetTagDigest.funcGetTagDigest(ctx, repository, tag) + } + mmGetTagDigest.t.Fatalf("Unexpected call to RegistryClientMock.GetTagDigest. %v %v %v", ctx, repository, tag) + return +} + +// GetTagDigestAfterCounter returns a count of finished RegistryClientMock.GetTagDigest invocations +func (mmGetTagDigest *RegistryClientMock) GetTagDigestAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmGetTagDigest.afterGetTagDigestCounter) +} + +// GetTagDigestBeforeCounter returns a count of RegistryClientMock.GetTagDigest invocations +func (mmGetTagDigest *RegistryClientMock) GetTagDigestBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmGetTagDigest.beforeGetTagDigestCounter) +} + +// Calls returns a list of arguments used in each call to RegistryClientMock.GetTagDigest. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmGetTagDigest *mRegistryClientMockGetTagDigest) Calls() []*RegistryClientMockGetTagDigestParams { + mmGetTagDigest.mutex.RLock() + + argCopy := make([]*RegistryClientMockGetTagDigestParams, len(mmGetTagDigest.callArgs)) + copy(argCopy, mmGetTagDigest.callArgs) + + mmGetTagDigest.mutex.RUnlock() + + return argCopy +} + +// MinimockGetTagDigestDone returns true if the count of the GetTagDigest invocations corresponds +// the number of defined expectations +func (m *RegistryClientMock) MinimockGetTagDigestDone() bool { + if m.GetTagDigestMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.GetTagDigestMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.GetTagDigestMock.invocationsDone() +} + +// MinimockGetTagDigestInspect logs each unmet expectation +func (m *RegistryClientMock) MinimockGetTagDigestInspect() { + for _, e := range m.GetTagDigestMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to RegistryClientMock.GetTagDigest with params: %#v", *e.params) + } + } + + afterGetTagDigestCounter := mm_atomic.LoadUint64(&m.afterGetTagDigestCounter) + // if default expectation was set then invocations count should be greater than zero + if m.GetTagDigestMock.defaultExpectation != nil && afterGetTagDigestCounter < 1 { + if m.GetTagDigestMock.defaultExpectation.params == nil { + m.t.Error("Expected call to RegistryClientMock.GetTagDigest") + } else { + m.t.Errorf("Expected call to RegistryClientMock.GetTagDigest with params: %#v", *m.GetTagDigestMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcGetTagDigest != nil && afterGetTagDigestCounter < 1 { + m.t.Error("Expected call to RegistryClientMock.GetTagDigest") + } + + if !m.GetTagDigestMock.invocationsDone() && afterGetTagDigestCounter > 0 { + m.t.Errorf("Expected %d calls to RegistryClientMock.GetTagDigest but found %d calls", + mm_atomic.LoadUint64(&m.GetTagDigestMock.expectedInvocations), afterGetTagDigestCounter) + } +} + type mRegistryClientMockListTags struct { + optional bool mock *RegistryClientMock defaultExpectation *RegistryClientMockListTagsExpectation expectations []*RegistryClientMockListTagsExpectation @@ -77,6 +793,16 @@ type RegistryClientMockListTagsResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmListTags *mRegistryClientMockListTags) Optional() *mRegistryClientMockListTags { + mmListTags.optional = true + return mmListTags +} + // Expect sets up expected params for RegistryClient.ListTags func (mmListTags *mRegistryClientMockListTags) Expect(ctx context.Context, repository string) *mRegistryClientMockListTags { if mmListTags.mock.funcListTags != nil { @@ -307,6 +1033,11 @@ func (mmListTags *mRegistryClientMockListTags) Calls() []*RegistryClientMockList // MinimockListTagsDone returns true if the count of the ListTags invocations corresponds // the number of defined expectations func (m *RegistryClientMock) MinimockListTagsDone() bool { + if m.ListTagsMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ListTagsMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -348,8 +1079,11 @@ func (m *RegistryClientMock) MinimockListTagsInspect() { func (m *RegistryClientMock) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { + m.MinimockDeleteTagInspect() + + m.MinimockGetTagDigestInspect() + m.MinimockListTagsInspect() - m.t.FailNow() } }) } @@ -373,5 +1107,7 @@ func (m *RegistryClientMock) MinimockWait(timeout mm_time.Duration) { func (m *RegistryClientMock) minimockDone() bool { done := true return done && + m.MinimockDeleteTagDone() && + m.MinimockGetTagDigestDone() && m.MinimockListTagsDone() } diff --git a/pkg/mock/repository_i_mock.gen.go b/pkg/mock/repository_i_mock.gen.go index 6226dea..19dbd48 100644 --- a/pkg/mock/repository_i_mock.gen.go +++ b/pkg/mock/repository_i_mock.gen.go @@ -1,4 +1,4 @@ -// Code generated by http://github.com/gojuno/minimock (v3.3.9). DO NOT EDIT. +// Code generated by http://github.com/gojuno/minimock (v3.3.13). DO NOT EDIT. package mock @@ -43,6 +43,12 @@ type RepositoryIMock struct { beforeDeleteKnowledgeBaseFileCounter uint64 DeleteKnowledgeBaseFileMock mRepositoryIMockDeleteKnowledgeBaseFile + funcDeleteRepositoryTag func(ctx context.Context, s1 string) (err error) + inspectFuncDeleteRepositoryTag func(ctx context.Context, s1 string) + afterDeleteRepositoryTagCounter uint64 + beforeDeleteRepositoryTagCounter uint64 + DeleteRepositoryTagMock mRepositoryIMockDeleteRepositoryTag + funcGetKnowledgeBaseByOwnerAndID func(ctx context.Context, ownerUID string, kbID string) (kp1 *mm_repository.KnowledgeBase, err error) inspectFuncGetKnowledgeBaseByOwnerAndID func(ctx context.Context, ownerUID string, kbID string) afterGetKnowledgeBaseByOwnerAndIDCounter uint64 @@ -106,6 +112,9 @@ func NewRepositoryIMock(t minimock.Tester) *RepositoryIMock { m.DeleteKnowledgeBaseFileMock = mRepositoryIMockDeleteKnowledgeBaseFile{mock: m} m.DeleteKnowledgeBaseFileMock.callArgs = []*RepositoryIMockDeleteKnowledgeBaseFileParams{} + m.DeleteRepositoryTagMock = mRepositoryIMockDeleteRepositoryTag{mock: m} + m.DeleteRepositoryTagMock.callArgs = []*RepositoryIMockDeleteRepositoryTagParams{} + m.GetKnowledgeBaseByOwnerAndIDMock = mRepositoryIMockGetKnowledgeBaseByOwnerAndID{mock: m} m.GetKnowledgeBaseByOwnerAndIDMock.callArgs = []*RepositoryIMockGetKnowledgeBaseByOwnerAndIDParams{} @@ -133,6 +142,7 @@ func NewRepositoryIMock(t minimock.Tester) *RepositoryIMock { } type mRepositoryIMockCreateKnowledgeBase struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockCreateKnowledgeBaseExpectation expectations []*RepositoryIMockCreateKnowledgeBaseExpectation @@ -170,6 +180,16 @@ type RepositoryIMockCreateKnowledgeBaseResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmCreateKnowledgeBase *mRepositoryIMockCreateKnowledgeBase) Optional() *mRepositoryIMockCreateKnowledgeBase { + mmCreateKnowledgeBase.optional = true + return mmCreateKnowledgeBase +} + // Expect sets up expected params for RepositoryI.CreateKnowledgeBase func (mmCreateKnowledgeBase *mRepositoryIMockCreateKnowledgeBase) Expect(ctx context.Context, kb mm_repository.KnowledgeBase) *mRepositoryIMockCreateKnowledgeBase { if mmCreateKnowledgeBase.mock.funcCreateKnowledgeBase != nil { @@ -400,6 +420,11 @@ func (mmCreateKnowledgeBase *mRepositoryIMockCreateKnowledgeBase) Calls() []*Rep // MinimockCreateKnowledgeBaseDone returns true if the count of the CreateKnowledgeBase invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockCreateKnowledgeBaseDone() bool { + if m.CreateKnowledgeBaseMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.CreateKnowledgeBaseMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -438,6 +463,7 @@ func (m *RepositoryIMock) MinimockCreateKnowledgeBaseInspect() { } type mRepositoryIMockCreateKnowledgeBaseFile struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockCreateKnowledgeBaseFileExpectation expectations []*RepositoryIMockCreateKnowledgeBaseFileExpectation @@ -475,6 +501,16 @@ type RepositoryIMockCreateKnowledgeBaseFileResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmCreateKnowledgeBaseFile *mRepositoryIMockCreateKnowledgeBaseFile) Optional() *mRepositoryIMockCreateKnowledgeBaseFile { + mmCreateKnowledgeBaseFile.optional = true + return mmCreateKnowledgeBaseFile +} + // Expect sets up expected params for RepositoryI.CreateKnowledgeBaseFile func (mmCreateKnowledgeBaseFile *mRepositoryIMockCreateKnowledgeBaseFile) Expect(ctx context.Context, kb mm_repository.KnowledgeBaseFile) *mRepositoryIMockCreateKnowledgeBaseFile { if mmCreateKnowledgeBaseFile.mock.funcCreateKnowledgeBaseFile != nil { @@ -705,6 +741,11 @@ func (mmCreateKnowledgeBaseFile *mRepositoryIMockCreateKnowledgeBaseFile) Calls( // MinimockCreateKnowledgeBaseFileDone returns true if the count of the CreateKnowledgeBaseFile invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockCreateKnowledgeBaseFileDone() bool { + if m.CreateKnowledgeBaseFileMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.CreateKnowledgeBaseFileMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -743,6 +784,7 @@ func (m *RepositoryIMock) MinimockCreateKnowledgeBaseFileInspect() { } type mRepositoryIMockDeleteKnowledgeBase struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockDeleteKnowledgeBaseExpectation expectations []*RepositoryIMockDeleteKnowledgeBaseExpectation @@ -782,6 +824,16 @@ type RepositoryIMockDeleteKnowledgeBaseResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmDeleteKnowledgeBase *mRepositoryIMockDeleteKnowledgeBase) Optional() *mRepositoryIMockDeleteKnowledgeBase { + mmDeleteKnowledgeBase.optional = true + return mmDeleteKnowledgeBase +} + // Expect sets up expected params for RepositoryI.DeleteKnowledgeBase func (mmDeleteKnowledgeBase *mRepositoryIMockDeleteKnowledgeBase) Expect(ctx context.Context, ownerUID string, kbID string) *mRepositoryIMockDeleteKnowledgeBase { if mmDeleteKnowledgeBase.mock.funcDeleteKnowledgeBase != nil { @@ -1038,6 +1090,11 @@ func (mmDeleteKnowledgeBase *mRepositoryIMockDeleteKnowledgeBase) Calls() []*Rep // MinimockDeleteKnowledgeBaseDone returns true if the count of the DeleteKnowledgeBase invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockDeleteKnowledgeBaseDone() bool { + if m.DeleteKnowledgeBaseMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.DeleteKnowledgeBaseMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1076,6 +1133,7 @@ func (m *RepositoryIMock) MinimockDeleteKnowledgeBaseInspect() { } type mRepositoryIMockDeleteKnowledgeBaseFile struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockDeleteKnowledgeBaseFileExpectation expectations []*RepositoryIMockDeleteKnowledgeBaseFileExpectation @@ -1112,6 +1170,16 @@ type RepositoryIMockDeleteKnowledgeBaseFileResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmDeleteKnowledgeBaseFile *mRepositoryIMockDeleteKnowledgeBaseFile) Optional() *mRepositoryIMockDeleteKnowledgeBaseFile { + mmDeleteKnowledgeBaseFile.optional = true + return mmDeleteKnowledgeBaseFile +} + // Expect sets up expected params for RepositoryI.DeleteKnowledgeBaseFile func (mmDeleteKnowledgeBaseFile *mRepositoryIMockDeleteKnowledgeBaseFile) Expect(ctx context.Context, fileUID string) *mRepositoryIMockDeleteKnowledgeBaseFile { if mmDeleteKnowledgeBaseFile.mock.funcDeleteKnowledgeBaseFile != nil { @@ -1342,6 +1410,11 @@ func (mmDeleteKnowledgeBaseFile *mRepositoryIMockDeleteKnowledgeBaseFile) Calls( // MinimockDeleteKnowledgeBaseFileDone returns true if the count of the DeleteKnowledgeBaseFile invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockDeleteKnowledgeBaseFileDone() bool { + if m.DeleteKnowledgeBaseFileMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.DeleteKnowledgeBaseFileMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1379,7 +1452,328 @@ func (m *RepositoryIMock) MinimockDeleteKnowledgeBaseFileInspect() { } } +type mRepositoryIMockDeleteRepositoryTag struct { + optional bool + mock *RepositoryIMock + defaultExpectation *RepositoryIMockDeleteRepositoryTagExpectation + expectations []*RepositoryIMockDeleteRepositoryTagExpectation + + callArgs []*RepositoryIMockDeleteRepositoryTagParams + mutex sync.RWMutex + + expectedInvocations uint64 +} + +// RepositoryIMockDeleteRepositoryTagExpectation specifies expectation struct of the RepositoryI.DeleteRepositoryTag +type RepositoryIMockDeleteRepositoryTagExpectation struct { + mock *RepositoryIMock + params *RepositoryIMockDeleteRepositoryTagParams + paramPtrs *RepositoryIMockDeleteRepositoryTagParamPtrs + results *RepositoryIMockDeleteRepositoryTagResults + Counter uint64 +} + +// RepositoryIMockDeleteRepositoryTagParams contains parameters of the RepositoryI.DeleteRepositoryTag +type RepositoryIMockDeleteRepositoryTagParams struct { + ctx context.Context + s1 string +} + +// RepositoryIMockDeleteRepositoryTagParamPtrs contains pointers to parameters of the RepositoryI.DeleteRepositoryTag +type RepositoryIMockDeleteRepositoryTagParamPtrs struct { + ctx *context.Context + s1 *string +} + +// RepositoryIMockDeleteRepositoryTagResults contains results of the RepositoryI.DeleteRepositoryTag +type RepositoryIMockDeleteRepositoryTagResults struct { + err error +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Optional() *mRepositoryIMockDeleteRepositoryTag { + mmDeleteRepositoryTag.optional = true + return mmDeleteRepositoryTag +} + +// Expect sets up expected params for RepositoryI.DeleteRepositoryTag +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Expect(ctx context.Context, s1 string) *mRepositoryIMockDeleteRepositoryTag { + if mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Set") + } + + if mmDeleteRepositoryTag.defaultExpectation == nil { + mmDeleteRepositoryTag.defaultExpectation = &RepositoryIMockDeleteRepositoryTagExpectation{} + } + + if mmDeleteRepositoryTag.defaultExpectation.paramPtrs != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by ExpectParams functions") + } + + mmDeleteRepositoryTag.defaultExpectation.params = &RepositoryIMockDeleteRepositoryTagParams{ctx, s1} + for _, e := range mmDeleteRepositoryTag.expectations { + if minimock.Equal(e.params, mmDeleteRepositoryTag.defaultExpectation.params) { + mmDeleteRepositoryTag.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmDeleteRepositoryTag.defaultExpectation.params) + } + } + + return mmDeleteRepositoryTag +} + +// ExpectCtxParam1 sets up expected param ctx for RepositoryI.DeleteRepositoryTag +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) ExpectCtxParam1(ctx context.Context) *mRepositoryIMockDeleteRepositoryTag { + if mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Set") + } + + if mmDeleteRepositoryTag.defaultExpectation == nil { + mmDeleteRepositoryTag.defaultExpectation = &RepositoryIMockDeleteRepositoryTagExpectation{} + } + + if mmDeleteRepositoryTag.defaultExpectation.params != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Expect") + } + + if mmDeleteRepositoryTag.defaultExpectation.paramPtrs == nil { + mmDeleteRepositoryTag.defaultExpectation.paramPtrs = &RepositoryIMockDeleteRepositoryTagParamPtrs{} + } + mmDeleteRepositoryTag.defaultExpectation.paramPtrs.ctx = &ctx + + return mmDeleteRepositoryTag +} + +// ExpectS1Param2 sets up expected param s1 for RepositoryI.DeleteRepositoryTag +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) ExpectS1Param2(s1 string) *mRepositoryIMockDeleteRepositoryTag { + if mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Set") + } + + if mmDeleteRepositoryTag.defaultExpectation == nil { + mmDeleteRepositoryTag.defaultExpectation = &RepositoryIMockDeleteRepositoryTagExpectation{} + } + + if mmDeleteRepositoryTag.defaultExpectation.params != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Expect") + } + + if mmDeleteRepositoryTag.defaultExpectation.paramPtrs == nil { + mmDeleteRepositoryTag.defaultExpectation.paramPtrs = &RepositoryIMockDeleteRepositoryTagParamPtrs{} + } + mmDeleteRepositoryTag.defaultExpectation.paramPtrs.s1 = &s1 + + return mmDeleteRepositoryTag +} + +// Inspect accepts an inspector function that has same arguments as the RepositoryI.DeleteRepositoryTag +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Inspect(f func(ctx context.Context, s1 string)) *mRepositoryIMockDeleteRepositoryTag { + if mmDeleteRepositoryTag.mock.inspectFuncDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("Inspect function is already set for RepositoryIMock.DeleteRepositoryTag") + } + + mmDeleteRepositoryTag.mock.inspectFuncDeleteRepositoryTag = f + + return mmDeleteRepositoryTag +} + +// Return sets up results that will be returned by RepositoryI.DeleteRepositoryTag +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Return(err error) *RepositoryIMock { + if mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Set") + } + + if mmDeleteRepositoryTag.defaultExpectation == nil { + mmDeleteRepositoryTag.defaultExpectation = &RepositoryIMockDeleteRepositoryTagExpectation{mock: mmDeleteRepositoryTag.mock} + } + mmDeleteRepositoryTag.defaultExpectation.results = &RepositoryIMockDeleteRepositoryTagResults{err} + return mmDeleteRepositoryTag.mock +} + +// Set uses given function f to mock the RepositoryI.DeleteRepositoryTag method +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Set(f func(ctx context.Context, s1 string) (err error)) *RepositoryIMock { + if mmDeleteRepositoryTag.defaultExpectation != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("Default expectation is already set for the RepositoryI.DeleteRepositoryTag method") + } + + if len(mmDeleteRepositoryTag.expectations) > 0 { + mmDeleteRepositoryTag.mock.t.Fatalf("Some expectations are already set for the RepositoryI.DeleteRepositoryTag method") + } + + mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag = f + return mmDeleteRepositoryTag.mock +} + +// When sets expectation for the RepositoryI.DeleteRepositoryTag which will trigger the result defined by the following +// Then helper +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) When(ctx context.Context, s1 string) *RepositoryIMockDeleteRepositoryTagExpectation { + if mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.mock.t.Fatalf("RepositoryIMock.DeleteRepositoryTag mock is already set by Set") + } + + expectation := &RepositoryIMockDeleteRepositoryTagExpectation{ + mock: mmDeleteRepositoryTag.mock, + params: &RepositoryIMockDeleteRepositoryTagParams{ctx, s1}, + } + mmDeleteRepositoryTag.expectations = append(mmDeleteRepositoryTag.expectations, expectation) + return expectation +} + +// Then sets up RepositoryI.DeleteRepositoryTag return parameters for the expectation previously defined by the When method +func (e *RepositoryIMockDeleteRepositoryTagExpectation) Then(err error) *RepositoryIMock { + e.results = &RepositoryIMockDeleteRepositoryTagResults{err} + return e.mock +} + +// Times sets number of times RepositoryI.DeleteRepositoryTag should be invoked +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Times(n uint64) *mRepositoryIMockDeleteRepositoryTag { + if n == 0 { + mmDeleteRepositoryTag.mock.t.Fatalf("Times of RepositoryIMock.DeleteRepositoryTag mock can not be zero") + } + mm_atomic.StoreUint64(&mmDeleteRepositoryTag.expectedInvocations, n) + return mmDeleteRepositoryTag +} + +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) invocationsDone() bool { + if len(mmDeleteRepositoryTag.expectations) == 0 && mmDeleteRepositoryTag.defaultExpectation == nil && mmDeleteRepositoryTag.mock.funcDeleteRepositoryTag == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmDeleteRepositoryTag.mock.afterDeleteRepositoryTagCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmDeleteRepositoryTag.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// DeleteRepositoryTag implements repository.RepositoryI +func (mmDeleteRepositoryTag *RepositoryIMock) DeleteRepositoryTag(ctx context.Context, s1 string) (err error) { + mm_atomic.AddUint64(&mmDeleteRepositoryTag.beforeDeleteRepositoryTagCounter, 1) + defer mm_atomic.AddUint64(&mmDeleteRepositoryTag.afterDeleteRepositoryTagCounter, 1) + + if mmDeleteRepositoryTag.inspectFuncDeleteRepositoryTag != nil { + mmDeleteRepositoryTag.inspectFuncDeleteRepositoryTag(ctx, s1) + } + + mm_params := RepositoryIMockDeleteRepositoryTagParams{ctx, s1} + + // Record call args + mmDeleteRepositoryTag.DeleteRepositoryTagMock.mutex.Lock() + mmDeleteRepositoryTag.DeleteRepositoryTagMock.callArgs = append(mmDeleteRepositoryTag.DeleteRepositoryTagMock.callArgs, &mm_params) + mmDeleteRepositoryTag.DeleteRepositoryTagMock.mutex.Unlock() + + for _, e := range mmDeleteRepositoryTag.DeleteRepositoryTagMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmDeleteRepositoryTag.DeleteRepositoryTagMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmDeleteRepositoryTag.DeleteRepositoryTagMock.defaultExpectation.Counter, 1) + mm_want := mmDeleteRepositoryTag.DeleteRepositoryTagMock.defaultExpectation.params + mm_want_ptrs := mmDeleteRepositoryTag.DeleteRepositoryTagMock.defaultExpectation.paramPtrs + + mm_got := RepositoryIMockDeleteRepositoryTagParams{ctx, s1} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmDeleteRepositoryTag.t.Errorf("RepositoryIMock.DeleteRepositoryTag got unexpected parameter ctx, want: %#v, got: %#v%s\n", *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.s1 != nil && !minimock.Equal(*mm_want_ptrs.s1, mm_got.s1) { + mmDeleteRepositoryTag.t.Errorf("RepositoryIMock.DeleteRepositoryTag got unexpected parameter s1, want: %#v, got: %#v%s\n", *mm_want_ptrs.s1, mm_got.s1, minimock.Diff(*mm_want_ptrs.s1, mm_got.s1)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmDeleteRepositoryTag.t.Errorf("RepositoryIMock.DeleteRepositoryTag got unexpected parameters, want: %#v, got: %#v%s\n", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmDeleteRepositoryTag.DeleteRepositoryTagMock.defaultExpectation.results + if mm_results == nil { + mmDeleteRepositoryTag.t.Fatal("No results are set for the RepositoryIMock.DeleteRepositoryTag") + } + return (*mm_results).err + } + if mmDeleteRepositoryTag.funcDeleteRepositoryTag != nil { + return mmDeleteRepositoryTag.funcDeleteRepositoryTag(ctx, s1) + } + mmDeleteRepositoryTag.t.Fatalf("Unexpected call to RepositoryIMock.DeleteRepositoryTag. %v %v", ctx, s1) + return +} + +// DeleteRepositoryTagAfterCounter returns a count of finished RepositoryIMock.DeleteRepositoryTag invocations +func (mmDeleteRepositoryTag *RepositoryIMock) DeleteRepositoryTagAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmDeleteRepositoryTag.afterDeleteRepositoryTagCounter) +} + +// DeleteRepositoryTagBeforeCounter returns a count of RepositoryIMock.DeleteRepositoryTag invocations +func (mmDeleteRepositoryTag *RepositoryIMock) DeleteRepositoryTagBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmDeleteRepositoryTag.beforeDeleteRepositoryTagCounter) +} + +// Calls returns a list of arguments used in each call to RepositoryIMock.DeleteRepositoryTag. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmDeleteRepositoryTag *mRepositoryIMockDeleteRepositoryTag) Calls() []*RepositoryIMockDeleteRepositoryTagParams { + mmDeleteRepositoryTag.mutex.RLock() + + argCopy := make([]*RepositoryIMockDeleteRepositoryTagParams, len(mmDeleteRepositoryTag.callArgs)) + copy(argCopy, mmDeleteRepositoryTag.callArgs) + + mmDeleteRepositoryTag.mutex.RUnlock() + + return argCopy +} + +// MinimockDeleteRepositoryTagDone returns true if the count of the DeleteRepositoryTag invocations corresponds +// the number of defined expectations +func (m *RepositoryIMock) MinimockDeleteRepositoryTagDone() bool { + if m.DeleteRepositoryTagMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.DeleteRepositoryTagMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.DeleteRepositoryTagMock.invocationsDone() +} + +// MinimockDeleteRepositoryTagInspect logs each unmet expectation +func (m *RepositoryIMock) MinimockDeleteRepositoryTagInspect() { + for _, e := range m.DeleteRepositoryTagMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to RepositoryIMock.DeleteRepositoryTag with params: %#v", *e.params) + } + } + + afterDeleteRepositoryTagCounter := mm_atomic.LoadUint64(&m.afterDeleteRepositoryTagCounter) + // if default expectation was set then invocations count should be greater than zero + if m.DeleteRepositoryTagMock.defaultExpectation != nil && afterDeleteRepositoryTagCounter < 1 { + if m.DeleteRepositoryTagMock.defaultExpectation.params == nil { + m.t.Error("Expected call to RepositoryIMock.DeleteRepositoryTag") + } else { + m.t.Errorf("Expected call to RepositoryIMock.DeleteRepositoryTag with params: %#v", *m.DeleteRepositoryTagMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcDeleteRepositoryTag != nil && afterDeleteRepositoryTagCounter < 1 { + m.t.Error("Expected call to RepositoryIMock.DeleteRepositoryTag") + } + + if !m.DeleteRepositoryTagMock.invocationsDone() && afterDeleteRepositoryTagCounter > 0 { + m.t.Errorf("Expected %d calls to RepositoryIMock.DeleteRepositoryTag but found %d calls", + mm_atomic.LoadUint64(&m.DeleteRepositoryTagMock.expectedInvocations), afterDeleteRepositoryTagCounter) + } +} + type mRepositoryIMockGetKnowledgeBaseByOwnerAndID struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockGetKnowledgeBaseByOwnerAndIDExpectation expectations []*RepositoryIMockGetKnowledgeBaseByOwnerAndIDExpectation @@ -1419,6 +1813,16 @@ type RepositoryIMockGetKnowledgeBaseByOwnerAndIDResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmGetKnowledgeBaseByOwnerAndID *mRepositoryIMockGetKnowledgeBaseByOwnerAndID) Optional() *mRepositoryIMockGetKnowledgeBaseByOwnerAndID { + mmGetKnowledgeBaseByOwnerAndID.optional = true + return mmGetKnowledgeBaseByOwnerAndID +} + // Expect sets up expected params for RepositoryI.GetKnowledgeBaseByOwnerAndID func (mmGetKnowledgeBaseByOwnerAndID *mRepositoryIMockGetKnowledgeBaseByOwnerAndID) Expect(ctx context.Context, ownerUID string, kbID string) *mRepositoryIMockGetKnowledgeBaseByOwnerAndID { if mmGetKnowledgeBaseByOwnerAndID.mock.funcGetKnowledgeBaseByOwnerAndID != nil { @@ -1675,6 +2079,11 @@ func (mmGetKnowledgeBaseByOwnerAndID *mRepositoryIMockGetKnowledgeBaseByOwnerAnd // MinimockGetKnowledgeBaseByOwnerAndIDDone returns true if the count of the GetKnowledgeBaseByOwnerAndID invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockGetKnowledgeBaseByOwnerAndIDDone() bool { + if m.GetKnowledgeBaseByOwnerAndIDMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.GetKnowledgeBaseByOwnerAndIDMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1713,6 +2122,7 @@ func (m *RepositoryIMock) MinimockGetKnowledgeBaseByOwnerAndIDInspect() { } type mRepositoryIMockGetRepositoryTag struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockGetRepositoryTagExpectation expectations []*RepositoryIMockGetRepositoryTagExpectation @@ -1750,6 +2160,16 @@ type RepositoryIMockGetRepositoryTagResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmGetRepositoryTag *mRepositoryIMockGetRepositoryTag) Optional() *mRepositoryIMockGetRepositoryTag { + mmGetRepositoryTag.optional = true + return mmGetRepositoryTag +} + // Expect sets up expected params for RepositoryI.GetRepositoryTag func (mmGetRepositoryTag *mRepositoryIMockGetRepositoryTag) Expect(ctx context.Context, r1 utils.RepositoryTagName) *mRepositoryIMockGetRepositoryTag { if mmGetRepositoryTag.mock.funcGetRepositoryTag != nil { @@ -1980,6 +2400,11 @@ func (mmGetRepositoryTag *mRepositoryIMockGetRepositoryTag) Calls() []*Repositor // MinimockGetRepositoryTagDone returns true if the count of the GetRepositoryTag invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockGetRepositoryTagDone() bool { + if m.GetRepositoryTagMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.GetRepositoryTagMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -2018,6 +2443,7 @@ func (m *RepositoryIMock) MinimockGetRepositoryTagInspect() { } type mRepositoryIMockListKnowledgeBaseFiles struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockListKnowledgeBaseFilesExpectation expectations []*RepositoryIMockListKnowledgeBaseFilesExpectation @@ -2067,6 +2493,16 @@ type RepositoryIMockListKnowledgeBaseFilesResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmListKnowledgeBaseFiles *mRepositoryIMockListKnowledgeBaseFiles) Optional() *mRepositoryIMockListKnowledgeBaseFiles { + mmListKnowledgeBaseFiles.optional = true + return mmListKnowledgeBaseFiles +} + // Expect sets up expected params for RepositoryI.ListKnowledgeBaseFiles func (mmListKnowledgeBaseFiles *mRepositoryIMockListKnowledgeBaseFiles) Expect(ctx context.Context, uid string, ownerUID string, kbUID string, pageSize int32, nextPageToken string, filesUID []string) *mRepositoryIMockListKnowledgeBaseFiles { if mmListKnowledgeBaseFiles.mock.funcListKnowledgeBaseFiles != nil { @@ -2427,6 +2863,11 @@ func (mmListKnowledgeBaseFiles *mRepositoryIMockListKnowledgeBaseFiles) Calls() // MinimockListKnowledgeBaseFilesDone returns true if the count of the ListKnowledgeBaseFiles invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockListKnowledgeBaseFilesDone() bool { + if m.ListKnowledgeBaseFilesMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ListKnowledgeBaseFilesMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -2465,6 +2906,7 @@ func (m *RepositoryIMock) MinimockListKnowledgeBaseFilesInspect() { } type mRepositoryIMockListKnowledgeBases struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockListKnowledgeBasesExpectation expectations []*RepositoryIMockListKnowledgeBasesExpectation @@ -2502,6 +2944,16 @@ type RepositoryIMockListKnowledgeBasesResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmListKnowledgeBases *mRepositoryIMockListKnowledgeBases) Optional() *mRepositoryIMockListKnowledgeBases { + mmListKnowledgeBases.optional = true + return mmListKnowledgeBases +} + // Expect sets up expected params for RepositoryI.ListKnowledgeBases func (mmListKnowledgeBases *mRepositoryIMockListKnowledgeBases) Expect(ctx context.Context, ownerUID string) *mRepositoryIMockListKnowledgeBases { if mmListKnowledgeBases.mock.funcListKnowledgeBases != nil { @@ -2732,6 +3184,11 @@ func (mmListKnowledgeBases *mRepositoryIMockListKnowledgeBases) Calls() []*Repos // MinimockListKnowledgeBasesDone returns true if the count of the ListKnowledgeBases invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockListKnowledgeBasesDone() bool { + if m.ListKnowledgeBasesMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ListKnowledgeBasesMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -2770,6 +3227,7 @@ func (m *RepositoryIMock) MinimockListKnowledgeBasesInspect() { } type mRepositoryIMockProcessKnowledgeBaseFiles struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockProcessKnowledgeBaseFilesExpectation expectations []*RepositoryIMockProcessKnowledgeBaseFilesExpectation @@ -2807,6 +3265,16 @@ type RepositoryIMockProcessKnowledgeBaseFilesResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmProcessKnowledgeBaseFiles *mRepositoryIMockProcessKnowledgeBaseFiles) Optional() *mRepositoryIMockProcessKnowledgeBaseFiles { + mmProcessKnowledgeBaseFiles.optional = true + return mmProcessKnowledgeBaseFiles +} + // Expect sets up expected params for RepositoryI.ProcessKnowledgeBaseFiles func (mmProcessKnowledgeBaseFiles *mRepositoryIMockProcessKnowledgeBaseFiles) Expect(ctx context.Context, fileUids []string) *mRepositoryIMockProcessKnowledgeBaseFiles { if mmProcessKnowledgeBaseFiles.mock.funcProcessKnowledgeBaseFiles != nil { @@ -3037,6 +3505,11 @@ func (mmProcessKnowledgeBaseFiles *mRepositoryIMockProcessKnowledgeBaseFiles) Ca // MinimockProcessKnowledgeBaseFilesDone returns true if the count of the ProcessKnowledgeBaseFiles invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockProcessKnowledgeBaseFilesDone() bool { + if m.ProcessKnowledgeBaseFilesMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ProcessKnowledgeBaseFilesMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -3075,6 +3548,7 @@ func (m *RepositoryIMock) MinimockProcessKnowledgeBaseFilesInspect() { } type mRepositoryIMockUpdateKnowledgeBase struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockUpdateKnowledgeBaseExpectation expectations []*RepositoryIMockUpdateKnowledgeBaseExpectation @@ -3114,6 +3588,16 @@ type RepositoryIMockUpdateKnowledgeBaseResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmUpdateKnowledgeBase *mRepositoryIMockUpdateKnowledgeBase) Optional() *mRepositoryIMockUpdateKnowledgeBase { + mmUpdateKnowledgeBase.optional = true + return mmUpdateKnowledgeBase +} + // Expect sets up expected params for RepositoryI.UpdateKnowledgeBase func (mmUpdateKnowledgeBase *mRepositoryIMockUpdateKnowledgeBase) Expect(ctx context.Context, ownerUID string, kb mm_repository.KnowledgeBase) *mRepositoryIMockUpdateKnowledgeBase { if mmUpdateKnowledgeBase.mock.funcUpdateKnowledgeBase != nil { @@ -3370,6 +3854,11 @@ func (mmUpdateKnowledgeBase *mRepositoryIMockUpdateKnowledgeBase) Calls() []*Rep // MinimockUpdateKnowledgeBaseDone returns true if the count of the UpdateKnowledgeBase invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockUpdateKnowledgeBaseDone() bool { + if m.UpdateKnowledgeBaseMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.UpdateKnowledgeBaseMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -3408,6 +3897,7 @@ func (m *RepositoryIMock) MinimockUpdateKnowledgeBaseInspect() { } type mRepositoryIMockUpsertRepositoryTag struct { + optional bool mock *RepositoryIMock defaultExpectation *RepositoryIMockUpsertRepositoryTagExpectation expectations []*RepositoryIMockUpsertRepositoryTagExpectation @@ -3445,6 +3935,16 @@ type RepositoryIMockUpsertRepositoryTagResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmUpsertRepositoryTag *mRepositoryIMockUpsertRepositoryTag) Optional() *mRepositoryIMockUpsertRepositoryTag { + mmUpsertRepositoryTag.optional = true + return mmUpsertRepositoryTag +} + // Expect sets up expected params for RepositoryI.UpsertRepositoryTag func (mmUpsertRepositoryTag *mRepositoryIMockUpsertRepositoryTag) Expect(ctx context.Context, rp1 *pb.RepositoryTag) *mRepositoryIMockUpsertRepositoryTag { if mmUpsertRepositoryTag.mock.funcUpsertRepositoryTag != nil { @@ -3675,6 +4175,11 @@ func (mmUpsertRepositoryTag *mRepositoryIMockUpsertRepositoryTag) Calls() []*Rep // MinimockUpsertRepositoryTagDone returns true if the count of the UpsertRepositoryTag invocations corresponds // the number of defined expectations func (m *RepositoryIMock) MinimockUpsertRepositoryTagDone() bool { + if m.UpsertRepositoryTagMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.UpsertRepositoryTagMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -3724,6 +4229,8 @@ func (m *RepositoryIMock) MinimockFinish() { m.MinimockDeleteKnowledgeBaseFileInspect() + m.MinimockDeleteRepositoryTagInspect() + m.MinimockGetKnowledgeBaseByOwnerAndIDInspect() m.MinimockGetRepositoryTagInspect() @@ -3737,7 +4244,6 @@ func (m *RepositoryIMock) MinimockFinish() { m.MinimockUpdateKnowledgeBaseInspect() m.MinimockUpsertRepositoryTagInspect() - m.t.FailNow() } }) } @@ -3765,6 +4271,7 @@ func (m *RepositoryIMock) minimockDone() bool { m.MinimockCreateKnowledgeBaseFileDone() && m.MinimockDeleteKnowledgeBaseDone() && m.MinimockDeleteKnowledgeBaseFileDone() && + m.MinimockDeleteRepositoryTagDone() && m.MinimockGetKnowledgeBaseByOwnerAndIDDone() && m.MinimockGetRepositoryTagDone() && m.MinimockListKnowledgeBaseFilesDone() && diff --git a/pkg/repository/tag.go b/pkg/repository/tag.go index 9e69870..2a10e39 100644 --- a/pkg/repository/tag.go +++ b/pkg/repository/tag.go @@ -19,6 +19,7 @@ import ( type TagI interface { GetRepositoryTag(context.Context, utils.RepositoryTagName) (*pb.RepositoryTag, error) UpsertRepositoryTag(context.Context, *pb.RepositoryTag) (*pb.RepositoryTag, error) + DeleteRepositoryTag(context.Context, string) error } // GetRepositoryTag fetches the tag information from the repository_tag table. @@ -78,3 +79,22 @@ func (r *Repository) UpsertRepositoryTag(_ context.Context, tag *pb.RepositoryTa UpdateTime: timestamppb.New(record.UpdateTime), }, nil } + +// DeleteRepositoryTag delete the tag information from the repository_tag table. +// The name param is the resource name of the tag, e.g. +// `repositories/admin/hello-world/tags/0.1.1-beta`. +func (r *Repository) DeleteRepositoryTag(_ context.Context, digest string) error { + record := new(repositoryTag) + if result := r.db.Model(record). + Where("digest = ?", digest). + Delete(record); result.Error != nil { + + if result.Error == gorm.ErrRecordNotFound { + return customerror.ErrNotFound + } + + return result.Error + } + + return nil +} diff --git a/pkg/service/registry_client.go b/pkg/service/registry_client.go index 8d161ca..3b7860a 100644 --- a/pkg/service/registry_client.go +++ b/pkg/service/registry_client.go @@ -6,4 +6,6 @@ import "context" // repositories. type RegistryClient interface { ListTags(_ context.Context, repository string) (tags []string, _ error) + DeleteTag(_ context.Context, repository string, digest string) (_ error) + GetTagDigest(_ context.Context, repository string, tag string) (digest string, _ error) } diff --git a/pkg/service/service.go b/pkg/service/service.go index fc5ebf1..7052ca3 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/instill-ai/artifact-backend/pkg/customerror" + "github.com/instill-ai/artifact-backend/pkg/logger" "github.com/instill-ai/artifact-backend/pkg/minio" "github.com/instill-ai/artifact-backend/pkg/repository" "github.com/instill-ai/artifact-backend/pkg/utils" @@ -46,6 +47,9 @@ func NewService( // ListRepositoryTags fetches and paginates the tags of a repository in a // remote distribution registry. func (s *Service) ListRepositoryTags(ctx context.Context, req *pb.ListRepositoryTagsRequest) (*pb.ListRepositoryTagsResponse, error) { + + logger, _ := logger.GetZapLogger(ctx) + pageSize := pageSizeInRange(req.GetPageSize()) page := pageInRange(req.GetPage()) idx0, idx1 := page*pageSize, (page+1)*pageSize @@ -83,9 +87,23 @@ func (s *Service) ListRepositoryTags(ctx context.Context, req *pb.ListRepository // The source of truth for tags is the registry. The local // repository only holds extra information we'll aggregate to the - // tag ID list. If no record is found locally, the tag object will - // be returned with empty optional fields. - rt = &pb.RepositoryTag{Name: string(name), Id: id} + // tag ID list. If no record is found locally, we create the missing + // record. + // rt = &pb.RepositoryTag{Name: string(name), Id: id} + if digest, err := s.registryClient.GetTagDigest(ctx, repo, id); err != nil { + rt = &pb.RepositoryTag{Name: string(name), Id: id} + } else { + rt = &pb.RepositoryTag{Name: string(name), Id: id, Digest: digest} + if _, err := s.CreateRepositoryTag(ctx, &pb.CreateRepositoryTagRequest{ + Tag: &pb.RepositoryTag{ + Name: string(name), + Id: id, + Digest: digest, + }, + }); err != nil { + logger.Warn(fmt.Sprintf("Create missing tag record error: %v", err)) + } + } } tags = append(tags, rt) @@ -139,3 +157,26 @@ func (s *Service) CreateRepositoryTag(ctx context.Context, req *pb.CreateReposit return &pb.CreateRepositoryTagResponse{Tag: storedTag}, nil } + +func (s *Service) DeleteRepositoryTag(ctx context.Context, req *pb.DeleteRepositoryTagRequest) (*pb.DeleteRepositoryTagResponse, error) { + name := utils.RepositoryTagName(req.GetName()) + repo, id, err := name.ExtractRepositoryAndID() + if err != nil { + return nil, fmt.Errorf("invalid tag name") + } + + rt, err := s.Repository.GetRepositoryTag(ctx, name) + if err != nil { + return nil, fmt.Errorf("failed to find existing tag %s: %w", id, err) + } + + if err := s.registryClient.DeleteTag(ctx, repo, rt.Digest); err != nil { + return nil, err + } + + if err := s.Repository.DeleteRepositoryTag(ctx, rt.Digest); err != nil { + return nil, err + } + + return &pb.DeleteRepositoryTagResponse{}, nil +} diff --git a/pkg/service/service_test.go b/pkg/service/service_test.go index 3dd3cc8..75da642 100644 --- a/pkg/service/service_test.go +++ b/pkg/service/service_test.go @@ -88,8 +88,9 @@ func TestService_ListRepositoryTags(t *testing.T) { name string in func(*artifactpb.ListRepositoryTagsRequest) - registryTags []string - registryErr error + registryTags []string + registryErr error + registryDigestErr error repoTags []*artifactpb.RepositoryTag repoErr error @@ -116,11 +117,12 @@ func TestService_ListRepositoryTags(t *testing.T) { wantErr: "failed to fetch tag .*: foo", }, { - name: "ok - not found in repo", - registryTags: tagIDs, - repoTags: want[:2], - repoErr: fmt.Errorf("repo error: %w", customerror.ErrNotFound), - wantTags: wantWithEmptyOptional[:2], + name: "ok - not found in repo", + registryTags: tagIDs, + repoTags: want[:2], + registryDigestErr: fmt.Errorf("foo"), + repoErr: fmt.Errorf("repo error: %w", customerror.ErrNotFound), + wantTags: wantWithEmptyOptional[:2], }, { name: "ok - no pagination", @@ -197,8 +199,13 @@ func TestService_ListRepositoryTags(t *testing.T) { repository := mock.NewRepositoryIMock(c) for _, repoTag := range tc.repoTags { name := utils.RepositoryTagName(repoTag.Name) + _, id, _ := name.ExtractRepositoryAndID() repository.GetRepositoryTagMock.When(minimock.AnyContext, name). Then(repoTag, tc.repoErr) + if tc.registryDigestErr != nil { + registry.GetTagDigestMock.When(minimock.AnyContext, repo, id). + Then("", tc.registryDigestErr) + } } s := NewService(repository, nil, nil, registry)