|
1 | | -#!/usr/bin/env bash |
| 1 | +#!/usr/bin/env bash |
2 | 2 | # test-lab-06-02.sh — Lab 06-02: External Dependencies |
3 | 3 | # Module 06: Nextcloud file sync, calendar, and office suite |
4 | 4 | # nextcloud with external PostgreSQL, Redis, and network integration |
@@ -29,43 +29,135 @@ echo "" |
29 | 29 | # ── PHASE 1: Setup ──────────────────────────────────────────────────────────── |
30 | 30 | info "Phase 1: Setup" |
31 | 31 | docker compose -f "${COMPOSE_FILE}" up -d |
32 | | -info "Waiting 30s for ${MODULE} to initialize..." |
33 | | -sleep 30 |
| 32 | +info "Waiting for PostgreSQL..." |
| 33 | +timeout 60 bash -c 'until docker compose -f docker/docker-compose.lan.yml exec -T db pg_isready -U ncuser -d nextcloud 2>/dev/null; do sleep 3; done' |
| 34 | +info "Waiting for Redis..." |
| 35 | +timeout 30 bash -c 'until docker compose -f docker/docker-compose.lan.yml exec -T redis redis-cli -a Lab02Redis! ping 2>/dev/null | grep -q PONG; do sleep 2; done' |
| 36 | +info "Waiting for Nextcloud (PostgreSQL first-boot ~3 min)..." |
| 37 | +timeout 360 bash -c 'until curl -sf http://localhost:8080/status.php | grep -q "\"installed\":true"; do sleep 10; done' |
34 | 38 |
|
35 | | -# ── PHASE 2: Health Checks ──────────────────────────────────────────────────── |
| 39 | +# ── PHASE 2: Health Checks ─────────────────────────────────────────────────── |
36 | 40 | info "Phase 2: Health Checks" |
37 | 41 |
|
38 | | -if docker compose -f "${COMPOSE_FILE}" ps | grep -q "running\|Up"; then |
39 | | - pass "Container is running" |
| 42 | +for c in nc-lan-db nc-lan-redis nc-lan-app; do |
| 43 | + if docker ps --filter "name=^/${c}$" --filter "status=running" --format '{{.Names}}' | grep -q "${c}"; then |
| 44 | + pass "Container ${c} is running" |
| 45 | + else |
| 46 | + fail "Container ${c} is not running" |
| 47 | + fi |
| 48 | +done |
| 49 | + |
| 50 | +if docker compose -f "${COMPOSE_FILE}" exec -T db pg_isready -U ncuser -d nextcloud 2>/dev/null; then |
| 51 | + pass "PostgreSQL: pg_isready OK" |
| 52 | +else |
| 53 | + fail "PostgreSQL: pg_isready failed" |
| 54 | +fi |
| 55 | + |
| 56 | +if docker compose -f "${COMPOSE_FILE}" exec -T redis redis-cli -a Lab02Redis! ping 2>/dev/null | grep -q PONG; then |
| 57 | + pass "Redis: PING → PONG" |
40 | 58 | else |
41 | | - fail "Container is not running" |
| 59 | + fail "Redis: no PONG response" |
42 | 60 | fi |
43 | 61 |
|
44 | | -# ── PHASE 3: Functional Tests ───────────────────────────────────────────────── |
| 62 | +if curl -sf http://localhost:8080/status.php | grep -q '"installed":true'; then |
| 63 | + pass "Nextcloud: status.php installed=true" |
| 64 | +else |
| 65 | + fail "Nextcloud: status.php not installed" |
| 66 | +fi |
| 67 | + |
| 68 | +# ── PHASE 3: Functional Tests ──────────────────────────────────────────────── |
45 | 69 | info "Phase 3: Functional Tests (Lab 02 — External Dependencies)" |
46 | 70 |
|
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 |
| 71 | +# Key Lab 02 test: database backend must be PostgreSQL, not SQLite |
| 72 | +DB_TYPE=$(docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 73 | + php /var/www/html/occ config:system:get dbtype 2>/dev/null | tr -d '[:space:]' || echo "unknown") |
| 74 | +if echo "${DB_TYPE}" | grep -qiE '^pgsql|^postgresql'; then |
| 75 | + pass "DB backend: ${DB_TYPE} (PostgreSQL confirmed, not SQLite)" |
| 76 | +else |
| 77 | + fail "DB backend: expected pgsql, got '${DB_TYPE}'" |
| 78 | +fi |
| 79 | + |
| 80 | +# Key Lab 02 test: Redis must be configured in config.php |
| 81 | +if docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 82 | + cat /var/www/html/config/config.php 2>/dev/null | grep -q "'redis'"; then |
| 83 | + pass "Redis section present in Nextcloud config.php" |
| 84 | +else |
| 85 | + fail "Redis not configured in config.php" |
| 86 | +fi |
| 87 | + |
| 88 | +# DB host is 'db' (external, not localhost) |
| 89 | +DB_HOST=$(docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 90 | + php /var/www/html/occ config:system:get dbhost 2>/dev/null | tr -d '[:space:]' || echo "") |
| 91 | +if [ "${DB_HOST}" = "db" ]; then |
| 92 | + pass "DB host: '${DB_HOST}' (external service)" |
| 93 | +else |
| 94 | + fail "DB host: expected 'db', got '${DB_HOST}'" |
| 95 | +fi |
| 96 | + |
| 97 | +# Maintenance mode off |
| 98 | +MAINTENANCE=$(docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 99 | + php /var/www/html/occ config:system:get maintenance 2>/dev/null | tr -d '[:space:]' || echo "false") |
| 100 | +if [ "${MAINTENANCE}" = "false" ]; then |
| 101 | + pass "Maintenance mode: disabled" |
| 102 | +else |
| 103 | + fail "Maintenance mode: enabled (unexpected)" |
| 104 | +fi |
| 105 | + |
| 106 | +# occ status |
| 107 | +if docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 108 | + php /var/www/html/occ status 2>/dev/null | grep -qi 'installed.*true'; then |
| 109 | + pass "occ status: installed=true" |
| 110 | +else |
| 111 | + fail "occ status: not installed" |
| 112 | +fi |
| 113 | + |
| 114 | +# Admin user in DB |
| 115 | +if docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 116 | + php /var/www/html/occ user:list 2>/dev/null | grep -q admin; then |
| 117 | + pass "occ user:list: admin user present" |
| 118 | +else |
| 119 | + fail "occ user:list: admin user missing" |
| 120 | +fi |
54 | 121 |
|
55 | | -warn "Functional tests for Lab 06-02 pending implementation" |
| 122 | +# WebDAV PROPFIND |
| 123 | +if curl -sf -u admin:Lab02Password! -X PROPFIND \ |
| 124 | + http://localhost:8080/remote.php/dav/ | grep -qi "multistatus"; then |
| 125 | + pass "WebDAV PROPFIND: multistatus response" |
| 126 | +else |
| 127 | + fail "WebDAV PROPFIND: no multistatus" |
| 128 | +fi |
| 129 | + |
| 130 | +# OCS Capabilities API |
| 131 | +if curl -sf -u admin:Lab02Password! \ |
| 132 | + 'http://localhost:8080/ocs/v1.php/cloud/capabilities?format=json' \ |
| 133 | + | grep -q '"status":"ok"'; then |
| 134 | + pass "OCS Capabilities API: status OK" |
| 135 | +else |
| 136 | + fail "OCS Capabilities API: unexpected response" |
| 137 | +fi |
| 138 | + |
| 139 | +# DB integrity |
| 140 | +info "Running occ db:add-missing-indices..." |
| 141 | +IDX_OUT=$(docker compose -f "${COMPOSE_FILE}" exec -T nextcloud \ |
| 142 | + php /var/www/html/occ db:add-missing-indices --no-interaction 2>&1 || true) |
| 143 | +if echo "${IDX_OUT}" | grep -qvi "error"; then |
| 144 | + pass "occ db:add-missing-indices: no errors" |
| 145 | +else |
| 146 | + warn "occ db:add-missing-indices: ${IDX_OUT}" |
| 147 | +fi |
56 | 148 |
|
57 | | -# ── PHASE 4: Cleanup ────────────────────────────────────────────────────────── |
| 149 | +# ── PHASE 4: Cleanup ───────────────────────────────────────────────────────── |
58 | 150 | info "Phase 4: Cleanup" |
59 | 151 | docker compose -f "${COMPOSE_FILE}" down -v --remove-orphans |
60 | 152 | info "Cleanup complete" |
61 | 153 |
|
62 | | -# ── Results ─────────────────────────────────────────────────────────────────── |
| 154 | +# ── Results ────────────────────────────────────────────────────────────────── |
63 | 155 | echo "" |
64 | 156 | echo -e "${CYAN}======================================${NC}" |
65 | 157 | echo -e " Lab ${LAB_ID} Complete" |
66 | 158 | echo -e " ${GREEN}PASS: ${PASS}${NC} | ${RED}FAIL: ${FAIL}${NC}" |
67 | 159 | echo -e "${CYAN}======================================${NC}" |
68 | 160 |
|
69 | 161 | if [ "${FAIL}" -gt 0 ]; then |
70 | | - exit 1 |
| 162 | + exit 1 |
71 | 163 | fi |
0 commit comments