ananke/internal/ups/nut_additional_test.go

109 lines
3.5 KiB
Go

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")
}
}