gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

⎇ main scripts/test-craft-ventana.sh Shell · 99 lines · 4.9 KB History raw

recetas: la suite ArtCraft entera (12 apps egui+wgpu) + el arnés que mide si pintan 584247c3d · Sergio ·

1#!/bin/sh
2# test-craft-ventana.sh <app> — ¿ABRE VENTANA Y PINTA una app de la suite ArtCraft acá, sin Vulkan?
3#
4# Copia la mecánica de `scripts/test-atuq-boveda-metal.py` (SDD 26 §7.sexies): rootfs del perfil
5# `escritorio-sway` hidratado, capas de `bwrap` con la ÚLTIMA ganando, sway headless con el
6# renderer `pixman` (el compositor no necesita GL) y el CLIENTE por software con **llvmpipe, no
7# softpipe** — softpipe se queda en GL 3.3 y wgpu exige compute shaders.
8#
9# La evidencia no es el log: es la captura y el árbol del compositor.
10#   · `app_id` en el árbol de sway  ⇒ la ventana EXISTE
11#   · nº de colores de la captura   ⇒ la ventana PINTÓ (1 color = sólo el fondo de swaybg)
12#
13# uso:  scripts/test-craft-ventana.sh gridcraft          # y el control, que es el que vale:
14#       BACKEND=auto scripts/test-craft-ventana.sh gridcraft  # sin WGPU_BACKEND, como en la imagen
15set -e
16APP=${1:-gridcraft}
17ROOT=${ROOT:-/opt/takana}
18STORE=${STORE:-$ROOT/store}
19RFS=${RFS:-$ROOT/work/sway-rootfs}
20ALPINE=${ALPINE:-$ROOT/.dev-fs/alpine}
21SAL=${SAL:-$ROOT/work/$APP-ventana}
22BACKEND=${BACKEND:-gl}   # `gl` fuerza el camino EGL/GLES · `auto` deja el default de egui-wgpu (PRIMARY|GL)
23ESPERA=${ESPERA:-120}
24
25hash_de() { "$ROOT/target/release/takana" --store "$STORE" hash "recipes/$1.toml" | tail -1 | sed 's/^b3://'; }
26capa() {
27  d="$STORE/$(cd "$ROOT" && hash_de "$1")-$1"
28  [ -d "$d" ] || { echo "!! falta el artefacto vigente de $1 ($d)" >&2; exit 1; }
29  echo "$d"
30}
31
32[ -d "$RFS" ] || { echo "!! no está el rootfs de sway en $RFS — hidratalo con scripts/hydrate-profile.py escritorio-sway --into work/sway-rootfs --allow-missing" >&2; exit 1; }
33
34GC=$(capa "$APP")
35L18=$(capa llvm18)
36MLP=$(capa mesa-llvmpipe)
37echo "capas: alpine + sway-rootfs + $(basename "$L18") + $(basename "$MLP") + $(basename "$GC")"
38
39rm -rf "$SAL"; mkdir -p "$SAL"
40
41cat > "$SAL/dentro.sh" <<EOF
42#!/bin/sh
43export XDG_RUNTIME_DIR=/run/user/0 HOME=/salida/hogar LANG=C XDG_DATA_DIRS=/usr/share
44export WLR_BACKENDS=headless WLR_HEADLESS_OUTPUTS=1 WLR_RENDERER=pixman
45export LIBGL_ALWAYS_SOFTWARE=1 LIBGL_DRIVERS_PATH=/usr/lib/dri GALLIUM_DRIVER=llvmpipe
46[ "$BACKEND" = auto ] || export WGPU_BACKEND=$BACKEND   # auto = como en la imagen de verdad: egui-wgpu pide PRIMARY|GL
47# OJO: este heredoc va SIN comillas (necesita expandir $BACKEND), asi que NADA de backticks aca dentro:
48# en un heredoc sin comillas son SUSTITUCION DE COMANDOS, hasta en un comentario. Ya mordio una vez.
49export RUST_BACKTRACE=1 RUST_LOG=info,wgpu_core=info,wgpu_hal=info
50mkdir -p "\$XDG_RUNTIME_DIR" /salida/hogar; chmod 700 "\$XDG_RUNTIME_DIR"
51(
52  i=0
53  while [ ! -S /run/user/0/wayland-1 ] && [ \$i -lt 40 ]; do sleep 1; i=\$((i+1)); done
54  [ -S /run/user/0/wayland-1 ] || { echo "@@ sin socket wayland" >> /salida/log.txt; exit 1; }
55  export WAYLAND_DISPLAY=wayland-1
56  export SWAYSOCK=\$(ls /run/user/0/sway-ipc.* 2>/dev/null | head -1)
57  echo "@@ wayland listo" >> /salida/log.txt
58  /usr/bin/swaybg -c '#1a4b8c' >> /salida/swaybg.log 2>&1 &
59  sleep 2
60  /usr/bin/grim /salida/antes.png 2>>/salida/log.txt
61  echo "@@ lanzo $APP (backend=$BACKEND)" >> /salida/log.txt
62  /usr/bin/$APP > /salida/app.log 2>&1 &
63  PID=\$!
64  j=0
65  while [ \$j -lt $ESPERA ]; do
66    /usr/bin/swaymsg -t get_tree -r 2>/dev/null | grep -q '"app_id": *"ai.storyteller.$APP"' && break
67    kill -0 \$PID 2>/dev/null || { echo "@@ $APP MURIÓ a los \${j}s" >> /salida/log.txt; break; }
68    sleep 1; j=\$((j+1))
69  done
70  echo "@@ ventana en el árbol a los \${j}s" >> /salida/log.txt
71  /usr/bin/swaymsg -t get_tree -r > /salida/arbol.json 2>/dev/null
72  # Margen para el PRIMER FRAME: bajo llvmpipe aparecer en el árbol y haber pintado no es lo mismo.
73  sleep 10
74  /usr/bin/grim /salida/captura.png 2>>/salida/log.txt && echo "@@ grim ok" >> /salida/log.txt
75  sleep 1
76  /usr/bin/swaymsg exit 2>/dev/null
77) &
78exec /usr/bin/sway -d > /salida/sway.log 2>&1
79EOF
80
81bwrap \
82  --overlay-src "$ALPINE" --overlay-src "$RFS" \
83  --overlay-src "$L18" --overlay-src "$MLP" --overlay-src "$GC" \
84  --tmp-overlay / \
85  --dev-bind /dev /dev --proc /proc --bind /sys /sys \
86  --tmpfs /tmp --tmpfs /run --unshare-pid \
87  --bind "$SAL" /salida \
88  --uid 0 --gid 0 \
89  --setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \
90  /bin/sh /salida/dentro.sh || echo "(bwrap salió con $?)"
91
92echo "── veredicto ──────────────────────────────────────────────"
93grep -c "\"app_id\": *\"ai.storyteller.$APP\"" "$SAL/arbol.json" 2>/dev/null \
94  | sed 's/^/ventanas con el app_id: /' || echo "ventanas con el app_id: 0 (no hay árbol)"
95cat "$SAL/log.txt" 2>/dev/null | sed 's/^/  /'
96echo "── log de la app (últimas 25) ─────────────────────────────"
97tail -25 "$SAL/app.log" 2>/dev/null | sed 's/^/  /'
98echo "── colores (1 color = sólo el fondo de swaybg ⇒ NADIE dibujó) ──"
99python3 "$(dirname "$0")/png-colores.py" "$SAL/antes.png" "$SAL/captura.png" 2>/dev/null || ls -l "$SAL"/*.png