golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/singleflight/singleflight_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package singleflight 6 7 import ( 8 "errors" 9 "fmt" 10 "sync" 11 "sync/atomic" 12 "testing" 13 "time" 14 ) 15 16 func TestDo(t *testing.T) { 17 var g Group 18 v, err, _ := g.Do("key", func() (interface{}, error) { 19 return "bar", nil 20 }) 21 if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want { 22 t.Errorf("Do = %v; want %v", got, want) 23 } 24 if err != nil { 25 t.Errorf("Do error = %v", err) 26 } 27 } 28 29 func TestDoErr(t *testing.T) { 30 var g Group 31 someErr := errors.New("Some error") 32 v, err, _ := g.Do("key", func() (interface{}, error) { 33 return nil, someErr 34 }) 35 if err != someErr { 36 t.Errorf("Do error = %v; want someErr %v", err, someErr) 37 } 38 if v != nil { 39 t.Errorf("unexpected non-nil value %#v", v) 40 } 41 } 42 43 func TestDoDupSuppress(t *testing.T) { 44 var g Group 45 c := make(chan string) 46 var calls int32 47 fn := func() (interface{}, error) { 48 atomic.AddInt32(&calls, 1) 49 return <-c, nil 50 } 51 52 const n = 10 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 if v.(string) != "bar" { 62 t.Errorf("got %q; want %q", v, "bar") 63 } 64 wg.Done() 65 }() 66 } 67 time.Sleep(100 * time.Millisecond) // let goroutines above block 68 c <- "bar" 69 wg.Wait() 70 if got := atomic.LoadInt32(&calls); got != 1 { 71 t.Errorf("number of calls = %d; want 1", got) 72 } 73 }