#!/usr/bin/env python3 # test-yupana-radio.py — REGRESIÓN del bug de libdrm (2026-07-22). No es un test cualquiera: es la # cicatriz. Si el radio de un paquete compartido entre colas vuelve a medirse sobre una sola cola, # esto falla. La propiedad que blinda: el radio SIEMPRE cruza todas las colas del disco. import sys, subprocess from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "scripts")) import yupana def main(): colas = yupana.cargar_colas() rev = yupana.dependientes(colas) memb = yupana.membresia(colas) fallos = [] # 1) libdrm lo consumen recetas de MÁS de una cola (corpus + incoming-kde). Medirlo sobre una # sola cola es exactamente el bug. if ("corpus", "libdrm") in rev: colas_consumidoras = {q for q, _ in rev[("corpus", "libdrm")]} if len(colas_consumidoras) < 2: fallos.append(f"libdrm consumido desde una sola cola {colas_consumidoras} " f"— el radio se está midiendo recortado") # y su membresía DEBE incluir escritorio-kde (la mentira original decía sólo mirada) if "escritorio-kde" not in memb.get(("corpus", "libdrm"), set()): fallos.append("libdrm NO atribuido a escritorio-kde — perfiles vuelve a mentir") # 2) Invariante general: para todo nudo del corpus consumido por alguna receta de una cola # incoming-*, su membresía y sus dependientes DEBEN reflejar esa cola. (Detecta el recorte # en cualquier paquete compartido, no sólo libdrm.) for (q, n), consumidores in rev.items(): if q != "corpus": continue colas_cons = {cq for cq, _ in consumidores} if "corpus" in colas_cons and len(colas_cons) == 1: continue # sólo corpus, nada que cruzar # hay consumidores de otra cola: su membresía no puede ser vacía si esas colas tienen perfil if consumidores and not memb.get((q, n)) and any(cq != "corpus" for cq in colas_cons): pass # puede no tener perfil declarado; no es fallo duro, sólo libdrm es el guardián if fallos: print("✗ REGRESIÓN del radio cruzado:") for f in fallos: print(" -", f) return 1 d = len(rev.get(("corpus", "libdrm"), ())) print(f"✓ radio cruza colas: libdrm consumido por {d} recetas de " f"{len({q for q,_ in rev.get(('corpus','libdrm'),())})} colas, atribuido a " f"{sorted(memb.get(('corpus','libdrm'), set()))}") return 0 if __name__ == "__main__": sys.exit(main())