github.com/matrixorigin/matrixone@v1.2.0/pkg/bootstrap/service_test.go (about) 1 // Copyright 2023 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bootstrap 16 17 import ( 18 "context" 19 "sync" 20 "sync/atomic" 21 "testing" 22 "time" 23 24 "github.com/matrixorigin/matrixone/pkg/common/mpool" 25 "github.com/matrixorigin/matrixone/pkg/common/runtime" 26 "github.com/matrixorigin/matrixone/pkg/container/types" 27 "github.com/matrixorigin/matrixone/pkg/txn/clock" 28 "github.com/matrixorigin/matrixone/pkg/util/executor" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestBootstrapAlreadyBootstrapped(t *testing.T) { 34 runtime.SetupProcessLevelRuntime(runtime.DefaultRuntime()) 35 36 n := 0 37 exec := executor.NewMemExecutor(func(sql string) (executor.Result, error) { 38 if sql == "show databases" { 39 n++ 40 memRes := executor.NewMemResult( 41 []types.Type{types.New(types.T_varchar, 2, 0)}, 42 mpool.MustNewZero()) 43 memRes.NewBatch() 44 executor.AppendStringRows(memRes, 0, []string{bootstrappedCheckerDB}) 45 return memRes.GetResult(), nil 46 } 47 return executor.Result{}, nil 48 }) 49 50 b := NewService( 51 &memLocker{}, 52 clock.NewHLCClock(func() int64 { return 0 }, 0), 53 nil, 54 exec) 55 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 56 defer cancel() 57 58 require.NoError(t, b.Bootstrap(ctx)) 59 assert.Equal(t, 1, n) 60 } 61 62 func TestBootstrapWithWait(t *testing.T) { 63 runtime.SetupProcessLevelRuntime(runtime.DefaultRuntime()) 64 65 var n atomic.Uint32 66 exec := executor.NewMemExecutor(func(sql string) (executor.Result, error) { 67 if sql == "show databases" && n.Load() == 1 { 68 memRes := executor.NewMemResult( 69 []types.Type{types.New(types.T_varchar, 2, 0)}, 70 mpool.MustNewZero()) 71 memRes.NewBatch() 72 executor.AppendStringRows(memRes, 0, []string{bootstrappedCheckerDB}) 73 return memRes.GetResult(), nil 74 } 75 n.Add(1) 76 return executor.Result{}, nil 77 }) 78 79 b := NewService( 80 &memLocker{ids: map[string]uint64{ 81 bootstrapKey: 1, 82 }}, 83 clock.NewHLCClock(func() int64 { return 0 }, 0), 84 nil, 85 exec) 86 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 87 defer cancel() 88 89 require.NoError(t, b.Bootstrap(ctx)) 90 assert.True(t, n.Load() > 0) 91 } 92 93 type memLocker struct { 94 sync.Mutex 95 ids map[string]uint64 96 } 97 98 func (l *memLocker) Get( 99 ctx context.Context, 100 key string) (bool, error) { 101 l.Lock() 102 defer l.Unlock() 103 if l.ids == nil { 104 l.ids = make(map[string]uint64) 105 } 106 107 l.ids[key]++ 108 return l.ids[key] == 1, nil 109 }