You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/core/syncx/lockedcalls_test.go

83 lines
1.4 KiB
Go

4 years ago
package syncx
import (
"errors"
"fmt"
"sync"
"testing"
"time"
)
func TestLockedCallDo(t *testing.T) {
g := NewLockedCalls()
v, err := g.Do("key", func() (any, error) {
4 years ago
return "bar", nil
})
if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want {
t.Errorf("Do = %v; want %v", got, want)
}
if err != nil {
t.Errorf("Do error = %v", err)
}
}
func TestLockedCallDoErr(t *testing.T) {
g := NewLockedCalls()
someErr := errors.New("some error")
v, err := g.Do("key", func() (any, error) {
4 years ago
return nil, someErr
})
if err != someErr {
t.Errorf("Do error = %v; want someErr", err)
}
if v != nil {
t.Errorf("unexpected non-nil value %#v", v)
}
}
func TestLockedCallDoDupSuppress(t *testing.T) {
g := NewLockedCalls()
c := make(chan string)
var calls int
fn := func() (any, error) {
4 years ago
calls++
ret := calls
<-c
calls--
return ret, nil
}
const n = 10
var results []int
var lock sync.Mutex
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
v, err := g.Do("key", fn)
if err != nil {
t.Errorf("Do error: %v", err)
}
lock.Lock()
results = append(results, v.(int))
lock.Unlock()
wg.Done()
}()
}
time.Sleep(100 * time.Millisecond) // let goroutines above block
for i := 0; i < n; i++ {
c <- "bar"
}
wg.Wait()
lock.Lock()
defer lock.Unlock()
for _, item := range results {
if item != 1 {
t.Errorf("number of calls = %d; want 1", item)
}
}
}