Skip to content

Commit 4a0103d

Browse files
committed
adding tests
1 parent a46e601 commit 4a0103d

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

fastdialer/dialer_private_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package fastdialer
2+
3+
import (
4+
"sync/atomic"
5+
"testing"
6+
"time"
7+
)
8+
9+
type mockCloser struct {
10+
closedCount atomic.Int32
11+
ch chan struct{}
12+
retErr error
13+
}
14+
15+
func newMockCloser(retErr error) *mockCloser {
16+
return &mockCloser{ch: make(chan struct{}, 1), retErr: retErr}
17+
}
18+
19+
func (m *mockCloser) Close() error {
20+
if m.closedCount.Add(1) == 1 {
21+
select {
22+
case m.ch <- struct{}{}:
23+
default:
24+
}
25+
}
26+
return m.retErr
27+
}
28+
29+
func waitClosed(t *testing.T, m *mockCloser, d time.Duration) bool {
30+
t.Helper()
31+
select {
32+
case <-m.ch:
33+
return true
34+
case <-time.After(d):
35+
return false
36+
}
37+
}
38+
39+
// Removed generic behavior tests; keeping context-focused tests only.
40+
41+
func TestCloseAfterTimeout_RespectsDeadlineTiming(t *testing.T) {
42+
t.Parallel()
43+
m := newMockCloser(nil)
44+
deadline := 60 * time.Millisecond
45+
start := time.Now()
46+
ctxFuncDone := closeAfterTimeout(deadline, m)
47+
defer ctxFuncDone()
48+
49+
if ok := waitClosed(t, m, 750*time.Millisecond); !ok {
50+
t.Fatalf("expected closer to be called before overall wait deadline")
51+
}
52+
elapsed := time.Since(start)
53+
// Allow some jitter, but ensure it didn't trigger too early (< 50% of deadline)
54+
if elapsed < deadline/2 {
55+
t.Fatalf("close triggered too early: elapsed=%v deadline=%v", elapsed, deadline)
56+
}
57+
// And also not excessively late (> 10x deadline)
58+
if elapsed > 10*deadline {
59+
t.Fatalf("close triggered too late: elapsed=%v deadline=%v", elapsed, deadline)
60+
}
61+
// Ensure internal timeout path invoked close exactly once
62+
if got := m.closedCount.Load(); got != 1 {
63+
t.Fatalf("expected close to be called once via internal timeout, got %d", got)
64+
}
65+
}
66+
67+
func TestCloseAfterTimeout_ExternalCancelPreemptsTimeout(t *testing.T) {
68+
t.Parallel()
69+
m := newMockCloser(nil)
70+
deadline := 250 * time.Millisecond
71+
cancel := closeAfterTimeout(deadline, m)
72+
// Cancel well before the deadline
73+
time.Sleep(20 * time.Millisecond)
74+
cancel()
75+
// Wait well past the original deadline to ensure it would have fired
76+
if ok := waitClosed(t, m, 500*time.Millisecond); ok {
77+
t.Fatalf("did not expect closer to be called after external cancel")
78+
}
79+
if got := m.closedCount.Load(); got != 0 {
80+
t.Fatalf("expected zero close calls with external cancel, got %d", got)
81+
}
82+
// Re-check at the very end after additional wait to ensure it stays zero
83+
time.Sleep(100 * time.Millisecond)
84+
if got := m.closedCount.Load(); got != 0 {
85+
t.Fatalf("expected zero close calls at end of test, got %d", got)
86+
}
87+
}

0 commit comments

Comments
 (0)