Match guest Discovery integration proof to native platform capabilities

Native Windows and macOS correctly advertise no PVE guest guard, so their real-server fixture must assert refusal before any config or QGA handoff. Keep the existing Linux admission, outcome and resumption assertions and exercise foreign platform labels without changing runtime capability policy.

Contract-Neutral: Test-only platform evidence repair; guest execution and Discovery runtime contracts, capability advertisement and safety gates are unchanged.
Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-04 22:49:53 +01:00
parent 6a20d10624
commit a2608c9fad
@@ -6,6 +6,7 @@ import (
"net/http"
"net/http/httptest"
"os/exec"
"runtime"
"strings"
"sync/atomic"
"testing"
@@ -39,13 +40,27 @@ func (e guestSafetyDiscoveryExecutor) IsAgentConnected(id string) bool {
// Real server/session/registration/agent/Discovery paths, with a fake non-QGA
// config reader and fake provider process. This is NOT native PVE acceptance.
func testGuestExecRealServerAgentDiscoveryAdmission(t *testing.T) {
platforms := []string{runtime.GOOS, "linux", "darwin", "windows"}
seen := make(map[string]bool)
for _, platform := range platforms {
if seen[platform] {
continue
}
seen[platform] = true
t.Run(platform, func(t *testing.T) {
testGuestExecRealServerAgentDiscoveryPlatform(t, platform)
})
}
}
func testGuestExecRealServerAgentDiscoveryPlatform(t *testing.T, platform string) {
s := agentexec.NewServer(func(token, agent, host string) bool {
return token == "fixture" && agent == "node-agent" && host == "node"
})
ts := httptest.NewServer(http.HandlerFunc(s.HandleWebSocket))
defer ts.Close()
logger := zerolog.Nop()
c := NewCommandClient(Config{PulseURL: ts.URL, APIToken: "fixture", StateDir: t.TempDir(), Logger: &logger}, "node-agent", "node", "linux", "6")
c := NewCommandClient(Config{PulseURL: ts.URL, APIToken: "fixture", StateDir: t.TempDir(), Logger: &logger}, "node-agent", "node", platform, "6")
var locked, lockDuringHandoff, failedGuest atomic.Bool
var qgaCalls, configReads atomic.Int32
locked.Store(true)
@@ -109,6 +124,27 @@ func testGuestExecRealServerAgentDiscoveryAdmission(t *testing.T) {
}
}
locked.Store(false)
if runtime.GOOS != "linux" || platform != "linux" {
// PVE admission belongs to a Linux host agent. A platform label must
// not make a non-Linux executable advertise that capability, and a
// Linux executable labelled as another platform must still be refused.
// Exercise the real registration and server gate, not a skipped test
// or an artificial capability override just to reach the happy path.
for _, rt := range []servicediscovery.ResourceType{servicediscovery.ResourceTypeVM, servicediscovery.ResourceTypeDockerVM} {
id := "105"
if rt == servicediscovery.ResourceTypeDockerVM {
id = "105:app"
}
got, err := scanner.Scan(context.Background(), servicediscovery.DiscoveryRequest{ResourceType: rt, ResourceID: id, TargetID: "node-agent"})
if err == nil || err.Error() != agentexec.GuestExecDeferred(agentexec.GuestExecGuardUnavailable).Error() || got == nil || len(got.CommandOutputs) != 0 || qgaCalls.Load() != 0 || configReads.Load() != 0 {
t.Fatalf("unsupported platform reached guest admission: %+v %v calls=%d reads=%d", got, err, qgaCalls.Load(), configReads.Load())
}
}
if !s.IsAgentConnected("node-agent") {
t.Fatal("platform deferral dropped session liveness")
}
return
}
got, err := scanner.ScanVM(context.Background(), "node-agent", "node", "105")
want := int32(len(servicediscovery.GetCommandsForResource(servicediscovery.ResourceTypeVM)))
if err != nil || got == nil || int32(len(got.CommandOutputs)) != want || qgaCalls.Load() != want {