-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservice_test.go
More file actions
151 lines (123 loc) · 2.75 KB
/
service_test.go
File metadata and controls
151 lines (123 loc) · 2.75 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//go:build testing
package sum
import (
"context"
"sync"
"testing"
"time"
)
func TestNewService(t *testing.T) {
// Reset singleton state
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
svc := New()
if svc == nil {
t.Fatal("expected non-nil service")
}
// Verify singleton behavior
svc2 := New()
if svc != svc2 {
t.Error("expected same instance from second New call")
}
}
func TestServiceEngineAndCatalog(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
svc := New()
if svc.Engine() == nil {
t.Error("expected non-nil engine")
}
if svc.Catalog() == nil {
t.Error("expected non-nil catalog")
}
}
func TestSvcPanicsWithoutInit(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
defer func() {
if r := recover(); r == nil {
t.Error("expected panic when calling svc() without initialization")
}
}()
svc()
}
func TestServiceShutdownWithoutStart(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
svc := New()
// Temporarily nil the engine to simulate not started state
originalEngine := svc.engine
svc.engine = nil
defer func() { svc.engine = originalEngine }()
ctx := context.Background()
err := svc.Shutdown(ctx)
if err == nil {
t.Error("expected error when shutting down non-started service")
}
}
func TestServiceTagAndHandle(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
svc := New()
// These should not panic
svc.Tag("users", "User management endpoints")
svc.Handle() // empty handlers
}
func TestServiceRunWithCancel(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
t.Skip("requires running server - see testing/integration/service_test.go")
}
func TestServiceStartStop(t *testing.T) {
instance = nil
once = sync.Once{}
t.Cleanup(func() {
instance = nil
once = sync.Once{}
})
svc := New()
errCh := make(chan error, 1)
go func() {
errCh <- svc.Start("localhost", 0) // Port 0 for random available port
}()
// Give server time to start
time.Sleep(100 * time.Millisecond)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := svc.Shutdown(ctx); err != nil {
t.Errorf("shutdown failed: %v", err)
}
select {
case err := <-errCh:
// Server should return nil or http.ErrServerClosed on clean shutdown
if err != nil && err.Error() != "http: Server closed" {
t.Errorf("unexpected start error: %v", err)
}
case <-time.After(5 * time.Second):
t.Error("timeout waiting for server to stop")
}
}