github.com/lingyao2333/mo-zero@v1.4.1/core/syncx/lockedcalls_test.go (about) 1 package syncx 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 "testing" 8 "time" 9 ) 10 11 func TestLockedCallDo(t *testing.T) { 12 g := NewLockedCalls() 13 v, err := g.Do("key", func() (interface{}, error) { 14 return "bar", nil 15 }) 16 if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want { 17 t.Errorf("Do = %v; want %v", got, want) 18 } 19 if err != nil { 20 t.Errorf("Do error = %v", err) 21 } 22 } 23 24 func TestLockedCallDoErr(t *testing.T) { 25 g := NewLockedCalls() 26 someErr := errors.New("some error") 27 v, err := g.Do("key", func() (interface{}, error) { 28 return nil, someErr 29 }) 30 if err != someErr { 31 t.Errorf("Do error = %v; want someErr", err) 32 } 33 if v != nil { 34 t.Errorf("unexpected non-nil value %#v", v) 35 } 36 } 37 38 func TestLockedCallDoDupSuppress(t *testing.T) { 39 g := NewLockedCalls() 40 c := make(chan string) 41 var calls int 42 fn := func() (interface{}, error) { 43 calls++ 44 ret := calls 45 <-c 46 calls-- 47 return ret, nil 48 } 49 50 const n = 10 51 var results []int 52 var lock sync.Mutex 53 var wg sync.WaitGroup 54 for i := 0; i < n; i++ { 55 wg.Add(1) 56 go func() { 57 v, err := g.Do("key", fn) 58 if err != nil { 59 t.Errorf("Do error: %v", err) 60 } 61 62 lock.Lock() 63 results = append(results, v.(int)) 64 lock.Unlock() 65 wg.Done() 66 }() 67 } 68 time.Sleep(100 * time.Millisecond) // let goroutines above block 69 for i := 0; i < n; i++ { 70 c <- "bar" 71 } 72 wg.Wait() 73 74 lock.Lock() 75 defer lock.Unlock() 76 77 for _, item := range results { 78 if item != 1 { 79 t.Errorf("number of calls = %d; want 1", item) 80 } 81 } 82 }