-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmanager_coverage_test.go
More file actions
241 lines (192 loc) · 6.66 KB
/
Copy pathmanager_coverage_test.go
File metadata and controls
241 lines (192 loc) · 6.66 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package dbmanager
import (
"fmt"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// TestMemoryManager_Unregister_DoesNotClose 验证 Unregister 仅移除管理器中的引用,
// 不关闭底层连接
func TestMemoryManager_Unregister_DoesNotClose(t *testing.T) {
manager := NewMemoryManager()
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("test_db", db)
assert.NoError(t, err)
// Unregister 不应关闭底层连接
err = manager.Unregister("test_db")
assert.NoError(t, err)
// 连接应从管理器中移除
_, err = manager.Get("test_db")
assert.Error(t, err)
assert.Contains(t, err.Error(), "connection \"test_db\" not found")
// 底层 sql.DB 应仍然可用
sqlDB, err := db.DB()
assert.NoError(t, err)
assert.NoError(t, sqlDB.Ping())
sqlDB.Close()
}
// TestMemoryManager_Unregister_EmptyName 验证 Unregister 空名称返回错误
func TestMemoryManager_Unregister_EmptyName(t *testing.T) {
manager := NewMemoryManager()
err := manager.Unregister("")
assert.Error(t, err)
assert.Contains(t, err.Error(), "connection name cannot be empty")
}
// TestMemoryManager_Unregister_NotExist 验证 Unregister 不存在的连接不报错
func TestMemoryManager_Unregister_NotExist(t *testing.T) {
manager := NewMemoryManager()
err := manager.Unregister("nonexistent")
assert.NoError(t, err)
}
// TestMemoryManager_CloseAll_Success 验证 CloseAll 正常关闭所有连接
func TestMemoryManager_CloseAll_Success(t *testing.T) {
manager := NewMemoryManager()
db1, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
db2, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("db1", db1)
assert.NoError(t, err)
err = manager.Register("db2", db2)
assert.NoError(t, err)
err = manager.CloseAll()
assert.NoError(t, err)
// 所有连接应已从管理器中移除
_, err = manager.Get("db1")
assert.Error(t, err)
_, err = manager.Get("db2")
assert.Error(t, err)
}
// TestMemoryManager_CloseAll_PartialError 验证 CloseAll 遇到非 *gorm.DB 条目时仍继续处理其余连接
func TestMemoryManager_CloseAll_PartialError(t *testing.T) {
manager := NewMemoryManager()
m := manager.(*memoryManager)
// 正常连接
goodDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("good_db", goodDB)
assert.NoError(t, err)
// 在 sync.Map 中直接插入非 *gorm.DB 类型,模拟类型断言失败
m.connections.Store("bad_entry", 42)
// CloseAll 不应因 bad_entry 类型断言失败而中断
err = manager.CloseAll()
assert.NoError(t, err) // 非数据库类型被跳过,不产生错误
// good_db 应被正常关闭并从管理器中移除
_, getErr := manager.Get("good_db")
assert.Error(t, getErr)
}
// TestMemoryManager_CloseAll_Empty 验证 CloseAll 在无连接时不报错
func TestMemoryManager_CloseAll_Empty(t *testing.T) {
manager := NewMemoryManager()
err := manager.CloseAll()
assert.NoError(t, err)
}
// TestMemoryManager_CloseAll_UnexpectedType 验证 CloseAll 遇到非 *gorm.DB 类型时跳过
func TestMemoryManager_CloseAll_UnexpectedType(t *testing.T) {
manager := NewMemoryManager()
m := manager.(*memoryManager)
// 存入非 *gorm.DB 类型
m.connections.Store("wrong_type", "not a database")
// 正常连接
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("good_db", db)
assert.NoError(t, err)
// CloseAll 不应因类型断言失败而 panic
err = manager.CloseAll()
assert.NoError(t, err)
}
// TestMemoryManager_CloseAll_ClosedDB 验证 CloseAll 中 db.DB() 返回错误时仍继续处理
func TestMemoryManager_CloseAll_ClosedDB(t *testing.T) {
manager := NewMemoryManager()
// 创建一个连接后关闭底层 sql.DB,使后续 DB() 调用可能返回错误
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
sqlDB, _ := db.DB()
sqlDB.Close()
err = manager.Register("closed_db", db)
assert.NoError(t, err)
// 另一个正常连接
goodDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("good_db", goodDB)
assert.NoError(t, err)
// CloseAll 不应 panic,且继续处理其他连接
err = manager.CloseAll()
// 无论 closed_db 是否报错,good_db 应被正常关闭并移除
_, getErr := manager.Get("good_db")
assert.Error(t, getErr)
}
// TestMemoryManager_ConcurrentRegisterUnregister 并发执行 Register / Unregister / Get
func TestMemoryManager_ConcurrentRegisterUnregister(t *testing.T) {
manager := NewMemoryManager()
const numGoroutines = 50
var wg sync.WaitGroup
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
errChan := make(chan error, numGoroutines*3)
// 并发 Register
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
name := fmt.Sprintf("concurrent_db_%d", id)
if err := manager.Register(name, db); err != nil {
errChan <- err
}
}(i)
}
// 并发 Unregister
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
name := fmt.Sprintf("concurrent_db_%d", id)
if err := manager.Unregister(name); err != nil {
errChan <- err
}
}(i)
}
// 并发 Get
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
name := fmt.Sprintf("concurrent_db_%d", id)
_, _ = manager.Get(name) // 可能找到也可能找不到,都正常
}(i)
}
wg.Wait()
close(errChan)
for err := range errChan {
assert.NoError(t, err)
}
}
// TestMemoryManager_EmptyName_Error 验证 Register 空名称返回错误
func TestMemoryManager_EmptyName_Error(t *testing.T) {
manager := NewMemoryManager()
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
assert.NoError(t, err)
err = manager.Register("", db)
assert.Error(t, err)
assert.Contains(t, err.Error(), "connection name cannot be empty")
}
// TestMemoryManager_NilConnection_Error 验证 Register nil 连接返回错误
func TestMemoryManager_NilConnection_Error(t *testing.T) {
manager := NewMemoryManager()
err := manager.Register("nil_db", nil)
assert.Error(t, err)
assert.Contains(t, err.Error(), "database connection cannot be nil")
}
// TestMemoryManager_UnexpectedType_Error 验证 Get 时类型断言失败返回错误
func TestMemoryManager_UnexpectedType_Error(t *testing.T) {
manager := NewMemoryManager()
m := manager.(*memoryManager)
m.connections.Store("bad_type", 12345)
_, err := manager.Get("bad_type")
assert.Error(t, err)
assert.Contains(t, err.Error(), "has unexpected type")
}