R-1247: the weekly upload line test — the agent's own iperf3 client to ep0's tunnel-only server, Tuesday 10:00-15:59 after 10 quiet minutes, under the heavy-op gate, best of 3; line_test stanza + GET /host/line-test; 15 tests red-proved; unreleased (next v0.164.0)
gates / gates (push) Successful in 1m35s
gates / gates (push) Successful in 1m35s
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// R-1247: the weekly line test has the fstrim shape (component + reporter seam + goroutine) plus a local-API reader,
|
||||
// so its wiring is asserted from the AST. It must share the ONE heavy-op gate (heavyOps) — or it could run beside a
|
||||
// backup — and take its server from the tunnel manager, never a literal address.
|
||||
func TestMainWiresTheLineTest(t *testing.T) {
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "main.go", nil, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("parse main.go: %v", err)
|
||||
}
|
||||
var withGate, withTunnelTarget, reporterWired, localAPIWired, started bool
|
||||
ast.Inspect(f, func(n ast.Node) bool {
|
||||
switch node := n.(type) {
|
||||
case *ast.CallExpr:
|
||||
if fn, ok := node.Fun.(*ast.SelectorExpr); ok {
|
||||
switch fn.Sel.Name {
|
||||
case "New":
|
||||
if pkg, ok := fn.X.(*ast.Ident); ok && pkg.Name == "linetest" && len(node.Args) >= 3 {
|
||||
if id, ok := node.Args[2].(*ast.Ident); ok && id.Name == "heavyOps" {
|
||||
withGate = true
|
||||
}
|
||||
if sel, ok := node.Args[1].(*ast.SelectorExpr); ok && sel.Sel.Name == "LineTestTarget" {
|
||||
withTunnelTarget = true
|
||||
}
|
||||
}
|
||||
case "SetLineTestReporter":
|
||||
reporterWired = true
|
||||
case "SetLineTest":
|
||||
localAPIWired = true
|
||||
}
|
||||
}
|
||||
case *ast.GoStmt:
|
||||
if sel, ok := node.Call.Fun.(*ast.SelectorExpr); ok && sel.Sel.Name == "Run" {
|
||||
if id, ok := sel.X.(*ast.Ident); ok && id.Name == "lineTest" {
|
||||
started = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
if !withGate {
|
||||
t.Error("main.go never calls linetest.New(..., heavyOps, ...) — no line test, or one outside the heavy-op gate")
|
||||
}
|
||||
if !withTunnelTarget {
|
||||
t.Error("linetest.New does not take its server from wgMgr.LineTestTarget")
|
||||
}
|
||||
if !reporterWired {
|
||||
t.Error("main.go never calls collector.SetLineTestReporter — the line_test stanza never reaches the hub")
|
||||
}
|
||||
if !localAPIWired {
|
||||
t.Error("main.go never calls localSrv.SetLineTest — the controller's GET /host/line-test always reads present:false")
|
||||
}
|
||||
if !started {
|
||||
t.Error("main.go never starts the line test with `go lineTest.Run(ctx)`")
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/guestnet"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/hub"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/lanresolver"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/linetest"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/localapi"
|
||||
applog "gitea.dooplex.hu/admin/felhom-agent/internal/log"
|
||||
"gitea.dooplex.hu/admin/felhom-agent/internal/mgmtplane"
|
||||
@@ -1641,6 +1642,24 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
|
||||
} else {
|
||||
logger.Info("fstrim: weekly guest disk trim disabled by config (disk_trim.disable)")
|
||||
}
|
||||
// R-1247 (operator ruling 2026-10-24 07:26): the weekly upload line test — a 10-second iperf3 upload from this host
|
||||
// to ep0's tunnel-only server, Tuesday 10:00-15:59 local, after 10 quiet minutes, under the one-heavy-op gate. Only
|
||||
// with the offsite tunnel (the server is reachable nowhere else). Not part of the errc fan-out.
|
||||
switch {
|
||||
case !cfg.LineTest.Enabled():
|
||||
logger.Info("linetest: weekly upload line test disabled by config (line_test.disable)")
|
||||
case wgMgr == nil:
|
||||
logger.Info("linetest: weekly upload line test off — no offsite tunnel on this host")
|
||||
default:
|
||||
lineTest := linetest.New(linetest.Client{Streams: linetest.Streams, Time: linetest.TestTime}, wgMgr.LineTestTarget,
|
||||
heavyOps, linetest.SysUplinkTx("/"), cfg.Hub.HostID,
|
||||
filepath.Join(cfg.OOB.WithDefaults().StateDir, "line-test.json"), logger)
|
||||
collector.SetLineTestReporter(lineTest)
|
||||
if localSrv != nil {
|
||||
localSrv.SetLineTest(lineTest)
|
||||
}
|
||||
go lineTest.Run(ctx)
|
||||
}
|
||||
if lanLoop != nil {
|
||||
lanServers = 1
|
||||
go func() { errc <- lanLoop.Run(ctx) }()
|
||||
|
||||
Reference in New Issue
Block a user