Skip to content

feat(LinuxTentacleE2E): Phase 12.M.L.B.3 — `service status` non-existent + unit Restart-hardening pin

Summary

Two surgical pins in one PR:

B5.u1-Linux — service status on non-registered service exits non-zero

Trivial sanity. Without this pin, a regression that swallows systemctl's "no such unit" error and exits 0 would break:

  • Operator scripts: service status && register patterns
  • Monitoring tools that interpret exit 0 as healthy

Sub-second runtime, no setup / cleanup.

B8.h-Linux — Unit file MUST contain crash-loop hardening directives

Directive Value Why pinned
Restart=on-failure (not always, not no) always = crash-loop floods journalctl/CPU; no = never recovers
RestartSec=10 10s Spacing between attempts
StartLimitBurst=3 3 Cap retries — systemd marks unit failed after 3 attempts
StartLimitIntervalSec=120 120s Sliding window for burst counter
TimeoutStopSec=330 330s Coordination with ShutdownDrainTimeoutSeconds=300 (lower → systemd SIGKILL before drain)

Coverage delta vs existing unit tests

Unit tier (ServiceCommandTests.GenerateUnitFile_*) pins the GENERATED string. E2E delta: round-trip from real binary → real /etc/systemd/system/ write → assert content. Catches integration regressions unit tests miss:

  • File.WriteAllText output mutated between generation + disk write (encoding / BOM)
  • Production code path that bypasses BuildUnitFile (regression that hardcodes a different template at the install call site)

Why hardening matters

Without Restart=on-failure + StartLimitBurst, a crashing v2 after upgrade would either:

  • Crash-loop forever (Restart=always) — floods journalctl, consumes CPU, masks the underlying bug
  • Stay permanently dead (Restart=no) — operator must manually intervene

The current 3-attempts-in-2-minutes policy is the operator-tuned middle ground (per BuildUnitFile rationale comments).

Fidelity tier

🟢 High (Rule 12.4): real binary + real systemd + real unit file content. B5.u1 runs without sudo (status reads world-readable systemctl state); B8.h uses fixture's sudo + cleanup pattern from B1.h/B2.h.

Test plan

  • Linux E2E workflow runs (manual workflow_dispatch after merge)
  • B5u1_ServiceStatus_NonExistentService_ExitsNonZero passes within ~1s
  • B8h_ServiceInstall_UnitFileContainsCrashLoopHardening passes within ~5s
  • No regression on existing 30 Linux E2E tests

🤖 Generated with Claude Code

Merge request reports

Loading