#!/usr/bin/env bash # Test della barra di avanzamento (src/progress.c). # # Verifica: # 1. modalita' auto con output rediretto -> NESSUN output di progresso # (cosi' l'output resta identico al client Python: vedi parity_test.sh); # 2. modalita' auto su terminale (PTY via `script`) -> barra disegnata per il # download e per l'estrazione, con riga di riepilogo finale; # 3. CELLAR_PROGRESS=plain -> una riga per soglia del 10%, niente barra; # 4. CELLAR_PROGRESS=off -> nessun output di progresso anche su PTY; # 5. l'output finale (Downloaded to / Installed bottle) resta corretto e # l'archivio scaricato e' integro. set -uo pipefail ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) C_BIN="${C_BIN:-$ROOT/dist/cellar-cli}" PY="${PYTHON:-python3}" WORK="$ROOT/tests/tmp-progress" PORT="${PORT:-18097}" THROTTLE="${THROTTLE:-3000000}" # 3 MB/s: la barra disegna piu' fotogrammi SRV_PID="" PASS=0 FAIL=0 ok() { PASS=$((PASS + 1)); printf ' PASS %s\n' "$1"; } ko() { FAIL=$((FAIL + 1)); printf ' FAIL %s\n' "$1"; } cleanup() { [ -n "$SRV_PID" ] && kill "$SRV_PID" 2>/dev/null wait 2>/dev/null return 0 } trap cleanup EXIT fail_if_missing() { [ -x "$C_BIN" ] || { echo "binario non trovato: $C_BIN (esegui make all)"; exit 1; } command -v script >/dev/null || { echo "serve util-linux 'script' per il test su PTY"; exit 1; } } fail_if_missing rm -rf "$WORK" mkdir -p "$WORK"/{state,inst,bottles,home} # bottiglia di prova con un file da ~12 MB (comprimibile poco, cosi' il # download dura qualche secondo con il throttling) bash "$ROOT/tests/make_fake_bottle.sh" "$WORK/bottles" >/dev/null head -c 12000000 /dev/urandom >"$WORK/bottles/Fake Bottle/drive_c/big.bin" "$PY" "$ROOT/tests/mock_server.py" --port "$PORT" --state "$WORK/state" --throttle "$THROTTLE" & SRV_PID=$! for _ in $(seq 60); do curl -sf "http://127.0.0.1:$PORT/health" >/dev/null 2>&1 && break sleep 0.1 done SRV="http://127.0.0.1:$PORT" export HOME="$WORK/home" # archivio tar.gz valido (l'estrazione deve poter funzionare) "$PY" - "$WORK/bottles/Fake Bottle" "$WORK/big.tar.gz" <<'PYEOF' import sys, tarfile with tarfile.open(sys.argv[2], "w:gz") as tf: tf.add(sys.argv[1], arcname="Fake Bottle") PYEOF "$C_BIN" --server "$SRV" upload "$WORK/big.tar.gz" --name BigBottle \ --bottle-name "Fake Bottle" >/dev/null 2>&1 echo " (server mock pronto, archivio valido da $(stat -c%s "$WORK/big.tar.gz") byte caricato)" # ---------------------------------------------------------------- 1. auto su pipe out=$(CELLAR_PROGRESS=auto "$C_BIN" --server "$SRV" download 1 "$WORK/dl-pipe.bin" 2>&1) if [ "$out" = "Downloaded to $WORK/dl-pipe.bin" ]; then ok "auto su pipe: nessun output di progresso" else ko "auto su pipe: nessun output di progresso (ottenuto: $(printf '%s' "$out" | head -2 | tr '\n' '|'))" fi # ------------------------------------------------------------ 2. auto su PTY (barra) pty_out=$(script -qec "CELLAR_PROGRESS=auto '$C_BIN' --server '$SRV' install 'Fake Bottle' --bottles-dir '$WORK/inst'" /dev/null 2>&1 | tr '\r' '\n') if grep -q "Scaricamento \[" <<<"$pty_out"; then ok "PTY: barra del download disegnata" else ko "PTY: barra del download disegnata" fi if grep -q "Estrazione \[" <<<"$pty_out" || grep -q "^Estrazione:" <<<"$pty_out"; then ok "PTY: fase di estrazione tracciata" else ko "PTY: fase di estrazione tracciata" fi if grep -qE "^Scaricamento: [0-9.]+ (B|kB|MB|GB) in [0-9.]+ s" <<<"$pty_out"; then ok "PTY: riepilogo finale del download" else ko "PTY: riepilogo finale del download" fi if grep -q "^Installed bottle 'Fake Bottle' to " <<<"$pty_out"; then ok "PTY: output finale corretto dopo la barra" else ko "PTY: output finale corretto dopo la barra" fi if grep -q "ETA" <<<"$pty_out"; then ok "PTY: ETA mostrata durante il trasferimento" else ko "PTY: ETA mostrata durante il trasferimento" fi # nessun codice ANSI (retro-compatibilita' delle console) if grep -qP '\x1b\[' <<<"$pty_out"; then ko "PTY: nessun codice ANSI nel disegno" else ok "PTY: nessun codice ANSI nel disegno" fi # la barra non deve eccedere la larghezza del terminale (script: 80 colonne). # I glifi Unicode sono multi-byte: si contano i code point, non i byte. # solo le righe disegnate dalla barra (l'output normale puo' essere lungo) bar_lines=$(grep -E "^(Scaricamento|Estrazione)[ :]" <<<"$pty_out") longest=$(printf '%s' "$bar_lines" | "$PY" -c "import sys; print(max((len(l) for l in sys.stdin.read().split('\\n')), default=0))") if [ "${longest:-0}" -le 80 ]; then ok "PTY: righe entro 80 colonne (max $longest)" else ko "PTY: righe entro 80 colonne (max $longest)" printf '%s' "$bar_lines" | "$PY" -c " import sys lines = sys.stdin.buffer.read().decode('utf-8', 'replace').split('\n') for n, l in sorted(((len(x), x) for x in lines), reverse=True)[:3]: print(f' {n:3} |{l}|') " fi # --------------------------------------------------------------- 3. modalita' plain plain_out=$(CELLAR_PROGRESS=plain "$C_BIN" --server "$SRV" download 1 "$WORK/dl-plain.bin" 2>&1) lines=$(grep -c "^Scaricamento: [0-9]" <<<"$plain_out") if [ "$lines" -ge 10 ]; then ok "plain: $lines righe di avanzamento (>=10)" else ko "plain: righe di avanzamento insufficienti ($lines)" fi if grep -q "^Scaricamento: completato" <<<"$plain_out" && ! grep -q "\[" <<<"$plain_out"; then ok "plain: riepilogo presente e nessuna barra grafica" else ko "plain: riepilogo presente e nessuna barra grafica" fi # ---------------------------------------------------------------------- 4. off off_out=$(script -qec "CELLAR_PROGRESS=off '$C_BIN' --server '$SRV' download 1 '$WORK/dl-off.bin'" /dev/null 2>&1 | tr '\r' '\n') if ! grep -qE "Scaricamento" <<<"$off_out"; then ok "off: nessun output di progresso (anche su PTY)" else ko "off: nessun output di progresso (anche su PTY)" fi # ------------------------------------------------- 5. integrita' dell'artefatto if [ -f "$WORK/dl-pipe.bin" ] && cmp -s "$WORK/dl-pipe.bin" "$WORK/big.tar.gz"; then ok "integrita': il file scaricato coincide con quello caricato" else ko "integrita': il file scaricato coincide con quello caricato" fi if [ -f "$WORK/inst/Fake Bottle/bottle.yml" ]; then ok "install: bottiglia installata nonostante il disegno della barra" else ko "install: bottiglia installata nonostante il disegno della barra" fi echo echo "==================================================" printf 'PASS: %d FAIL: %d\n' "$PASS" "$FAIL" [ "$FAIL" -eq 0 ] || exit 1 echo "barra di avanzamento ok ✔"