mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
chore: 清理 emoji 与修正发布脚本仓库名
产品代码统一为纯文本风格(照参考实现),去掉 emoji:billing/quota/usage 插件、 channels 的提示文案、WebUI 文案,以及 go 测试、docs、packaging 脚本中的 注意/OK/FAIL 等符号化写法。第三方目录(vendor、node_modules、.probe)不动。 另:packaging/upload-release.sh 的仓库名改为真实全名 JianFeeeee/ModelRouter → HeNanMU-EEA/ModelRouter(前者是重定向,POST/PUT 不跟随 会 404)。
This commit is contained in:
@ -909,7 +909,7 @@ func TestBillingTracksCacheUsage(t *testing.T) {
|
||||
}
|
||||
// Only the first request reported a cache number.
|
||||
if total["cache_reported_reqs"] != float64(1) {
|
||||
t.Errorf("★ total.cache_reported_reqs = %v, want 1 — a source that never "+
|
||||
t.Errorf("total.cache_reported_reqs = %v, want 1 — a source that never "+
|
||||
"reports cache usage must be distinguishable from one reporting zero hits",
|
||||
total["cache_reported_reqs"])
|
||||
}
|
||||
@ -986,11 +986,11 @@ func TestBillingCacheHitClampedInStats(t *testing.T) {
|
||||
st := ps.State("billing").(map[string]interface{})
|
||||
tot := st["total"].(map[string]interface{})
|
||||
if tot["cache_hit_tokens"] != float64(100) {
|
||||
t.Errorf("★ cache_hit_tokens = %v, want 100 (clamped to prompt_tokens)",
|
||||
t.Errorf("cache_hit_tokens = %v, want 100 (clamped to prompt_tokens)",
|
||||
tot["cache_hit_tokens"])
|
||||
}
|
||||
if tot["cache_fresh_tokens"] != float64(0) {
|
||||
t.Errorf("★ cache_fresh_tokens = %v, want 0, never negative",
|
||||
t.Errorf("cache_fresh_tokens = %v, want 0, never negative",
|
||||
tot["cache_fresh_tokens"])
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ func TestBillingPageCoversItsData(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestPluginIconIsNotARawEmoji guards the sidebar icon. The billing plugin
|
||||
// declared icon = "💰" and the WebUI drops that verbatim into the button, while
|
||||
// declared icon = "" and the WebUI drops that verbatim into the button, while
|
||||
// every native tab uses an inline SVG styled with `stroke: currentColor`. An
|
||||
// emoji there renders at the wrong size and ignores the theme, so it does not
|
||||
// match its neighbours — which is what the operator reported.
|
||||
@ -335,7 +335,7 @@ func TestBillingTableHeaderMatchesRowColumns(t *testing.T) {
|
||||
td := strings.Count(row, "</td>")
|
||||
|
||||
if th != td {
|
||||
t.Errorf("★ header declares %d columns but row() emits %d cells — the "+
|
||||
t.Errorf("header declares %d columns but row() emits %d cells — the "+
|
||||
"table is misaligned from the first differing column on", th, td)
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ func TestFastPathIsActuallyUsed(t *testing.T) {
|
||||
"ts": float64(1700000000),
|
||||
}
|
||||
if _, ok := fastToPlain(realistic); !ok {
|
||||
t.Errorf("★ the realistic request payload does NOT take the fast path — " +
|
||||
t.Errorf("the realistic request payload does NOT take the fast path — " +
|
||||
"the JSON round-trip is still on the hot path for real traffic")
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ return p
|
||||
psOut := ps.Fire(StageRequestEnd, map[string]interface{}{"model": "m"})
|
||||
|
||||
if singleOut["who"] != "from-aaa" {
|
||||
t.Errorf("★ single-plugin path dropped the return value: %v", singleOut)
|
||||
t.Errorf("single-plugin path dropped the return value: %v", singleOut)
|
||||
}
|
||||
// Two plugins both return `who`; the merge order decides the winner, and it
|
||||
// must be deterministic (load order), not scheduler-dependent.
|
||||
@ -120,7 +120,7 @@ return p
|
||||
for i := 0; i < 60; i++ {
|
||||
got := ps.Fire(StageRequestEnd, map[string]interface{}{"model": "m"})["winner"]
|
||||
if got != first {
|
||||
t.Fatalf("★ winner changed between runs: %q then %q — merge depends on goroutine "+
|
||||
t.Fatalf("winner changed between runs: %q then %q — merge depends on goroutine "+
|
||||
"scheduling, so the same configuration behaves differently run to run", first, got)
|
||||
}
|
||||
}
|
||||
@ -164,7 +164,7 @@ return p
|
||||
t.Fatal("healthy plugin has no state")
|
||||
}
|
||||
if n := st["n"]; n != float64(1) {
|
||||
t.Errorf("★ healthy plugin did not run alongside the throwing one: n = %v", n)
|
||||
t.Errorf("healthy plugin did not run alongside the throwing one: n = %v", n)
|
||||
}
|
||||
he := ps.HookErrors()
|
||||
if len(he) == 0 {
|
||||
|
||||
@ -91,7 +91,7 @@ func TestStateSurvivesRestart(t *testing.T) {
|
||||
loadCounter(t, ps2)
|
||||
|
||||
if got := stateN(t, ps2); got != 25 {
|
||||
t.Fatalf("★ total after restart = %v, want 25 — this is the 'restart loses the books' bug", got)
|
||||
t.Fatalf("total after restart = %v, want 25 — this is the 'restart loses the books' bug", got)
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ func TestPricesOnlyUpdatePersists(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if saved.Prices["rate"] != float64(42) {
|
||||
t.Errorf("★ new price not persisted: %v — a restart would revert to the old price", saved.Prices)
|
||||
t.Errorf("new price not persisted: %v — a restart would revert to the old price", saved.Prices)
|
||||
}
|
||||
if saved.State["n"] != float64(5) {
|
||||
t.Errorf("state was clobbered by a price change: %v", saved.State["n"])
|
||||
@ -189,7 +189,7 @@ return plugin
|
||||
}
|
||||
out := ps.Fire(StageRequestEnd, map[string]interface{}{"model": "m", "source": "s"})
|
||||
if out["cost_usd"] != 1.25 {
|
||||
t.Errorf("★ hook return value lost: payload = %v", out)
|
||||
t.Errorf("hook return value lost: payload = %v", out)
|
||||
}
|
||||
if out["verdict"] != "billed" {
|
||||
t.Errorf("merged field lost: %v", out)
|
||||
@ -269,7 +269,7 @@ func TestCloseFlushesTail(t *testing.T) {
|
||||
|
||||
b, err := os.ReadFile(ps.stateFile("counter"))
|
||||
if err != nil {
|
||||
t.Fatalf("★ Close() did not flush: %v — a shutdown loses the tail", err)
|
||||
t.Fatalf("Close() did not flush: %v — a shutdown loses the tail", err)
|
||||
}
|
||||
var saved struct {
|
||||
State map[string]interface{} `json:"state"`
|
||||
@ -325,7 +325,7 @@ return plugin
|
||||
|
||||
b, err := os.ReadFile(ps.stateFile("ondemand"))
|
||||
if err != nil {
|
||||
t.Fatalf("★ an exported call did not mark the plugin dirty: %v — a plugin "+
|
||||
t.Fatalf("an exported call did not mark the plugin dirty: %v — a plugin "+
|
||||
"with no hooks can never persist its work", err)
|
||||
}
|
||||
var saved struct {
|
||||
|
||||
@ -47,6 +47,6 @@ return plugin`
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
if err := exec.Command("kill", "-0", pid).Run(); err == nil {
|
||||
exec.Command("kill", "-9", pid).Run()
|
||||
t.Fatal("★ unload 后进程仍存活 —— on_unload 未被调用")
|
||||
t.Fatal("unload 后进程仍存活 —— on_unload 未被调用")
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +260,7 @@ end
|
||||
-- 语义:命中任一 window ⇒ 乘以 multiplier。hours 用 {起,止} 闭区间,跨零点
|
||||
-- 用 {{22,24}} 表示 22:00-24:00(24 是"当天最后一刻")。
|
||||
--
|
||||
-- ★ 为什么用 os.date 的 ! 前缀取 UTC:provider 的费率表按 UTC 标注,而网关
|
||||
-- 关键:为什么用 os.date 的 ! 前缀取 UTC:provider 的费率表按 UTC 标注,而网关
|
||||
-- 跑在本地时区(这台机是 Asia/Hong_Kong)。混用本地小时会让峰谷整体偏移 8
|
||||
-- 小时,白天算成夜间——比不做峰谷还糟。
|
||||
local function inPeakWindow(ev)
|
||||
|
||||
@ -1177,7 +1177,7 @@ PLUGIN.ui = {
|
||||
'" style="width:'+Math.min(100,p)+'%"></div></div>'+
|
||||
'<div class="qa-w-d">$'+used.toFixed(2)+' / $'+cap.toFixed(0)+'</div>';
|
||||
if(r.cap_mismatch){
|
||||
h+='<div class="qa-warnl" title="已用+余额 与套餐额度不符,比例仅供参考">⚠ 额度口径可能有变</div>';
|
||||
h+='<div class="qa-warnl" title="已用+余额 与套餐额度不符,比例仅供参考">注意 额度口径可能有变</div>';
|
||||
}
|
||||
return h+"</div>";
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
-- 取自己的 /api/stats —— 它已按调用 key 隔离(实测:user key 231 次 = 自己的,
|
||||
-- admin 33847 次 = 全量)。
|
||||
--
|
||||
-- ★ 必须传**掩码**,不能传完整 key。
|
||||
-- 关键:必须传**掩码**,不能传完整 key。
|
||||
-- /api/stats 的统计 map 以 keyID(req.Key)(即 "***f9a9ed")为键 —— by_key
|
||||
-- 返回的就是它,面板传的也是它。而 admin 身份下 ?key= 接受任意值:传完整 key
|
||||
-- 会查不到,拿到零值。实测:
|
||||
|
||||
@ -220,7 +220,7 @@ p.ui = {
|
||||
page = {
|
||||
page_id = "billing",
|
||||
title = "Billing",
|
||||
icon = "💰",
|
||||
icon = "",
|
||||
order = 50,
|
||||
mount = "<div id=billing>hi</div><script>console.log('m')</script>",
|
||||
},
|
||||
|
||||
@ -98,7 +98,7 @@ func TestSecretVaultEncryptedAtRest(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(string(raw), "SUPER-TOKEN-123") {
|
||||
t.Fatalf("★ 保险库明文落盘! 文件内容含 token:\n%s", raw)
|
||||
t.Fatalf("保险库明文落盘! 文件内容含 token:\n%s", raw)
|
||||
}
|
||||
if !strings.Contains(string(raw), testEncPrefix) {
|
||||
t.Fatalf("落盘值应带 %s 前缀(统一密文形态):\n%s", testEncPrefix, raw)
|
||||
@ -140,7 +140,7 @@ func TestSecretVaultPlaintextFallbackAndUpgrade(t *testing.T) {
|
||||
}
|
||||
raw, _ := os.ReadFile(filepath.Join(dir, ".secrets", "channels.json"))
|
||||
if strings.Contains(string(raw), "OLD-PLAIN") {
|
||||
t.Fatalf("★ 升级写后旧明文值仍在盘上:\n%s", raw)
|
||||
t.Fatalf("升级写后旧明文值仍在盘上:\n%s", raw)
|
||||
}
|
||||
var m map[string]string
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
@ -169,7 +169,7 @@ func TestSecretVaultWrongMasterKey(t *testing.T) {
|
||||
// 换一把钥匙(模拟 master.key 丢失重建)
|
||||
ps.SetSecretBox(failBox{})
|
||||
if _, _, err := ps.GetSecret("channels", "k"); err == nil {
|
||||
t.Fatal("★ 换 master key 后读库未报错 —— 会静默吞凭据")
|
||||
t.Fatal("换 master key 后读库未报错 —— 会静默吞凭据")
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ func TestSecretVaultConcurrentPlugins(t *testing.T) {
|
||||
// 跨插件必须不可见
|
||||
other := "plug" + string(rune('A'+(p+1)%plugins))
|
||||
if _, ok, _ := ps.GetSecret(other, key); ok {
|
||||
t.Errorf("★ 凭据串台: %s 的键在 %s 可见", name, other)
|
||||
t.Errorf("凭据串台: %s 的键在 %s 可见", name, other)
|
||||
return
|
||||
}
|
||||
if g == 1 && i%10 == 9 {
|
||||
|
||||
Reference in New Issue
Block a user