diff --git a/.deadcode-out b/.deadcode-out index b8c236daf6..b70be3e800 100644 --- a/.deadcode-out +++ b/.deadcode-out @@ -222,9 +222,6 @@ forgejo.org/modules/zstd forgejo.org/routers/web/org MustEnableProjects -forgejo.org/services/auth/method - OverrideAuthorizedIntegrationHTTPClient - forgejo.org/services/context GetPrivateContext diff --git a/.mockery.yml b/.mockery.yml new file mode 100644 index 0000000000..7c98b29508 --- /dev/null +++ b/.mockery.yml @@ -0,0 +1,16 @@ +formatter: gofmt +template: testify +packages: + forgejo.org/modules/nosql: + config: + filename: mocks.go # make mocks public so that external packages can use + forgejo.org/services/authz: + config: + filename: authorization_reducer_mock.go # make mocks public so that external packages can use + code.forgejo.org/go-chi/cache: + interfaces: + Cache: + config: + pkgname: cache + dir: modules/cache + filename: mocks.go # make mocks public, not `_test.go`, so that external packages can mock caching diff --git a/Makefile b/Makefile index a499443ddd..a17f79d3a9 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,8 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses/v2@v2.0.1 # renovate: datas GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.44.0 # renovate: datasource=go ERRORTYPE_PACKAGE ?= fillmore-labs.com/errortype@v0.0.11 # renovate: datasource=go -GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.6.0 # renovate: datasource=go RENOVATE_NPM_PACKAGE ?= renovate@43.141.6 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate +MOCKERY_PACKAGE ?= github.com/vektra/mockery/v3@v3.7.0 # renovate: datasource=go # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... @@ -245,7 +245,7 @@ help: @echo " - generate-license update license files" @echo " - generate-gitignore update gitignore files" @echo " - generate-manpage generate manpage" - @echo " - generate-gomock generate gomock files" + @echo " - generate-mockery generate mockery files" @echo " - generate-forgejo-api generate the forgejo API from spec" @echo " - forgejo-api-validate check if the forgejo API matches the specs" @echo " - generate-swagger generate the swagger spec from code comments" @@ -968,8 +968,8 @@ deps-tools: $(GO) install $(XGO_PACKAGE) $(GO) install $(GO_LICENSES_PACKAGE) $(GO) install $(GOVULNCHECK_PACKAGE) - $(GO) install $(GOMOCK_PACKAGE) $(GO) install $(ERRORTYPE_PACKAGE) + $(GO) install $(MOCKERY_PACKAGE) node_modules: package-lock.json npm install --no-save @@ -1024,9 +1024,9 @@ generate-license: generate-gitignore: $(GO) run build/generate-gitignores.go -.PHONY: generate-gomock -generate-gomock: - $(GO) run $(GOMOCK_PACKAGE) -package mock -destination ./modules/queue/mock/redisuniversalclient.go forgejo.org/modules/nosql RedisClient +.PHONY: generate-mockery +generate-mockery: + $(GO) run $(MOCKERY_PACKAGE) .PHONY: generate-images generate-images: | node_modules diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index ae22c02609..40dd7d56db 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2846,3 +2846,7 @@ LEVEL = Info ;; Default is false. ;; If a domain is allowed by ALLOWED_DOMAINS, this option will be ignored. ;ALLOW_LOCALNETWORKS = false +; +;; Remote requests are cached after being received for the cache time-to-live (TTL). Default is 10 minutes. +;; Caching uses the configured adapter in the [cache] config section. +;CACHE_TTL = 10m diff --git a/go.mod b/go.mod index 33a8152647..f228f4bc1d 100644 --- a/go.mod +++ b/go.mod @@ -100,7 +100,6 @@ require ( github.com/yuin/goldmark v1.8.2 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc gitlab.com/gitlab-org/api/client-go v0.143.2 - go.uber.org/mock v0.6.0 go.yaml.in/yaml/v3 v3.0.4 golang.org/x/crypto v0.50.0 golang.org/x/image v0.39.0 diff --git a/modules/cache/mocks.go b/modules/cache/mocks.go new file mode 100644 index 0000000000..8bfec19d6b --- /dev/null +++ b/modules/cache/mocks.go @@ -0,0 +1,497 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package cache + +import ( + "code.forgejo.org/go-chi/cache" + mock "github.com/stretchr/testify/mock" +) + +// NewMockCache creates a new instance of MockCache. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockCache(t interface { + mock.TestingT + Cleanup(func()) +}, +) *MockCache { + mock := &MockCache{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockCache is an autogenerated mock type for the Cache type +type MockCache struct { + mock.Mock +} + +type MockCache_Expecter struct { + mock *mock.Mock +} + +func (_m *MockCache) EXPECT() *MockCache_Expecter { + return &MockCache_Expecter{mock: &_m.Mock} +} + +// Decr provides a mock function for the type MockCache +func (_mock *MockCache) Decr(key string) error { + ret := _mock.Called(key) + + if len(ret) == 0 { + panic("no return value specified for Decr") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string) error); ok { + r0 = returnFunc(key) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Decr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decr' +type MockCache_Decr_Call struct { + *mock.Call +} + +// Decr is a helper method to define mock.On call +// - key string +func (_e *MockCache_Expecter) Decr(key any) *MockCache_Decr_Call { + return &MockCache_Decr_Call{Call: _e.mock.On("Decr", key)} +} + +func (_c *MockCache_Decr_Call) Run(run func(key string)) *MockCache_Decr_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_Decr_Call) Return(err error) *MockCache_Decr_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Decr_Call) RunAndReturn(run func(key string) error) *MockCache_Decr_Call { + _c.Call.Return(run) + return _c +} + +// Delete provides a mock function for the type MockCache +func (_mock *MockCache) Delete(key string) error { + ret := _mock.Called(key) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string) error); ok { + r0 = returnFunc(key) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type MockCache_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - key string +func (_e *MockCache_Expecter) Delete(key any) *MockCache_Delete_Call { + return &MockCache_Delete_Call{Call: _e.mock.On("Delete", key)} +} + +func (_c *MockCache_Delete_Call) Run(run func(key string)) *MockCache_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_Delete_Call) Return(err error) *MockCache_Delete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Delete_Call) RunAndReturn(run func(key string) error) *MockCache_Delete_Call { + _c.Call.Return(run) + return _c +} + +// Flush provides a mock function for the type MockCache +func (_mock *MockCache) Flush() error { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Flush") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func() error); ok { + r0 = returnFunc() + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Flush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Flush' +type MockCache_Flush_Call struct { + *mock.Call +} + +// Flush is a helper method to define mock.On call +func (_e *MockCache_Expecter) Flush() *MockCache_Flush_Call { + return &MockCache_Flush_Call{Call: _e.mock.On("Flush")} +} + +func (_c *MockCache_Flush_Call) Run(run func()) *MockCache_Flush_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockCache_Flush_Call) Return(err error) *MockCache_Flush_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Flush_Call) RunAndReturn(run func() error) *MockCache_Flush_Call { + _c.Call.Return(run) + return _c +} + +// Get provides a mock function for the type MockCache +func (_mock *MockCache) Get(key string) any { + ret := _mock.Called(key) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 any + if returnFunc, ok := ret.Get(0).(func(string) any); ok { + r0 = returnFunc(key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(any) + } + } + return r0 +} + +// MockCache_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type MockCache_Get_Call struct { + *mock.Call +} + +// Get is a helper method to define mock.On call +// - key string +func (_e *MockCache_Expecter) Get(key any) *MockCache_Get_Call { + return &MockCache_Get_Call{Call: _e.mock.On("Get", key)} +} + +func (_c *MockCache_Get_Call) Run(run func(key string)) *MockCache_Get_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_Get_Call) Return(v any) *MockCache_Get_Call { + _c.Call.Return(v) + return _c +} + +func (_c *MockCache_Get_Call) RunAndReturn(run func(key string) any) *MockCache_Get_Call { + _c.Call.Return(run) + return _c +} + +// Incr provides a mock function for the type MockCache +func (_mock *MockCache) Incr(key string) error { + ret := _mock.Called(key) + + if len(ret) == 0 { + panic("no return value specified for Incr") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string) error); ok { + r0 = returnFunc(key) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Incr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Incr' +type MockCache_Incr_Call struct { + *mock.Call +} + +// Incr is a helper method to define mock.On call +// - key string +func (_e *MockCache_Expecter) Incr(key any) *MockCache_Incr_Call { + return &MockCache_Incr_Call{Call: _e.mock.On("Incr", key)} +} + +func (_c *MockCache_Incr_Call) Run(run func(key string)) *MockCache_Incr_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_Incr_Call) Return(err error) *MockCache_Incr_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Incr_Call) RunAndReturn(run func(key string) error) *MockCache_Incr_Call { + _c.Call.Return(run) + return _c +} + +// IsExist provides a mock function for the type MockCache +func (_mock *MockCache) IsExist(key string) bool { + ret := _mock.Called(key) + + if len(ret) == 0 { + panic("no return value specified for IsExist") + } + + var r0 bool + if returnFunc, ok := ret.Get(0).(func(string) bool); ok { + r0 = returnFunc(key) + } else { + r0 = ret.Get(0).(bool) + } + return r0 +} + +// MockCache_IsExist_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsExist' +type MockCache_IsExist_Call struct { + *mock.Call +} + +// IsExist is a helper method to define mock.On call +// - key string +func (_e *MockCache_Expecter) IsExist(key any) *MockCache_IsExist_Call { + return &MockCache_IsExist_Call{Call: _e.mock.On("IsExist", key)} +} + +func (_c *MockCache_IsExist_Call) Run(run func(key string)) *MockCache_IsExist_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_IsExist_Call) Return(b bool) *MockCache_IsExist_Call { + _c.Call.Return(b) + return _c +} + +func (_c *MockCache_IsExist_Call) RunAndReturn(run func(key string) bool) *MockCache_IsExist_Call { + _c.Call.Return(run) + return _c +} + +// Ping provides a mock function for the type MockCache +func (_mock *MockCache) Ping() error { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Ping") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func() error); ok { + r0 = returnFunc() + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Ping_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ping' +type MockCache_Ping_Call struct { + *mock.Call +} + +// Ping is a helper method to define mock.On call +func (_e *MockCache_Expecter) Ping() *MockCache_Ping_Call { + return &MockCache_Ping_Call{Call: _e.mock.On("Ping")} +} + +func (_c *MockCache_Ping_Call) Run(run func()) *MockCache_Ping_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockCache_Ping_Call) Return(err error) *MockCache_Ping_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Ping_Call) RunAndReturn(run func() error) *MockCache_Ping_Call { + _c.Call.Return(run) + return _c +} + +// Put provides a mock function for the type MockCache +func (_mock *MockCache) Put(key string, val any, timeout int64) error { + ret := _mock.Called(key, val, timeout) + + if len(ret) == 0 { + panic("no return value specified for Put") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, any, int64) error); ok { + r0 = returnFunc(key, val, timeout) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' +type MockCache_Put_Call struct { + *mock.Call +} + +// Put is a helper method to define mock.On call +// - key string +// - val any +// - timeout int64 +func (_e *MockCache_Expecter) Put(key, val, timeout any) *MockCache_Put_Call { + return &MockCache_Put_Call{Call: _e.mock.On("Put", key, val, timeout)} +} + +func (_c *MockCache_Put_Call) Run(run func(key string, val any, timeout int64)) *MockCache_Put_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 any + if args[1] != nil { + arg1 = args[1].(any) + } + var arg2 int64 + if args[2] != nil { + arg2 = args[2].(int64) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockCache_Put_Call) Return(err error) *MockCache_Put_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_Put_Call) RunAndReturn(run func(key string, val any, timeout int64) error) *MockCache_Put_Call { + _c.Call.Return(run) + return _c +} + +// StartAndGC provides a mock function for the type MockCache +func (_mock *MockCache) StartAndGC(opt cache.Options) error { + ret := _mock.Called(opt) + + if len(ret) == 0 { + panic("no return value specified for StartAndGC") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(cache.Options) error); ok { + r0 = returnFunc(opt) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockCache_StartAndGC_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartAndGC' +type MockCache_StartAndGC_Call struct { + *mock.Call +} + +// StartAndGC is a helper method to define mock.On call +// - opt cache.Options +func (_e *MockCache_Expecter) StartAndGC(opt any) *MockCache_StartAndGC_Call { + return &MockCache_StartAndGC_Call{Call: _e.mock.On("StartAndGC", opt)} +} + +func (_c *MockCache_StartAndGC_Call) Run(run func(opt cache.Options)) *MockCache_StartAndGC_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 cache.Options + if args[0] != nil { + arg0 = args[0].(cache.Options) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCache_StartAndGC_Call) Return(err error) *MockCache_StartAndGC_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockCache_StartAndGC_Call) RunAndReturn(run func(opt cache.Options) error) *MockCache_StartAndGC_Call { + _c.Call.Return(run) + return _c +} diff --git a/modules/nosql/manager.go b/modules/nosql/manager.go index 7eea069e09..748afe7587 100644 --- a/modules/nosql/manager.go +++ b/modules/nosql/manager.go @@ -30,6 +30,8 @@ type Manager struct { // RedisClient is a subset of redis.UniversalClient, it exposes less methods // to avoid generating machine code for unused methods. New method definitions // should be copied from the definitions in the Redis library github.com/redis/go-redis. +// +//mockery:generate: true type RedisClient interface { // redis.GenericCmdable Del(ctx context.Context, keys ...string) *redis.IntCmd diff --git a/modules/nosql/mocks.go b/modules/nosql/mocks.go new file mode 100644 index 0000000000..39d0d1fea3 --- /dev/null +++ b/modules/nosql/mocks.go @@ -0,0 +1,1240 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package nosql + +import ( + "context" + "time" + + "github.com/redis/go-redis/v9" + mock "github.com/stretchr/testify/mock" +) + +// NewMockRedisClient creates a new instance of MockRedisClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockRedisClient(t interface { + mock.TestingT + Cleanup(func()) +}, +) *MockRedisClient { + mock := &MockRedisClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockRedisClient is an autogenerated mock type for the RedisClient type +type MockRedisClient struct { + mock.Mock +} + +type MockRedisClient_Expecter struct { + mock *mock.Mock +} + +func (_m *MockRedisClient) EXPECT() *MockRedisClient_Expecter { + return &MockRedisClient_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Close() error { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func() error); ok { + r0 = returnFunc() + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockRedisClient_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockRedisClient_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockRedisClient_Expecter) Close() *MockRedisClient_Close_Call { + return &MockRedisClient_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockRedisClient_Close_Call) Run(run func()) *MockRedisClient_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockRedisClient_Close_Call) Return(err error) *MockRedisClient_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockRedisClient_Close_Call) RunAndReturn(run func() error) *MockRedisClient_Close_Call { + _c.Call.Return(run) + return _c +} + +// DBSize provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) DBSize(ctx context.Context) *redis.IntCmd { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for DBSize") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context) *redis.IntCmd); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_DBSize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DBSize' +type MockRedisClient_DBSize_Call struct { + *mock.Call +} + +// DBSize is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockRedisClient_Expecter) DBSize(ctx any) *MockRedisClient_DBSize_Call { + return &MockRedisClient_DBSize_Call{Call: _e.mock.On("DBSize", ctx)} +} + +func (_c *MockRedisClient_DBSize_Call) Run(run func(ctx context.Context)) *MockRedisClient_DBSize_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockRedisClient_DBSize_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_DBSize_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_DBSize_Call) RunAndReturn(run func(ctx context.Context) *redis.IntCmd) *MockRedisClient_DBSize_Call { + _c.Call.Return(run) + return _c +} + +// Decr provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Decr(ctx context.Context, key string) *redis.IntCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for Decr") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_Decr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decr' +type MockRedisClient_Decr_Call struct { + *mock.Call +} + +// Decr is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) Decr(ctx, key any) *MockRedisClient_Decr_Call { + return &MockRedisClient_Decr_Call{Call: _e.mock.On("Decr", ctx, key)} +} + +func (_c *MockRedisClient_Decr_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_Decr_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_Decr_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_Decr_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_Decr_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.IntCmd) *MockRedisClient_Decr_Call { + _c.Call.Return(run) + return _c +} + +// Del provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Del(ctx context.Context, keys ...string) *redis.IntCmd { + var tmpRet mock.Arguments + if len(keys) > 0 { + tmpRet = _mock.Called(ctx, keys) + } else { + tmpRet = _mock.Called(ctx) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for Del") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, ...string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, keys...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_Del_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Del' +type MockRedisClient_Del_Call struct { + *mock.Call +} + +// Del is a helper method to define mock.On call +// - ctx context.Context +// - keys ...string +func (_e *MockRedisClient_Expecter) Del(ctx any, keys ...any) *MockRedisClient_Del_Call { + return &MockRedisClient_Del_Call{Call: _e.mock.On("Del", + append([]any{ctx}, keys...)...)} +} + +func (_c *MockRedisClient_Del_Call) Run(run func(ctx context.Context, keys ...string)) *MockRedisClient_Del_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 []string + var variadicArgs []string + if len(args) > 1 { + variadicArgs = args[1].([]string) + } + arg1 = variadicArgs + run( + arg0, + arg1..., + ) + }) + return _c +} + +func (_c *MockRedisClient_Del_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_Del_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_Del_Call) RunAndReturn(run func(ctx context.Context, keys ...string) *redis.IntCmd) *MockRedisClient_Del_Call { + _c.Call.Return(run) + return _c +} + +// Exists provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Exists(ctx context.Context, keys ...string) *redis.IntCmd { + var tmpRet mock.Arguments + if len(keys) > 0 { + tmpRet = _mock.Called(ctx, keys) + } else { + tmpRet = _mock.Called(ctx) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for Exists") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, ...string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, keys...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_Exists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exists' +type MockRedisClient_Exists_Call struct { + *mock.Call +} + +// Exists is a helper method to define mock.On call +// - ctx context.Context +// - keys ...string +func (_e *MockRedisClient_Expecter) Exists(ctx any, keys ...any) *MockRedisClient_Exists_Call { + return &MockRedisClient_Exists_Call{Call: _e.mock.On("Exists", + append([]any{ctx}, keys...)...)} +} + +func (_c *MockRedisClient_Exists_Call) Run(run func(ctx context.Context, keys ...string)) *MockRedisClient_Exists_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 []string + var variadicArgs []string + if len(args) > 1 { + variadicArgs = args[1].([]string) + } + arg1 = variadicArgs + run( + arg0, + arg1..., + ) + }) + return _c +} + +func (_c *MockRedisClient_Exists_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_Exists_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_Exists_Call) RunAndReturn(run func(ctx context.Context, keys ...string) *redis.IntCmd) *MockRedisClient_Exists_Call { + _c.Call.Return(run) + return _c +} + +// FlushDB provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) FlushDB(ctx context.Context) *redis.StatusCmd { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for FlushDB") + } + + var r0 *redis.StatusCmd + if returnFunc, ok := ret.Get(0).(func(context.Context) *redis.StatusCmd); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StatusCmd) + } + } + return r0 +} + +// MockRedisClient_FlushDB_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FlushDB' +type MockRedisClient_FlushDB_Call struct { + *mock.Call +} + +// FlushDB is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockRedisClient_Expecter) FlushDB(ctx any) *MockRedisClient_FlushDB_Call { + return &MockRedisClient_FlushDB_Call{Call: _e.mock.On("FlushDB", ctx)} +} + +func (_c *MockRedisClient_FlushDB_Call) Run(run func(ctx context.Context)) *MockRedisClient_FlushDB_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockRedisClient_FlushDB_Call) Return(statusCmd *redis.StatusCmd) *MockRedisClient_FlushDB_Call { + _c.Call.Return(statusCmd) + return _c +} + +func (_c *MockRedisClient_FlushDB_Call) RunAndReturn(run func(ctx context.Context) *redis.StatusCmd) *MockRedisClient_FlushDB_Call { + _c.Call.Return(run) + return _c +} + +// Get provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Get(ctx context.Context, key string) *redis.StringCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *redis.StringCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.StringCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StringCmd) + } + } + return r0 +} + +// MockRedisClient_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type MockRedisClient_Get_Call struct { + *mock.Call +} + +// Get is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) Get(ctx, key any) *MockRedisClient_Get_Call { + return &MockRedisClient_Get_Call{Call: _e.mock.On("Get", ctx, key)} +} + +func (_c *MockRedisClient_Get_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_Get_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_Get_Call) Return(stringCmd *redis.StringCmd) *MockRedisClient_Get_Call { + _c.Call.Return(stringCmd) + return _c +} + +func (_c *MockRedisClient_Get_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.StringCmd) *MockRedisClient_Get_Call { + _c.Call.Return(run) + return _c +} + +// HDel provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd { + var tmpRet mock.Arguments + if len(fields) > 0 { + tmpRet = _mock.Called(ctx, key, fields) + } else { + tmpRet = _mock.Called(ctx, key) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for HDel") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, ...string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key, fields...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_HDel_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HDel' +type MockRedisClient_HDel_Call struct { + *mock.Call +} + +// HDel is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - fields ...string +func (_e *MockRedisClient_Expecter) HDel(ctx, key any, fields ...any) *MockRedisClient_HDel_Call { + return &MockRedisClient_HDel_Call{Call: _e.mock.On("HDel", + append([]any{ctx, key}, fields...)...)} +} + +func (_c *MockRedisClient_HDel_Call) Run(run func(ctx context.Context, key string, fields ...string)) *MockRedisClient_HDel_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []string + var variadicArgs []string + if len(args) > 2 { + variadicArgs = args[2].([]string) + } + arg2 = variadicArgs + run( + arg0, + arg1, + arg2..., + ) + }) + return _c +} + +func (_c *MockRedisClient_HDel_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_HDel_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_HDel_Call) RunAndReturn(run func(ctx context.Context, key string, fields ...string) *redis.IntCmd) *MockRedisClient_HDel_Call { + _c.Call.Return(run) + return _c +} + +// HKeys provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) HKeys(ctx context.Context, key string) *redis.StringSliceCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for HKeys") + } + + var r0 *redis.StringSliceCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.StringSliceCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StringSliceCmd) + } + } + return r0 +} + +// MockRedisClient_HKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HKeys' +type MockRedisClient_HKeys_Call struct { + *mock.Call +} + +// HKeys is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) HKeys(ctx, key any) *MockRedisClient_HKeys_Call { + return &MockRedisClient_HKeys_Call{Call: _e.mock.On("HKeys", ctx, key)} +} + +func (_c *MockRedisClient_HKeys_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_HKeys_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_HKeys_Call) Return(stringSliceCmd *redis.StringSliceCmd) *MockRedisClient_HKeys_Call { + _c.Call.Return(stringSliceCmd) + return _c +} + +func (_c *MockRedisClient_HKeys_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.StringSliceCmd) *MockRedisClient_HKeys_Call { + _c.Call.Return(run) + return _c +} + +// HSet provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) HSet(ctx context.Context, key string, values ...any) *redis.IntCmd { + var tmpRet mock.Arguments + if len(values) > 0 { + tmpRet = _mock.Called(ctx, key, values) + } else { + tmpRet = _mock.Called(ctx, key) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for HSet") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, ...any) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key, values...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_HSet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HSet' +type MockRedisClient_HSet_Call struct { + *mock.Call +} + +// HSet is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - values ...any +func (_e *MockRedisClient_Expecter) HSet(ctx, key any, values ...any) *MockRedisClient_HSet_Call { + return &MockRedisClient_HSet_Call{Call: _e.mock.On("HSet", + append([]any{ctx, key}, values...)...)} +} + +func (_c *MockRedisClient_HSet_Call) Run(run func(ctx context.Context, key string, values ...any)) *MockRedisClient_HSet_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []any + var variadicArgs []any + if len(args) > 2 { + variadicArgs = args[2].([]any) + } + arg2 = variadicArgs + run( + arg0, + arg1, + arg2..., + ) + }) + return _c +} + +func (_c *MockRedisClient_HSet_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_HSet_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_HSet_Call) RunAndReturn(run func(ctx context.Context, key string, values ...any) *redis.IntCmd) *MockRedisClient_HSet_Call { + _c.Call.Return(run) + return _c +} + +// Incr provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Incr(ctx context.Context, key string) *redis.IntCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for Incr") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_Incr_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Incr' +type MockRedisClient_Incr_Call struct { + *mock.Call +} + +// Incr is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) Incr(ctx, key any) *MockRedisClient_Incr_Call { + return &MockRedisClient_Incr_Call{Call: _e.mock.On("Incr", ctx, key)} +} + +func (_c *MockRedisClient_Incr_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_Incr_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_Incr_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_Incr_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_Incr_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.IntCmd) *MockRedisClient_Incr_Call { + _c.Call.Return(run) + return _c +} + +// LLen provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) LLen(ctx context.Context, key string) *redis.IntCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for LLen") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_LLen_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LLen' +type MockRedisClient_LLen_Call struct { + *mock.Call +} + +// LLen is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) LLen(ctx, key any) *MockRedisClient_LLen_Call { + return &MockRedisClient_LLen_Call{Call: _e.mock.On("LLen", ctx, key)} +} + +func (_c *MockRedisClient_LLen_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_LLen_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_LLen_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_LLen_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_LLen_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.IntCmd) *MockRedisClient_LLen_Call { + _c.Call.Return(run) + return _c +} + +// LPop provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) LPop(ctx context.Context, key string) *redis.StringCmd { + ret := _mock.Called(ctx, key) + + if len(ret) == 0 { + panic("no return value specified for LPop") + } + + var r0 *redis.StringCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *redis.StringCmd); ok { + r0 = returnFunc(ctx, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StringCmd) + } + } + return r0 +} + +// MockRedisClient_LPop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LPop' +type MockRedisClient_LPop_Call struct { + *mock.Call +} + +// LPop is a helper method to define mock.On call +// - ctx context.Context +// - key string +func (_e *MockRedisClient_Expecter) LPop(ctx, key any) *MockRedisClient_LPop_Call { + return &MockRedisClient_LPop_Call{Call: _e.mock.On("LPop", ctx, key)} +} + +func (_c *MockRedisClient_LPop_Call) Run(run func(ctx context.Context, key string)) *MockRedisClient_LPop_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRedisClient_LPop_Call) Return(stringCmd *redis.StringCmd) *MockRedisClient_LPop_Call { + _c.Call.Return(stringCmd) + return _c +} + +func (_c *MockRedisClient_LPop_Call) RunAndReturn(run func(ctx context.Context, key string) *redis.StringCmd) *MockRedisClient_LPop_Call { + _c.Call.Return(run) + return _c +} + +// Ping provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Ping(ctx context.Context) *redis.StatusCmd { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Ping") + } + + var r0 *redis.StatusCmd + if returnFunc, ok := ret.Get(0).(func(context.Context) *redis.StatusCmd); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StatusCmd) + } + } + return r0 +} + +// MockRedisClient_Ping_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Ping' +type MockRedisClient_Ping_Call struct { + *mock.Call +} + +// Ping is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockRedisClient_Expecter) Ping(ctx any) *MockRedisClient_Ping_Call { + return &MockRedisClient_Ping_Call{Call: _e.mock.On("Ping", ctx)} +} + +func (_c *MockRedisClient_Ping_Call) Run(run func(ctx context.Context)) *MockRedisClient_Ping_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockRedisClient_Ping_Call) Return(statusCmd *redis.StatusCmd) *MockRedisClient_Ping_Call { + _c.Call.Return(statusCmd) + return _c +} + +func (_c *MockRedisClient_Ping_Call) RunAndReturn(run func(ctx context.Context) *redis.StatusCmd) *MockRedisClient_Ping_Call { + _c.Call.Return(run) + return _c +} + +// RPush provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) RPush(ctx context.Context, key string, values ...any) *redis.IntCmd { + var tmpRet mock.Arguments + if len(values) > 0 { + tmpRet = _mock.Called(ctx, key, values) + } else { + tmpRet = _mock.Called(ctx, key) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for RPush") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, ...any) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key, values...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_RPush_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RPush' +type MockRedisClient_RPush_Call struct { + *mock.Call +} + +// RPush is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - values ...any +func (_e *MockRedisClient_Expecter) RPush(ctx, key any, values ...any) *MockRedisClient_RPush_Call { + return &MockRedisClient_RPush_Call{Call: _e.mock.On("RPush", + append([]any{ctx, key}, values...)...)} +} + +func (_c *MockRedisClient_RPush_Call) Run(run func(ctx context.Context, key string, values ...any)) *MockRedisClient_RPush_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []any + var variadicArgs []any + if len(args) > 2 { + variadicArgs = args[2].([]any) + } + arg2 = variadicArgs + run( + arg0, + arg1, + arg2..., + ) + }) + return _c +} + +func (_c *MockRedisClient_RPush_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_RPush_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_RPush_Call) RunAndReturn(run func(ctx context.Context, key string, values ...any) *redis.IntCmd) *MockRedisClient_RPush_Call { + _c.Call.Return(run) + return _c +} + +// SAdd provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) SAdd(ctx context.Context, key string, members ...any) *redis.IntCmd { + var tmpRet mock.Arguments + if len(members) > 0 { + tmpRet = _mock.Called(ctx, key, members) + } else { + tmpRet = _mock.Called(ctx, key) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for SAdd") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, ...any) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key, members...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_SAdd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SAdd' +type MockRedisClient_SAdd_Call struct { + *mock.Call +} + +// SAdd is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - members ...any +func (_e *MockRedisClient_Expecter) SAdd(ctx, key any, members ...any) *MockRedisClient_SAdd_Call { + return &MockRedisClient_SAdd_Call{Call: _e.mock.On("SAdd", + append([]any{ctx, key}, members...)...)} +} + +func (_c *MockRedisClient_SAdd_Call) Run(run func(ctx context.Context, key string, members ...any)) *MockRedisClient_SAdd_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []any + var variadicArgs []any + if len(args) > 2 { + variadicArgs = args[2].([]any) + } + arg2 = variadicArgs + run( + arg0, + arg1, + arg2..., + ) + }) + return _c +} + +func (_c *MockRedisClient_SAdd_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_SAdd_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_SAdd_Call) RunAndReturn(run func(ctx context.Context, key string, members ...any) *redis.IntCmd) *MockRedisClient_SAdd_Call { + _c.Call.Return(run) + return _c +} + +// SIsMember provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) SIsMember(ctx context.Context, key string, member any) *redis.BoolCmd { + ret := _mock.Called(ctx, key, member) + + if len(ret) == 0 { + panic("no return value specified for SIsMember") + } + + var r0 *redis.BoolCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, any) *redis.BoolCmd); ok { + r0 = returnFunc(ctx, key, member) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.BoolCmd) + } + } + return r0 +} + +// MockRedisClient_SIsMember_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SIsMember' +type MockRedisClient_SIsMember_Call struct { + *mock.Call +} + +// SIsMember is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - member any +func (_e *MockRedisClient_Expecter) SIsMember(ctx, key, member any) *MockRedisClient_SIsMember_Call { + return &MockRedisClient_SIsMember_Call{Call: _e.mock.On("SIsMember", ctx, key, member)} +} + +func (_c *MockRedisClient_SIsMember_Call) Run(run func(ctx context.Context, key string, member any)) *MockRedisClient_SIsMember_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 any + if args[2] != nil { + arg2 = args[2].(any) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockRedisClient_SIsMember_Call) Return(boolCmd *redis.BoolCmd) *MockRedisClient_SIsMember_Call { + _c.Call.Return(boolCmd) + return _c +} + +func (_c *MockRedisClient_SIsMember_Call) RunAndReturn(run func(ctx context.Context, key string, member any) *redis.BoolCmd) *MockRedisClient_SIsMember_Call { + _c.Call.Return(run) + return _c +} + +// SRem provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) SRem(ctx context.Context, key string, members ...any) *redis.IntCmd { + var tmpRet mock.Arguments + if len(members) > 0 { + tmpRet = _mock.Called(ctx, key, members) + } else { + tmpRet = _mock.Called(ctx, key) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for SRem") + } + + var r0 *redis.IntCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, ...any) *redis.IntCmd); ok { + r0 = returnFunc(ctx, key, members...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.IntCmd) + } + } + return r0 +} + +// MockRedisClient_SRem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SRem' +type MockRedisClient_SRem_Call struct { + *mock.Call +} + +// SRem is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - members ...any +func (_e *MockRedisClient_Expecter) SRem(ctx, key any, members ...any) *MockRedisClient_SRem_Call { + return &MockRedisClient_SRem_Call{Call: _e.mock.On("SRem", + append([]any{ctx, key}, members...)...)} +} + +func (_c *MockRedisClient_SRem_Call) Run(run func(ctx context.Context, key string, members ...any)) *MockRedisClient_SRem_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []any + var variadicArgs []any + if len(args) > 2 { + variadicArgs = args[2].([]any) + } + arg2 = variadicArgs + run( + arg0, + arg1, + arg2..., + ) + }) + return _c +} + +func (_c *MockRedisClient_SRem_Call) Return(intCmd *redis.IntCmd) *MockRedisClient_SRem_Call { + _c.Call.Return(intCmd) + return _c +} + +func (_c *MockRedisClient_SRem_Call) RunAndReturn(run func(ctx context.Context, key string, members ...any) *redis.IntCmd) *MockRedisClient_SRem_Call { + _c.Call.Return(run) + return _c +} + +// Set provides a mock function for the type MockRedisClient +func (_mock *MockRedisClient) Set(ctx context.Context, key string, value any, expiration time.Duration) *redis.StatusCmd { + ret := _mock.Called(ctx, key, value, expiration) + + if len(ret) == 0 { + panic("no return value specified for Set") + } + + var r0 *redis.StatusCmd + if returnFunc, ok := ret.Get(0).(func(context.Context, string, any, time.Duration) *redis.StatusCmd); ok { + r0 = returnFunc(ctx, key, value, expiration) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*redis.StatusCmd) + } + } + return r0 +} + +// MockRedisClient_Set_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Set' +type MockRedisClient_Set_Call struct { + *mock.Call +} + +// Set is a helper method to define mock.On call +// - ctx context.Context +// - key string +// - value any +// - expiration time.Duration +func (_e *MockRedisClient_Expecter) Set(ctx, key, value, expiration any) *MockRedisClient_Set_Call { + return &MockRedisClient_Set_Call{Call: _e.mock.On("Set", ctx, key, value, expiration)} +} + +func (_c *MockRedisClient_Set_Call) Run(run func(ctx context.Context, key string, value any, expiration time.Duration)) *MockRedisClient_Set_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 any + if args[2] != nil { + arg2 = args[2].(any) + } + var arg3 time.Duration + if args[3] != nil { + arg3 = args[3].(time.Duration) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *MockRedisClient_Set_Call) Return(statusCmd *redis.StatusCmd) *MockRedisClient_Set_Call { + _c.Call.Return(statusCmd) + return _c +} + +func (_c *MockRedisClient_Set_Call) RunAndReturn(run func(ctx context.Context, key string, value any, expiration time.Duration) *redis.StatusCmd) *MockRedisClient_Set_Call { + _c.Call.Return(run) + return _c +} diff --git a/modules/queue/base_redis_test.go b/modules/queue/base_redis_test.go index bf3ad5b97b..297a49229a 100644 --- a/modules/queue/base_redis_test.go +++ b/modules/queue/base_redis_test.go @@ -7,18 +7,17 @@ import ( "context" "testing" - "forgejo.org/modules/queue/mock" + "forgejo.org/modules/nosql" + queue_mock "forgejo.org/modules/queue/mock" "forgejo.org/modules/setting" "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" - "go.uber.org/mock/gomock" ) type baseRedisUnitTestSuite struct { suite.Suite - - mockController *gomock.Controller } func TestBaseRedis(t *testing.T) { @@ -26,7 +25,6 @@ func TestBaseRedis(t *testing.T) { } func (suite *baseRedisUnitTestSuite) SetupSuite() { - suite.mockController = gomock.NewController(suite.T()) } func (suite *baseRedisUnitTestSuite) TestBasic() { @@ -71,39 +69,47 @@ func (suite *baseRedisUnitTestSuite) TestBasic() { } // Configure expectations. - mockRedisStore := mock.NewInMemoryMockRedis() - redisClient := mock.NewMockRedisClient(suite.mockController) + mockRedisStore := queue_mock.NewInMemoryMockRedis() + redisClient := nosql.NewMockRedisClient(suite.T()) redisClient.EXPECT(). - Ping(gomock.Any()). - Times(1). - Return(&redis.StatusCmd{}) + Ping(mock.Anything). + Return(&redis.StatusCmd{}). + Times(1) redisClient.EXPECT(). - LLen(gomock.Any(), testCase.QueueName). - Times(1). - DoAndReturn(mockRedisStore.LLen) + LLen(mock.Anything, testCase.QueueName). + RunAndReturn(mockRedisStore.LLen). + Times(1) redisClient.EXPECT(). - LPop(gomock.Any(), testCase.QueueName). - Times(1). - DoAndReturn(mockRedisStore.LPop) + LPop(mock.Anything, testCase.QueueName). + RunAndReturn(mockRedisStore.LPop). + Times(1) redisClient.EXPECT(). - RPush(gomock.Any(), testCase.QueueName, gomock.Any()). - Times(1). - DoAndReturn(mockRedisStore.RPush) + RPush(mock.Anything, testCase.QueueName, mock.Anything). + RunAndReturn(func(ctx context.Context, key string, values ...any) *redis.IntCmd { + return mockRedisStore.RPush(ctx, key, values[0].([]byte)) + }). + Times(1) if testCase.Unique { redisClient.EXPECT(). - SAdd(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). - Times(1). - DoAndReturn(mockRedisStore.SAdd) + SAdd(mock.Anything, testCase.QueueName+"_unique", mock.Anything). + RunAndReturn(func(ctx context.Context, key string, members ...any) *redis.IntCmd { + return mockRedisStore.SAdd(ctx, key, members[0].([]byte)) + }). + Times(1) redisClient.EXPECT(). - SRem(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). - Times(1). - DoAndReturn(mockRedisStore.SRem) + SRem(mock.Anything, testCase.QueueName+"_unique", mock.Anything). + RunAndReturn(func(ctx context.Context, key string, members ...any) *redis.IntCmd { + return mockRedisStore.SRem(ctx, key, members[0].([]byte)) + }). + Times(1) redisClient.EXPECT(). - SIsMember(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). - Times(2). - DoAndReturn(mockRedisStore.SIsMember) + SIsMember(mock.Anything, testCase.QueueName+"_unique", mock.Anything). + RunAndReturn(func(ctx context.Context, key string, member any) *redis.BoolCmd { + return mockRedisStore.SIsMember(ctx, key, member.([]byte)) + }). + Times(2) } client, err := newBaseRedisGeneric( diff --git a/modules/queue/mock/redisuniversalclient.go b/modules/queue/mock/redisuniversalclient.go deleted file mode 100644 index a19e639ac1..0000000000 --- a/modules/queue/mock/redisuniversalclient.go +++ /dev/null @@ -1,344 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: forgejo.org/modules/nosql (interfaces: RedisClient) -// -// Generated by this command: -// -// mockgen -package mock -destination ./modules/queue/mock/redisuniversalclient.go forgejo.org/modules/nosql RedisClient -// - -// Package mock is a generated GoMock package. -package mock - -import ( - context "context" - reflect "reflect" - time "time" - - redis "github.com/redis/go-redis/v9" - gomock "go.uber.org/mock/gomock" -) - -// MockRedisClient is a mock of RedisClient interface. -type MockRedisClient struct { - ctrl *gomock.Controller - recorder *MockRedisClientMockRecorder - isgomock struct{} -} - -// MockRedisClientMockRecorder is the mock recorder for MockRedisClient. -type MockRedisClientMockRecorder struct { - mock *MockRedisClient -} - -// NewMockRedisClient creates a new mock instance. -func NewMockRedisClient(ctrl *gomock.Controller) *MockRedisClient { - mock := &MockRedisClient{ctrl: ctrl} - mock.recorder = &MockRedisClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockRedisClient) EXPECT() *MockRedisClientMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockRedisClient) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockRedisClientMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockRedisClient)(nil).Close)) -} - -// DBSize mocks base method. -func (m *MockRedisClient) DBSize(ctx context.Context) *redis.IntCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DBSize", ctx) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// DBSize indicates an expected call of DBSize. -func (mr *MockRedisClientMockRecorder) DBSize(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DBSize", reflect.TypeOf((*MockRedisClient)(nil).DBSize), ctx) -} - -// Decr mocks base method. -func (m *MockRedisClient) Decr(ctx context.Context, key string) *redis.IntCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Decr", ctx, key) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// Decr indicates an expected call of Decr. -func (mr *MockRedisClientMockRecorder) Decr(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decr", reflect.TypeOf((*MockRedisClient)(nil).Decr), ctx, key) -} - -// Del mocks base method. -func (m *MockRedisClient) Del(ctx context.Context, keys ...string) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx} - for _, a := range keys { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Del", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// Del indicates an expected call of Del. -func (mr *MockRedisClientMockRecorder) Del(ctx any, keys ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx}, keys...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Del", reflect.TypeOf((*MockRedisClient)(nil).Del), varargs...) -} - -// Exists mocks base method. -func (m *MockRedisClient) Exists(ctx context.Context, keys ...string) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx} - for _, a := range keys { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Exists", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// Exists indicates an expected call of Exists. -func (mr *MockRedisClientMockRecorder) Exists(ctx any, keys ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx}, keys...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockRedisClient)(nil).Exists), varargs...) -} - -// FlushDB mocks base method. -func (m *MockRedisClient) FlushDB(ctx context.Context) *redis.StatusCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlushDB", ctx) - ret0, _ := ret[0].(*redis.StatusCmd) - return ret0 -} - -// FlushDB indicates an expected call of FlushDB. -func (mr *MockRedisClientMockRecorder) FlushDB(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlushDB", reflect.TypeOf((*MockRedisClient)(nil).FlushDB), ctx) -} - -// Get mocks base method. -func (m *MockRedisClient) Get(ctx context.Context, key string) *redis.StringCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ctx, key) - ret0, _ := ret[0].(*redis.StringCmd) - return ret0 -} - -// Get indicates an expected call of Get. -func (mr *MockRedisClientMockRecorder) Get(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRedisClient)(nil).Get), ctx, key) -} - -// HDel mocks base method. -func (m *MockRedisClient) HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx, key} - for _, a := range fields { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "HDel", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// HDel indicates an expected call of HDel. -func (mr *MockRedisClientMockRecorder) HDel(ctx, key any, fields ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, key}, fields...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HDel", reflect.TypeOf((*MockRedisClient)(nil).HDel), varargs...) -} - -// HKeys mocks base method. -func (m *MockRedisClient) HKeys(ctx context.Context, key string) *redis.StringSliceCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HKeys", ctx, key) - ret0, _ := ret[0].(*redis.StringSliceCmd) - return ret0 -} - -// HKeys indicates an expected call of HKeys. -func (mr *MockRedisClientMockRecorder) HKeys(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HKeys", reflect.TypeOf((*MockRedisClient)(nil).HKeys), ctx, key) -} - -// HSet mocks base method. -func (m *MockRedisClient) HSet(ctx context.Context, key string, values ...any) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx, key} - for _, a := range values { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "HSet", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// HSet indicates an expected call of HSet. -func (mr *MockRedisClientMockRecorder) HSet(ctx, key any, values ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, key}, values...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HSet", reflect.TypeOf((*MockRedisClient)(nil).HSet), varargs...) -} - -// Incr mocks base method. -func (m *MockRedisClient) Incr(ctx context.Context, key string) *redis.IntCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Incr", ctx, key) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// Incr indicates an expected call of Incr. -func (mr *MockRedisClientMockRecorder) Incr(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Incr", reflect.TypeOf((*MockRedisClient)(nil).Incr), ctx, key) -} - -// LLen mocks base method. -func (m *MockRedisClient) LLen(ctx context.Context, key string) *redis.IntCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LLen", ctx, key) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// LLen indicates an expected call of LLen. -func (mr *MockRedisClientMockRecorder) LLen(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LLen", reflect.TypeOf((*MockRedisClient)(nil).LLen), ctx, key) -} - -// LPop mocks base method. -func (m *MockRedisClient) LPop(ctx context.Context, key string) *redis.StringCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LPop", ctx, key) - ret0, _ := ret[0].(*redis.StringCmd) - return ret0 -} - -// LPop indicates an expected call of LPop. -func (mr *MockRedisClientMockRecorder) LPop(ctx, key any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LPop", reflect.TypeOf((*MockRedisClient)(nil).LPop), ctx, key) -} - -// Ping mocks base method. -func (m *MockRedisClient) Ping(ctx context.Context) *redis.StatusCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Ping", ctx) - ret0, _ := ret[0].(*redis.StatusCmd) - return ret0 -} - -// Ping indicates an expected call of Ping. -func (mr *MockRedisClientMockRecorder) Ping(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockRedisClient)(nil).Ping), ctx) -} - -// RPush mocks base method. -func (m *MockRedisClient) RPush(ctx context.Context, key string, values ...any) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx, key} - for _, a := range values { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "RPush", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// RPush indicates an expected call of RPush. -func (mr *MockRedisClientMockRecorder) RPush(ctx, key any, values ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, key}, values...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RPush", reflect.TypeOf((*MockRedisClient)(nil).RPush), varargs...) -} - -// SAdd mocks base method. -func (m *MockRedisClient) SAdd(ctx context.Context, key string, members ...any) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx, key} - for _, a := range members { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "SAdd", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// SAdd indicates an expected call of SAdd. -func (mr *MockRedisClientMockRecorder) SAdd(ctx, key any, members ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, key}, members...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SAdd", reflect.TypeOf((*MockRedisClient)(nil).SAdd), varargs...) -} - -// SIsMember mocks base method. -func (m *MockRedisClient) SIsMember(ctx context.Context, key string, member any) *redis.BoolCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SIsMember", ctx, key, member) - ret0, _ := ret[0].(*redis.BoolCmd) - return ret0 -} - -// SIsMember indicates an expected call of SIsMember. -func (mr *MockRedisClientMockRecorder) SIsMember(ctx, key, member any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SIsMember", reflect.TypeOf((*MockRedisClient)(nil).SIsMember), ctx, key, member) -} - -// SRem mocks base method. -func (m *MockRedisClient) SRem(ctx context.Context, key string, members ...any) *redis.IntCmd { - m.ctrl.T.Helper() - varargs := []any{ctx, key} - for _, a := range members { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "SRem", varargs...) - ret0, _ := ret[0].(*redis.IntCmd) - return ret0 -} - -// SRem indicates an expected call of SRem. -func (mr *MockRedisClientMockRecorder) SRem(ctx, key any, members ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{ctx, key}, members...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SRem", reflect.TypeOf((*MockRedisClient)(nil).SRem), varargs...) -} - -// Set mocks base method. -func (m *MockRedisClient) Set(ctx context.Context, key string, value any, expiration time.Duration) *redis.StatusCmd { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Set", ctx, key, value, expiration) - ret0, _ := ret[0].(*redis.StatusCmd) - return ret0 -} - -// Set indicates an expected call of Set. -func (mr *MockRedisClientMockRecorder) Set(ctx, key, value, expiration any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockRedisClient)(nil).Set), ctx, key, value, expiration) -} diff --git a/modules/setting/authorized_integration.go b/modules/setting/authorized_integration.go index 778232e3ad..0a84f44afe 100644 --- a/modules/setting/authorized_integration.go +++ b/modules/setting/authorized_integration.go @@ -10,6 +10,7 @@ var AuthorizedIntegration = struct { BlockedDomains string AllowLocalNetworks bool RequestTimeout time.Duration + CacheTTL time.Duration }{} func loadAuthorizedIntegrationFrom(rootCfg ConfigProvider) { @@ -18,4 +19,5 @@ func loadAuthorizedIntegrationFrom(rootCfg ConfigProvider) { AuthorizedIntegration.BlockedDomains = sec.Key("BLOCKED_DOMAINS").MustString("") AuthorizedIntegration.AllowLocalNetworks = sec.Key("ALLOW_LOCALNETWORKS").MustBool(false) AuthorizedIntegration.RequestTimeout = sec.Key("REQUEST_TIMEOUT").MustDuration(10 * time.Second) + AuthorizedIntegration.CacheTTL = sec.Key("CACHE_TTL").MustDuration(10 * time.Minute) } diff --git a/services/auth/method/authorized_integration.go b/services/auth/method/authorized_integration.go index 000383d8c5..f908780e09 100644 --- a/services/auth/method/authorized_integration.go +++ b/services/auth/method/authorized_integration.go @@ -4,6 +4,8 @@ package method import ( + "bufio" + "bytes" "errors" "fmt" "io" @@ -15,6 +17,7 @@ import ( auth_model "forgejo.org/models/auth" user_model "forgejo.org/models/user" + "forgejo.org/modules/cache" "forgejo.org/modules/hostmatcher" "forgejo.org/modules/json" "forgejo.org/modules/jwtx" @@ -42,6 +45,7 @@ var ( initHTTPClient.Do(initAuthorizedIntegrationHTTPClient) return aiHTTPClient } + getCache = cache.GetCache ) // Restrict document size to prevent resource exhaustion attack with a malicious authorized integration; largest @@ -126,8 +130,7 @@ func (a *AuthorizedIntegration) Verify(req *http.Request, w http.ResponseWriter, issuerOIDCURL := issuerURL.JoinPath(".well-known/openid-configuration") var oidcConfig openIDConfiguration - // TODO: cache external OIDC configuration, with a fixed timeout (not LRU/MRU) - if err := a.fetchJSON(issuerOIDCURL.String(), &oidcConfig); err != nil { + if err := authorizedIntegrationFetchJSON(issuerOIDCURL.String(), &oidcConfig); err != nil { return nil, fmt.Errorf("error when fetching .well-known/openid-configuration from %s: %w", issuerOIDCURL, err) } @@ -149,8 +152,7 @@ func (a *AuthorizedIntegration) Verify(req *http.Request, w http.ResponseWriter, return nil, fmt.Errorf("jwks_uri host mismatch: must be the same as issuer host %q, but was %q", issuerURL.Host, jwksURI.Host) } var keys openIDKeys - // TODO: cache JWKS, with a fixed timeout (not LRU/MRU) - if err := a.fetchJSON(oidcConfig.JwksURI, &keys); err != nil { + if err := authorizedIntegrationFetchJSON(oidcConfig.JwksURI, &keys); err != nil { return nil, fmt.Errorf("error when fetching JWKS from %s: %w", oidcConfig.JwksURI, err) } @@ -247,7 +249,56 @@ func initAuthorizedIntegrationHTTPClient() { } } -func (a *AuthorizedIntegration) fetchJSON(urlString string, v any) error { +func authorizedIntegrationCacheKey(urlString string) string { + return fmt.Sprintf("auth-int-remote:%s", urlString) +} + +func authorizedIntegrationCacheGetJSON[K any](urlString string, v *K) bool { + conn := getCache() + if conn == nil { + return false + } + + cachedAny := conn.Get(authorizedIntegrationCacheKey(urlString)) + if cachedAny == nil { + return false + } + cachedBytes, ok := cachedAny.([]byte) + if !ok { + cachedString, ok := cachedAny.(string) + if !ok { + log.Error("cached content was not []byte or string, but was %T", cachedAny) + return false + } + cachedBytes = []byte(cachedString) + } + + err := json.Unmarshal(cachedBytes, &v) + if err != nil { + // This error case shouldn't occur, as we only store data in the cache once we're sure we could unmarshal it. + // If it does occur, log and fallback to treating as uncached. + log.Error("failed to Unmarshal cached content: %s", err) + // Caller may reuse `v` in a future unmarshal/decode call, and failure here may have polluted it. + var zeroValue K + *v = zeroValue + return false + } + + return true +} + +func authorizedIntegrationCacheSetJSON(urlString string, buf []byte) { + conn := getCache() + if conn == nil { + return + } + err := conn.Put(authorizedIntegrationCacheKey(urlString), buf, int64(setting.AuthorizedIntegration.CacheTTL.Seconds())) + if err != nil { + log.Error("failed to put cache: %s", err) + } +} + +func authorizedIntegrationFetchJSON[K any](urlString string, v *K) error { parsedURL, err := url.Parse(urlString) if err != nil { return fmt.Errorf("failed parsing URL %q: %w", urlString, err) @@ -259,6 +310,11 @@ func (a *AuthorizedIntegration) fetchJSON(urlString string, v any) error { return fmt.Errorf("unsupported URL scheme: %q", parsedURL.String()) } + // Check our cache, save a remote HTTP interaction. + if authorizedIntegrationCacheGetJSON(urlString, v) { + return nil + } + resp, err := GetAuthorizedIntegrationHTTPClient().Get(parsedURL.String()) if err != nil { return err @@ -269,15 +325,24 @@ func (a *AuthorizedIntegration) fetchJSON(urlString string, v any) error { return fmt.Errorf("non-OK response code: %s", resp.Status) } - body := io.LimitReader(resp.Body, authorizedIntegrationRequestBodyLimit) - decoder := json.NewDecoder(body) - err = decoder.Decode(&v) + bodyReader := io.LimitReader(resp.Body, authorizedIntegrationRequestBodyLimit) + var buf bytes.Buffer + _, err = io.Copy(bufio.NewWriter(&buf), bodyReader) + if err != nil { + return fmt.Errorf("read from remote error: %w", err) + } + + err = json.Unmarshal(buf.Bytes(), &v) if err != nil { // If a decoding error is hit, decorate with information about the limited body size so that it doesn't look // like the remote server provided an incomplete response. err should be something like `io.UnexpectedEOF` in // this case, but it actually isn't, so don't bother trying to detect precisely. return fmt.Errorf("failed to decode (response body restricted to %d bytes): %w", authorizedIntegrationRequestBodyLimit, err) } + + // Successfully decoded the response -- cache the raw bytes for later access. + authorizedIntegrationCacheSetJSON(urlString, buf.Bytes()) + return nil } diff --git a/services/auth/method/authorized_integration_test.go b/services/auth/method/authorized_integration_test.go index f2afbd3896..28524b7a6c 100644 --- a/services/auth/method/authorized_integration_test.go +++ b/services/auth/method/authorized_integration_test.go @@ -14,14 +14,18 @@ import ( auth_model "forgejo.org/models/auth" "forgejo.org/models/db" + "forgejo.org/modules/cache" "forgejo.org/modules/json" "forgejo.org/modules/jwtx" + "forgejo.org/modules/setting" "forgejo.org/modules/test" "forgejo.org/services/auth" + mc "code.forgejo.org/go-chi/cache" "github.com/golang-jwt/jwt/v5" gouuid "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -557,6 +561,102 @@ func TestAuthorizedIntegration(t *testing.T) { require.NoError(t, err) assert.False(t, writeAdmin, "write:admin") }) + + t.Run("cache", func(t *testing.T) { + t.Run("miss and store", func(t *testing.T) { + c := cache.NewMockCache(t) + defer test.MockVariableValue(&getCache, func() mc.Cache { return c })() + defer test.MockVariableValue(&setting.AuthorizedIntegration.CacheTTL, 10*time.Minute)() + + var cacheKey string + c.On("Get", mock.AnythingOfType("string")). + Run(func(args mock.Arguments) { + key := args.Get(0).(string) + assert.True(t, strings.HasPrefix(key, "auth-int-remote:https://"), "key %s should have key prefix", key) + cacheKey = key + }).Return(nil) + c.On("Put", mock.Anything, mock.Anything, mock.Anything). + Once(). + Run(func(args mock.Arguments) { + putKey := args.Get(0).(string) + assert.Equal(t, cacheKey, putKey) + putContents := args.Get(1).([]byte) + assert.Contains(t, string(putContents), "\"issuer\":") + assert.Contains(t, string(putContents), "\"jwks_uri\":") + assert.EqualValues(t, 600, args.Get(2)) + }).Return(nil) + c.On("Put", mock.Anything, mock.Anything, mock.Anything). + Once(). + Run(func(args mock.Arguments) { + putKey := args.Get(0).(string) + assert.Equal(t, cacheKey, putKey) + putContents := args.Get(1).([]byte) + assert.Contains(t, string(putContents), "\"alg\":\"RS256\"") + assert.Contains(t, string(putContents), "\"kty\":\"RSA\"") + assert.EqualValues(t, 600, args.Get(2)) + }).Return(nil) + + ait := newAITester(t) + defer ait.close() + output := ait.bearerRequest() + requireOutput[*auth.AuthenticationSuccess](t, output) + }) + + t.Run("hit", func(t *testing.T) { + var oidcMetadata []byte + var jwksData []byte + ait := newAITester(t, + openIDTweak(func(oi *openIDConfiguration, ait *AuthorizedIntegrationTester) { + var err error + oidcMetadata, err = json.Marshal(oi) + require.NoError(t, err) + }), + jwksTweak(func(oi *openIDKeys) { + var err error + jwksData, err = json.Marshal(oi) + require.NoError(t, err) + }), + ) + defer ait.close() + ait.bearerRequest() // populate oidcMetadata & jwksData by making a request + + t.Run("cache returns []byte", func(t *testing.T) { + c := cache.NewMockCache(t) + defer test.MockVariableValue(&getCache, func() mc.Cache { return c })() + + c.On("Get", + mock.MatchedBy(func(key string) bool { + return strings.Contains(key, ".well-known/openid-configuration") + })). + Return(oidcMetadata) + c.On("Get", + mock.MatchedBy(func(key string) bool { + return strings.Contains(key, ".keys") + })). + Return(jwksData) + + ait.bearerRequest() + }) + + t.Run("cache returns string", func(t *testing.T) { + c := cache.NewMockCache(t) + defer test.MockVariableValue(&getCache, func() mc.Cache { return c })() + + c.On("Get", + mock.MatchedBy(func(key string) bool { + return strings.Contains(key, ".well-known/openid-configuration") + })). + Return(string(oidcMetadata)) + c.On("Get", + mock.MatchedBy(func(key string) bool { + return strings.Contains(key, ".keys") + })). + Return(string(jwksData)) + + ait.bearerRequest() + }) + }) + }) } type AuthorizedIntegrationTester struct { diff --git a/services/authz/authorization_reducer.go b/services/authz/authorization_reducer.go index 7485f74f40..f2bc8d4f71 100644 --- a/services/authz/authorization_reducer.go +++ b/services/authz/authorization_reducer.go @@ -9,6 +9,8 @@ import ( // Defines an API for reducing available permissions to specific resources. Typically associated with a fine-grained // access tokens and provides methods to reduce authorization that the access token provides down to specific resources. +// +//mockery:generate: true type AuthorizationReducer interface { // Incorporate all the methods of [RepositoryAuthorizationReducer], which allows reducing permissions related to // repositories specifically. diff --git a/services/authz/authorization_reducer_mock.go b/services/authz/authorization_reducer_mock.go index 79562917c4..c31030b29a 100644 --- a/services/authz/authorization_reducer_mock.go +++ b/services/authz/authorization_reducer_mock.go @@ -1,86 +1,19 @@ -// Code generated by mockery v2.53.5. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify package authz import ( - context "context" + "context" "forgejo.org/models/perm" - repo_model "forgejo.org/models/repo" + "forgejo.org/models/repo" mock "github.com/stretchr/testify/mock" "xorm.io/builder" ) -// MockAuthorizationReducer is an autogenerated mock type for the AuthorizationReducer type -type MockAuthorizationReducer struct { - mock.Mock -} - -// AllowAdminOverride provides a mock function with no fields -func (_m *MockAuthorizationReducer) AllowAdminOverride() bool { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for AllowAdminOverride") - } - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// ReduceRepoAccess provides a mock function with given fields: ctx, repo, accessMode -func (_m *MockAuthorizationReducer) ReduceRepoAccess(ctx context.Context, repo *repo_model.Repository, accessMode perm.AccessMode) (perm.AccessMode, error) { - ret := _m.Called(ctx, repo, accessMode) - - if len(ret) == 0 { - panic("no return value specified for ReduceRepoAccess") - } - - var r0 perm.AccessMode - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *repo_model.Repository, perm.AccessMode) (perm.AccessMode, error)); ok { - return rf(ctx, repo, accessMode) - } - if rf, ok := ret.Get(0).(func(context.Context, *repo_model.Repository, perm.AccessMode) perm.AccessMode); ok { - r0 = rf(ctx, repo, accessMode) - } else { - r0 = ret.Get(0).(perm.AccessMode) - } - - if rf, ok := ret.Get(1).(func(context.Context, *repo_model.Repository, perm.AccessMode) error); ok { - r1 = rf(ctx, repo, accessMode) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RepoFilter provides a mock function with given fields: accessMode -func (_m *MockAuthorizationReducer) RepoReadAccessFilter() builder.Cond { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for AllowAdminOverride") - } - - var r0 builder.Cond - if rf, ok := ret.Get(0).(func() builder.Cond); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(builder.Cond) - } - - return r0 -} - // NewMockAuthorizationReducer creates a new instance of MockAuthorizationReducer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewMockAuthorizationReducer(t interface { @@ -95,3 +28,178 @@ func NewMockAuthorizationReducer(t interface { return mock } + +// MockAuthorizationReducer is an autogenerated mock type for the AuthorizationReducer type +type MockAuthorizationReducer struct { + mock.Mock +} + +type MockAuthorizationReducer_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAuthorizationReducer) EXPECT() *MockAuthorizationReducer_Expecter { + return &MockAuthorizationReducer_Expecter{mock: &_m.Mock} +} + +// AllowAdminOverride provides a mock function for the type MockAuthorizationReducer +func (_mock *MockAuthorizationReducer) AllowAdminOverride() bool { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for AllowAdminOverride") + } + + var r0 bool + if returnFunc, ok := ret.Get(0).(func() bool); ok { + r0 = returnFunc() + } else { + r0 = ret.Get(0).(bool) + } + return r0 +} + +// MockAuthorizationReducer_AllowAdminOverride_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AllowAdminOverride' +type MockAuthorizationReducer_AllowAdminOverride_Call struct { + *mock.Call +} + +// AllowAdminOverride is a helper method to define mock.On call +func (_e *MockAuthorizationReducer_Expecter) AllowAdminOverride() *MockAuthorizationReducer_AllowAdminOverride_Call { + return &MockAuthorizationReducer_AllowAdminOverride_Call{Call: _e.mock.On("AllowAdminOverride")} +} + +func (_c *MockAuthorizationReducer_AllowAdminOverride_Call) Run(run func()) *MockAuthorizationReducer_AllowAdminOverride_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAuthorizationReducer_AllowAdminOverride_Call) Return(b bool) *MockAuthorizationReducer_AllowAdminOverride_Call { + _c.Call.Return(b) + return _c +} + +func (_c *MockAuthorizationReducer_AllowAdminOverride_Call) RunAndReturn(run func() bool) *MockAuthorizationReducer_AllowAdminOverride_Call { + _c.Call.Return(run) + return _c +} + +// ReduceRepoAccess provides a mock function for the type MockAuthorizationReducer +func (_mock *MockAuthorizationReducer) ReduceRepoAccess(ctx context.Context, repo1 *repo.Repository, accessMode perm.AccessMode) (perm.AccessMode, error) { + ret := _mock.Called(ctx, repo1, accessMode) + + if len(ret) == 0 { + panic("no return value specified for ReduceRepoAccess") + } + + var r0 perm.AccessMode + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, *repo.Repository, perm.AccessMode) (perm.AccessMode, error)); ok { + return returnFunc(ctx, repo1, accessMode) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, *repo.Repository, perm.AccessMode) perm.AccessMode); ok { + r0 = returnFunc(ctx, repo1, accessMode) + } else { + r0 = ret.Get(0).(perm.AccessMode) + } + if returnFunc, ok := ret.Get(1).(func(context.Context, *repo.Repository, perm.AccessMode) error); ok { + r1 = returnFunc(ctx, repo1, accessMode) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockAuthorizationReducer_ReduceRepoAccess_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReduceRepoAccess' +type MockAuthorizationReducer_ReduceRepoAccess_Call struct { + *mock.Call +} + +// ReduceRepoAccess is a helper method to define mock.On call +// - ctx context.Context +// - repo1 *repo.Repository +// - accessMode perm.AccessMode +func (_e *MockAuthorizationReducer_Expecter) ReduceRepoAccess(ctx, repo1, accessMode any) *MockAuthorizationReducer_ReduceRepoAccess_Call { + return &MockAuthorizationReducer_ReduceRepoAccess_Call{Call: _e.mock.On("ReduceRepoAccess", ctx, repo1, accessMode)} +} + +func (_c *MockAuthorizationReducer_ReduceRepoAccess_Call) Run(run func(ctx context.Context, repo1 *repo.Repository, accessMode perm.AccessMode)) *MockAuthorizationReducer_ReduceRepoAccess_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 *repo.Repository + if args[1] != nil { + arg1 = args[1].(*repo.Repository) + } + var arg2 perm.AccessMode + if args[2] != nil { + arg2 = args[2].(perm.AccessMode) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockAuthorizationReducer_ReduceRepoAccess_Call) Return(accessMode1 perm.AccessMode, err error) *MockAuthorizationReducer_ReduceRepoAccess_Call { + _c.Call.Return(accessMode1, err) + return _c +} + +func (_c *MockAuthorizationReducer_ReduceRepoAccess_Call) RunAndReturn(run func(ctx context.Context, repo1 *repo.Repository, accessMode perm.AccessMode) (perm.AccessMode, error)) *MockAuthorizationReducer_ReduceRepoAccess_Call { + _c.Call.Return(run) + return _c +} + +// RepoReadAccessFilter provides a mock function for the type MockAuthorizationReducer +func (_mock *MockAuthorizationReducer) RepoReadAccessFilter() builder.Cond { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for RepoReadAccessFilter") + } + + var r0 builder.Cond + if returnFunc, ok := ret.Get(0).(func() builder.Cond); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(builder.Cond) + } + } + return r0 +} + +// MockAuthorizationReducer_RepoReadAccessFilter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RepoReadAccessFilter' +type MockAuthorizationReducer_RepoReadAccessFilter_Call struct { + *mock.Call +} + +// RepoReadAccessFilter is a helper method to define mock.On call +func (_e *MockAuthorizationReducer_Expecter) RepoReadAccessFilter() *MockAuthorizationReducer_RepoReadAccessFilter_Call { + return &MockAuthorizationReducer_RepoReadAccessFilter_Call{Call: _e.mock.On("RepoReadAccessFilter")} +} + +func (_c *MockAuthorizationReducer_RepoReadAccessFilter_Call) Run(run func()) *MockAuthorizationReducer_RepoReadAccessFilter_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAuthorizationReducer_RepoReadAccessFilter_Call) Return(cond builder.Cond) *MockAuthorizationReducer_RepoReadAccessFilter_Call { + _c.Call.Return(cond) + return _c +} + +func (_c *MockAuthorizationReducer_RepoReadAccessFilter_Call) RunAndReturn(run func() builder.Cond) *MockAuthorizationReducer_RepoReadAccessFilter_Call { + _c.Call.Return(run) + return _c +}