-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathdefault_checker_test.go
More file actions
126 lines (105 loc) · 2.77 KB
/
Copy pathdefault_checker_test.go
File metadata and controls
126 lines (105 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package tcp
import (
"sync"
"testing"
"time"
)
func TestDefaultCheckerImmediatelyReady(t *testing.T) {
checker := DefaultChecker()
// Should be ready immediately after function returns
select {
case <-checker.WaitReady():
// Expected behavior
case <-time.After(100 * time.Millisecond):
t.Error("Checker should be ready immediately after DefaultChecker() returns")
}
}
func TestDefaultCheckerNotNil(t *testing.T) {
if DefaultChecker() == nil {
t.Fatalf("DefaultChecker() returned nil")
}
}
func TestDefaultCheckerBasicFunctionality(t *testing.T) {
// Start a test server to check against
testAddr, stopServer := StartTestServer()
defer stopServer()
checker := DefaultChecker()
// Test that we can perform a check
err := checker.CheckAddr(testAddr, time.Second)
if err != nil {
t.Fatalf("Check against test server failed with error: %v", err)
}
}
func TestDefaultCheckerSingleton(t *testing.T) {
// Get first instance
first := DefaultChecker()
// Get second instance
second := DefaultChecker()
// They should be the same instance
if first != second {
t.Fatalf("DefaultChecker() did not return a singleton instance")
}
// Verify that the checker is ready
select {
case <-first.WaitReady():
// Checker is ready as expected
case <-time.After(5 * time.Second):
t.Fatalf("DefaultChecker() did not become ready within 5 seconds")
}
}
func TestDefaultCheckerConcurrentAccess(t *testing.T) {
// Test concurrent access to the singleton
ch := make(chan *Checker, 10)
done := make(chan struct{})
// Start multiple goroutines trying to get the checker
for i := 0; i < 10; i++ {
go func() {
ch <- DefaultChecker()
done <- struct{}{}
}()
}
// Collect all results
checkers := make([]*Checker, 10)
for i := 0; i < 10; i++ {
select {
case checker := <-ch:
checkers[i] = checker
case <-time.After(5 * time.Second):
t.Fatalf("Timeout waiting for checker")
}
}
// Wait for all goroutines to finish
for i := 0; i < 10; i++ {
select {
case <-done:
case <-time.After(5 * time.Second):
t.Fatalf("Timeout waiting for goroutine completion")
}
}
// All checkers should be the same instance
for _, checker := range checkers {
if checker != checkers[0] {
t.Errorf("Concurrent access returned different checker instances")
}
}
}
func TestDefaultCheckerOnceBehavior(t *testing.T) {
// This test verifies that the once.Do function only executes once
// even when called concurrently
var wg sync.WaitGroup
checkers := make([]*Checker, 10)
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
checkers[i] = DefaultChecker()
}(i)
}
wg.Wait()
// All should be the same instance
for _, checker := range checkers {
if checker != checkers[0] {
t.Errorf("Different instances returned despite once.Do usage")
}
}
}