diff --git a/common/log/testlogger/testlogger.go b/common/log/testlogger/testlogger.go index 9fb009b78c3..fbde78e546e 100644 --- a/common/log/testlogger/testlogger.go +++ b/common/log/testlogger/testlogger.go @@ -23,9 +23,6 @@ package testlogger import ( - "testing" - - "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" "github.com/uber/cadence/common/log" @@ -34,11 +31,6 @@ import ( // New is a helper to create new development logger in unit test func New(t zaptest.TestingT) log.Logger { - if testing.Verbose() { - logger, err := loggerimpl.NewDevelopment() - require.NoError(t, err) - return logger - } - // test logger samples all logs + // test logger that emits all logs (none dropped / sample func never returns false) return loggerimpl.NewLogger(zaptest.NewLogger(t), loggerimpl.WithSampleFunc(func(int) bool { return true })) } diff --git a/common/persistence/client/factory.go b/common/persistence/client/factory.go index b4fa933f1b1..2cad29638f5 100644 --- a/common/persistence/client/factory.go +++ b/common/persistence/client/factory.go @@ -18,6 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:generate mockgen -package $GOPACKAGE -source $GOFILE -destination factory_mock.go + package client import ( diff --git a/common/persistence/client/factory_mock.go b/common/persistence/client/factory_mock.go new file mode 100644 index 00000000000..3e6bee36c9a --- /dev/null +++ b/common/persistence/client/factory_mock.go @@ -0,0 +1,346 @@ +// The MIT License (MIT) + +// Copyright (c) 2017-2020 Uber Technologies Inc. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// Code generated by MockGen. DO NOT EDIT. +// Source: factory.go + +// Package client is a generated GoMock package. +package client + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + + persistence "github.com/uber/cadence/common/persistence" + service "github.com/uber/cadence/common/service" +) + +// MockFactory is a mock of Factory interface. +type MockFactory struct { + ctrl *gomock.Controller + recorder *MockFactoryMockRecorder +} + +// MockFactoryMockRecorder is the mock recorder for MockFactory. +type MockFactoryMockRecorder struct { + mock *MockFactory +} + +// NewMockFactory creates a new mock instance. +func NewMockFactory(ctrl *gomock.Controller) *MockFactory { + mock := &MockFactory{ctrl: ctrl} + mock.recorder = &MockFactoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFactory) EXPECT() *MockFactoryMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockFactory) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockFactoryMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockFactory)(nil).Close)) +} + +// NewConfigStoreManager mocks base method. +func (m *MockFactory) NewConfigStoreManager() (persistence.ConfigStoreManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewConfigStoreManager") + ret0, _ := ret[0].(persistence.ConfigStoreManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewConfigStoreManager indicates an expected call of NewConfigStoreManager. +func (mr *MockFactoryMockRecorder) NewConfigStoreManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConfigStoreManager", reflect.TypeOf((*MockFactory)(nil).NewConfigStoreManager)) +} + +// NewDomainManager mocks base method. +func (m *MockFactory) NewDomainManager() (persistence.DomainManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewDomainManager") + ret0, _ := ret[0].(persistence.DomainManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewDomainManager indicates an expected call of NewDomainManager. +func (mr *MockFactoryMockRecorder) NewDomainManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDomainManager", reflect.TypeOf((*MockFactory)(nil).NewDomainManager)) +} + +// NewDomainReplicationQueueManager mocks base method. +func (m *MockFactory) NewDomainReplicationQueueManager() (persistence.QueueManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewDomainReplicationQueueManager") + ret0, _ := ret[0].(persistence.QueueManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewDomainReplicationQueueManager indicates an expected call of NewDomainReplicationQueueManager. +func (mr *MockFactoryMockRecorder) NewDomainReplicationQueueManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDomainReplicationQueueManager", reflect.TypeOf((*MockFactory)(nil).NewDomainReplicationQueueManager)) +} + +// NewExecutionManager mocks base method. +func (m *MockFactory) NewExecutionManager(shardID int) (persistence.ExecutionManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewExecutionManager", shardID) + ret0, _ := ret[0].(persistence.ExecutionManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewExecutionManager indicates an expected call of NewExecutionManager. +func (mr *MockFactoryMockRecorder) NewExecutionManager(shardID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewExecutionManager", reflect.TypeOf((*MockFactory)(nil).NewExecutionManager), shardID) +} + +// NewHistoryManager mocks base method. +func (m *MockFactory) NewHistoryManager() (persistence.HistoryManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewHistoryManager") + ret0, _ := ret[0].(persistence.HistoryManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewHistoryManager indicates an expected call of NewHistoryManager. +func (mr *MockFactoryMockRecorder) NewHistoryManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewHistoryManager", reflect.TypeOf((*MockFactory)(nil).NewHistoryManager)) +} + +// NewShardManager mocks base method. +func (m *MockFactory) NewShardManager() (persistence.ShardManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewShardManager") + ret0, _ := ret[0].(persistence.ShardManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewShardManager indicates an expected call of NewShardManager. +func (mr *MockFactoryMockRecorder) NewShardManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewShardManager", reflect.TypeOf((*MockFactory)(nil).NewShardManager)) +} + +// NewTaskManager mocks base method. +func (m *MockFactory) NewTaskManager() (persistence.TaskManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewTaskManager") + ret0, _ := ret[0].(persistence.TaskManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewTaskManager indicates an expected call of NewTaskManager. +func (mr *MockFactoryMockRecorder) NewTaskManager() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewTaskManager", reflect.TypeOf((*MockFactory)(nil).NewTaskManager)) +} + +// NewVisibilityManager mocks base method. +func (m *MockFactory) NewVisibilityManager(params *Params, serviceConfig *service.Config) (persistence.VisibilityManager, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewVisibilityManager", params, serviceConfig) + ret0, _ := ret[0].(persistence.VisibilityManager) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewVisibilityManager indicates an expected call of NewVisibilityManager. +func (mr *MockFactoryMockRecorder) NewVisibilityManager(params, serviceConfig interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewVisibilityManager", reflect.TypeOf((*MockFactory)(nil).NewVisibilityManager), params, serviceConfig) +} + +// MockDataStoreFactory is a mock of DataStoreFactory interface. +type MockDataStoreFactory struct { + ctrl *gomock.Controller + recorder *MockDataStoreFactoryMockRecorder +} + +// MockDataStoreFactoryMockRecorder is the mock recorder for MockDataStoreFactory. +type MockDataStoreFactoryMockRecorder struct { + mock *MockDataStoreFactory +} + +// NewMockDataStoreFactory creates a new mock instance. +func NewMockDataStoreFactory(ctrl *gomock.Controller) *MockDataStoreFactory { + mock := &MockDataStoreFactory{ctrl: ctrl} + mock.recorder = &MockDataStoreFactoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDataStoreFactory) EXPECT() *MockDataStoreFactoryMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockDataStoreFactory) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockDataStoreFactoryMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDataStoreFactory)(nil).Close)) +} + +// NewConfigStore mocks base method. +func (m *MockDataStoreFactory) NewConfigStore() (persistence.ConfigStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewConfigStore") + ret0, _ := ret[0].(persistence.ConfigStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewConfigStore indicates an expected call of NewConfigStore. +func (mr *MockDataStoreFactoryMockRecorder) NewConfigStore() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConfigStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewConfigStore)) +} + +// NewDomainStore mocks base method. +func (m *MockDataStoreFactory) NewDomainStore() (persistence.DomainStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewDomainStore") + ret0, _ := ret[0].(persistence.DomainStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewDomainStore indicates an expected call of NewDomainStore. +func (mr *MockDataStoreFactoryMockRecorder) NewDomainStore() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDomainStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewDomainStore)) +} + +// NewExecutionStore mocks base method. +func (m *MockDataStoreFactory) NewExecutionStore(shardID int) (persistence.ExecutionStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewExecutionStore", shardID) + ret0, _ := ret[0].(persistence.ExecutionStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewExecutionStore indicates an expected call of NewExecutionStore. +func (mr *MockDataStoreFactoryMockRecorder) NewExecutionStore(shardID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewExecutionStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewExecutionStore), shardID) +} + +// NewHistoryStore mocks base method. +func (m *MockDataStoreFactory) NewHistoryStore() (persistence.HistoryStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewHistoryStore") + ret0, _ := ret[0].(persistence.HistoryStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewHistoryStore indicates an expected call of NewHistoryStore. +func (mr *MockDataStoreFactoryMockRecorder) NewHistoryStore() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewHistoryStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewHistoryStore)) +} + +// NewQueue mocks base method. +func (m *MockDataStoreFactory) NewQueue(queueType persistence.QueueType) (persistence.Queue, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewQueue", queueType) + ret0, _ := ret[0].(persistence.Queue) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewQueue indicates an expected call of NewQueue. +func (mr *MockDataStoreFactoryMockRecorder) NewQueue(queueType interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewQueue", reflect.TypeOf((*MockDataStoreFactory)(nil).NewQueue), queueType) +} + +// NewShardStore mocks base method. +func (m *MockDataStoreFactory) NewShardStore() (persistence.ShardStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewShardStore") + ret0, _ := ret[0].(persistence.ShardStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewShardStore indicates an expected call of NewShardStore. +func (mr *MockDataStoreFactoryMockRecorder) NewShardStore() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewShardStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewShardStore)) +} + +// NewTaskStore mocks base method. +func (m *MockDataStoreFactory) NewTaskStore() (persistence.TaskStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewTaskStore") + ret0, _ := ret[0].(persistence.TaskStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewTaskStore indicates an expected call of NewTaskStore. +func (mr *MockDataStoreFactoryMockRecorder) NewTaskStore() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewTaskStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewTaskStore)) +} + +// NewVisibilityStore mocks base method. +func (m *MockDataStoreFactory) NewVisibilityStore(sortByCloseTime bool) (persistence.VisibilityStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewVisibilityStore", sortByCloseTime) + ret0, _ := ret[0].(persistence.VisibilityStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewVisibilityStore indicates an expected call of NewVisibilityStore. +func (mr *MockDataStoreFactoryMockRecorder) NewVisibilityStore(sortByCloseTime interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewVisibilityStore", reflect.TypeOf((*MockDataStoreFactory)(nil).NewVisibilityStore), sortByCloseTime) +} diff --git a/common/persistence/client/factory_test.go b/common/persistence/client/factory_test.go new file mode 100644 index 00000000000..c3112604c6d --- /dev/null +++ b/common/persistence/client/factory_test.go @@ -0,0 +1,222 @@ +// The MIT License (MIT) + +// Copyright (c) 2017-2020 Uber Technologies Inc. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package client + +import ( + "math/rand" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/uber-go/tally" + + "github.com/uber/cadence/common/config" + "github.com/uber/cadence/common/dynamicconfig" + "github.com/uber/cadence/common/log/testlogger" + "github.com/uber/cadence/common/metrics" + "github.com/uber/cadence/common/persistence" + "github.com/uber/cadence/common/service" +) + +/* +New...Manager methods are intentionally NOT tested here. + +They require importing a datastore plugin, which imports the persistence tests, +which imports this package, leading to a cycle. +They also generally try to connect to the target datastore *immediately* upon construction, +which means these would need to be integration tests... +...which we already have, in the persistence/persistence-tests package. +*/ + +func TestNew(t *testing.T) { + // largely a sanity test for makeFactory, but it does ensure it constructs and closes, + // though this does not actually achieve very much. + fact := makeFactory(t) + fact.Close() +} + +// check ensures the func returns a value and no error. +// most manager-constructors can use this, but not all. +func check[T interface{}](t *testing.T, fn func() (T, error)) { + val, err := fn() + assert.NoError(t, err, "manager-constructor method should not error") + assert.NotNil(t, val, "manager-constructor method should return a non-nil value") +} + +func TestFactoryMethods(t *testing.T) { + mockDatastore := func(t *testing.T, fact Factory, store storeType) *MockDataStoreFactory { + ctrl := gomock.NewController(t) + impl := fact.(*factoryImpl) + + // I would prefer to mock everything so calls to the wrong store could have better errors, + // but there doesn't seem to be a way to "name" these or say "any call fails with X message", + // nor can you check what calls occurred after the fact. + // + // so just mock the only thing expected, so you get a nil panic stack trace when it fails + // somewhere in a persistence database connection or something. it's sometimes easier to debug. + mock := NewMockDataStoreFactory(ctrl) + ds := impl.datastores[store] + ds.factory = mock + impl.datastores[store] = ds // write back the value type + + return mock + } + + t.Run("NewTaskManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeTask) + + ds.EXPECT().NewTaskStore().Return(nil, nil).MinTimes(1) + check(t, fact.NewTaskManager) + }) + t.Run("NewShardManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeShard) + + ds.EXPECT().NewShardStore().Return(nil, nil).MinTimes(1) + check(t, fact.NewShardManager) + }) + t.Run("NewHistoryManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeHistory) + + ds.EXPECT().NewHistoryStore().Return(nil, nil).MinTimes(1) + check(t, fact.NewHistoryManager) + }) + t.Run("NewDomainManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeMetadata) + + ds.EXPECT().NewDomainStore().Return(nil, nil).MinTimes(1) + check(t, fact.NewDomainManager) + }) + t.Run("NewExecutionManager", func(t *testing.T) { + // cannot control the persistence.NewExecutionManagerImpl call, so we must prevent calls to it. + // currently the only call is the metrics wrapper calling GetShardID(), so just don't use the metrics wrapper. + fact := makeFactoryWithMetrics(t, false) + ds := mockDatastore(t, fact, storeTypeExecution) + + shard := rand.Int() + ds.EXPECT().NewExecutionStore(shard).Return(nil, nil).MinTimes(1) + em, err := fact.NewExecutionManager(shard) + assert.NoError(t, err) + assert.NotNil(t, em) + }) + t.Run("NewVisibilityManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeVisibility) + + // true/false does not matter, but it should be passed through. + // true has been chosen because it's not a zero value, so it's a bit more likely to be + // the intended source of `true`. + readFromClosed := true + ds.EXPECT().NewVisibilityStore(readFromClosed).Return(nil, nil).MinTimes(1) + vm, err := fact.NewVisibilityManager(&Params{ + PersistenceConfig: config.Persistence{ + // a configured VisibilityStore uses the db store, which is mockable, + // unlike basically every other store. + VisibilityStore: "fake", + }, + }, &service.Config{ + // must be non-nil to create a "manager", else nil return from NewVisibilityManager is expected + EnableReadVisibilityFromES: func(domain string) bool { + return false // any value is fine as there are no read calls + }, + // non-nil avoids a warning log + EnableReadDBVisibilityFromClosedExecutionV2: func(opts ...dynamicconfig.FilterOption) bool { + return readFromClosed // any value is fine as there are no read calls + }, + }) + assert.NoError(t, err) + assert.NotNil(t, vm) + }) + t.Run("NewVisibilityManager can be nil", func(t *testing.T) { + fact := makeFactory(t) + // no datastores are mocked as there are no calls at all expected + vm, err := fact.NewVisibilityManager( + nil, // params are unused + &service.Config{ + // if both of these are nil, a nil response is correct, + // because no "manager" is needed: + // ES cannot be dynamically enabled, so no dual-writing / etc is + // needed, so the baseline database store is sufficient. + EnableReadVisibilityFromES: nil, + AdvancedVisibilityWritingMode: nil, + }) + assert.NoError(t, err) + assert.Nil(t, vm, "nil response is expected if advanced visibility cannot be enabled dynamically") + }) + t.Run("NewDomainReplicationQueueManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeQueue) + + ds.EXPECT().NewQueue(persistence.DomainReplicationQueueType).Return(nil, nil).MinTimes(1) + check(t, fact.NewDomainReplicationQueueManager) + }) + t.Run("NewConfigStoreManager", func(t *testing.T) { + fact := makeFactory(t) + ds := mockDatastore(t, fact, storeTypeConfigStore) + + ds.EXPECT().NewConfigStore().Return(nil, nil).MinTimes(1) + check(t, fact.NewConfigStoreManager) + }) +} + +func makeFactory(t *testing.T) Factory { + return makeFactoryWithMetrics(t, true) +} + +func makeFactoryWithMetrics(t *testing.T, withMetrics bool) Factory { + qpsFn := func() float64 { return 1000 } // anything non-zero exercises the ratelimit config paths + logger := testlogger.New(t) + var met metrics.Client + if withMetrics { + met = metrics.NewClient( + tally.NewTestScope("", nil), + service.GetMetricsServiceIdx(service.Frontend, logger), + ) + } + ctrl := gomock.NewController(t) + dc := dynamicconfig.NewCollection(dynamicconfig.NewMockClient(ctrl), logger) + pdc := persistence.NewDynamicConfiguration(dc) + + cfg := &config.Persistence{ + DefaultStore: "fake", + VisibilityStore: "fake", + AdvancedVisibilityStore: "fake", + NumHistoryShards: 1024, + DataStores: map[string]config.DataStore{ + "fake": { + NoSQL: &config.NoSQL{}, // fields are unused but must be non-nil + ElasticSearch: &config.ElasticSearchConfig{}, // fields are unused but must be non-nil + Pinot: &config.PinotVisibilityConfig{}, // fields are unused but must be non-nil + }, + }, + TransactionSizeLimit: nil, + ErrorInjectionRate: func(opts ...dynamicconfig.FilterOption) float64 { + return 0.5 // half errors, unused in these tests beyond "nonzero" so it wraps with the error injector + }, + } + + return NewFactory(cfg, qpsFn, "test cluster", met, logger, pdc) +}