fix: 应用 xhigh 代码评审的跨端修复
ci / server (push) Failing after 13s
ci / design-tokens (push) Failing after 11s

来自 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:
wangjia
2026-06-13 11:50:08 +08:00
parent 50b49f3cbe
commit b5ab92a57e
42 changed files with 2125 additions and 469 deletions
+34 -25
View File
@@ -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) {