Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
2bfb1629
"backend/vscode:/vscode.git/clone" did not exist on "9ee7d3935d0d858d5e5a9492b36e6ea9c2c006ff"
Commit
2bfb1629
authored
Feb 09, 2026
by
yangjianbo
Browse files
fix(unit): 修复 unit tag 测试编译与账号选择用例
parent
d367d1cd
Changes
5
Show whitespace changes
Inline
Side-by-side
backend/internal/handler/sora_gateway_handler_test.go
View file @
2bfb1629
...
@@ -78,6 +78,9 @@ func (r *stubAccountRepo) GetByCRSAccountID(ctx context.Context, crsAccountID st
...
@@ -78,6 +78,9 @@ func (r *stubAccountRepo) GetByCRSAccountID(ctx context.Context, crsAccountID st
func
(
r
*
stubAccountRepo
)
FindByExtraField
(
ctx
context
.
Context
,
key
string
,
value
any
)
([]
service
.
Account
,
error
)
{
func
(
r
*
stubAccountRepo
)
FindByExtraField
(
ctx
context
.
Context
,
key
string
,
value
any
)
([]
service
.
Account
,
error
)
{
return
nil
,
nil
return
nil
,
nil
}
}
func
(
r
*
stubAccountRepo
)
ListCRSAccountIDs
(
ctx
context
.
Context
)
(
map
[
string
]
int64
,
error
)
{
return
map
[
string
]
int64
{},
nil
}
func
(
r
*
stubAccountRepo
)
Update
(
ctx
context
.
Context
,
account
*
service
.
Account
)
error
{
return
nil
}
func
(
r
*
stubAccountRepo
)
Update
(
ctx
context
.
Context
,
account
*
service
.
Account
)
error
{
return
nil
}
func
(
r
*
stubAccountRepo
)
Delete
(
ctx
context
.
Context
,
id
int64
)
error
{
return
nil
}
func
(
r
*
stubAccountRepo
)
Delete
(
ctx
context
.
Context
,
id
int64
)
error
{
return
nil
}
func
(
r
*
stubAccountRepo
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
func
(
r
*
stubAccountRepo
)
List
(
ctx
context
.
Context
,
params
pagination
.
PaginationParams
)
([]
service
.
Account
,
*
pagination
.
PaginationResult
,
error
)
{
...
@@ -138,9 +141,6 @@ func (r *stubAccountRepo) ListSchedulableByGroupIDAndPlatforms(ctx context.Conte
...
@@ -138,9 +141,6 @@ func (r *stubAccountRepo) ListSchedulableByGroupIDAndPlatforms(ctx context.Conte
func
(
r
*
stubAccountRepo
)
SetRateLimited
(
ctx
context
.
Context
,
id
int64
,
resetAt
time
.
Time
)
error
{
func
(
r
*
stubAccountRepo
)
SetRateLimited
(
ctx
context
.
Context
,
id
int64
,
resetAt
time
.
Time
)
error
{
return
nil
return
nil
}
}
func
(
r
*
stubAccountRepo
)
SetAntigravityQuotaScopeLimit
(
ctx
context
.
Context
,
id
int64
,
scope
service
.
AntigravityQuotaScope
,
resetAt
time
.
Time
)
error
{
return
nil
}
func
(
r
*
stubAccountRepo
)
SetModelRateLimit
(
ctx
context
.
Context
,
id
int64
,
scope
string
,
resetAt
time
.
Time
)
error
{
func
(
r
*
stubAccountRepo
)
SetModelRateLimit
(
ctx
context
.
Context
,
id
int64
,
scope
string
,
resetAt
time
.
Time
)
error
{
return
nil
return
nil
}
}
...
@@ -227,6 +227,9 @@ func (r *stubGroupRepo) GetAccountIDsByGroupIDs(ctx context.Context, groupIDs []
...
@@ -227,6 +227,9 @@ func (r *stubGroupRepo) GetAccountIDsByGroupIDs(ctx context.Context, groupIDs []
func
(
r
*
stubGroupRepo
)
BindAccountsToGroup
(
ctx
context
.
Context
,
groupID
int64
,
accountIDs
[]
int64
)
error
{
func
(
r
*
stubGroupRepo
)
BindAccountsToGroup
(
ctx
context
.
Context
,
groupID
int64
,
accountIDs
[]
int64
)
error
{
return
nil
return
nil
}
}
func
(
r
*
stubGroupRepo
)
UpdateSortOrders
(
ctx
context
.
Context
,
updates
[]
service
.
GroupSortOrderUpdate
)
error
{
return
nil
}
type
stubUsageLogRepo
struct
{}
type
stubUsageLogRepo
struct
{}
...
@@ -367,7 +370,7 @@ func TestSoraGatewayHandler_ChatCompletions(t *testing.T) {
...
@@ -367,7 +370,7 @@ func TestSoraGatewayHandler_ChatCompletions(t *testing.T) {
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
testutil
.
StubGatewayCache
{}
,
cfg
,
cfg
,
nil
,
nil
,
concurrencyService
,
concurrencyService
,
...
@@ -378,6 +381,7 @@ func TestSoraGatewayHandler_ChatCompletions(t *testing.T) {
...
@@ -378,6 +381,7 @@ func TestSoraGatewayHandler_ChatCompletions(t *testing.T) {
nil
,
nil
,
deferredService
,
deferredService
,
nil
,
nil
,
testutil
.
StubSessionLimitCache
{},
nil
,
nil
,
)
)
...
...
backend/internal/service/gateway_account_selection_test.go
View file @
2bfb1629
...
@@ -74,11 +74,24 @@ func TestSortAccountsByPriorityAndLastUsed_StableSort(t *testing.T) {
...
@@ -74,11 +74,24 @@ func TestSortAccountsByPriorityAndLastUsed_StableSort(t *testing.T) {
{
ID
:
2
,
Priority
:
1
,
LastUsedAt
:
nil
,
Type
:
AccountTypeAPIKey
},
{
ID
:
2
,
Priority
:
1
,
LastUsedAt
:
nil
,
Type
:
AccountTypeAPIKey
},
{
ID
:
3
,
Priority
:
1
,
LastUsedAt
:
nil
,
Type
:
AccountTypeAPIKey
},
{
ID
:
3
,
Priority
:
1
,
LastUsedAt
:
nil
,
Type
:
AccountTypeAPIKey
},
}
}
sortAccountsByPriorityAndLastUsed
(
accounts
,
false
)
// 稳定排序:相同键值的元素保持原始顺序
// sortAccountsByPriorityAndLastUsed 内部会在同组(Priority+LastUsedAt)内做随机打散,
require
.
Equal
(
t
,
int64
(
1
),
accounts
[
0
]
.
ID
)
// 因此这里不再断言“稳定排序”。我们只验证:
require
.
Equal
(
t
,
int64
(
2
),
accounts
[
1
]
.
ID
)
// 1) 元素集合不变;2) 多次运行能产生不同的顺序。
require
.
Equal
(
t
,
int64
(
3
),
accounts
[
2
]
.
ID
)
seenFirst
:=
map
[
int64
]
bool
{}
for
i
:=
0
;
i
<
100
;
i
++
{
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
copy
(
cpy
,
accounts
)
sortAccountsByPriorityAndLastUsed
(
cpy
,
false
)
seenFirst
[
cpy
[
0
]
.
ID
]
=
true
ids
:=
map
[
int64
]
bool
{}
for
_
,
a
:=
range
cpy
{
ids
[
a
.
ID
]
=
true
}
require
.
True
(
t
,
ids
[
1
]
&&
ids
[
2
]
&&
ids
[
3
])
}
require
.
GreaterOrEqual
(
t
,
len
(
seenFirst
),
2
,
"同组账号应能被随机打散"
)
}
}
func
TestSortAccountsByPriorityAndLastUsed_MixedPriorityAndTime
(
t
*
testing
.
T
)
{
func
TestSortAccountsByPriorityAndLastUsed_MixedPriorityAndTime
(
t
*
testing
.
T
)
{
...
@@ -98,101 +111,96 @@ func TestSortAccountsByPriorityAndLastUsed_MixedPriorityAndTime(t *testing.T) {
...
@@ -98,101 +111,96 @@ func TestSortAccountsByPriorityAndLastUsed_MixedPriorityAndTime(t *testing.T) {
require
.
Equal
(
t
,
int64
(
4
),
accounts
[
3
]
.
ID
,
"优先级2 + 有时间"
)
require
.
Equal
(
t
,
int64
(
4
),
accounts
[
3
]
.
ID
,
"优先级2 + 有时间"
)
}
}
// ---
selectByCallCount
---
// ---
filterByMinPriority
---
func
Test
SelectByCallCount
_Empty
(
t
*
testing
.
T
)
{
func
Test
FilterByMinPriority
_Empty
(
t
*
testing
.
T
)
{
result
:=
selectByCallCount
(
nil
,
nil
,
false
)
result
:=
filterByMinPriority
(
nil
)
require
.
Nil
(
t
,
result
)
require
.
Nil
(
t
,
result
)
}
}
func
Test
SelectByCallCount_Single
(
t
*
testing
.
T
)
{
func
Test
FilterByMinPriority_SelectsMinPriority
(
t
*
testing
.
T
)
{
accounts
:=
[]
accountWithLoad
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
1
,
5
,
10
,
nil
,
AccountTypeAPIKey
),
}
makeAccWithLoad
(
2
,
1
,
10
,
nil
,
AccountTypeAPIKey
),
result
:=
selectByCallCount
(
accounts
,
map
[
int64
]
*
ModelLoadInfo
{
1
:
{
CallCount
:
10
}},
false
)
makeAccWithLoad
(
3
,
1
,
20
,
nil
,
AccountTypeAPIKey
),
require
.
NotNil
(
t
,
result
)
makeAccWithLoad
(
4
,
2
,
10
,
nil
,
AccountTypeAPIKey
),
require
.
Equal
(
t
,
int64
(
1
),
result
.
account
.
ID
)
}
result
:=
filterByMinPriority
(
accounts
)
require
.
Len
(
t
,
result
,
2
)
require
.
Equal
(
t
,
int64
(
2
),
result
[
0
]
.
account
.
ID
)
require
.
Equal
(
t
,
int64
(
3
),
result
[
1
]
.
account
.
ID
)
}
}
func
TestSelectByCallCount_NilModelLoadFallsBackToLRU
(
t
*
testing
.
T
)
{
// --- filterByMinLoadRate ---
now
:=
time
.
Now
()
accounts
:=
[]
accountWithLoad
{
func
TestFilterByMinLoadRate_Empty
(
t
*
testing
.
T
)
{
makeAccWithLoad
(
1
,
1
,
50
,
testTimePtr
(
now
),
AccountTypeAPIKey
),
result
:=
filterByMinLoadRate
(
nil
)
makeAccWithLoad
(
2
,
1
,
50
,
testTimePtr
(
now
.
Add
(
-
1
*
time
.
Hour
)),
AccountTypeAPIKey
),
require
.
Nil
(
t
,
result
)
}
result
:=
selectByCallCount
(
accounts
,
nil
,
false
)
require
.
NotNil
(
t
,
result
)
require
.
Equal
(
t
,
int64
(
2
),
result
.
account
.
ID
,
"nil modelLoadMap 应回退到 LRU 选择"
)
}
}
func
Test
SelectByCallCount
_SelectsMin
CallCount
(
t
*
testing
.
T
)
{
func
Test
FilterByMinLoadRate
_SelectsMin
LoadRate
(
t
*
testing
.
T
)
{
accounts
:=
[]
accountWithLoad
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
1
,
1
,
30
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
10
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
3
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
3
,
1
,
10
,
nil
,
AccountTypeAPIKey
),
}
makeAccWithLoad
(
4
,
1
,
20
,
nil
,
AccountTypeAPIKey
),
modelLoad
:=
map
[
int64
]
*
ModelLoadInfo
{
}
1
:
{
CallCount
:
100
},
result
:=
filterByMinLoadRate
(
accounts
)
2
:
{
CallCount
:
5
},
require
.
Len
(
t
,
result
,
2
)
3
:
{
CallCount
:
50
},
require
.
Equal
(
t
,
int64
(
2
),
result
[
0
]
.
account
.
ID
)
}
require
.
Equal
(
t
,
int64
(
3
),
result
[
1
]
.
account
.
ID
)
// 运行多次确认总是选调用次数最少的
}
for
i
:=
0
;
i
<
10
;
i
++
{
result
:=
selectByCallCount
(
accounts
,
modelLoad
,
false
)
// --- selectByLRU ---
func
TestSelectByLRU_Empty
(
t
*
testing
.
T
)
{
result
:=
selectByLRU
(
nil
,
false
)
require
.
Nil
(
t
,
result
)
}
func
TestSelectByLRU_Single
(
t
*
testing
.
T
)
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
10
,
nil
,
AccountTypeAPIKey
)}
result
:=
selectByLRU
(
accounts
,
false
)
require
.
NotNil
(
t
,
result
)
require
.
NotNil
(
t
,
result
)
require
.
Equal
(
t
,
int64
(
2
),
result
.
account
.
ID
,
"应选择调用次数最少的账号"
)
require
.
Equal
(
t
,
int64
(
1
),
result
.
account
.
ID
)
}
}
}
func
TestSelectByCallCount_NewAccountUsesAverage
(
t
*
testing
.
T
)
{
func
TestSelectByLRU_NilLastUsedAtWins
(
t
*
testing
.
T
)
{
now
:=
time
.
Now
()
accounts
:=
[]
accountWithLoad
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
1
,
1
,
10
,
testTimePtr
(
now
),
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
10
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
3
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
3
,
1
,
10
,
testTimePtr
(
now
.
Add
(
-
1
*
time
.
Hour
)),
AccountTypeAPIKey
),
}
// 账号1和2有调用记录,账号3是新账号(CallCount=0)
// 平均调用次数 = (100 + 200) / 2 = 150
// 新账号用平均值 150,比账号1(100)多,所以应选账号1
modelLoad
:=
map
[
int64
]
*
ModelLoadInfo
{
1
:
{
CallCount
:
100
},
2
:
{
CallCount
:
200
},
// 3 没有记录
}
}
for
i
:=
0
;
i
<
10
;
i
++
{
result
:=
selectByLRU
(
accounts
,
false
)
result
:=
selectByCallCount
(
accounts
,
modelLoad
,
false
)
require
.
NotNil
(
t
,
result
)
require
.
NotNil
(
t
,
result
)
require
.
Equal
(
t
,
int64
(
1
),
result
.
account
.
ID
,
"新账号虚拟调用次数(150)高于账号1(100),应选账号1"
)
require
.
Equal
(
t
,
int64
(
2
),
result
.
account
.
ID
)
}
}
}
func
TestSelectByCallCount_AllNewAccountsFallToAvgZero
(
t
*
testing
.
T
)
{
func
TestSelectByLRU_EarliestTimeWins
(
t
*
testing
.
T
)
{
now
:=
time
.
Now
()
accounts
:=
[]
accountWithLoad
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
1
,
1
,
10
,
testTimePtr
(
now
),
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
10
,
testTimePtr
(
now
.
Add
(
-
1
*
time
.
Hour
)),
AccountTypeAPIKey
),
makeAccWithLoad
(
3
,
1
,
10
,
testTimePtr
(
now
.
Add
(
-
2
*
time
.
Hour
)),
AccountTypeAPIKey
),
}
}
// 所有账号都是新的,avgCallCount = 0,所有人 effectiveCallCount 都是 0
result
:=
selectByLRU
(
accounts
,
false
)
modelLoad
:=
map
[
int64
]
*
ModelLoadInfo
{}
validIDs
:=
map
[
int64
]
bool
{
1
:
true
,
2
:
true
}
for
i
:=
0
;
i
<
10
;
i
++
{
result
:=
selectByCallCount
(
accounts
,
modelLoad
,
false
)
require
.
NotNil
(
t
,
result
)
require
.
NotNil
(
t
,
result
)
require
.
True
(
t
,
validIDs
[
result
.
account
.
ID
],
"所有新账号应随机选择"
)
require
.
Equal
(
t
,
int64
(
3
),
result
.
account
.
ID
)
}
}
}
func
TestSelectByCallCount_PreferOAuth
(
t
*
testing
.
T
)
{
func
TestSelectByLRU_TiePreferOAuth
(
t
*
testing
.
T
)
{
now
:=
time
.
Now
()
// 账号 1/2 LastUsedAt 相同,且同为最小值。
accounts
:=
[]
accountWithLoad
{
accounts
:=
[]
accountWithLoad
{
makeAccWithLoad
(
1
,
1
,
50
,
nil
,
AccountTypeAPIKey
),
makeAccWithLoad
(
1
,
1
,
10
,
testTimePtr
(
now
),
AccountTypeAPIKey
),
makeAccWithLoad
(
2
,
1
,
50
,
nil
,
AccountTypeOAuth
),
makeAccWithLoad
(
2
,
1
,
10
,
testTimePtr
(
now
),
AccountTypeOAuth
),
}
makeAccWithLoad
(
3
,
1
,
10
,
testTimePtr
(
now
.
Add
(
1
*
time
.
Hour
)),
AccountTypeAPIKey
),
// 两个账号调用次数相同
modelLoad
:=
map
[
int64
]
*
ModelLoadInfo
{
1
:
{
CallCount
:
10
},
2
:
{
CallCount
:
10
},
}
}
for
i
:=
0
;
i
<
1
0
;
i
++
{
for
i
:=
0
;
i
<
5
0
;
i
++
{
result
:=
selectBy
CallCount
(
accounts
,
modelLoad
,
true
)
result
:=
selectBy
LRU
(
accounts
,
true
)
require
.
NotNil
(
t
,
result
)
require
.
NotNil
(
t
,
result
)
require
.
Equal
(
t
,
int64
(
2
),
result
.
account
.
ID
,
"调用次数相同时应优先选择 OAuth 账号"
)
require
.
Equal
(
t
,
AccountTypeOAuth
,
result
.
account
.
Type
)
require
.
Equal
(
t
,
int64
(
2
),
result
.
account
.
ID
)
}
}
}
}
backend/internal/service/gateway_service.go
View file @
2bfb1629
...
@@ -1937,7 +1937,7 @@ func sortAccountsByPriorityAndLastUsed(accounts []*Account, preferOAuth bool) {
...
@@ -1937,7 +1937,7 @@ func sortAccountsByPriorityAndLastUsed(accounts []*Account, preferOAuth bool) {
return
a
.
LastUsedAt
.
Before
(
*
b
.
LastUsedAt
)
return
a
.
LastUsedAt
.
Before
(
*
b
.
LastUsedAt
)
}
}
})
})
shuffleWithinPriorityAndLastUsed
(
accounts
)
shuffleWithinPriorityAndLastUsed
(
accounts
,
preferOAuth
)
}
}
// shuffleWithinSortGroups 对排序后的 accountWithLoad 切片,按 (Priority, LoadRate, LastUsedAt) 分组后组内随机打乱。
// shuffleWithinSortGroups 对排序后的 accountWithLoad 切片,按 (Priority, LoadRate, LastUsedAt) 分组后组内随机打乱。
...
@@ -1973,7 +1973,12 @@ func sameAccountWithLoadGroup(a, b accountWithLoad) bool {
...
@@ -1973,7 +1973,12 @@ func sameAccountWithLoadGroup(a, b accountWithLoad) bool {
}
}
// shuffleWithinPriorityAndLastUsed 对排序后的 []*Account 切片,按 (Priority, LastUsedAt) 分组后组内随机打乱。
// shuffleWithinPriorityAndLastUsed 对排序后的 []*Account 切片,按 (Priority, LastUsedAt) 分组后组内随机打乱。
func
shuffleWithinPriorityAndLastUsed
(
accounts
[]
*
Account
)
{
//
// 注意:当 preferOAuth=true 时,需要保证 OAuth 账号在同组内仍然优先,否则会把排序时的偏好打散掉。
// 因此这里采用“组内分区 + 分区内 shuffle”的方式:
// - 先把同组账号按 (OAuth / 非 OAuth) 拆成两段,保持 OAuth 段在前;
// - 再分别在各段内随机打散,避免热点。
func
shuffleWithinPriorityAndLastUsed
(
accounts
[]
*
Account
,
preferOAuth
bool
)
{
if
len
(
accounts
)
<=
1
{
if
len
(
accounts
)
<=
1
{
return
return
}
}
...
@@ -1984,10 +1989,30 @@ func shuffleWithinPriorityAndLastUsed(accounts []*Account) {
...
@@ -1984,10 +1989,30 @@ func shuffleWithinPriorityAndLastUsed(accounts []*Account) {
j
++
j
++
}
}
if
j
-
i
>
1
{
if
j
-
i
>
1
{
if
preferOAuth
{
oauth
:=
make
([]
*
Account
,
0
,
j
-
i
)
others
:=
make
([]
*
Account
,
0
,
j
-
i
)
for
_
,
acc
:=
range
accounts
[
i
:
j
]
{
if
acc
.
Type
==
AccountTypeOAuth
{
oauth
=
append
(
oauth
,
acc
)
}
else
{
others
=
append
(
others
,
acc
)
}
}
if
len
(
oauth
)
>
1
{
mathrand
.
Shuffle
(
len
(
oauth
),
func
(
a
,
b
int
)
{
oauth
[
a
],
oauth
[
b
]
=
oauth
[
b
],
oauth
[
a
]
})
}
if
len
(
others
)
>
1
{
mathrand
.
Shuffle
(
len
(
others
),
func
(
a
,
b
int
)
{
others
[
a
],
others
[
b
]
=
others
[
b
],
others
[
a
]
})
}
copy
(
accounts
[
i
:
],
oauth
)
copy
(
accounts
[
i
+
len
(
oauth
)
:
],
others
)
}
else
{
mathrand
.
Shuffle
(
j
-
i
,
func
(
a
,
b
int
)
{
mathrand
.
Shuffle
(
j
-
i
,
func
(
a
,
b
int
)
{
accounts
[
i
+
a
],
accounts
[
i
+
b
]
=
accounts
[
i
+
b
],
accounts
[
i
+
a
]
accounts
[
i
+
a
],
accounts
[
i
+
b
]
=
accounts
[
i
+
b
],
accounts
[
i
+
a
]
})
})
}
}
}
i
=
j
i
=
j
}
}
}
}
...
...
backend/internal/service/scheduler_shuffle_test.go
View file @
2bfb1629
...
@@ -125,13 +125,13 @@ func TestShuffleWithinSortGroups_MixedGroups(t *testing.T) {
...
@@ -125,13 +125,13 @@ func TestShuffleWithinSortGroups_MixedGroups(t *testing.T) {
// ============ shuffleWithinPriorityAndLastUsed 测试 ============
// ============ shuffleWithinPriorityAndLastUsed 测试 ============
func
TestShuffleWithinPriorityAndLastUsed_Empty
(
t
*
testing
.
T
)
{
func
TestShuffleWithinPriorityAndLastUsed_Empty
(
t
*
testing
.
T
)
{
shuffleWithinPriorityAndLastUsed
(
nil
)
shuffleWithinPriorityAndLastUsed
(
nil
,
false
)
shuffleWithinPriorityAndLastUsed
([]
*
Account
{})
shuffleWithinPriorityAndLastUsed
([]
*
Account
{}
,
false
)
}
}
func
TestShuffleWithinPriorityAndLastUsed_SingleElement
(
t
*
testing
.
T
)
{
func
TestShuffleWithinPriorityAndLastUsed_SingleElement
(
t
*
testing
.
T
)
{
accounts
:=
[]
*
Account
{{
ID
:
1
,
Priority
:
1
}}
accounts
:=
[]
*
Account
{{
ID
:
1
,
Priority
:
1
}}
shuffleWithinPriorityAndLastUsed
(
accounts
)
shuffleWithinPriorityAndLastUsed
(
accounts
,
false
)
require
.
Equal
(
t
,
int64
(
1
),
accounts
[
0
]
.
ID
)
require
.
Equal
(
t
,
int64
(
1
),
accounts
[
0
]
.
ID
)
}
}
...
@@ -146,7 +146,7 @@ func TestShuffleWithinPriorityAndLastUsed_SameGroup_Shuffled(t *testing.T) {
...
@@ -146,7 +146,7 @@ func TestShuffleWithinPriorityAndLastUsed_SameGroup_Shuffled(t *testing.T) {
for
i
:=
0
;
i
<
100
;
i
++
{
for
i
:=
0
;
i
<
100
;
i
++
{
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
copy
(
cpy
,
accounts
)
copy
(
cpy
,
accounts
)
shuffleWithinPriorityAndLastUsed
(
cpy
)
shuffleWithinPriorityAndLastUsed
(
cpy
,
false
)
seen
[
cpy
[
0
]
.
ID
]
=
true
seen
[
cpy
[
0
]
.
ID
]
=
true
}
}
require
.
GreaterOrEqual
(
t
,
len
(
seen
),
2
,
"same group should be shuffled"
)
require
.
GreaterOrEqual
(
t
,
len
(
seen
),
2
,
"same group should be shuffled"
)
...
@@ -162,7 +162,7 @@ func TestShuffleWithinPriorityAndLastUsed_DifferentPriority_OrderPreserved(t *te
...
@@ -162,7 +162,7 @@ func TestShuffleWithinPriorityAndLastUsed_DifferentPriority_OrderPreserved(t *te
for
i
:=
0
;
i
<
20
;
i
++
{
for
i
:=
0
;
i
<
20
;
i
++
{
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
copy
(
cpy
,
accounts
)
copy
(
cpy
,
accounts
)
shuffleWithinPriorityAndLastUsed
(
cpy
)
shuffleWithinPriorityAndLastUsed
(
cpy
,
false
)
require
.
Equal
(
t
,
int64
(
1
),
cpy
[
0
]
.
ID
)
require
.
Equal
(
t
,
int64
(
1
),
cpy
[
0
]
.
ID
)
require
.
Equal
(
t
,
int64
(
2
),
cpy
[
1
]
.
ID
)
require
.
Equal
(
t
,
int64
(
2
),
cpy
[
1
]
.
ID
)
require
.
Equal
(
t
,
int64
(
3
),
cpy
[
2
]
.
ID
)
require
.
Equal
(
t
,
int64
(
3
),
cpy
[
2
]
.
ID
)
...
@@ -182,7 +182,7 @@ func TestShuffleWithinPriorityAndLastUsed_DifferentLastUsedAt_OrderPreserved(t *
...
@@ -182,7 +182,7 @@ func TestShuffleWithinPriorityAndLastUsed_DifferentLastUsedAt_OrderPreserved(t *
for
i
:=
0
;
i
<
20
;
i
++
{
for
i
:=
0
;
i
<
20
;
i
++
{
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
cpy
:=
make
([]
*
Account
,
len
(
accounts
))
copy
(
cpy
,
accounts
)
copy
(
cpy
,
accounts
)
shuffleWithinPriorityAndLastUsed
(
cpy
)
shuffleWithinPriorityAndLastUsed
(
cpy
,
false
)
require
.
Equal
(
t
,
int64
(
1
),
cpy
[
0
]
.
ID
)
require
.
Equal
(
t
,
int64
(
1
),
cpy
[
0
]
.
ID
)
require
.
Equal
(
t
,
int64
(
2
),
cpy
[
1
]
.
ID
)
require
.
Equal
(
t
,
int64
(
2
),
cpy
[
1
]
.
ID
)
require
.
Equal
(
t
,
int64
(
3
),
cpy
[
2
]
.
ID
)
require
.
Equal
(
t
,
int64
(
3
),
cpy
[
2
]
.
ID
)
...
...
backend/internal/testutil/stubs.go
View file @
2bfb1629
...
@@ -90,18 +90,6 @@ func (c StubGatewayCache) RefreshSessionTTL(_ context.Context, _ int64, _ string
...
@@ -90,18 +90,6 @@ func (c StubGatewayCache) RefreshSessionTTL(_ context.Context, _ int64, _ string
func
(
c
StubGatewayCache
)
DeleteSessionAccountID
(
_
context
.
Context
,
_
int64
,
_
string
)
error
{
func
(
c
StubGatewayCache
)
DeleteSessionAccountID
(
_
context
.
Context
,
_
int64
,
_
string
)
error
{
return
nil
return
nil
}
}
func
(
c
StubGatewayCache
)
IncrModelCallCount
(
_
context
.
Context
,
_
int64
,
_
string
)
(
int64
,
error
)
{
return
0
,
nil
}
func
(
c
StubGatewayCache
)
GetModelLoadBatch
(
_
context
.
Context
,
_
[]
int64
,
_
string
)
(
map
[
int64
]
*
service
.
ModelLoadInfo
,
error
)
{
return
nil
,
nil
}
func
(
c
StubGatewayCache
)
FindGeminiSession
(
_
context
.
Context
,
_
int64
,
_
,
_
string
)
(
string
,
int64
,
bool
)
{
return
""
,
0
,
false
}
func
(
c
StubGatewayCache
)
SaveGeminiSession
(
_
context
.
Context
,
_
int64
,
_
,
_
,
_
string
,
_
int64
)
error
{
return
nil
}
// ============================================================
// ============================================================
// StubSessionLimitCache — service.SessionLimitCache 的空实现
// StubSessionLimitCache — service.SessionLimitCache 的空实现
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment