gcli2api / internal /pool /sessiondead_test.go
a3216's picture
chore: 同步到上游 1.12.0-panel + 凭证同步/独立启动器/保活
6d60378 verified
Raw History Blame Contribute Delete
5.01 kB
package pool
import (
"path/filepath"
"testing"
"github.com/linguo2625469/workbuddy2api-panel/internal/auth"
)
// TestNoteSessionDeadThresholdNotReached 前 2 次连续 12153 不 Disable(误判防护)。
func TestNoteSessionDeadThresholdNotReached(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
if p.NoteSessionDead("u1") {
t.Fatal("第 1 次 12153 不应禁用")
}
if p.NoteSessionDead("u1") {
t.Fatal("第 2 次 12153 不应禁用")
}
st, ok := p.Status("u1")
if !ok {
t.Fatal("no status")
}
if st.Disabled {
t.Fatalf("连续 2 次 12153 不应禁用: %+v", st)
}
// 未达阈值时账号仍可选(keepalive 失败不污染选号)。
if got := p.Pick(); got == nil || got.UID != "u1" {
t.Fatalf("账号应保持可选, got %+v", got)
}
}
// TestNoteSessionDeadDisablesAtThird 连续第 3 次 12153 → 禁用并清计数。
func TestNoteSessionDeadDisablesAtThird(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.NoteSessionDead("u1")
p.NoteSessionDead("u1")
if !p.NoteSessionDead("u1") {
t.Fatal("第 3 次 12153 应禁用")
}
st, _ := p.Status("u1")
if !st.Disabled {
t.Fatalf("第 3 次后应 disabled: %+v", st)
}
if st.Reason != "12153 session dead" {
t.Errorf("reason=%q want 12153 session dead", st.Reason)
}
// 禁用后不再可选。
if p.Pick() != nil {
t.Fatal("禁用账号不可被选中")
}
}
// TestClearSessionDeadResetsCount 中间成功(refresh 成功)清计数,后续从 1 重新计。
func TestClearSessionDeadResetsCount(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.NoteSessionDead("u1")
p.NoteSessionDead("u1")
p.ClearSessionDead("u1") // 模拟 refresh 成功:清计数
if p.NoteSessionDead("u1") {
t.Fatal("清计数后第 1 次不应禁用")
}
if p.NoteSessionDead("u1") {
t.Fatal("清计数后第 2 次不应禁用")
}
if !p.NoteSessionDead("u1") {
t.Fatal("清计数后第 3 次应禁用(从 1 重新计够 3 次)")
}
}
// TestNoteSuccessClearsSessionDeadCount 任意成功(chat 成功)也是 session 未死的强证据,
// 同样清计数——与 refresh 成功口径一致。
func TestNoteSuccessClearsSessionDeadCount(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.NoteSessionDead("u1")
p.NoteSessionDead("u1")
p.NoteSuccess("u1")
if p.NoteSessionDead("u1") {
t.Fatal("成功清计数后第 1 次不应禁用")
}
}
// TestReviveDisabled 复活入口:清 disabled + reason + 误判计数,账号回到池子。
func TestReviveDisabled(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.NoteSessionDead("u1")
p.NoteSessionDead("u1")
p.NoteSessionDead("u1") // 触发禁用
if st, _ := p.Status("u1"); !st.Disabled {
t.Fatal("precondition: 应已禁用")
}
p.ReviveDisabled("u1")
st, ok := p.Status("u1")
if !ok {
t.Fatal("no status")
}
if st.Disabled {
t.Fatalf("revive 应清 disabled: %+v", st)
}
if st.Reason != "" {
t.Errorf("reason=%q want 空(revive 清 reason)", st.Reason)
}
if got := p.Pick(); got == nil || got.UID != "u1" {
t.Fatalf("复活后账号应回到池子, got %+v", got)
}
// 误判计数一并清零:复活后重新计满 3 次才禁用。
p.NoteSessionDead("u1")
if p.NoteSessionDead("u1") {
t.Fatal("复活后第 2 次不应禁用(应从新计数)")
}
if !p.NoteSessionDead("u1") {
t.Fatal("复活后第 3 次应禁用(从新计数够 3 次)")
}
}
// TestReviveDisabledPersists 复活清 disabled + reason 落盘持久化(重启后不回退)。
func TestReviveDisabledPersists(t *testing.T) {
dir := t.TempDir()
fp := filepath.Join(dir, "state.json")
p := New(fp)
p.Add(&auth.Auth{UID: "u1"})
p.Disable("u1", "12153 session dead")
p.ReviveDisabled("u1")
p.Flush()
p2 := New(fp)
p2.Add(&auth.Auth{UID: "u1"})
st, ok := p2.Status("u1")
if !ok || st.Disabled || st.Reason != "" {
t.Fatalf("revive 应持久化(disabled=%v reason=%q)ok=%v", st.Disabled, st.Reason, ok)
}
}
// TestStatusDisabledReasonDisabled when disabled, Status 透出 disabled_reason。
func TestStatusDisabledReasonDisabled(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.Disable("u1", "12153 session dead")
st, _ := p.Status("u1")
if !st.Disabled || st.DisabledReason != "12153 session dead" {
t.Errorf("disabled_reason=%q want 12153 session dead (disabled=%v)", st.DisabledReason, st.Disabled)
}
}
// TestStatusDisabledReasonClearedByRevive 复活后 disabled_reason 归空。
func TestStatusDisabledReasonClearedByRevive(t *testing.T) {
p := New("")
p.Add(&auth.Auth{UID: "u1"})
p.Disable("u1", "12153 session dead")
p.ReviveDisabled("u1")
st, _ := p.Status("u1")
if st.DisabledReason != "" {
t.Errorf("revive 后 disabled_reason=%q want 空", st.DisabledReason)
}
if st.Reason != "" {
t.Errorf("revive 后 reason=%q want 空", st.Reason)
}
}