diff --git a/pkg/varlogtest/config.go b/pkg/varlogtest/config.go new file mode 100644 index 000000000..32a3b3d17 --- /dev/null +++ b/pkg/varlogtest/config.go @@ -0,0 +1,61 @@ +package varlogtest + +import ( + "fmt" + + "github.com/kakao/varlog/pkg/types" +) + +type config struct { + clusterID types.ClusterID + replicationFactor int +} + +func newConfig(opts []Option) (config, error) { + cfg := config{} + for _, opt := range opts { + opt.apply(&cfg) + } + if err := cfg.validate(); err != nil { + return config{}, err + } + return cfg, nil +} + +func (cfg *config) validate() error { + if cfg.clusterID.Invalid() { + return fmt.Errorf("invalid cluster id %d", cfg.clusterID) + } + if cfg.replicationFactor < 1 { + return fmt.Errorf("invalid replication factor %d", cfg.replicationFactor) + } + return nil +} + +type Option interface { + apply(*config) +} + +type funcOption struct { + f func(*config) +} + +func newFuncOption(f func(*config)) *funcOption { + return &funcOption{f: f} +} + +func (fo *funcOption) apply(cfg *config) { + fo.f(cfg) +} + +func WithClusterID(cid types.ClusterID) Option { + return newFuncOption(func(cfg *config) { + cfg.clusterID = cid + }) +} + +func WithReplicationFactor(repfactor int) Option { + return newFuncOption(func(cfg *config) { + cfg.replicationFactor = repfactor + }) +} diff --git a/pkg/varlogtest/varlogtest.go b/pkg/varlogtest/varlogtest.go index ff26363f3..f9be967eb 100644 --- a/pkg/varlogtest/varlogtest.go +++ b/pkg/varlogtest/varlogtest.go @@ -15,12 +15,11 @@ import ( ) type VarlogTest struct { + config + admin *testAdmin vlg *testLog - clusterID types.ClusterID - replicationFactor int - rng *rand.Rand mu sync.Mutex @@ -41,22 +40,26 @@ type VarlogTest struct { varlogClientClosed bool } -func New(clusterID types.ClusterID, replicationFactor int) *VarlogTest { +func New(opts ...Option) (*VarlogTest, error) { + cfg, err := newConfig(opts) + if err != nil { + return nil, err + } + vt := &VarlogTest{ - clusterID: clusterID, - replicationFactor: replicationFactor, - rng: rand.New(rand.NewSource(time.Now().UnixMilli())), - storageNodes: make(map[types.StorageNodeID]snpb.StorageNodeMetadataDescriptor), - logStreams: make(map[types.LogStreamID]varlogpb.LogStreamDescriptor), - topics: make(map[types.TopicID]varlogpb.TopicDescriptor), - globalLogEntries: make(map[types.TopicID][]*varlogpb.LogEntry), - localLogEntries: make(map[types.LogStreamID][]*varlogpb.LogEntry), - trimGLSNs: make(map[types.TopicID]types.GLSN), + config: cfg, + rng: rand.New(rand.NewSource(time.Now().UnixMilli())), + storageNodes: make(map[types.StorageNodeID]snpb.StorageNodeMetadataDescriptor), + logStreams: make(map[types.LogStreamID]varlogpb.LogStreamDescriptor), + topics: make(map[types.TopicID]varlogpb.TopicDescriptor), + globalLogEntries: make(map[types.TopicID][]*varlogpb.LogEntry), + localLogEntries: make(map[types.LogStreamID][]*varlogpb.LogEntry), + trimGLSNs: make(map[types.TopicID]types.GLSN), } vt.cond = sync.NewCond(&vt.mu) vt.admin = &testAdmin{vt: vt} vt.vlg = &testLog{vt: vt} - return vt + return vt, nil } func (vt *VarlogTest) Admin() varlog.Admin { diff --git a/pkg/varlogtest/varlogtest_test.go b/pkg/varlogtest/varlogtest_test.go index 7751fc915..52f6d58d0 100644 --- a/pkg/varlogtest/varlogtest_test.go +++ b/pkg/varlogtest/varlogtest_test.go @@ -108,7 +108,12 @@ func TestVarlotTest_LogStreamAppender(t *testing.T) { for _, tc := range tcs { tc := tc t.Run(tc.name, func(t *testing.T) { - vt := varlogtest.New(cid, replicationFactor) + vt, err := varlogtest.New( + varlogtest.WithClusterID(cid), + varlogtest.WithReplicationFactor(replicationFactor), + ) + require.NoError(t, err) + adm := vt.Admin() vlg := vt.Log() defer func() { @@ -164,7 +169,12 @@ func TestVarlogTest(t *testing.T) { rng := rand.New(rand.NewSource(time.Now().UnixMilli())) - vt := varlogtest.New(clusterID, replicationFactor) + vt, err := varlogtest.New( + varlogtest.WithClusterID(clusterID), + varlogtest.WithReplicationFactor(replicationFactor), + ) + require.NoError(t, err) + adm := vt.Admin() vlg := vt.Log() defer func() { @@ -181,7 +191,7 @@ func TestVarlogTest(t *testing.T) { ) // No topic 1 - _, err := adm.DescribeTopic(context.Background(), types.TopicID(1)) + _, err = adm.DescribeTopic(context.Background(), types.TopicID(1)) require.Error(t, err) // Add topics @@ -577,7 +587,12 @@ func TestVarlogTest_Trim(t *testing.T) { numLogs = 10 ) - vt := varlogtest.New(clusterID, replicationFactor) + vt, err := varlogtest.New( + varlogtest.WithClusterID(clusterID), + varlogtest.WithReplicationFactor(replicationFactor), + ) + require.NoError(t, err) + adm := vt.Admin() vlg := vt.Log() defer func() {