11#! /usr/bin/env bash
22# test-lab-10-03.sh — Lab 10-03: Advanced Features
33# Module 10: FreePBX/Asterisk VoIP PBX
4- # freepbx with TLS, resource limits, and production-grade configuration
4+ # Tests: resource limits + AMI interface + recordings/MOH/voicemail volumes + dialplan
55set -euo pipefail
66
77LAB_ID=" 10-03"
@@ -11,61 +11,142 @@ COMPOSE_FILE="docker/docker-compose.advanced.yml"
1111PASS=0
1212FAIL=0
1313
14- # ── Colors ────────────────────────────────────────────────────────────────────
1514RED=' \033[0;31m' ; GREEN=' \033[0;32m' ; YELLOW=' \033[1;33m'
1615CYAN=' \033[0;36m' ; NC=' \033[0m'
1716
18- pass () { echo -e " ${GREEN} [PASS]${NC} $1 " ; (( PASS++ )) ; }
19- fail () { echo -e " ${RED} [FAIL]${NC} $1 " ; (( FAIL++ )) ; }
20- info () { echo -e " ${CYAN} [INFO] $ {NC} $1 " ; }
21- warn () { echo -e " ${YELLOW} [WARN ]${NC} $1 " ; }
17+ pass () { echo -e " ${GREEN} [PASS]${NC} $1 " ; (( PASS++ )) ; }
18+ fail () { echo -e " ${RED} [FAIL]${NC} $1 " ; (( FAIL++ )) ; }
19+ section () { echo -e " \n ${CYAN} ── $1 ── $ {NC}" ; }
20+ info () { echo -e " ${CYAN} [INFO ]${NC} $1 " ; }
2221
23- echo -e " ${CYAN} ======================================${NC} "
22+ CLEANUP=true
23+ [[ " ${1:- } " == " --no-cleanup" ]] && CLEANUP=false
24+
25+ cleanup () {
26+ if [[ " ${CLEANUP} " == " true" ]]; then
27+ info " Cleaning up..."
28+ docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans 2> /dev/null || true
29+ fi
30+ }
31+ trap cleanup EXIT
32+
33+ echo -e " ${CYAN} ========================================${NC} "
2434echo -e " ${CYAN} Lab ${LAB_ID} : ${LAB_NAME}${NC} "
2535echo -e " ${CYAN} Module: ${MODULE}${NC} "
26- echo -e " ${CYAN} ======================================${NC} "
27- echo " "
36+ echo -e " ${CYAN} ========================================${NC} "
2837
2938# ── PHASE 1: Setup ────────────────────────────────────────────────────────────
30- info " Phase 1: Setup"
39+ section " Phase 1: Setup"
3140docker compose -f " ${COMPOSE_FILE} " up -d
32- info " Waiting 30s for ${MODULE} to initialize..."
33- sleep 30
3441
3542# ── PHASE 2: Health Checks ────────────────────────────────────────────────────
36- info " Phase 2: Health Checks"
43+ section " Phase 2: Health Checks"
44+
45+ info " Waiting for MariaDB (up to 90s)..."
46+ for i in $( seq 1 18) ; do
47+ if docker exec freepbx-a03-db mysqladmin ping -uroot -pRootLab03! --silent 2> /dev/null; then
48+ pass " MariaDB healthy" ; break
49+ fi
50+ [[ $i -eq 18 ]] && fail " MariaDB timed out"
51+ sleep 5
52+ done
53+
54+ info " Waiting for Mailhog (up to 60s)..."
55+ for i in $( seq 1 12) ; do
56+ if curl -sf http://localhost:8620/api/v2/messages > /dev/null 2>&1 ; then
57+ pass " Mailhog reachable on :8620" ; break
58+ fi
59+ [[ $i -eq 12 ]] && fail " Mailhog not reachable on :8620"
60+ sleep 5
61+ done
62+
63+ info " Waiting for FreePBX web (up to 4 min)..."
64+ for i in $( seq 1 48) ; do
65+ if curl -sf http://localhost:8320/admin/config.php 2> /dev/null | grep -qi ' freepbx\|asterisk\|login' ; then
66+ pass " FreePBX admin UI on :8320" ; break
67+ fi
68+ [[ $i -eq 48 ]] && fail " FreePBX not reachable on :8320"
69+ sleep 5
70+ done
71+
72+ # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
73+ section " Phase 3: Functional Tests"
74+
75+ # Container states
76+ for cname in freepbx-a03-db freepbx-a03-mail freepbx-a03-app; do
77+ if docker inspect " ${cname} " --format ' {{.State.Status}}' 2> /dev/null | grep -q running; then
78+ pass " ${cname} running"
79+ else
80+ fail " ${cname} not running"
81+ fi
82+ done
3783
38- if docker compose -f " ${COMPOSE_FILE} " ps | grep -q " running\|Up" ; then
39- pass " Container is running"
84+ # AMI port accessible from host
85+ if nc -z localhost 5038 2> /dev/null; then
86+ pass " AMI port :5038 accessible"
4087else
41- fail " Container is not running "
88+ fail " AMI port :5038 not accessible "
4289fi
4390
44- # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45- info " Phase 3: Functional Tests (Lab 03 — Advanced Features)"
91+ # Asterisk core responding
92+ if docker exec freepbx-a03-app asterisk -rx " core show version" 2> /dev/null | grep -qi asterisk; then
93+ pass " Asterisk core show version responds"
94+ else
95+ fail " Asterisk core not responding"
96+ fi
4697
47- # TODO: Add module-specific functional tests here
48- # Example:
49- # if curl -sf http://localhost:5060/health > /dev/null 2>&1 ; then
50- # pass "Health endpoint responds "
51- # else
52- # fail "Health endpoint not reachable "
53- # fi
98+ # Asterisk dialplan loaded
99+ CONTEXTS= $( docker exec freepbx-a03-app asterisk -rx " dialplan show " 2> /dev/null | grep -c " ^== " || echo 0 )
100+ if [[ " ${CONTEXTS :- 0} " -gt 0 ]] ; then
101+ pass " Asterisk dialplan has ${CONTEXTS} contexts "
102+ else
103+ fail " Asterisk dialplan empty or not loaded "
104+ fi
54105
55- warn " Functional tests for Lab 10-03 pending implementation"
106+ # Asterisk channels list
107+ if docker exec freepbx-a03-app asterisk -rx " core show channels" 2> /dev/null | grep -q ' active channel\|0 active' ; then
108+ pass " Asterisk core show channels responds"
109+ else
110+ fail " Asterisk show channels failed"
111+ fi
56112
57- # ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58- info " Phase 4: Cleanup"
59- docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans
60- info " Cleanup complete"
113+ # Resource limits applied
114+ MEM_LIMIT=$( docker inspect freepbx-a03-app --format ' {{.HostConfig.Memory}}' 2> /dev/null || echo 0)
115+ if [[ " ${MEM_LIMIT:- 0} " -gt 0 ]]; then
116+ pass " Memory limit set on freepbx-a03-app (${MEM_LIMIT} bytes)"
117+ else
118+ fail " No memory limit set on freepbx-a03-app"
119+ fi
120+
121+ # Advanced volumes exist
122+ for vol in freepbx-a03-recordings freepbx-a03-moh freepbx-a03-voicemail freepbx-a03-data freepbx-a03-logs; do
123+ if docker volume ls --format ' {{.Name}}' | grep -q " ${vol} " ; then
124+ pass " Volume ${vol} exists"
125+ else
126+ fail " Volume ${vol} missing"
127+ fi
128+ done
129+
130+ # SMTP / Mailhog env
131+ if docker exec freepbx-a03-app printenv SMTP_HOST 2> /dev/null | grep -q ' freepbx-a03-mail' ; then
132+ pass " SMTP_HOST → freepbx-a03-mail"
133+ else
134+ fail " SMTP_HOST not pointing to Mailhog"
135+ fi
136+
137+ # HTTP response code
138+ HTTP_CODE=$( curl -o /dev/null -s -w " %{http_code}" http://localhost:8320/admin/config.php 2> /dev/null || echo 000)
139+ if [[ " ${HTTP_CODE} " =~ ^(200| 301| 302)$ ]]; then
140+ pass " FreePBX HTTP ${HTTP_CODE} on :8320"
141+ else
142+ fail " FreePBX HTTP ${HTTP_CODE} "
143+ fi
61144
62145# ── Results ───────────────────────────────────────────────────────────────────
63146echo " "
64- echo -e " ${CYAN} ======================================${NC} "
65- echo -e " Lab ${LAB_ID} Complete "
147+ echo -e " ${CYAN} ======================================== ${NC} "
148+ echo " Lab ${LAB_ID} Results "
66149echo -e " ${GREEN} PASS: ${PASS}${NC} | ${RED} FAIL: ${FAIL}${NC} "
67- echo -e " ${CYAN} ======================================${NC} "
68-
69- if [ " ${FAIL} " -gt 0 ]; then
70- exit 1
71- fi
150+ echo -e " ${CYAN} ========================================${NC} "
151+ [[ " ${FAIL} " -gt 0 ]] && exit 1
152+ exit 0
0 commit comments