11#! /usr/bin/env bash
2- # test-lab-13-01.sh — Lab 13-01: Standalone
3- # Module 13: Odoo ERP and business management
4- # Basic odoo functionality in complete isolation
2+ # test-lab-13-01.sh — Odoo Lab 01: Standalone
3+ # Module 13 | Lab 01 | Tests: basic Odoo ERP functionality in isolation
54set -euo pipefail
65
7- LAB_ID=" 13-01"
8- LAB_NAME=" Standalone"
9- MODULE=" odoo"
10- COMPOSE_FILE=" docker/docker-compose.standalone.yml"
11- PASS=0
12- FAIL=0
13-
14- # ── Colors ────────────────────────────────────────────────────────────────────
15- RED=' \033[0;31m' ; GREEN=' \033[0;32m' ; YELLOW=' \033[1;33m'
16- CYAN=' \033[0;36m' ; NC=' \033[0m'
17-
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 " ; }
22-
23- echo -e " ${CYAN} ======================================${NC} "
24- echo -e " ${CYAN} Lab ${LAB_ID} : ${LAB_NAME}${NC} "
25- echo -e " ${CYAN} Module: ${MODULE}${NC} "
26- echo -e " ${CYAN} ======================================${NC} "
27- echo " "
6+ COMPOSE_FILE=" $( dirname " $0 " ) /../docker/docker-compose.standalone.yml"
7+ CLEANUP=true
8+ for arg in " $@ " ; do [[ " $arg " == " --no-cleanup" ]] && CLEANUP=false; done
9+
10+ WEB_PORT=8303
11+ DB_USER=" odoo"
12+ DB_PASS=" OdooLab01!"
13+
14+ PASS=0; FAIL=0
15+ pass () { echo " [PASS] $1 " ; (( PASS++ )) || true ; }
16+ fail () { echo " [FAIL] $1 " ; (( FAIL++ )) || true ; }
17+ section () { echo " " ; echo " === $1 ===" ; }
18+
19+ cleanup () {
20+ if [[ " $CLEANUP " == " true" ]]; then
21+ echo " Cleaning up..."
22+ docker compose -f " $COMPOSE_FILE " down -v --remove-orphans 2> /dev/null || true
23+ fi
24+ }
25+ trap cleanup EXIT
26+
27+ section " Starting Lab 01 Standalone Stack"
28+ docker compose -f " $COMPOSE_FILE " up -d
29+ echo " Waiting for PostgreSQL and Odoo to initialize..."
2830
29- # ── PHASE 1: Setup ────────────────────────────────────────────────────────────
30- info " Phase 1: Setup"
31- docker compose -f " ${COMPOSE_FILE} " up -d
32- info " Waiting 30s for ${MODULE} to initialize..."
33- sleep 30
31+ section " PostgreSQL Health Check"
32+ for i in $( seq 1 30) ; do
33+ status=$( docker inspect odoo-s01-db --format ' {{.State.Health.Status}}' 2> /dev/null || echo " waiting" )
34+ [[ " $status " == " healthy" ]] && break ; sleep 5
35+ done
36+ [[ " $( docker inspect odoo-s01-db --format ' {{.State.Health.Status}}' ) " == " healthy" ]] && pass " PostgreSQL healthy" || fail " PostgreSQL not healthy"
3437
35- # ── PHASE 2: Health Checks ────────────────────────────────────────────────────
36- info " Phase 2: Health Checks"
38+ section " Odoo App Health Check"
39+ for i in $( seq 1 60) ; do
40+ status=$( docker inspect odoo-s01-app --format ' {{.State.Health.Status}}' 2> /dev/null || echo " waiting" )
41+ [[ " $status " == " healthy" ]] && break
42+ echo " Waiting for Odoo ($i /60)..."
43+ sleep 10
44+ done
45+ [[ " $( docker inspect odoo-s01-app --format ' {{.State.Health.Status}}' ) " == " healthy" ]] && pass " Odoo app healthy" || fail " Odoo app not healthy"
3746
38- if docker compose -f " ${COMPOSE_FILE} " ps | grep -q " running\|Up" ; then
39- pass " Container is running"
47+ section " Odoo Web UI"
48+ http_code=$( curl -so /dev/null -w " %{http_code}" -L " http://localhost:${WEB_PORT} /" 2> /dev/null || echo " 000" )
49+ [[ " $http_code " =~ ^(200| 303| 302)$ ]] && pass " Odoo web accessible (HTTP $http_code )" || fail " Odoo web returned HTTP $http_code "
50+
51+ curl -sf -L " http://localhost:${WEB_PORT} /" 2> /dev/null | grep -qi " odoo\|login\|openerp\|web client" && pass " Odoo web page content OK" || fail " Odoo web page content unexpected"
52+
53+ section " Odoo Health Endpoint"
54+ health_resp=$( curl -sf " http://localhost:${WEB_PORT} /web/health" 2> /dev/null || echo " " )
55+ if echo " $health_resp " | grep -qiE ' "status"\s*:\s*"pass"|"ok"|\{' ; then
56+ pass " Odoo /web/health endpoint responding"
4057else
41- fail " Container is not running"
58+ # Older Odoo versions may not have /web/health — check Odoo root
59+ curl -sf " http://localhost:${WEB_PORT} /" | grep -qi " odoo" && pass " Odoo web accessible (health endpoint alt check)" || fail " Odoo health check failed"
4260fi
4361
44- # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45- info " Phase 3: Functional Tests (Lab 01 — Standalone)"
62+ section " Odoo JSON-RPC API"
63+ api_resp=$( curl -sf -X POST " http://localhost:${WEB_PORT} /web/dataset/call_kw" \
64+ -H " Content-Type: application/json" \
65+ -d ' {"jsonrpc":"2.0","method":"call","id":1,"params":{"model":"res.lang","method":"search_read","args":[[]],"kwargs":{"fields":["name"],"limit":1}}}' \
66+ 2> /dev/null || echo " " )
67+ echo " $api_resp " | grep -q ' "result"' && pass " Odoo JSON-RPC API responding" || {
68+ echo " $api_resp " | grep -q ' "error"' && pass " Odoo JSON-RPC API responding (auth error expected)" || fail " Odoo JSON-RPC API not responding"
69+ }
4670
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
71+ section " Database Connectivity"
72+ docker exec odoo-s01-db psql -U " ${DB_USER} " -l 2> /dev/null | grep -q " odoo\|postgres" && pass " PostgreSQL accessible as odoo user" || fail " PostgreSQL connection failed"
5473
55- warn " Functional tests for Lab 13-01 pending implementation"
74+ section " Container Configuration"
75+ restart_policy=$( docker inspect odoo-s01-app --format ' {{.HostConfig.RestartPolicy.Name}}' )
76+ [[ " $restart_policy " == " unless-stopped" ]] && pass " Restart policy: unless-stopped" || fail " Unexpected restart policy: $restart_policy "
5677
57- # ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58- info " Phase 4: Cleanup"
59- docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans
60- info " Cleanup complete"
78+ db_host=$( docker inspect odoo-s01-app --format ' {{range .Config.Env}}{{println .}}{{end}}' | grep " ^HOST=" | cut -d= -f2)
79+ [[ " $db_host " == " odoo-s01-db" ]] && pass " HOST env var set correctly" || fail " HOST env var not set (got: $db_host )"
6180
62- # ── Results ───────────────────────────────────────────────────────────────────
63- echo " "
64- echo -e " ${CYAN} ======================================${NC} "
65- echo -e " Lab ${LAB_ID} Complete"
66- echo -e " ${GREEN} PASS: ${PASS}${NC} | ${RED} FAIL: ${FAIL}${NC} "
67- echo -e " ${CYAN} ======================================${NC} "
81+ section " Named Volumes"
82+ docker volume ls | grep -q " odoo-s01-db-data" && pass " Volume odoo-s01-db-data exists" || fail " Volume odoo-s01-db-data missing"
83+ docker volume ls | grep -q " odoo-s01-data" && pass " Volume odoo-s01-data exists" || fail " Volume odoo-s01-data missing"
6884
69- if [ " ${FAIL} " -gt 0 ]; then
70- exit 1
71- fi
85+ echo " "
86+ echo " ================================================"
87+ echo " Lab 01 Results: ${PASS} passed, ${FAIL} failed"
88+ echo " ================================================"
89+ [[ $FAIL -eq 0 ]] && exit 0 || exit 1
0 commit comments