github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/core/upgradelock_internal_test.go (about) 1 // Package core provides core metadata and in-cluster API 2 /* 3 * Copyright (c) 2021-2024, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package core 6 7 import ( 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/NVIDIA/aistore/cmn/atomic" 13 "github.com/NVIDIA/aistore/cmn/cos" 14 "github.com/NVIDIA/aistore/tools/tassert" 15 "github.com/NVIDIA/aistore/tools/trand" 16 ) 17 18 func TestUpgradeLock(t *testing.T) { 19 if testing.Short() { 20 t.Skipf("skipping %s in short mode", t.Name()) 21 } 22 for _, test := range []string{"downgrade", "unlock"} { 23 t.Run(test, func(t *testing.T) { 24 const threadCnt = 10000 25 var ( 26 n = &nlc{} 27 wg = &sync.WaitGroup{} 28 sema = cos.NewDynSemaphore(threadCnt) 29 counter = atomic.NewInt32(0) 30 uname = trand.String(10) 31 ) 32 n.init() 33 34 // Additional stray reader which forces the other to block on `UpgradeLock`. 35 n.Lock(uname, false) 36 37 sema.Acquire(threadCnt) 38 wg.Add(threadCnt) 39 for range threadCnt { 40 go func() { 41 defer wg.Done() 42 43 n.Lock(uname, false) 44 45 sema.Acquire() 46 if finished := n.UpgradeLock(uname); finished { 47 tassert.Fatalf(t, counter.Load() > 0, "counter should be already updated") 48 n.Unlock(uname, false) 49 return 50 } 51 52 // Imitate doing job. 53 counter.Inc() 54 time.Sleep(time.Second) 55 56 switch test { 57 case "downgrade": 58 n.DowngradeLock(uname) 59 n.Unlock(uname, false) 60 case "unlock": 61 n.Unlock(uname, true) 62 default: 63 panic(test) 64 } 65 }() 66 } 67 68 // Make sure all other threads are past `n.Lock` and blocked on `sema.Acquire`. 69 time.Sleep(500 * time.Millisecond) 70 71 sema.Release(threadCnt) 72 // Wait a while to make sure that all goroutines started and blocked on `UpgradeLock`. 73 time.Sleep(500 * time.Millisecond) 74 75 // Should wake up one of the waiter which should start doing job. 76 n.Unlock(uname, false) 77 78 wg.Wait() 79 tassert.Fatalf(t, counter.Load() == 1, "counter should be equal to 1 (counter: %d)", counter.Load()) 80 }) 81 } 82 }