test(hosts): pin the symlink guard and the regex anchor of the temp sweep (#38) #43
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/vps-health-api#43
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-38-sweep-symlink-anchor-tests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #38
Two promises of
sweepStaleTempFiles()were held by no test (review of PR #37). Tests only:index.jsis unchanged.Added cases (
__tests__/hosts.test.js).thinkpad.4242.1700000000000.tmpto a regular file two hours old. The link and its target survive the sweep, with noconsole.error. The link itself is aged withlutimesSync, so the age check cannot be what spares it.prefix.thinkpad.4242.1700000000000.tmpadded to the "never touches" cases.Mutations on
index.jslstatSync->statSync^removed fromTEMP_FILE_RE!stat.isFile()droppedUnder the
statSyncmutation, the red comes from the return value and the vanished link. The target survives and nothing is logged either way: those two assertions are what the issue asks for, not what detects the mutation.The third mutation is beyond the issue: it follows from aging the link.
index.jswas restored from a backup copy and checked byte-identical (cmp,git diff --quiet).bash test-curl.sh45 / 45,scripts/boot-from-copy.shPASS.Out of scope, as in the issue: the exact one-hour threshold (
<=vs<).CLAUDE.md: counts 353 -> 355 and 171 -> 173.🤖 Generated with Claude Code
Revue adversariale : APPROVE
Résumé. Les deux cas demandés par #38 sont présents et rougissent sous leur mutation, rejouée par le relecteur sur une copie hors dépôt de la tête
198e1cf.index.jsn'est pas modifié par la PR ; le diff se limite à__tests__/hosts.test.jset aux compteurs deCLAUDE.md.Ce qui a été exécuté
hosts.test.jslstatSync->statSync(import ajouté, pour ne pas rougir sur unReferenceError)^retiré deTEMP_FILE_RE!stat.isFile()retiré!stat.isFile()->stat.isDirectory()(mutation du relecteur)Les trois premières lignes confirment le tableau de la PR. La quatrième est nouvelle : une garde qui n'écarterait que les dossiers laissait la suite verte avant cette PR, le cas symlink la ferme, grâce au vieillissement du lien par
lutimesSync.Copie restaurée et vérifiée par
cmp; l'arbre du dépôt n'a pas été touché.198e1cf:CI / verification (pull_request)ensuccess(statut de commit).pull_refde la PR #43 avecref_action: closes, l'issue se fermera au merge.CLAUDE.md(355 et 173) conformes au résultat mesuré.skip/only, aucun secret, pas de code de production modifié.Non rejoués par le relecteur :
bash test-curl.shetscripts/boot-from-copy.sh(couverts par la CI verte, et la PR ne touche aucun fichier qu'ils exercent).Suggestions (non bloquantes)
__tests__/hosts.test.js, cas symlink : la cibletarget.jsonn'a pas un nom de fichier temporaire, donc sa survie ne dépend pas du code testé. L'assertion répond à la lettre de l'issue, et le corps de la PR le dit déjà ; rien à changer, à garder en tête si le cas est repris.<=contre<) reste sans test.