github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/util/atomic_test.go (about) 1 // Copyright 2024 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 util 15 16 import ( 17 "context" 18 "math/rand" 19 "sync" 20 "sync/atomic" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestMustCompareAndIncrease(t *testing.T) { 27 t.Parallel() 28 29 var target atomic.Int64 30 target.Store(10) 31 32 ctx, cancel := context.WithCancel(context.Background()) 33 wg := sync.WaitGroup{} 34 35 doIncrease := func() { 36 for { 37 select { 38 case <-ctx.Done(): 39 return 40 default: 41 delta := rand.Int63n(100) 42 v := target.Load() + delta 43 MustCompareAndMonotonicIncrease(&target, v) 44 require.GreaterOrEqual(t, target.Load(), v) 45 } 46 } 47 } 48 49 // Test target increase. 50 wg.Add(2) 51 go func() { 52 defer wg.Done() 53 doIncrease() 54 }() 55 go func() { 56 defer wg.Done() 57 doIncrease() 58 }() 59 60 wg.Add(1) 61 // Test target never decrease. 62 go func() { 63 defer wg.Done() 64 for { 65 select { 66 case <-ctx.Done(): 67 return 68 default: 69 v := target.Load() - 1 70 MustCompareAndMonotonicIncrease(&target, v) 71 require.Greater(t, target.Load(), v) 72 } 73 } 74 }() 75 76 cancel() 77 wg.Wait() 78 } 79 80 func TestCompareAndIncrease(t *testing.T) { 81 t.Parallel() 82 83 var target atomic.Int64 84 target.Store(10) 85 require.True(t, CompareAndIncrease(&target, 10)) 86 require.Equal(t, int64(10), target.Load()) 87 88 require.True(t, CompareAndIncrease(&target, 20)) 89 require.Equal(t, int64(20), target.Load()) 90 require.False(t, CompareAndIncrease(&target, 19)) 91 require.Equal(t, int64(20), target.Load()) 92 } 93 94 func TestCompareAndMonotonicIncrease(t *testing.T) { 95 t.Parallel() 96 97 var target atomic.Int64 98 target.Store(10) 99 require.False(t, CompareAndMonotonicIncrease(&target, 10)) 100 require.Equal(t, int64(10), target.Load()) 101 102 require.True(t, CompareAndMonotonicIncrease(&target, 11)) 103 require.Equal(t, int64(11), target.Load()) 104 require.False(t, CompareAndMonotonicIncrease(&target, 10)) 105 require.Equal(t, int64(11), target.Load()) 106 }