From 2d801e20f32a4320bca2861294021669ea1dfdd3 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 19 Aug 2026 09:45:44 +0100 Subject: [PATCH] test(hostagent): stop the standby tests reading the runner's own disks TestCollectDeviceSMARTStandby and its observability twin stub smartctl's execution but not the device-class probe, so collectDeviceSMART fell through to the *runner's* real /sys/block/sda/queue/rotational. smartctlArgs only sends the -n standby guard when the disk is not a confirmed SSD (#1516), and smartctlArgsUseStandbyExitStatus gates the standby reading of exit status 3 on that guard having been sent. On a Linux host whose own /dev/sda is non-rotational the guard is dropped, exit 3 stops meaning standby, and both tests fail deterministically: run smartctl for /dev/sda: exit status 3 They pass on macOS only because linuxNonRotationalBlockDevice returns false off Linux, and on Linux only where /dev/sda is absent or spinning. That makes the release-qualification suite unrunnable on an ordinary SSD-backed Linux worker. Pin the probed disk to rotational through the package's existing stubLinuxSysfs seam so the guard is always in play. Product behaviour is untouched; this only stops two unit tests depending on the hardware underneath them. --- internal/hostagent/collector_observability_test.go | 8 ++++++++ internal/hostagent/smartctl_coverage_test.go | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/internal/hostagent/collector_observability_test.go b/internal/hostagent/collector_observability_test.go index ca43cbd6b..7a528a8e8 100644 --- a/internal/hostagent/collector_observability_test.go +++ b/internal/hostagent/collector_observability_test.go @@ -118,6 +118,14 @@ func TestCollectDeviceSMART_LogsStructuredContextWhenDeviceInStandby(t *testing. execLookPath = origLook }) + // Same host-sysfs leak as TestCollectDeviceSMARTStandby: the -n standby + // guard, and therefore the standby meaning of exit status 3, depends on + // the probed disk not being a confirmed SSD. Pin it to rotational instead + // of reading the runner's own /sys/block/sda/queue/rotational. + stubLinuxSysfs(t, []string{"sda"}, map[string]string{ + "/sys/block/sda/queue/rotational": "1\n", + }) + execLookPath = func(string) (string, error) { return "smartctl", nil } smartRunCommandOutput = func(ctx context.Context, name string, args ...string) ([]byte, error) { return exec.CommandContext(ctx, "sh", "-c", "exit 3").Output() diff --git a/internal/hostagent/smartctl_coverage_test.go b/internal/hostagent/smartctl_coverage_test.go index 4d868c69c..82e45099f 100644 --- a/internal/hostagent/smartctl_coverage_test.go +++ b/internal/hostagent/smartctl_coverage_test.go @@ -584,6 +584,16 @@ func TestCollectDeviceSMARTStandby(t *testing.T) { timeNow = origNow }) + // smartctlArgs only sends the -n standby guard for disks that are not + // confirmed SSDs, and exit status 3 only means standby when that guard + // was sent. Without a stubbed sysfs this reads the *runner's* real + // /sys/block/sda/queue/rotational, so the case under test evaporates on + // any Linux host whose own /dev/sda is an SSD. Pin the probed disk to + // rotational so the guard is always in play. + stubLinuxSysfs(t, []string{"sda"}, map[string]string{ + "/sys/block/sda/queue/rotational": "1\n", + }) + fixed := time.Date(2024, 2, 3, 4, 5, 6, 0, time.UTC) timeNow = func() time.Time { return fixed } execLookPath = func(string) (string, error) { return "smartctl", nil }