github.com/igoogolx/clash@v1.19.8/common/singledo/singledo_test.go (about)

     1  package singledo
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"go.uber.org/atomic"
    10  )
    11  
    12  func TestBasic(t *testing.T) {
    13  	single := NewSingle(time.Millisecond * 30)
    14  	foo := 0
    15  	shardCount := atomic.NewInt32(0)
    16  	call := func() (any, error) {
    17  		foo++
    18  		time.Sleep(time.Millisecond * 5)
    19  		return nil, nil
    20  	}
    21  
    22  	var wg sync.WaitGroup
    23  	const n = 5
    24  	wg.Add(n)
    25  	for i := 0; i < n; i++ {
    26  		go func() {
    27  			_, _, shard := single.Do(call)
    28  			if shard {
    29  				shardCount.Inc()
    30  			}
    31  			wg.Done()
    32  		}()
    33  	}
    34  
    35  	wg.Wait()
    36  	assert.Equal(t, 1, foo)
    37  	assert.Equal(t, int32(4), shardCount.Load())
    38  }
    39  
    40  func TestTimer(t *testing.T) {
    41  	single := NewSingle(time.Millisecond * 30)
    42  	foo := 0
    43  	call := func() (any, error) {
    44  		foo++
    45  		return nil, nil
    46  	}
    47  
    48  	single.Do(call)
    49  	time.Sleep(10 * time.Millisecond)
    50  	_, _, shard := single.Do(call)
    51  
    52  	assert.Equal(t, 1, foo)
    53  	assert.True(t, shard)
    54  }
    55  
    56  func TestReset(t *testing.T) {
    57  	single := NewSingle(time.Millisecond * 30)
    58  	foo := 0
    59  	call := func() (any, error) {
    60  		foo++
    61  		return nil, nil
    62  	}
    63  
    64  	single.Do(call)
    65  	single.Reset()
    66  	single.Do(call)
    67  
    68  	assert.Equal(t, 2, foo)
    69  }