83 lines
2.7 KiB
Go
83 lines
2.7 KiB
Go
|
|
package upsquality
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"scm.bstein.dev/bstein/ananke/internal/ups"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TestNUTProviderReadCommandFailure runs one orchestration or CLI step.
|
||
|
|
// Signature: TestNUTProviderReadCommandFailure(t *testing.T).
|
||
|
|
// Why: ensures upsc execution failures are surfaced with target context.
|
||
|
|
func TestNUTProviderReadCommandFailure(t *testing.T) {
|
||
|
|
dir := t.TempDir()
|
||
|
|
upsc := filepath.Join(dir, "upsc")
|
||
|
|
script := "#!/usr/bin/env sh\necho boom >&2\nexit 7\n"
|
||
|
|
if err := os.WriteFile(upsc, []byte(script), 0o755); err != nil {
|
||
|
|
t.Fatalf("write fake upsc: %v", err)
|
||
|
|
}
|
||
|
|
t.Setenv("PATH", dir+":"+os.Getenv("PATH"))
|
||
|
|
|
||
|
|
p := ups.NewNUTProvider("statera@localhost")
|
||
|
|
_, err := p.Read(context.Background())
|
||
|
|
if err == nil || !strings.Contains(err.Error(), "upsc statera@localhost") {
|
||
|
|
t.Fatalf("expected contextual upsc failure, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestNUTProviderReadCoversNumericParseFailureBranch runs one orchestration or CLI step.
|
||
|
|
// Signature: TestNUTProviderReadCoversNumericParseFailureBranch(t *testing.T).
|
||
|
|
// Why: exercises parseFloat failure branch after symbol stripping.
|
||
|
|
func TestNUTProviderReadCoversNumericParseFailureBranch(t *testing.T) {
|
||
|
|
dir := t.TempDir()
|
||
|
|
upsc := filepath.Join(dir, "upsc")
|
||
|
|
script := `#!/usr/bin/env sh
|
||
|
|
cat <<'EOF'
|
||
|
|
ups.status: OB
|
||
|
|
battery.runtime: 10
|
||
|
|
battery.charge: ++
|
||
|
|
ups.load: --
|
||
|
|
ups.realpower.nominal: ..
|
||
|
|
EOF
|
||
|
|
`
|
||
|
|
if err := os.WriteFile(upsc, []byte(script), 0o755); err != nil {
|
||
|
|
t.Fatalf("write fake upsc: %v", err)
|
||
|
|
}
|
||
|
|
t.Setenv("PATH", dir+":"+os.Getenv("PATH"))
|
||
|
|
|
||
|
|
p := ups.NewNUTProvider("pyrphoros@localhost")
|
||
|
|
sample, err := p.Read(context.Background())
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("read sample: %v", err)
|
||
|
|
}
|
||
|
|
if !sample.OnBattery {
|
||
|
|
t.Fatalf("expected OB status to set OnBattery, got %+v", sample)
|
||
|
|
}
|
||
|
|
if sample.BatteryCharge != 0 || sample.LoadPercent != 0 || sample.NominalPowerW != 0 {
|
||
|
|
t.Fatalf("expected parse failures to leave numeric fields at zero, got %+v", sample)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestNUTProviderReadScannerTooLongError runs one orchestration or CLI step.
|
||
|
|
// Signature: TestNUTProviderReadScannerTooLongError(t *testing.T).
|
||
|
|
// Why: covers scanner error handling branch for malformed oversized NUT output lines.
|
||
|
|
func TestNUTProviderReadScannerTooLongError(t *testing.T) {
|
||
|
|
dir := t.TempDir()
|
||
|
|
upsc := filepath.Join(dir, "upsc")
|
||
|
|
long := strings.Repeat("x", 80*1024)
|
||
|
|
script := "#!/usr/bin/env sh\nprintf '%s\\n' '" + long + "'\n"
|
||
|
|
if err := os.WriteFile(upsc, []byte(script), 0o755); err != nil {
|
||
|
|
t.Fatalf("write fake upsc: %v", err)
|
||
|
|
}
|
||
|
|
t.Setenv("PATH", dir+":"+os.Getenv("PATH"))
|
||
|
|
|
||
|
|
p := ups.NewNUTProvider("oversize@localhost")
|
||
|
|
if _, err := p.Read(context.Background()); err == nil {
|
||
|
|
t.Fatalf("expected scanner token-size parse error")
|
||
|
|
}
|
||
|
|
}
|