mihomo/common/observable/observable_test.go

147 lines
2.5 KiB
Go
Raw Normal View History

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