1 package syncs
2
3 import (
4 "testing"
5 "time"
6
7
8 _ "github.com/onsi/ginkgo/v2"
9 _ "github.com/onsi/gomega"
10 )
11
12 func TestMergeChans(t *testing.T) {
13 tests := []struct {
14 name string
15 count int
16 signal int
17 }{
18 {
19 name: "single channel, close 0",
20 count: 1,
21 signal: 0,
22 },
23 {
24 name: "double channel, close 0",
25 count: 2,
26 signal: 0,
27 },
28 {
29 name: "five channel, close 0",
30 count: 5,
31 signal: 0,
32 },
33 {
34 name: "five channel, close 1",
35 count: 5,
36 signal: 1,
37 },
38 {
39 name: "five channel, close 2",
40 count: 5,
41 signal: 2,
42 },
43 {
44 name: "five channel, close 3",
45 count: 5,
46 signal: 3,
47 },
48 {
49 name: "five channel, close 4",
50 count: 5,
51 signal: 4,
52 },
53 {
54 name: "single channel, cancel",
55 count: 1,
56 signal: -1,
57 },
58 {
59 name: "double channel, cancel",
60 count: 2,
61 signal: -1,
62 },
63 {
64 name: "five channel, cancel",
65 count: 5,
66 signal: -1,
67 },
68 }
69 for _, test := range tests {
70 t.Run(test.name, func(t *testing.T) {
71 if callAndClose(test.count, test.signal, 1) {
72 t.Error("timeout before merged channel closed")
73 }
74 })
75 }
76 }
77
78 func callAndClose(numChans, signalChan, timeoutSeconds int) bool {
79 chans := make([]chan struct{}, numChans)
80 readOnlyChans := make([]<-chan struct{}, numChans)
81 for i := range chans {
82 chans[i] = make(chan struct{})
83 readOnlyChans[i] = chans[i]
84 }
85 defer func() {
86 for i := range chans {
87 close(chans[i])
88 }
89 }()
90
91 merged, cancel := MergeChans(readOnlyChans...)
92 defer cancel()
93
94 timer := time.NewTimer(time.Duration(timeoutSeconds) * time.Second)
95
96 if signalChan >= 0 {
97 chans[signalChan] <- struct{}{}
98 } else {
99 cancel()
100 }
101 select {
102 case <-merged:
103 return false
104 case <-timer.C:
105 return true
106 }
107 }
108
View as plain text