Files
fn_registry/dev/proposals_e2e_checks_0121/sqlite_api.yaml
T
egutierrez 68bb9fbdae feat(0121a): wave 2 e2e_checks proposals (8 apps) + README updated
8 fn-recopilador design-e2e paralelos:
- services_api      (Go service, schema custom operations.db)
- registry_mcp      (Go stdio MCP, JSON-RPC handshake test)
- sqlite_api        (Go service read-only HTTP, query_endpoint)
- registry_dashboard (C++ ImGui, NO Go+React como yo supuse)
- primitives_gallery (C++ build gate de toda API C++ del registry, 44 .cpp)
- pipeline_launcher (Go TUI bubbletea)
- docker_tui        (Go TUI + go-duckdb)
- fn_match          (subcmd ./fn, hook helper, fuzzy match)

13/26 apps cubiertas. README documenta:
- 6 bugs/drift descubiertos lateral (dag_engine x3, deploy_server,
  pipeline_launcher, docker_tui).
- 3 correcciones de mi prompt (yo asumi stacks incorrectos).
- Hallazgos arquitectonicos (primitives_gallery = build gate C++).

Pendiente wave 3 (13 apps) + 0121b + 0121c.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:43:09 +02:00

115 lines
5.3 KiB
YAML

# e2e_checks proposal — sqlite_api
# app_id: projects/fn_monitoring/apps/sqlite_api
# lang: go
# stack: Go service, net/http, CGO_ENABLED=1, SQLite FTS5
# module: fn-registry (go.mod en raiz del repo)
# binary: projects/fn_monitoring/apps/sqlite_api/sqlite_api (pre-compilado)
# systemd: sqlite_api.service (user scope, ExecStart usa el binario compilado)
# e2e port: 8684 (prod 8484 + 200)
# e2e db: /tmp/sqlite_api_e2e.db
# date: 2026-05-19
# issue: 0121a wave 2
# nota: service critico — caida 20h el 2026-05-17 por Restart=on-failure
# (ya corregido a Restart=always en el unit). Checks refuerzan
# que el binario arranca, responde, y ejecuta queries correctamente.
e2e_checks:
# --- build ------------------------------------------------------------------
- id: build
# Compila el binario del service con CGO+FTS5.
# El binario resultante es el mismo que usa el systemd unit.
# Correr desde la raiz del repo porque go.mod vive ahi.
cmd: >
cd /home/lucas/fn_registry &&
CGO_ENABLED=1 go build -tags fts5
-o projects/fn_monitoring/apps/sqlite_api/sqlite_api
./projects/fn_monitoring/apps/sqlite_api/
timeout_s: 120
severity: critical
# --- tests ------------------------------------------------------------------
- id: tests
# Suite de tests unitarios Go existente (handlers_test.go).
# Cubre: /health, /api/databases, /api/databases/:db/query,
# ValidateQuery (whitelist SELECT/PRAGMA/WITH/EXPLAIN),
# DiscoverDatabases, /tables, /schema, 404 para DB inexistente.
# Usan DB en t.TempDir() — totalmente efimeros.
cmd: >
cd /home/lucas/fn_registry &&
CGO_ENABLED=1 go test -tags fts5 -count=1 -v
./projects/fn_monitoring/apps/sqlite_api/
timeout_s: 60
severity: critical
# --- smoke ------------------------------------------------------------------
- id: smoke
# Arranca el binario compilado con BD efimera y puerto alto.
# FN_REGISTRY_ROOT apunta a la raiz para que DiscoverDatabases
# encuentre registry.db real (necesario para /api/databases).
# El proceso queda en background; fn-analizador lo mata al terminar.
cmd: >
FN_REGISTRY_ROOT=/home/lucas/fn_registry
/home/lucas/fn_registry/projects/fn_monitoring/apps/sqlite_api/sqlite_api
--bind 127.0.0.1:8684
--data-factory-db /tmp/sqlite_api_e2e_df.db &
health: "http://127.0.0.1:8684/api/databases"
timeout_s: 10
severity: critical
# --- query_endpoint ---------------------------------------------------------
- id: query_endpoint
# Valida que el endpoint POST /api/databases/:db/query funciona end-to-end:
# 1. Crea una BD SQLite efimera con una tabla trivial.
# 2. La registra como argumento de query via BD de registro en /api/databases.
# 3. Ejecuta SELECT 1 contra la BD "registry" (siempre disponible si hay
# FN_REGISTRY_ROOT correcto) y valida JSON con count>=1 y campo "columns".
# Alternativa mas simple: hit directo al endpoint con la BD ya registrada.
cmd: >
curl -sf -X POST http://127.0.0.1:8684/api/databases/registry/query
-H 'Content-Type: application/json'
-d '{"sql":"SELECT 1 AS ping"}'
| python3 -c "
import sys, json
r = json.load(sys.stdin)
assert r.get('count') == 1, f'count != 1: {r}'
assert 'columns' in r, f'no columns: {r}'
assert r['columns'][0] == 'ping', f'col != ping: {r}'
print('query_endpoint OK:', r)
"
timeout_s: 10
severity: critical
# --- write_rejection --------------------------------------------------------
- id: write_rejection
# El service se declara read-only. Verifica que INSERT es rechazado con 400.
# Regresion directa del contrato de seguridad de sqlite_api.
cmd: >
STATUS=$(curl -s -o /dev/null -w "%{http_code}"
-X POST http://127.0.0.1:8684/api/databases/registry/query
-H 'Content-Type: application/json'
-d '{"sql":"INSERT INTO functions VALUES (\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\")"}') &&
[ "$STATUS" = "400" ]
timeout_s: 10
severity: critical
# --- auth_check -------------------------------------------------------------
- id: auth_check
# Service actualmente NO requiere auth (bind 127.0.0.1 mitiga).
# Este check documenta el estado actual: cualquier cliente local puede
# hacer queries. Si en el futuro se añade X-Registry-Token, este check
# debe actualizarse para enviar el token correcto y esperar 401 sin token.
# Por ahora verifica que el endpoint responde sin auth header (comportamiento esperado).
cmd: >
curl -sf http://127.0.0.1:8684/health
| python3 -c "import sys,json; r=json.load(sys.stdin); assert r['status']=='ok'"
timeout_s: 5
severity: warning
# --- ops_audit --------------------------------------------------------------
- id: ops_audit
# Invoca al fn-recopilador sobre las operations.db de apps de fn_monitoring.
# sqlite_api no tiene su propio operations.db pero es parte del proyecto
# fn_monitoring que sí tiene call_monitor con operations.db activa.
ref: "fn-recopilador:projects/fn_monitoring/apps/sqlite_api"
severity: warning