env_validation.bats
tests/env_validation.bats
6 passed
✓
Falla si CULTIVA_API_KEY no está definida
run deploy-agent.sh → status≠0, output contains "CULTIVA_API_KEY"
12ms
✓
Falla si AGENT_NAME no está definida
run deploy-agent.sh → status≠0, output contains "AGENT_NAME"
9ms
✓
Falla si ENV no está definida
run deploy-agent.sh → status≠0, output contains "ENV"
11ms
✓
Mensaje de error incluye instrucciones de uso
output contains "Usage:" when variables missing
10ms
✓
Falla si ENV tiene valor no permitido (solo staging/prod)
ENV=development → status≠0, output contains "invalid ENV"
13ms
✓
Acepta ENV=staging y ENV=prod como válidos
mock cultiva-cli success → status=0 for both values
28ms
error_conditions.bats
tests/error_conditions.bats
5 passed
✓
Falla si el directorio de trabajo no tiene permisos de escritura
chmod 555 WORK_DIR → status≠0, output contains "permission denied"
18ms
✓
Falla si curl devuelve HTTP 401 (API key inválida)
mock_curl returns 401 → status≠0, output contains "unauthorized"
22ms
✓
Falla si curl no puede conectar al endpoint
mock_curl exits 6 (curl: couldn't connect) → status≠0
14ms
✓
Falla si cultiva-cli devuelve exit code 1
mock_cultiva_cli exits 1 → propagates error, log contains FAILED
19ms
✓
Limpia directorio temporal incluso al fallar (trap EXIT)
inject failure mid-deploy → TMPDIR should be removed after run
31ms
mocks.bats
tests/mocks.bats
5 passed
✓
Mock curl devuelve JSON de config del agente
curl mock → {"agent":"lead-scorer","version":"2.1.0"}
16ms
✓
Mock cultiva-cli registra el comando correcto
mock logs invocation → assert "deploy lead-scorer --env staging"
20ms
✓
Deploy exitoso escribe entrada en log con timestamp
run complete flow → log file contains ISO timestamp + DEPLOYED
27ms
✓
Script pasa CULTIVA_API_KEY al header Authorization de curl
curl mock captures args → assert "-H Authorization: Bearer test-key"
15ms
✓
Operaciones paralelas no colisionan en TMPDIR
5 concurrent runs → each creates isolated subdir, all complete ok
89ms
shell_compat.bats
tests/shell_compat.bats
2 passed
1 skipped
✓
Script funciona con bash
bash deploy-agent.sh → status=0 with mocked deps
44ms
✓
Script funciona con sh (POSIX)
sh deploy-agent.sh → status=0 with mocked deps
38ms
◎
Script funciona con dash
skipped — dash not installed on runner
0ms
logging.bats
tests/logging.bats
2 passed
2 skipped
✓
Log de éxito incluye AGENT_NAME y ENV
grep log → "lead-scorer" + "staging" in same line
21ms
✓
Log de fallo incluye código de error de cultiva-cli
mock exit 2 → log contains "EXIT_CODE=2"
19ms
◎
Rotación de log si supera 10MB
skipped — jq not installed (requires stat + awk)
0ms
◎
Log con formato JSON si LOG_FORMAT=json
skipped — feature not yet implemented
0ms
tests/mocks/curl — mock de dependencia externa
bash
1#!/usr/bin/env bash
2# Mock de curl para tests unitarios de deploy-agent.sh
3# Intercepta llamadas sin red real; responde según MOCK_CURL_STATUS
4
5MOCK_STATUS="${MOCK_CURL_STATUS:-200}"
6
7# Registrar invocación para asserts posteriores
8echo "curl $*" >> "${MOCK_CURL_LOG:-/tmp/mock_curl.log}"
9
10if [[ $MOCK_STATUS == "401" ]]; then
11 echo '{"error":"unauthorized","message":"Invalid API key"}' >&2
12 exit 22 # curl exit code for HTTP error
13elif [[ $MOCK_STATUS == "conn" ]]; then
14 echo "curl: (6) Could not resolve host: api.cultivaia.com" >&2
15 exit 6
16else
17 # Happy path: devuelve config del agente
18 echo '{"agent":"lead-scorer","version":"2.1.0","env":"staging"}'
19 exit 0
20fi
tests/mocks.bats — test con mock y asserts
bats
1#!/usr/bin/env bats
2
3load 'test_helper'
4
5setup() {
6 setup_test_dir
7 # Inyectar mocks antes que los binarios reales
8 export PATH="${BATS_TEST_DIRNAME}/mocks:$PATH"
9 export CULTIVA_API_KEY="test-key-abc123"
10 export AGENT_NAME="lead-scorer"
11 export ENV="staging"
12 export MOCK_CURL_LOG="$TEST_DIR/curl.log"
13}
14
15teardown() {
16 cleanup_test_dir
17}
18
19@test "Script pasa CULTIVA_API_KEY al header Authorization de curl" {
20 run bash "${BATS_TEST_DIRNAME}/../bin/deploy-agent.sh"
21 [ "$status" -eq 0 ]
22 # Verificar que curl recibió el header correcto
23 run grep "-H" "$MOCK_CURL_LOG"
24 [[ "$output" == *"Authorization: Bearer test-key-abc123"* ]]
25}
26
27@test "Falla si curl devuelve HTTP 401 (API key inválida)" {
28 export MOCK_CURL_STATUS="401"
29 run bash "${BATS_TEST_DIRNAME}/../bin/deploy-agent.sh"
30 [ "$status" -ne 0 ]
31 [[ "$output" == *"unauthorized"* ]]
32}
●
GitHub Actions — .github/workflows/test.yml
Run #47 — passed
Checkout
3s
Install Bats
8s
Run Tests
5s
TAP Report
2s
Upload Logs
1s
Patrones aplicados
- error Validación de variables de entorno
- mock Intercepción de curl y cultiva-cli vía PATH
- error Permisos, HTTP 4xx, timeout de red
- helper setup/teardown con mktemp + trap EXIT
- compat bash / sh — compatibilidad POSIX
- CI GitHub Actions + TAP reporter
Cobertura de rutas
- ✓ Happy path: deploy completo ok
- ✓ ENV vars faltantes / inválidas (4 casos)
- ✓ Errores de red (curl 401, curl 6)
- ✓ cultiva-cli exit ≠ 0
- ✓ Permisos de directorio denegados
- ✓ Limpieza de TMPDIR (trap EXIT)