Files
wehub-resource-sync 36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:06 +08:00

107 lines
3.1 KiB
Go

//go:build linux
package source
import (
"math"
"os"
"testing"
"time"
)
func TestCalendarSpec(t *testing.T) {
// D-Bus delivers TimersCalendar as [][]interface{}{{base, spec, next}}.
v := [][]interface{}{{"OnCalendar", "*-*-* 06,18:00:00", uint64(123)}}
if got := calendarSpec(v); got != "*-*-* 06,18:00:00" {
t.Errorf("calendarSpec = %q, want the calendar expression", got)
}
if got := calendarSpec(nil); got != "" {
t.Errorf("calendarSpec(nil) = %q, want empty", got)
}
}
func TestMonotonicSpec(t *testing.T) {
day := uint64((24 * time.Hour) / time.Microsecond)
tests := []struct {
base string
want string
}{
{"OnUnitActiveUSec", "every 1d"},
{"OnBootUSec", "every boot + 1d"},
{"OnUnitInactiveUSec", "every 1d after idle"},
}
for _, tt := range tests {
v := [][]interface{}{{tt.base, day, uint64(0)}}
if got := monotonicSpec(v); got != tt.want {
t.Errorf("monotonicSpec(%s) = %q, want %q", tt.base, got, tt.want)
}
}
if got := monotonicSpec(nil); got != "" {
t.Errorf("monotonicSpec(nil) = %q, want empty", got)
}
}
func TestHumanDuration(t *testing.T) {
cases := map[time.Duration]string{
25 * time.Hour: "1d 1h",
24 * time.Hour: "1d",
90 * time.Minute: "1h 30min",
90 * time.Second: "1min 30s",
5 * time.Second: "5s",
}
for d, want := range cases {
if got := humanDuration(d); got != want {
t.Errorf("humanDuration(%v) = %q, want %q", d, got, want)
}
}
}
func TestUsecToTime(t *testing.T) {
if !usecToTime(0).IsZero() {
t.Error("usecToTime(0) should be the zero time")
}
if !usecToTime(math.MaxUint64).IsZero() {
t.Error("usecToTime(MaxUint64) should be the zero time (systemd 'n/a' sentinel)")
}
got := usecToTime(uint64(time.Date(2024, 1, 2, 3, 4, 5, 0, time.UTC).UnixMicro()))
if got.IsZero() || got.UTC().Year() != 2024 {
t.Errorf("usecToTime(real value) = %v, want a 2024 time", got)
}
}
func TestFormatRelativeTime(t *testing.T) {
now := time.Now()
// Durations are buffered off the truncation boundaries so sub-second drift
// between now and the time.Since() call inside the function can't flip an
// "N min" bucket to "N-1".
cases := []struct {
d time.Duration // offset from now; negative = past, positive = future
want string
}{
{-30 * time.Second, "<1 min ago"},
{-(5*time.Minute + 30*time.Second), "5 min ago"},
{-(3*time.Hour + 30*time.Minute), "3h ago"},
{-50 * time.Hour, "2d ago"},
{30 * time.Second, "in <1 min"},
{5*time.Minute + 30*time.Second, "in 5 min"},
{3*time.Hour + 30*time.Minute, "in 3h"},
{50 * time.Hour, "in 2d"},
}
for _, tc := range cases {
if got := formatRelativeTime(now.Add(tc.d)); got != tc.want {
t.Errorf("formatRelativeTime(now%+v) = %q, want %q", tc.d, got, tc.want)
}
}
}
func TestGetUnitNameFromCgroupSelf(t *testing.T) {
// The result depends on the host's cgroup layout (a .scope, a .service, or
// nothing), so we only exercise the read+parse without asserting a value.
_ = getUnitNameFromCgroup(os.Getpid())
// PID 0 has no cgroup file, so the read fails and we get "".
if got := getUnitNameFromCgroup(0); got != "" {
t.Errorf("getUnitNameFromCgroup(0) = %q, want empty", got)
}
}