11#! /usr/bin/env bash
2- # test-lab-12-01.sh — Lab 12-01: Standalone
3- # Module 12: SuiteCRM customer relationship management
4- # Basic suitecrm functionality in complete isolation
2+ # test-lab-12-01.sh — SuiteCRM Lab 01: Standalone
3+ # Module 12 | Lab 01 | Tests: basic SuiteCRM CRM functionality in isolation
54set -euo pipefail
65
7- LAB_ID=" 12-01"
8- LAB_NAME=" Standalone"
9- MODULE=" suitecrm"
10- COMPOSE_FILE=" docker/docker-compose.standalone.yml"
11- PASS=0
12- FAIL=0
6+ COMPOSE_FILE=" $( dirname " $0 " ) /../docker/docker-compose.standalone.yml"
7+ CLEANUP=true
8+ for arg in " $@ " ; do [[ " $arg " == " --no-cleanup" ]] && CLEANUP=false; done
139
14- # ── Colors ────────────────────────────────────────────────────────────────────
15- RED=' \033[0;31m' ; GREEN=' \033[0;32m' ; YELLOW=' \033[1;33m'
16- CYAN=' \033[0;36m' ; NC=' \033[0m'
10+ WEB_PORT=8302
11+ DB_USER=" suitecrm"
12+ DB_PASS=" SuiteLab01!"
13+ ADMIN_USER=" admin"
14+ ADMIN_PASS=" Admin01!"
1715
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 " ; }
16+ PASS=0 ; FAIL=0
17+ pass () { echo " [PASS] $1 " ; (( PASS ++ )) || true ; }
18+ fail () { echo " [FAIL] $1 " ; (( FAIL ++ )) || true ; }
19+ section () { echo " " ; echo " === $1 === " ; }
2220
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 " "
21+ cleanup () {
22+ if [[ " $CLEANUP " == " true" ]]; then
23+ echo " Cleaning up..."
24+ docker compose -f " $COMPOSE_FILE " down -v --remove-orphans 2> /dev/null || true
25+ fi
26+ }
27+ trap cleanup EXIT
2828
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
29+ section " Starting Lab 01 Standalone Stack"
30+ docker compose -f " $COMPOSE_FILE " up -d
31+ echo " Waiting for MariaDB and SuiteCRM to initialize (may take 2-3 minutes)..."
3432
35- # ── PHASE 2: Health Checks ────────────────────────────────────────────────────
36- info " Phase 2: Health Checks"
33+ section " MariaDB Health Check"
34+ for i in $( seq 1 30) ; do
35+ status=$( docker inspect suitecrm-s01-db --format ' {{.State.Health.Status}}' 2> /dev/null || echo " waiting" )
36+ [[ " $status " == " healthy" ]] && break ; sleep 5
37+ done
38+ [[ " $( docker inspect suitecrm-s01-db --format ' {{.State.Health.Status}}' ) " == " healthy" ]] && pass " MariaDB healthy" || fail " MariaDB not healthy"
3739
38- if docker compose -f " ${COMPOSE_FILE} " ps | grep -q " running\|Up" ; then
39- pass " Container is running"
40- else
41- fail " Container is not running"
42- fi
40+ section " SuiteCRM App Health Check"
41+ for i in $( seq 1 60) ; do
42+ status=$( docker inspect suitecrm-s01-app --format ' {{.State.Health.Status}}' 2> /dev/null || echo " waiting" )
43+ [[ " $status " == " healthy" ]] && break
44+ echo " Waiting for SuiteCRM ($i /60)..."
45+ sleep 10
46+ done
47+ [[ " $( docker inspect suitecrm-s01-app --format ' {{.State.Health.Status}}' ) " == " healthy" ]] && pass " SuiteCRM app healthy" || fail " SuiteCRM app not healthy"
4348
44- # ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45- info " Phase 3: Functional Tests (Lab 01 — Standalone)"
49+ section " SuiteCRM Web UI"
50+ http_code=$( curl -so /dev/null -w " %{http_code}" -L " http://localhost:${WEB_PORT} /index.php" 2> /dev/null || echo " 000" )
51+ [[ " $http_code " =~ ^(200| 302)$ ]] && pass " SuiteCRM login page accessible (HTTP $http_code )" || fail " SuiteCRM login page returned HTTP $http_code "
4652
47- # TODO: Add module-specific functional tests here
48- # Example:
49- # if curl -sf http://localhost:80/health > /dev/null 2>&1; then
50- # pass "Health endpoint responds"
51- # else
52- # fail "Health endpoint not reachable"
53- # fi
53+ # Verify login page contains expected content
54+ curl -sf -L " http://localhost:${WEB_PORT} /index.php" 2> /dev/null | grep -qi " suitecrm\|login\|username\|password" && pass " SuiteCRM login page content OK" || fail " SuiteCRM login page content unexpected"
5455
55- warn " Functional tests for Lab 12-01 pending implementation"
56+ section " SuiteCRM REST API"
57+ login_response=$( curl -sf -c /tmp/suitecrm-cookies.txt -X POST " http://localhost:${WEB_PORT} /index.php?module=Users&action=Authenticate" \
58+ -d " user_name=${ADMIN_USER} &user_password=$( echo -n ${ADMIN_PASS} | md5sum | awk ' {print $1}' ) " \
59+ -w " \n%{http_code}" 2> /dev/null || echo " 000" )
60+ login_code=$( echo " $login_response " | tail -1)
61+ [[ " $login_code " =~ ^(200| 302)$ ]] && pass " SuiteCRM auth endpoint accessible (HTTP $login_code )" || fail " SuiteCRM auth endpoint HTTP $login_code "
5662
57- # ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58- info " Phase 4: Cleanup"
59- docker compose -f " ${COMPOSE_FILE} " down -v --remove-orphans
60- info " Cleanup complete"
63+ section " Database Checks"
64+ db_tables=$( docker exec suitecrm-s01-db mysql -u " ${DB_USER} " -p" ${DB_PASS} " suitecrm -e " SHOW TABLES;" 2> /dev/null | wc -l || echo 0)
65+ [[ " $db_tables " -gt 10 ]] && pass " SuiteCRM DB has tables (count: $db_tables )" || fail " SuiteCRM DB seems empty (count: $db_tables )"
6166
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} "
67+ section " Container Configuration "
68+ restart_policy= $( docker inspect suitecrm-s01-app --format ' {{.HostConfig.RestartPolicy.Name}} ' )
69+ [[ " $restart_policy " == " unless-stopped " ]] && pass " Restart policy: unless-stopped " || fail " Unexpected restart policy: $restart_policy "
70+
71+ db_host= $( docker inspect suitecrm-s01-app --format ' {{range .Config.Env}}{{println .}}{{end}} ' | grep " ^SUITECRM_DATABASE_HOST= " | cut -d= -f2 )
72+ [[ " $db_host " == " suitecrm-s01-db " ]] && pass " SUITECRM_DATABASE_HOST env set correctly " || fail " SUITECRM_DATABASE_HOST not set (got: $db_host ) "
6873
69- if [ " ${FAIL} " -gt 0 ]; then
70- exit 1
71- fi
74+ section " Named Volumes"
75+ docker volume ls | grep -q " suitecrm-s01-db-data" && pass " Volume suitecrm-s01-db-data exists" || fail " Volume suitecrm-s01-db-data missing"
76+ docker volume ls | grep -q " suitecrm-s01-data" && pass " Volume suitecrm-s01-data exists" || fail " Volume suitecrm-s01-data missing"
77+
78+ echo " "
79+ echo " ================================================"
80+ echo " Lab 01 Results: ${PASS} passed, ${FAIL} failed"
81+ echo " ================================================"
82+ [[ $FAIL -eq 0 ]] && exit 0 || exit 1
0 commit comments