Files
pangolin/server/internal/nodes/hub_isonline_test.go
wangjia 4c1a289633 fix(nodes): 节点健康/connect 绑定 agent 在线状态,不再伪装连上
本次 google 打不开暴露:agent 离线 6 天,节点却一直显示健康、还让客户端
"连上"(凭证推送失败被 _ = 吞掉),实际节点不认 UUID。三处收口:

- Hub.IsOnline(nodeUUID):基于本地 agent 流注册的存活信号(单实例权威;
  多实例需 Redis presence,另议)。
- ListNodes:effectiveNodeStatus 把 DB='up' 但 agent 离线的节点降级为
  "down",不再永远显示健康(status 列只反映供给/调度,不反映 agent 死活)。
- ConnectNode:agent 离线即 503 ErrNodeUnavailable(凭证持久化留待 resync),
  在线时 push 失败也 503——不再吞 pushErr、不再下发节点无法兑现的配置。

测试:TestHub_IsOnline(注册/结束/未注册)、TestEffectiveNodeStatus
(up+离线→down 等)。新增 apierr.ErrNodeUnavailable(503)。

掉线告警 + 静默吞错全量审计另起 TODO。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 08:36:31 +08:00

28 lines
721 B
Go

package nodes
import "testing"
// TestHub_IsOnline verifies the agent-liveness signal that ListNodes/ConnectNode
// now rely on: a node is online exactly while its agent stream is registered.
func TestHub_IsOnline(t *testing.T) {
h := NewHub(nil) // IsOnline/Register touch only the subs map, never Redis.
const node = "node-1"
if h.IsOnline(node) {
t.Fatal("IsOnline=true before any agent registered")
}
_, done := h.Register(node)
if !h.IsOnline(node) {
t.Fatal("IsOnline=false while agent stream registered")
}
if h.IsOnline("other") {
t.Fatal("IsOnline=true for a never-registered node")
}
done() // agent stream ends
if h.IsOnline(node) {
t.Fatal("IsOnline=true after the stream ended")
}
}