Review round 2: a media restart no longer starts an app the household stopped (R-721); the file manager's header name file appears whole (R-1100 race, 44/300 -> 0/300); both red-proved; unreleased
gates / gates (push) Successful in 1m22s
gates / gates (push) Successful in 1m22s
This commit is contained in:
@@ -283,6 +283,21 @@ func (m *Manager) MediaApps() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// MediaAppsToRecreate is MediaApps without the apps the household stopped (R-721, „a Stop holds"): the media restart
|
||||
// and the safe removal recreate with `up -d --force-recreate` (RestartStack), which would START a stopped app. Their
|
||||
// override is already written for the drives present now, so their next start sees them. `stopped` is returned for the
|
||||
// caller's log. Found by review round 2 (2026-10-24); pinned by TestMediaAppsToRecreate_SkipsAppsTheHouseholdStopped.
|
||||
func (m *Manager) MediaAppsToRecreate() (recreate, stopped []string) {
|
||||
for _, name := range m.MediaApps() {
|
||||
if m.WantsStopped(name) {
|
||||
stopped = append(stopped, name)
|
||||
continue
|
||||
}
|
||||
recreate = append(recreate, name)
|
||||
}
|
||||
return recreate, stopped
|
||||
}
|
||||
|
||||
// MediaAppsNeedingRestart renders every media app's override for the drives present NOW and returns the apps whose
|
||||
// binds changed — the apps that must restart to see a drive that was added, removed or came back (the notice of
|
||||
// decision 238). It writes the files; the restart itself is the household's „restart now" (RestartStack).
|
||||
|
||||
@@ -187,3 +187,30 @@ func TestAfterStartField_NotAskedAtInstall(t *testing.T) {
|
||||
t.Fatalf("the template shape must parse as required + after_start: %+v %v", meta.DeployFields, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Review round 2 (2026-10-24, DOC-D2 U2): the media restart („Újraindítás most", „Később") and the safe removal
|
||||
// recreate every media app with `up -d --force-recreate`, which STARTED an app the household had stopped — against
|
||||
// R-721 („a Stop holds"). COMPANION RED-PROOF: return every MediaApps() entry from MediaAppsToRecreate → the stopped app
|
||||
// is in `recreate` and this test fails. Restored.
|
||||
func TestMediaAppsToRecreate_SkipsAppsTheHouseholdStopped(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desired string
|
||||
wantRecreate bool
|
||||
}{{DesiredStateStopped, false}, {DesiredStateRunning, true}, {"", true}} {
|
||||
m, _ := newInstalledManager(t, sonarrLike, "deployed: true\nenv: {}\ndesired_state: "+tc.desired+"\n")
|
||||
dir := filepath.Dir(m.stacks["bookstack"].ComposePath)
|
||||
if err := os.WriteFile(filepath.Join(dir, ".felhom.yml"), []byte("media_library:\n read_only: true\n"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := m.MediaApps(); len(got) != 1 {
|
||||
t.Fatalf("fixture: want one media app, got %v", got)
|
||||
}
|
||||
recreate, stopped := m.MediaAppsToRecreate()
|
||||
if tc.wantRecreate && (len(recreate) != 1 || len(stopped) != 0) {
|
||||
t.Fatalf("desired %q: want recreated, got recreate=%v stopped=%v", tc.desired, recreate, stopped)
|
||||
}
|
||||
if !tc.wantRecreate && (len(recreate) != 0 || len(stopped) != 1) {
|
||||
t.Fatalf("desired %q: a stopped app must NOT be recreated (it would start), got recreate=%v stopped=%v", tc.desired, recreate, stopped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user