| index dd6634b00..530789309 100644 |
| --- a/internal/appconfig/unitsync_test.go |
| +++ b/internal/appconfig/unitsync_test.go |
| @@ -434,6 +434,41 @@ func TestSyncUnitsRefusedRouteKeepsAnEarlierMarker(t *testing.T) { |
| } |
| } |
| |
| +func TestSyncUnitsUnreadableDropInKeepsMarker(t *testing.T) { |
| + ctx, s, reg, envDir, priv := unitKit(t) |
| + f := newFakeUnits(t) |
| + f.loaded("relay.service", envDir, "relay.example.com") |
| + upsertStamped(t, reg, "relay.example.com", "relay.service", nil) |
| + syncOnce(t, ctx, reg, s, priv, envDir, f) // delivered, cleared |
| + |
| + // Make the drop-in unreadable with something other than not-exist: a |
| + // directory in its place. os.ReadFile on a directory errors without |
| + // os.IsNotExist, exactly the case readDropIn's caller must not treat |
| + // as "reaped". |
| + dropInPath := filepath.Join(dropInDir(f.root, "relay.service"), DropInFile) |
| + if err := os.Remove(dropInPath); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := os.Mkdir(dropInPath, 0o755); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := writePending(f.root, "relay.service"); err != nil { |
| + t.Fatal(err) |
| + } |
| + f.restarted = nil |
| + // The route is refused this pass (a second route names the unit), so |
| + // the only path that could clear or keep the marker is the drop-in |
| + // read at the top of the loop. |
| + upsertStamped(t, reg, "b.example.com", "relay.service", nil) |
| + out := syncOnce(t, ctx, reg, s, priv, envDir, f) |
| + if len(f.restarted) != 0 || !hasPending(f.root, "relay.service") { |
| + t.Fatalf("unreadable drop-in: restarted=%v pending=%v, want no restart and the marker kept", f.restarted, hasPending(f.root, "relay.service")) |
| + } |
| + if !strings.Contains(out, "read drop-in") { |
| + t.Fatalf("expected a read-drop-in failure line, got %q", out) |
| + } |
| +} |
| + |
| func TestEnvFilesMatch(t *testing.T) { |
| want := "/etc/carlos/apps/h.env" |
| if !envFilesMatch([]string{want}, want) { |