reap --dry-run says what would go, not that it went (#461)

A dry run printed "deleted <path> (N MB)" for every file and "deleted N
old file(s)" at the end, word for word a real reap, of files it kept:
Reaped and ReapDone carried no flag to say otherwise. Both now carry
dry_run (serde default false, so an older message still reads), and the
words are "would delete".

Found writing the browser suite's first test of retention, which ran on
the daemon's own clock and nowhere in the suite: over a tiny quota, a dry
reap lists the downloads and leaves them, and a reap with no limits
deletes nothing and only tidies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-14 03:59:02 +00:00
parent 61c38bacc1
commit f9f50fcf07
5 changed files with 50 additions and 9 deletions

View File

@@ -2915,3 +2915,28 @@ test('each service serves its metrics as Prometheus reads them, the requests mad
expect(play).toMatch(/^play_build_info\{version="[^"]+"\} 1$/m);
expect(play).toMatch(/^play_uptime_seconds [0-9]/m);
});
test('a reap over the quota says what it would delete and, dry, deletes nothing', async ({ page }) => {
// Retention (retention.rs) runs on the daemon's own clock in production, once a day; nothing in
// the suite ran it. Dry, so the files the tests after this one play are still there.
const env = { ...process.env, IPX_CONFIG: `${setup.root}/config/config.toml`, IPX_DATA_DIR: `${setup.root}/data` };
const ipx = (args: string[]) => execFileSync(setup.IPX_BIN, args, { env, encoding: 'utf8', timeout: 30_000 });
const files = () => fs.readdirSync(`${setup.root}/downloads`, { recursive: true, withFileTypes: true }).filter(f => f.isFile()).length;
const had = (await (await page.request.get('/api/settings')).json()).max_total_gb;
const before = files();
expect(before, 'the suite has downloaded files by now').toBeGreaterThan(0);
expect((await page.request.patch('/api/settings', { data: { max_total_gb: 0.000001 } })).status()).toBe(204);
try {
const out = ipx(['reap', '--dry-run']);
// Said as what would go, not as gone (#461).
expect(out).toMatch(/^would delete [1-9]\d* old file\(s\)/m);
expect(out).toMatch(/^would delete .+\/downloads\/.+ \(\d+\.\d MB\)$/m);
expect(out).not.toMatch(/^deleted /m);
expect(files(), 'a dry run deletes nothing').toBe(before);
} finally {
await page.request.patch('/api/settings', { data: { max_total_gb: had } });
}
// No limit: a real reap only tidies (the directory, where unread lists start, the artwork kept).
expect(ipx(['reap'])).toContain('deleted 0 old file(s), 0.0 MB');
expect(files()).toBe(before);
});