11#! /usr/bin/env bash
22# test-lab-13-02.sh — Lab 13-02: External Dependencies
3- # Module 13: Odoo ERP and business management
4- # odoo with external PostgreSQL, Redis, and network integration
3+ # Module 13: Odoo ERP
4+ # Tests: external PostgreSQL + Redis cache/sessions + Mailhog SMTP relay
55set -euo pipefail
66
77LAB_ID=" 13-02"
@@ -11,61 +11,147 @@ 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 PostgreSQL (odoo-l02-db, up to 60s)..."
46+ for i in $( seq 1 12) ; do
47+ if docker exec odoo-l02-db pg_isready -U odoo -d odoo_lab02 > /dev/null 2>&1 ; then
48+ pass " External PostgreSQL healthy" ; break
49+ fi
50+ [[ $i -eq 12 ]] && fail " External PostgreSQL timed out"
51+ sleep 5
52+ done
53+
54+ info " Waiting for Redis (odoo-l02-redis, up to 30s)..."
55+ for i in $( seq 1 6) ; do
56+ if docker exec odoo-l02-redis redis-cli ping 2> /dev/null | grep -q PONG; then
57+ pass " Redis healthy (PONG)" ; break
58+ fi
59+ [[ $i -eq 6 ]] && fail " Redis not responding"
60+ sleep 5
61+ done
62+
63+ info " Waiting for Mailhog (odoo-l02-mail, up to 60s)..."
64+ for i in $( seq 1 12) ; do
65+ if curl -sf http://localhost:8612/api/v2/messages > /dev/null 2>&1 ; then
66+ pass " Mailhog UI reachable on :8612" ; break
67+ fi
68+ [[ $i -eq 12 ]] && fail " Mailhog not reachable on :8612"
69+ sleep 5
70+ done
3771
38- if docker compose -f " ${COMPOSE_FILE} " ps | grep -q " running\|Up" ; then
39- pass " Container is running"
72+ info " Waiting for Odoo (up to 2 min)..."
73+ for i in $( seq 1 24) ; do
74+ if curl -sf http://localhost:8312/web/health 2> /dev/null | grep -q ' ok\|pass' ; then
75+ pass " Odoo /web/health returns ok on :8312" ; break
76+ fi
77+ [[ $i -eq 24 ]] && fail " Odoo not reachable on :8312"
78+ sleep 5
79+ done
80+
81+ # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
82+ section " Phase 3: Functional Tests"
83+
84+ # Container states
85+ for cname in odoo-l02-db odoo-l02-redis odoo-l02-mail odoo-l02-app; do
86+ if docker inspect " ${cname} " --format ' {{.State.Status}}' 2> /dev/null | grep -q running; then
87+ pass " ${cname} running"
88+ else
89+ fail " ${cname} not running"
90+ fi
91+ done
92+
93+ # External DB connectivity from app
94+ if docker exec odoo-l02-app psql -h odoo-l02-db -U odoo -d odoo_lab02 \
95+ -c " SELECT 1;" > /dev/null 2>&1 ; then
96+ pass " App connects to external PostgreSQL (odoo_lab02)"
4097else
41- fail " Container is not running "
98+ fail " App cannot connect to external PostgreSQL "
4299fi
43100
44- # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45- info " Phase 3: Functional Tests (Lab 02 — External Dependencies)"
101+ # Redis connectivity from app
102+ if docker exec odoo-l02-app redis-cli -h odoo-l02-redis ping 2> /dev/null | grep -q PONG; then
103+ pass " App connects to Redis"
104+ else
105+ fail " App cannot reach Redis"
106+ fi
46107
47- # TODO: Add module-specific functional tests here
48- # Example:
49- # if curl -sf http://localhost:8069/health > /dev/null 2>&1; then
50- # pass "Health endpoint responds"
51- # else
52- # fail "Health endpoint not reachable"
53- # fi
108+ # Odoo web health
109+ if curl -sf http://localhost:8312/web/health | grep -q ' ok\|pass' ; then
110+ pass " Odoo /web/health endpoint OK"
111+ else
112+ fail " Odoo /web/health not OK"
113+ fi
54114
55- warn " Functional tests for Lab 13-02 pending implementation"
115+ # Odoo JSON-RPC database list
116+ DB_LIST=$( curl -sf -X POST http://localhost:8312/web/database/get_list \
117+ -H ' Content-Type: application/json' \
118+ -d ' {"jsonrpc":"2.0","method":"call","params":{}}' 2> /dev/null || echo " {}" )
119+ if echo " ${DB_LIST} " | grep -q ' result\|odoo' ; then
120+ pass " Odoo JSON-RPC /web/database/get_list responds"
121+ else
122+ fail " Odoo JSON-RPC not responding"
123+ fi
56124
57- # ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58- info " Phase 4: Cleanup"
59- docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans
60- info " Cleanup complete"
125+ # Mailhog API
126+ if curl -sf http://localhost:8612/api/v2/messages | grep -q ' total\|items' ; then
127+ pass " Mailhog API returns valid JSON"
128+ else
129+ fail " Mailhog API not valid"
130+ fi
131+
132+ # Environment variables
133+ for envvar in HOST PORT USER PASSWORD; do
134+ if docker exec odoo-l02-app printenv " ${envvar} " > /dev/null 2>&1 ; then
135+ pass " Env var ${envvar} set"
136+ else
137+ fail " Env var ${envvar} missing"
138+ fi
139+ done
140+
141+ # Volumes
142+ for vol in odoo-l02-db-data odoo-l02-redis-data odoo-l02-data odoo-l02-addons; do
143+ if docker volume ls --format ' {{.Name}}' | grep -q " ${vol} " ; then
144+ pass " Volume ${vol} exists"
145+ else
146+ fail " Volume ${vol} missing"
147+ fi
148+ done
61149
62150# ── Results ───────────────────────────────────────────────────────────────────
63151echo " "
64- echo -e " ${CYAN} ======================================${NC} "
65- echo -e " Lab ${LAB_ID} Complete "
152+ echo -e " ${CYAN} ======================================== ${NC} "
153+ echo " Lab ${LAB_ID} Results "
66154echo -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
155+ echo -e " ${CYAN} ========================================${NC} "
156+ [[ " ${FAIL} " -gt 0 ]] && exit 1
157+ exit 0
0 commit comments