Skip to content

Commit 5e98010

Browse files
committed
Improve code cov for agent_handlers
1 parent b01b5f6 commit 5e98010

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

agent_handlers_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/pion/transport/v3/test"
1111
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
1213
)
1314

1415
func TestConnectionStateNotifier(t *testing.T) {
@@ -70,3 +71,119 @@ func TestConnectionStateNotifier(t *testing.T) {
7071
notifer.Close(true)
7172
})
7273
}
74+
75+
func TestHandlerNotifier_Close_AlreadyClosed(t *testing.T) {
76+
defer test.CheckRoutines(t)()
77+
78+
notifier := &handlerNotifier{
79+
connectionStateFunc: func(ConnectionState) {},
80+
candidateFunc: func(Candidate) {},
81+
candidatePairFunc: func(*CandidatePair) {},
82+
done: make(chan struct{}),
83+
}
84+
85+
// first close
86+
notifier.Close(false)
87+
88+
isClosed := func(ch <-chan struct{}) bool {
89+
select {
90+
case <-ch:
91+
return true
92+
default:
93+
return false
94+
}
95+
}
96+
assert.True(t, isClosed(notifier.done), "expected h.done to be closed after first Close")
97+
98+
// second close should hit `case <-h.done` and return immediately
99+
// without blocking on the WaitGroup.
100+
finished := make(chan struct{}, 1)
101+
go func() {
102+
notifier.Close(true)
103+
close(finished)
104+
}()
105+
106+
assert.Eventually(t, func() bool {
107+
select {
108+
case <-finished:
109+
return true
110+
default:
111+
return false
112+
}
113+
}, 250*time.Millisecond, 10*time.Millisecond, "second Close(true) did not return promptly")
114+
115+
// ensure still closed afterwards
116+
assert.True(t, isClosed(notifier.done), "expected h.done to remain closed after second Close")
117+
118+
// sanity: no enqueues should start after close.
119+
require.False(t, notifier.running)
120+
require.Zero(t, len(notifier.connectionStates))
121+
require.Zero(t, len(notifier.candidates))
122+
require.Zero(t, len(notifier.selectedCandidatePairs))
123+
}
124+
125+
func TestHandlerNotifier_EnqueueConnectionState_AfterClose(t *testing.T) {
126+
defer test.CheckRoutines(t)()
127+
128+
connCh := make(chan struct{}, 1)
129+
notifier := &handlerNotifier{
130+
connectionStateFunc: func(ConnectionState) { connCh <- struct{}{} },
131+
done: make(chan struct{}),
132+
}
133+
134+
notifier.Close(false)
135+
notifier.EnqueueConnectionState(ConnectionStateConnected)
136+
137+
assert.Never(t, func() bool {
138+
select {
139+
case <-connCh:
140+
return true
141+
default:
142+
return false
143+
}
144+
}, 250*time.Millisecond, 10*time.Millisecond, "connectionStateFunc should not be called after close")
145+
}
146+
147+
func TestHandlerNotifier_EnqueueCandidate_AfterClose(t *testing.T) {
148+
defer test.CheckRoutines(t)()
149+
150+
candidateCh := make(chan struct{}, 1)
151+
h := &handlerNotifier{
152+
candidateFunc: func(Candidate) { candidateCh <- struct{}{} },
153+
done: make(chan struct{}),
154+
}
155+
156+
h.Close(false)
157+
h.EnqueueCandidate(nil)
158+
159+
assert.Never(t, func() bool {
160+
select {
161+
case <-candidateCh:
162+
return true
163+
default:
164+
return false
165+
}
166+
}, 250*time.Millisecond, 10*time.Millisecond, "candidateFunc should not be called after close")
167+
}
168+
169+
func TestHandlerNotifier_EnqueueSelectedCandidatePair_AfterClose(t *testing.T) {
170+
defer test.CheckRoutines(t)()
171+
172+
pairCh := make(chan struct{}, 1)
173+
h := &handlerNotifier{
174+
candidatePairFunc: func(*CandidatePair) { pairCh <- struct{}{} },
175+
done: make(chan struct{}),
176+
}
177+
178+
h.Close(false)
179+
h.EnqueueSelectedCandidatePair(nil)
180+
181+
assert.Never(t, func() bool {
182+
select {
183+
case <-pairCh:
184+
return true
185+
default:
186+
return false
187+
}
188+
}, 250*time.Millisecond, 10*time.Millisecond, "candidatePairFunc should not be called after close")
189+
}

0 commit comments

Comments
 (0)