fix: 应用 xhigh 代码评审的跨端修复
来自 xhigh code review 的正确性/健壮性修复,覆盖全部五端: - server:鉴权 fail-closed、计量交叉校验与配额扣穿处理、WS 网关并发与关闭顺序、 billing 行锁、redis Lua 过期与设备槽刷新、config 解析 - desktop:会话 epoch 防串话、WS 重连与 401 处理、api 客户端复用、统一 usePoll 轮询 - android:握手时序、请求头封装、账户状态派生、按需重组 - ios:finalize 宽限、串行采集、错误文案服务端优先、删除死代码 CommitController Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@@ -155,35 +154,45 @@ func TestQuotaExceededOnStart(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// mrConsumeAll 把 u1 的当日试用直接耗尽(经 quota 通道,保证键一致)。
|
||||
// mrConsumeAll 把 u1 的当日试用耗尽(经 quota 通道,保证键一致)。
|
||||
// 单会话被截断在略低于 180s 处(截断帧不再计费,16A),故一会话不足以扣满 180s 试用;
|
||||
// 此处循环开会话推音频,直到某个 usage 帧报告 TrialRemaining<=0 为止。
|
||||
func mrConsumeAll(t *testing.T, srv *httptest.Server, db *gorm.DB) {
|
||||
t.Helper()
|
||||
conn := dial(t, srv)
|
||||
start, _ := json.Marshal(protocol.ClientMsg{Type: "start", SessionID: "s0", SampleRate: 16000})
|
||||
_ = conn.WriteMessage(websocket.TextMessage, start)
|
||||
frame := make([]byte, protocol.FrameBytes)
|
||||
// 180s 音频 = 1800 帧
|
||||
for i := 0; i < protocol.TrialDailySeconds*10; i++ {
|
||||
if err := conn.WriteMessage(websocket.BinaryMessage, frame); err != nil {
|
||||
t.Fatal(err)
|
||||
deadline := time.Now().Add(15 * time.Second)
|
||||
for sess := 0; sess < 5 && time.Now().Before(deadline); sess++ {
|
||||
conn := dial(t, srv)
|
||||
sid := "s0_" + string(rune('a'+sess))
|
||||
start, _ := json.Marshal(protocol.ClientMsg{Type: "start", SessionID: sid, SampleRate: 16000})
|
||||
_ = conn.WriteMessage(websocket.TextMessage, start)
|
||||
// 推 180s 音频(1800 帧)→ 会话在临界处截断
|
||||
for i := 0; i < protocol.TrialDailySeconds*10; i++ {
|
||||
if err := conn.WriteMessage(websocket.BinaryMessage, frame); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
stop, _ := json.Marshal(protocol.ClientMsg{Type: "stop", SessionID: sid})
|
||||
_ = conn.WriteMessage(websocket.TextMessage, stop)
|
||||
|
||||
exhausted := false
|
||||
for time.Now().Before(deadline) {
|
||||
_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||
var msg protocol.ServerMsg
|
||||
if err := conn.ReadJSON(&msg); err != nil {
|
||||
break
|
||||
}
|
||||
if msg.Type == protocol.MsgUsage && msg.TrialRemaining <= 0 {
|
||||
exhausted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
conn.Close()
|
||||
if exhausted {
|
||||
return
|
||||
}
|
||||
}
|
||||
stop, _ := json.Marshal(protocol.ClientMsg{Type: "stop", SessionID: "s0"})
|
||||
_ = conn.WriteMessage(websocket.TextMessage, stop)
|
||||
// 读到连接收尾的 usage 帧为止
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||
var msg protocol.ServerMsg
|
||||
if err := conn.ReadJSON(&msg); err != nil {
|
||||
break
|
||||
}
|
||||
if msg.Type == protocol.MsgUsage && msg.SessionSeconds >= protocol.TrialDailySeconds {
|
||||
break
|
||||
}
|
||||
}
|
||||
conn.Close()
|
||||
_ = context.Background()
|
||||
t.Fatal("failed to exhaust trial via repeated sessions")
|
||||
}
|
||||
|
||||
func TestSessionLimitTruncates(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user