github.com/cilium/cilium@v1.16.2/pkg/lock/sortable_mutex_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package lock 5 6 import ( 7 "math/rand/v2" 8 "slices" 9 "sync" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestSortableMutex(t *testing.T) { 17 smu1 := NewSortableMutex() 18 smu2 := NewSortableMutex() 19 require.Greater(t, smu2.Seq(), smu1.Seq()) 20 smu1.Lock() 21 smu2.Lock() 22 smu1.Unlock() 23 smu2.Unlock() 24 smus := SortableMutexes{smu1, smu2} 25 smus.Lock() 26 smus.Unlock() 27 smus.Lock() 28 smus.Unlock() 29 } 30 31 func TestSortableMutex_Chaos(t *testing.T) { 32 smus := SortableMutexes{ 33 NewSortableMutex(), 34 NewSortableMutex(), 35 NewSortableMutex(), 36 NewSortableMutex(), 37 NewSortableMutex(), 38 } 39 40 nMonkeys := 10 41 iterations := 100 42 var wg sync.WaitGroup 43 wg.Add(nMonkeys) 44 45 monkey := func() { 46 defer wg.Done() 47 for i := 0; i < iterations; i++ { 48 // Take a random subset of the sortable mutexes. 49 subSmus := slices.Clone(smus) 50 rand.Shuffle(len(subSmus), func(i, j int) { 51 subSmus[i], subSmus[j] = subSmus[j], subSmus[i] 52 }) 53 n := rand.IntN(len(subSmus)) 54 subSmus = subSmus[:n] 55 56 time.Sleep(time.Microsecond) 57 subSmus.Lock() 58 time.Sleep(time.Microsecond) 59 subSmus.Unlock() 60 time.Sleep(time.Microsecond) 61 } 62 } 63 64 for i := 0; i < nMonkeys; i++ { 65 go monkey() 66 } 67 68 wg.Wait() 69 }