package ups import ( "context" "os" "path/filepath" "strings" "testing" ) // TestParseNUTRejectsMissingStatus runs one orchestration or CLI step. // Signature: TestParseNUTRejectsMissingStatus(t *testing.T). // Why: covers parser error path when mandatory status line is absent. func TestParseNUTRejectsMissingStatus(t *testing.T) { if _, err := parseNUT("battery.charge: 88"); err == nil { t.Fatalf("expected missing status error") } } // TestParseNUTParsesOptionalNumbers runs one orchestration or CLI step. // Signature: TestParseNUTParsesOptionalNumbers(t *testing.T). // Why: covers numeric extraction branches for charge/load/nominal fields. func TestParseNUTParsesOptionalNumbers(t *testing.T) { raw := strings.Join([]string{ "ups.status: OB LB", "battery.runtime: 1024", "battery.charge: 71.5 Percent", "ups.load: 12.0 Percent", "ups.realpower.nominal: 900 W", "", }, "\n") s, err := parseNUT(raw) if err != nil { t.Fatalf("parseNUT failed: %v", err) } if !s.OnBattery || !s.LowBattery || s.RuntimeSeconds != 1024 { t.Fatalf("unexpected status parse: %+v", s) } if s.BatteryCharge != 71.5 || s.LoadPercent != 12 || s.NominalPowerW != 900 { t.Fatalf("unexpected numeric parse: %+v", s) } } // TestNUTProviderReadViaPathShim runs one orchestration or CLI step. // Signature: TestNUTProviderReadViaPathShim(t *testing.T). // Why: covers provider command execution success path deterministically. func TestNUTProviderReadViaPathShim(t *testing.T) { tmp := t.TempDir() upscPath := filepath.Join(tmp, "upsc") script := `#!/usr/bin/env bash set -euo pipefail echo "ups.status: OL" echo "battery.runtime: 500" ` if err := os.WriteFile(upscPath, []byte(script), 0o755); err != nil { t.Fatalf("write fake upsc: %v", err) } t.Setenv("PATH", tmp+":"+os.Getenv("PATH")) sample, err := NewNUTProvider("statera@localhost").Read(context.Background()) if err != nil { t.Fatalf("provider read failed: %v", err) } if sample.OnBattery { t.Fatalf("expected OL to report not-on-battery") } if sample.RuntimeSeconds != 500 { t.Fatalf("expected runtime 500, got %d", sample.RuntimeSeconds) } } // TestNUTProviderReadRejectsEmptyTarget runs one orchestration or CLI step. // Signature: TestNUTProviderReadRejectsEmptyTarget(t *testing.T). // Why: covers provider guard for empty NUT target values. func TestNUTProviderReadRejectsEmptyTarget(t *testing.T) { if _, err := NewNUTProvider("").Read(context.Background()); err == nil { t.Fatalf("expected empty-target read error") } } // TestParseNumberRejectsInvalid runs one orchestration or CLI step. // Signature: TestParseNumberRejectsInvalid(t *testing.T). // Why: covers parseNumber false-return branch for invalid input. func TestParseNumberRejectsInvalid(t *testing.T) { if _, ok := parseNumber("not-a-number"); ok { t.Fatalf("expected parseNumber to reject invalid input") } } // TestNUTProviderReadCommandFailure runs one orchestration or CLI step. // Signature: TestNUTProviderReadCommandFailure(t *testing.T). // Why: covers provider error propagation when upsc exits non-zero. func TestNUTProviderReadCommandFailure(t *testing.T) { tmp := t.TempDir() upscPath := filepath.Join(tmp, "upsc") script := `#!/usr/bin/env bash set -euo pipefail echo "upsc failed" >&2 exit 2 ` if err := os.WriteFile(upscPath, []byte(script), 0o755); err != nil { t.Fatalf("write fake upsc: %v", err) } t.Setenv("PATH", tmp+":"+os.Getenv("PATH")) if _, err := NewNUTProvider("pyrphoros@localhost").Read(context.Background()); err == nil { t.Fatalf("expected provider read error on upsc failure") } }