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  }