clash/common/observable/observable_test.go

148 lines
2.6 KiB
Go
Raw Normal View History

2018-06-10 14:50:03 +00:00
package observable
import (
"sync"
"testing"
"time"
"github.com/Dreamacro/clash/common/atomic"
"github.com/stretchr/testify/assert"
2018-06-10 14:50:03 +00:00
)
2022-04-23 18:07:57 +00:00
func iterator[T any](item []T) chan T {
ch := make(chan T)
2018-06-10 14:50:03 +00:00
go func() {
time.Sleep(100 * time.Millisecond)
for _, elm := range item {
ch <- elm
}
close(ch)
}()
return ch
}
func TestObservable(t *testing.T) {
2022-04-23 18:07:57 +00:00
iter := iterator[int]([]int{1, 2, 3, 4, 5})
src := NewObservable[int](iter)
2018-06-10 14:50:03 +00:00
data, err := src.Subscribe()
assert.Nil(t, err)
2018-06-10 14:50:03 +00:00
count := 0
for range data {
2019-10-14 09:13:23 +00:00
count++
2018-06-10 14:50:03 +00:00
}
assert.Equal(t, count, 5)
2018-06-10 14:50:03 +00:00
}
func TestObservable_MultiSubscribe(t *testing.T) {
2022-04-23 18:07:57 +00:00
iter := iterator[int]([]int{1, 2, 3, 4, 5})
src := NewObservable[int](iter)
2018-06-10 14:50:03 +00:00
ch1, _ := src.Subscribe()
ch2, _ := src.Subscribe()
2021-10-10 15:44:09 +00:00
count := atomic.NewInt32(0)
2018-06-10 14:50:03 +00:00
var wg sync.WaitGroup
wg.Add(2)
2022-04-23 18:07:57 +00:00
waitCh := func(ch <-chan int) {
for range ch {
count.Add(1)
2018-06-10 14:50:03 +00:00
}
wg.Done()
}
go waitCh(ch1)
go waitCh(ch2)
wg.Wait()
assert.Equal(t, int32(10), count.Load())
2018-06-10 14:50:03 +00:00
}
func TestObservable_UnSubscribe(t *testing.T) {
2022-04-23 18:07:57 +00:00
iter := iterator[int]([]int{1, 2, 3, 4, 5})
src := NewObservable[int](iter)
2018-06-10 14:50:03 +00:00
data, err := src.Subscribe()
assert.Nil(t, err)
2018-06-10 14:50:03 +00:00
src.UnSubscribe(data)
_, open := <-data
assert.False(t, open)
2018-06-10 14:50:03 +00:00
}
func TestObservable_SubscribeClosedSource(t *testing.T) {
2022-04-23 18:07:57 +00:00
iter := iterator[int]([]int{1})
src := NewObservable[int](iter)
data, _ := src.Subscribe()
<-data
_, closed := src.Subscribe()
assert.NotNil(t, closed)
}
func TestObservable_UnSubscribeWithNotExistSubscription(t *testing.T) {
2022-04-23 18:07:57 +00:00
sub := Subscription[int](make(chan int))
iter := iterator[int]([]int{1})
src := NewObservable[int](iter)
src.UnSubscribe(sub)
}
2018-06-10 14:50:03 +00:00
func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
2022-04-23 18:07:57 +00:00
iter := iterator[int]([]int{1, 2, 3, 4, 5})
src := NewObservable[int](iter)
max := 100
2018-06-10 14:50:03 +00:00
2022-04-23 18:07:57 +00:00
var list []Subscription[int]
for i := 0; i < max; i++ {
2018-06-10 14:50:03 +00:00
ch, _ := src.Subscribe()
list = append(list, ch)
}
var wg sync.WaitGroup
wg.Add(max)
2022-04-23 18:07:57 +00:00
waitCh := func(ch <-chan int) {
for range ch {
2018-06-10 14:50:03 +00:00
}
wg.Done()
}
for _, ch := range list {
go waitCh(ch)
}
wg.Wait()
2020-07-18 12:56:13 +00:00
for _, sub := range list {
_, more := <-sub
assert.False(t, more)
}
_, more := <-list[0]
assert.False(t, more)
2018-06-10 14:50:03 +00:00
}
2020-10-20 09:44:39 +00:00
func Benchmark_Observable_1000(b *testing.B) {
2022-04-23 18:07:57 +00:00
ch := make(chan int)
o := NewObservable[int](ch)
2020-10-20 09:44:39 +00:00
num := 1000
2022-04-23 18:07:57 +00:00
subs := []Subscription[int]{}
2020-10-20 09:44:39 +00:00
for i := 0; i < num; i++ {
sub, _ := o.Subscribe()
subs = append(subs, sub)
}
wg := sync.WaitGroup{}
wg.Add(num)
b.ResetTimer()
for _, sub := range subs {
2022-04-23 18:07:57 +00:00
go func(s Subscription[int]) {
2020-10-20 09:44:39 +00:00
for range s {
}
wg.Done()
}(sub)
}
for i := 0; i < b.N; i++ {
ch <- i
}
close(ch)
wg.Wait()
}