github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/dm/ticker/ticker_test.go (about) 1 // Copyright 2022 PingCAP, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ticker 15 16 import ( 17 "context" 18 "sync" 19 "testing" 20 "time" 21 22 "github.com/pingcap/tiflow/pkg/errors" 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestDefaultTicker(t *testing.T) { 27 t.Parallel() 28 29 ctx, cancel := context.WithCancel(context.Background()) 30 defer cancel() 31 dummyTicker := NewDummyTicker() 32 var wg sync.WaitGroup 33 34 tickError := errors.New("tick error") 35 dummyTicker.SetResult([]error{tickError, tickError, nil}) 36 37 wg.Add(1) 38 // run task manager 39 go func() { 40 defer wg.Done() 41 t := time.NewTicker(50 * time.Millisecond) 42 for { 43 select { 44 case <-ctx.Done(): 45 return 46 case <-t.C: 47 dummyTicker.DoTick(ctx) 48 } 49 } 50 }() 51 52 // first tick when start 53 require.Eventually(t, dummyTicker.ResultAllMeet, 5*time.Second, 100*time.Millisecond) 54 55 // mock manual trigger a tick 56 dummyTicker.SetResult([]error{tickError, tickError, nil}) 57 dummyTicker.SetNextCheckTime(time.Now()) 58 require.Eventually(t, dummyTicker.ResultAllMeet, 5*time.Second, 100*time.Millisecond) 59 60 // mock trigger with delay 61 dummyTicker.SetResult([]error{nil}) 62 dummyTicker.SetNextCheckTime(time.Now().Add(time.Second)) 63 require.Eventually(t, dummyTicker.ResultAllMeet, 5*time.Second, 100*time.Millisecond) 64 65 cancel() 66 wg.Wait() 67 } 68 69 type DummyTicker struct { 70 *DefaultTicker 71 72 sync.Mutex 73 results []error 74 } 75 76 func NewDummyTicker() *DummyTicker { 77 dummyTicker := &DummyTicker{ 78 DefaultTicker: NewDefaultTicker(time.Hour, 100*time.Millisecond), 79 } 80 dummyTicker.DefaultTicker.Ticker = dummyTicker 81 return dummyTicker 82 } 83 84 func (t *DummyTicker) SetResult(results []error) { 85 t.Lock() 86 defer t.Unlock() 87 t.results = append(t.results, results...) 88 } 89 90 func (t *DummyTicker) TickImpl(ctx context.Context) error { 91 t.Lock() 92 defer t.Unlock() 93 if len(t.results) == 0 { 94 panic("no result in dummy scheduler") 95 } 96 result := t.results[0] 97 t.results = t.results[1:] 98 return result 99 } 100 101 func (t *DummyTicker) ResultAllMeet() bool { 102 t.Lock() 103 defer t.Unlock() 104 return len(t.results) == 0 105 }