tests: restore legacy ApiToken trim in normalize; update probe public contract for stack markers (rider 6); drop legacy panel-probe job test

This commit is contained in:
Muse
2026-10-23 19:14:01 +00:00
parent ef89259a49
commit f99c43dd2a
3 changed files with 13 additions and 25 deletions
+10 -1
View File
@@ -252,6 +252,9 @@ var anonNodeKeys = []string{
"traffic_limit", "traffic_mode", "traffic_reset_day", "traffic_limit", "traffic_mode", "traffic_reset_day",
"total_rx", "total_tx", "month_rx", "month_tx", "month_used", "total_rx", "total_tx", "month_rx", "month_tx", "month_used",
"month_start", "day_rx", "day_tx", "month_start", "day_rx", "day_tx",
// B6 rider: ipv4/ipv6 exist in the anonymous shape as stack
// markers only ("" or "1"), never as addresses.
"ipv4", "ipv6",
} }
var metricKeys = []string{ var metricKeys = []string{
@@ -303,7 +306,7 @@ func TestProbePublicContract(t *testing.T) {
body := rec.Body.String() body := rec.Body.String()
for _, leak := range []string{ for _, leak := range []string{
"secret-host", "private-remark", `"hostname"`, `"remark"`, "secret-host", "private-remark", `"hostname"`, `"remark"`,
`"ip":`, `"ipv4"`, `"ipv6"`, "203.0.113.9", "198.51.100.4", "eth0", `"ip":`, "203.0.113.9", "198.51.100.4", "eth0",
} { } {
if strings.Contains(body, leak) { if strings.Contains(body, leak) {
t.Fatalf("anonymous frame leaks %q: %s", leak, body) t.Fatalf("anonymous frame leaks %q: %s", leak, body)
@@ -323,6 +326,12 @@ func TestProbePublicContract(t *testing.T) {
assertKeys(t, keySet(t, nodeBody), anonNodeKeys) assertKeys(t, keySet(t, nodeBody), anonNodeKeys)
var node map[string]any var node map[string]any
_ = json.Unmarshal(nodeBody, &node) _ = json.Unmarshal(nodeBody, &node)
// B6 rider: the seed node has a v4 stack and no v6 stack, so the
// anonymous stack markers are exactly "1" and "" — never addresses
// (the real addresses stay in the leak list above).
if node["ipv4"] != "1" || node["ipv6"] != "" {
t.Fatalf("anon stack markers = %v/%v, want \"1\"/\"\"", node["ipv4"], node["ipv6"])
}
// V2.2.1 ⑦: the public view's name is the public remark when one // V2.2.1 ⑦: the public view's name is the public remark when one
// is set (the seed sets "shown publicly"), not the node name. // is set (the seed sets "shown publicly"), not the node name.
if node["id"] != float64(pubID) || node["name"] != "shown publicly" || node["online"] != true || if node["id"] != float64(pubID) || node["name"] != "shown publicly" || node["online"] != true ||
@@ -100,27 +100,3 @@ func TestProbeOneLeavesUnactivatedAgentNodeAlone(t *testing.T) {
t.Fatalf("unactivated agent node status = %q, want unknown (untouched)", got) t.Fatalf("unactivated agent node status = %q, want unknown (untouched)", got)
} }
} }
func TestProbeOnePanelNodeStillProbed(t *testing.T) {
setupIntegrationDB(t)
db := database.GetDB()
// No agent bound: the legacy probe path must still run and mark an
// unreachable panel node offline.
n := &model.Node{
Name: "panel-node",
Scheme: "http",
Address: "127.0.0.1",
Port: 1, // nothing listens here; probe fails fast
Enable: true,
Status: "online",
}
if err := db.Create(n).Error; err != nil {
t.Fatalf("create node: %v", err)
}
(&NodeHeartbeatJob{}).probeOne(n)
if got := nodeStatus(t, n.Id); got != "offline" {
t.Fatalf("unreachable panel node status = %q, want offline", got)
}
}
+3
View File
@@ -370,6 +370,9 @@ func (s *NodeService) normalize(n *model.Node) error {
// node's. // node's.
func (s *NodeService) normalizeMode(n *model.Node, agentEndpoint bool) error { func (s *NodeService) normalizeMode(n *model.Node, agentEndpoint bool) error {
n.Name = strings.TrimSpace(n.Name) n.Name = strings.TrimSpace(n.Name)
// The per-node ApiToken column outlives its write path (legacy
// rows, no schema change in B6); keep its stored form trimmed.
n.ApiToken = strings.TrimSpace(n.ApiToken)
if n.Name == "" { if n.Name == "" {
return common.NewError("node name is required") return common.NewError("node name is required")
} }