github.com/msales/pkg/v3@v3.24.0/syncx/mutex_test.go (about)

     1  package syncx_test
     2  
     3  import (
     4  	"reflect"
     5  	"sync"
     6  	"testing"
     7  
     8  	"github.com/msales/pkg/v3/syncx"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestMutexLayout(t *testing.T) {
    13  	sf := reflect.TypeOf((*syncx.Mutex)(nil)).Elem().FieldByIndex([]int{0, 0})
    14  
    15  	if sf.Name != "state" {
    16  		assert.FailNow(t, "sync.Mutex first field should have name state")
    17  	}
    18  
    19  	if sf.Offset != uintptr(0) {
    20  		assert.FailNow(t, "sync.Mutex state field should have zero offset")
    21  	}
    22  
    23  	if sf.Type != reflect.TypeOf(int32(1)) {
    24  		assert.FailNow(t, "sync.Mutex state field type should be int32")
    25  	}
    26  }
    27  
    28  func TestMutex_ImplementsLocker(t *testing.T) {
    29  	var mu syncx.Mutex
    30  
    31  	assert.Implements(t, (*sync.Locker)(nil), &mu)
    32  }
    33  
    34  func TestMutex_TryLock(t *testing.T) {
    35  	var mu syncx.Mutex
    36  	if !mu.TryLock() {
    37  		assert.FailNow(t, "mutex must be unlocked")
    38  	}
    39  	if mu.TryLock() {
    40  		assert.FailNow(t, "mutex must be locked")
    41  	}
    42  
    43  	mu.Unlock()
    44  	if !mu.TryLock() {
    45  		assert.FailNow(t, "mutex must be unlocked")
    46  	}
    47  	if mu.TryLock() {
    48  		assert.FailNow(t, "mutex must be locked")
    49  	}
    50  
    51  	mu.Unlock()
    52  	mu.Lock()
    53  	if mu.TryLock() {
    54  		assert.FailNow(t, "mutex must be locked")
    55  	}
    56  	if mu.TryLock() {
    57  		assert.FailNow(t, "mutex must be locked")
    58  	}
    59  	mu.Unlock()
    60  }
    61  
    62  func TestMutex_TryLockPointer(t *testing.T) {
    63  	mu := &syncx.Mutex{}
    64  	if !mu.TryLock() {
    65  		assert.FailNow(t, "mutex must be unlocked")
    66  	}
    67  	if mu.TryLock() {
    68  		assert.FailNow(t, "mutex must be locked")
    69  	}
    70  
    71  	mu.Unlock()
    72  	if !mu.TryLock() {
    73  		assert.FailNow(t, "mutex must be unlocked")
    74  	}
    75  	if mu.TryLock() {
    76  		assert.FailNow(t, "mutex must be locked")
    77  	}
    78  
    79  	mu.Unlock()
    80  	mu.Lock()
    81  	if mu.TryLock() {
    82  		assert.FailNow(t, "mutex must be locked")
    83  	}
    84  	if mu.TryLock() {
    85  		assert.FailNow(t, "mutex must be locked")
    86  	}
    87  	mu.Unlock()
    88  }
    89  
    90  func TestMutex_Race(t *testing.T) {
    91  	var mu syncx.Mutex
    92  	var x int
    93  	for i := 0; i < 1024; i++ {
    94  		if i%2 == 0 {
    95  			go func() {
    96  				if mu.TryLock() {
    97  					x++
    98  					mu.Unlock()
    99  				}
   100  			}()
   101  			continue
   102  		}
   103  
   104  		go func() {
   105  			mu.Lock()
   106  			x++
   107  			mu.Unlock()
   108  		}()
   109  	}
   110  }