mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Release v3.8.42 — full CHANGELOG in CHANGELOG.md. CI: 103 checks green incl. CodeQL (all languages), Semgrep, all 8 unit shards, coverage, Node 24 compat, and integration tests. Full unit suite validated locally: 19437 pass / 0 fail. The 3 red checks are advisory and do not gate main (no required status checks): SonarCloud/SonarQube new-code coverage gate, and PR Test Policy (test-masking detector flagging the legitimate dead-Phind provider removal in #5530 — reviewed, correct). Includes cycle-close reconciliation + repair of inherited base-red tests from #5480/#5527/#5427/#5521 that the PR->release fast-path did not exercise.
38 lines
1.7 KiB
TypeScript
38 lines
1.7 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, join } from "node:path";
|
|
|
|
// Regression guard for #5406: the database-import route deleted the live
|
|
// storage.sqlite + WAL/-shm/-journal sidecars with a plain synchronous
|
|
// `fs.unlinkSync` and no retry. On Windows the OS releases the SQLite file
|
|
// handle asynchronously after `db.close()` (mmap / antivirus), so the immediate
|
|
// unlink races and throws EBUSY. The restore path already solved this with
|
|
// `unlinkFileWithRetry` (EBUSY/EPERM backoff); the import path must use the
|
|
// same helper instead of raw `fs.unlinkSync`.
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = join(here, "..", "..");
|
|
const importRoute = join(repoRoot, "src/app/api/db-backups/import/route.ts");
|
|
|
|
test("#5406: import route uses unlinkFileWithRetry (EBUSY-safe on Windows)", () => {
|
|
const src = readFileSync(importRoute, "utf8");
|
|
assert.match(
|
|
src,
|
|
/unlinkFileWithRetry/,
|
|
"import route must delete the sqlite files via unlinkFileWithRetry (EBUSY retry)"
|
|
);
|
|
});
|
|
|
|
test("#5406: import route does not raw-unlink the live sqlite files (EBUSY race)", () => {
|
|
const src = readFileSync(importRoute, "utf8");
|
|
// The buggy code deleted the sqlite + WAL sidecars with `fs.unlinkSync(filePath)`
|
|
// inside the sqliteFilesToReplace loop. Only that path races to EBUSY; the
|
|
// temp-upload cleanup (`fs.unlinkSync(tmpPath)`) is a different, unlocked file.
|
|
assert.ok(
|
|
!/fs\.unlinkSync\s*\(\s*filePath\b/.test(src),
|
|
"the sqlite-replace loop must use unlinkFileWithRetry, not raw fs.unlinkSync(filePath)"
|
|
);
|
|
});
|