11#! /usr/bin/env bash
22# test-lab-14-02.sh — Lab 14-02: External Dependencies
3- # Module 14: OpenKM document management system
4- # openkm with external PostgreSQL, Redis, and network integration
3+ # Module 14: OpenKM Document Management
4+ # Tests: external MySQL + Mailhog SMTP relay + REST API
55set -euo pipefail
66
77LAB_ID=" 14-02"
@@ -11,61 +11,151 @@ COMPOSE_FILE="docker/docker-compose.lan.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 external MySQL (openkm-l02-db, up to 90s)..."
46+ for i in $( seq 1 18) ; do
47+ if docker exec openkm-l02-db mysqladmin ping -uroot -pRootLab02! --silent 2> /dev/null; then
48+ pass " External MySQL healthy" ; break
49+ fi
50+ [[ $i -eq 18 ]] && fail " External MySQL timed out"
51+ sleep 5
52+ done
3753
38- if docker compose -f " ${COMPOSE_FILE} " ps | grep -q " running\|Up" ; then
39- pass " Container is running"
54+ info " Waiting for Mailhog (openkm-l02-mail, up to 60s)..."
55+ for i in $( seq 1 12) ; do
56+ if curl -sf http://localhost:8613/api/v2/messages > /dev/null 2>&1 ; then
57+ pass " Mailhog UI reachable on :8613" ; break
58+ fi
59+ [[ $i -eq 12 ]] && fail " Mailhog not reachable on :8613"
60+ sleep 5
61+ done
62+
63+ info " Waiting for OpenKM (up to 2 min)..."
64+ for i in $( seq 1 24) ; do
65+ if curl -sf http://localhost:8313/openkm/ > /dev/null 2>&1 ; then
66+ pass " OpenKM reachable on :8313/openkm/" ; break
67+ fi
68+ [[ $i -eq 24 ]] && fail " OpenKM not reachable on :8313/openkm/"
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 openkm-l02-db openkm-l02-mail openkm-l02-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
83+
84+ # External DB connectivity from app
85+ if docker exec openkm-l02-app mysql -hopenkm-l02-db -uopenkm -pOpenKMLab02! openkm \
86+ -e " SELECT 1;" > /dev/null 2>&1 ; then
87+ pass " App connects to external MySQL (openkm DB)"
4088else
41- fail " Container is not running "
89+ fail " App cannot connect to external MySQL "
4290fi
4391
44- # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45- info " Phase 3: Functional Tests (Lab 02 — External Dependencies)"
92+ # DB has OpenKM tables
93+ TABLE_COUNT=$( docker exec openkm-l02-db mysql -uroot -pRootLab02! openkm \
94+ -e " SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='openkm';" \
95+ --skip-column-names 2> /dev/null || echo 0)
96+ if [[ " ${TABLE_COUNT:- 0} " -gt 20 ]]; then
97+ pass " External DB has ${TABLE_COUNT} OpenKM tables"
98+ else
99+ fail " External DB has only ${TABLE_COUNT:- 0} tables (expected >20)"
100+ fi
46101
47- # TODO: Add module-specific functional tests here
48- # Example:
49- # if curl -sf http://localhost:8080/health > /dev/null 2>&1; then
50- # pass "Health endpoint responds"
51- # else
52- # fail "Health endpoint not reachable"
53- # fi
102+ # Mailhog API
103+ if curl -sf http://localhost:8613/api/v2/messages | grep -q ' total\|items' ; then
104+ pass " Mailhog API returns valid JSON"
105+ else
106+ fail " Mailhog API not valid"
107+ fi
108+
109+ # OpenKM REST API
110+ HTTP_CODE=$( curl -o /dev/null -s -w " %{http_code}" \
111+ -u okmAdmin:admin \
112+ http://localhost:8313/openkm/services/rest/repository/info 2> /dev/null || echo 000)
113+ if [[ " ${HTTP_CODE} " =~ ^(200| 201)$ ]]; then
114+ pass " OpenKM REST /repository/info HTTP ${HTTP_CODE} "
115+ else
116+ fail " OpenKM REST HTTP ${HTTP_CODE} (expected 200)"
117+ fi
118+
119+ # SMTP config points to Mailhog
120+ if docker exec openkm-l02-app printenv OPENKM_SMTP_HOST 2> /dev/null | grep -q ' openkm-l02-mail' ; then
121+ pass " SMTP_HOST configured to openkm-l02-mail"
122+ else
123+ fail " SMTP_HOST not pointing to Mailhog container"
124+ fi
125+
126+ # DB charset is utf8mb4
127+ CHARSET=$( docker exec openkm-l02-db mysql -uroot -pRootLab02! \
128+ -e " SELECT DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='openkm';" \
129+ --skip-column-names 2> /dev/null || echo " unknown" )
130+ if [[ " ${CHARSET} " == " utf8mb4" ]]; then
131+ pass " DB charset is utf8mb4"
132+ else
133+ fail " DB charset is ${CHARSET} (expected utf8mb4)"
134+ fi
54135
55- warn " Functional tests for Lab 14-02 pending implementation"
136+ # Environment variables
137+ for envvar in OPENKM_DB_HOST OPENKM_DB_NAME OPENKM_DB_USER OPENKM_DB_PASS OPENKM_SMTP_HOST; do
138+ if docker exec openkm-l02-app printenv " ${envvar} " > /dev/null 2>&1 ; then
139+ pass " Env var ${envvar} set"
140+ else
141+ fail " Env var ${envvar} missing"
142+ fi
143+ done
56144
57- # ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58- info " Phase 4: Cleanup"
59- docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans
60- info " Cleanup complete"
145+ # Volumes
146+ for vol in openkm-l02-db-data openkm-l02-data openkm-l02-logs; do
147+ if docker volume ls --format ' {{.Name}}' | grep -q " ${vol} " ; then
148+ pass " Volume ${vol} exists"
149+ else
150+ fail " Volume ${vol} missing"
151+ fi
152+ done
61153
62154# ── Results ───────────────────────────────────────────────────────────────────
63155echo " "
64- echo -e " ${CYAN} ======================================${NC} "
65- echo -e " Lab ${LAB_ID} Complete "
156+ echo -e " ${CYAN} ======================================== ${NC} "
157+ echo " Lab ${LAB_ID} Results "
66158echo -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
159+ echo -e " ${CYAN} ========================================${NC} "
160+ [[ " ${FAIL} " -gt 0 ]] && exit 1
161+ exit 0
0 commit comments