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  }