1
2
3
4
5 package main
6
7 import (
8 "./a"
9 "context"
10 "fmt"
11 "runtime"
12 "sort"
13 "sync"
14 "time"
15 )
16
17 func TestReadAll() {
18 c := make(chan int)
19 go func() {
20 c <- 4
21 c <- 2
22 c <- 5
23 close(c)
24 }()
25 got := a.ReadAll(context.Background(), c)
26 want := []int{4, 2, 5}
27 if !a.SliceEqual(got, want) {
28 panic(fmt.Sprintf("ReadAll returned %v, want %v", got, want))
29 }
30 }
31
32 func TestMerge() {
33 c1 := make(chan int)
34 c2 := make(chan int)
35 go func() {
36 c1 <- 1
37 c1 <- 3
38 c1 <- 5
39 close(c1)
40 }()
41 go func() {
42 c2 <- 2
43 c2 <- 4
44 c2 <- 6
45 close(c2)
46 }()
47 ctx := context.Background()
48 got := a.ReadAll(ctx, a.Merge(ctx, c1, c2))
49 sort.Ints(got)
50 want := []int{1, 2, 3, 4, 5, 6}
51 if !a.SliceEqual(got, want) {
52 panic(fmt.Sprintf("Merge returned %v, want %v", got, want))
53 }
54 }
55
56 func TestFilter() {
57 c := make(chan int)
58 go func() {
59 c <- 1
60 c <- 2
61 c <- 3
62 close(c)
63 }()
64 even := func(i int) bool { return i%2 == 0 }
65 ctx := context.Background()
66 got := a.ReadAll(ctx, a.Filter(ctx, c, even))
67 want := []int{2}
68 if !a.SliceEqual(got, want) {
69 panic(fmt.Sprintf("Filter returned %v, want %v", got, want))
70 }
71 }
72
73 func TestSink() {
74 c := a.Sink[int](context.Background())
75 after := time.NewTimer(time.Minute)
76 defer after.Stop()
77 send := func(v int) {
78 select {
79 case c <- v:
80 case <-after.C:
81 panic("timed out sending to Sink")
82 }
83 }
84 send(1)
85 send(2)
86 send(3)
87 close(c)
88 }
89
90 func TestExclusive() {
91 val := 0
92 ex := a.MakeExclusive(&val)
93
94 var wg sync.WaitGroup
95 f := func() {
96 defer wg.Done()
97 for i := 0; i < 10; i++ {
98 p := ex.Acquire()
99 (*p)++
100 ex.Release(p)
101 }
102 }
103
104 wg.Add(2)
105 go f()
106 go f()
107
108 wg.Wait()
109 if val != 20 {
110 panic(fmt.Sprintf("after Acquire/Release loop got %d, want 20", val))
111 }
112 }
113
114 func TestExclusiveTry() {
115 s := ""
116 ex := a.MakeExclusive(&s)
117 p, ok := ex.TryAcquire()
118 if !ok {
119 panic("TryAcquire failed")
120 }
121 *p = "a"
122
123 var wg sync.WaitGroup
124 wg.Add(1)
125 go func() {
126 defer wg.Done()
127 _, ok := ex.TryAcquire()
128 if ok {
129 panic(fmt.Sprintf("TryAcquire succeeded unexpectedly"))
130 }
131 }()
132 wg.Wait()
133
134 ex.Release(p)
135
136 p, ok = ex.TryAcquire()
137 if !ok {
138 panic(fmt.Sprintf("TryAcquire failed"))
139 }
140 }
141
142 func TestRanger() {
143 s, r := a.Ranger[int]()
144
145 ctx := context.Background()
146 go func() {
147
148 v, ok := r.Next(ctx)
149 if !ok {
150 panic(fmt.Sprintf("did not receive any values"))
151 } else if v != 1 {
152 panic(fmt.Sprintf("received %d, want 1", v))
153 }
154 }()
155
156 c1 := make(chan bool)
157 c2 := make(chan bool)
158 go func() {
159 defer close(c2)
160 if !s.Send(ctx, 1) {
161 panic(fmt.Sprintf("Send failed unexpectedly"))
162 }
163 close(c1)
164 if s.Send(ctx, 2) {
165 panic(fmt.Sprintf("Send succeeded unexpectedly"))
166 }
167 }()
168
169 <-c1
170
171
172 runtime.GC()
173
174 select {
175 case <-c2:
176 case <-time.After(time.Minute):
177 panic("Ranger Send should have failed, but timed out")
178 }
179 }
180
181 func main() {
182 TestReadAll()
183 TestMerge()
184 TestFilter()
185 TestSink()
186 TestExclusive()
187 TestExclusiveTry()
188 TestRanger()
189 }
190
View as plain text