atuq §6.9: el guardián del torrent dejaba un daemon suelto y decía ✓

Encontrado con `ps` sobre la máquina, no por un test: al cerrar el sandbox quedaban
vivos el daemon y su `bwrap` interno, sosteniendo overlays ya borrados. Es correcto que
el daemon se quede —su torrent de prueba no tiene enjambre, así que nunca termina y
nunca está «sin nada»—, lo que faltaba era despedirlo y MEDIR que se fue.

- el guión de adentro le pide `puriy-costura-torrent stop` (el verbo del producto);
- la huella del socket se anota adentro y ANTES del stop: el daemon lo borra al irse;
- el guardián censa daemons antes/después con `ps -C` (nunca `pkill -f`) y falla
  nombrando el PID; el `finally` barre lo propio para que un test rojo no deje basura;
- tope de 180 s al sandbox, como seguro contra un cuelgue.

Comprobado en los dos sentidos con una copia rota fuera del repo: sin el `stop` el
guardián daba ✓ igual, y con la aserción nueva sale ✗ nombrando el PID. La hipótesis
de que se COLGARÍA era falsa: el `bwrap` externo vuelve; el que espera es el interno.

Verde: positivo, control negativo y rotura a propósito.
This commit is contained in:
Sergio
2026-09-10 21:29:28 +00:00
parent adeda7e499
commit b98c46b530
2 changed files with 92 additions and 6 deletions
+22
View File
@@ -901,6 +901,28 @@ estaba bien: **el que no llegaba a llamarla era el bucle**. Una decisión correc
igual que una que no existe. Arreglado (sin sesión = nada activo) y fijado con dos tests que corren el
PROCESO y el reloj de verdad, el segundo comprobado volviendo a poner el `continue`.
**La pereza tiene un residuo, y el guardián lo daba por bueno (2026-09-10).** El daemon se va
«tras 300 s **sin nada**», y un torrent sin enjambre nunca termina ⇒ nunca está sin nada: se queda,
que es lo correcto para un cliente de torrent. Pero el guardián cerraba el sandbox y se iba, y
**quedaba vivo el daemon Y el `bwrap` interno**, sosteniendo abiertos overlays ya borrados —
encontrado con `ps` sobre la máquina, no por un test. La corrección tiene dos mitades y ninguna
sobra:
1. el guión de adentro **despide al daemon** con `puriy-costura-torrent stop` — el propio verbo del
producto, así que de paso se ejerce;
2. el guardián **cuenta los daemons antes y después** (`ps -C`, nunca `pkill -f`, que empareja la
línea de comandos y se lleva la shell del que corre el test) y **falla nombrando el PID** si quedó
alguno; y barre lo propio en el `finally`, para que un test rojo tampoco deje basura.
Y el orden importa: la huella del socket se anota **adentro y antes** del `stop`, porque al irse el
daemon lo borra — mirarlo desde el hub después mediría el reloj, no el hecho. Comprobado en los dos
sentidos, quitando el `stop` en una copia fuera del repo: sin él el guardián decía ✓ igual y dejaba
un daemon suelto; con la aserción nueva sale
`✗ quedó un daemon vivo tras cerrar el sandbox: PID(s) [20157]`. La primera hipótesis —que sin `stop`
el guardián se COLGARÍA, porque `bwrap --unshare-pid` espera a su namespace— **era falsa y la
medición la descartó**: el `bwrap` externo vuelve, y el que se queda esperando es el interno. El tope
de 180 s quedó igual, pero por lo que es: seguro contra un cuelgue, no el que detecta la fuga.
**Lo que sigue sin estar en ningún test automático: un transfer real entre peers.** Haría falta un
sembrador y una espera que volverían la suite una que nadie corre. Está dicho también en el test del
daemon, al pie, para que nadie lo lea como «probado de punta a punta».