cyclecad 2.1.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BILLING-IMPLEMENTATION-SUMMARY.md +425 -0
- package/BILLING-INDEX.md +293 -0
- package/BILLING-INTEGRATION-GUIDE.md +414 -0
- package/COLLABORATION-INDEX.md +440 -0
- package/COLLABORATION-SYSTEM-SUMMARY.md +548 -0
- package/DELIVERABLES.txt +296 -445
- package/DOCKER-BUILD-MANIFEST.txt +483 -0
- package/DOCKER-FILES-REFERENCE.md +440 -0
- package/DOCKER-INFRASTRUCTURE.md +475 -0
- package/DOCKER-README.md +435 -0
- package/Dockerfile +33 -55
- package/ENHANCEMENT_COMPLETION_REPORT.md +383 -0
- package/ENHANCEMENT_SUMMARY.txt +308 -0
- package/FEATURE_INVENTORY.md +235 -0
- package/FUSION360_FEATURES_SUMMARY.md +452 -0
- package/FUSION360_PARITY_ENHANCEMENTS.md +461 -0
- package/FUSION360_PARITY_SUMMARY.md +520 -0
- package/FUSION360_QUICK_REFERENCE.md +351 -0
- package/MODULE_API_REFERENCE.md +712 -0
- package/MODULE_INVENTORY.txt +264 -0
- package/PWA-FILES-CREATED.txt +350 -0
- package/QUICK-START-TESTING.md +126 -0
- package/STEP-IMPORT-QUICKSTART.md +347 -0
- package/STEP-IMPORT-SYSTEM-SUMMARY.md +502 -0
- package/app/css/mobile.css +1074 -0
- package/app/icons/generate-icons.js +203 -0
- package/app/index.html +1342 -5031
- package/app/js/app.js +1312 -514
- package/app/js/billing-ui.js +990 -0
- package/app/js/brep-kernel.js +933 -981
- package/app/js/collab-client.js +750 -0
- package/app/js/mobile-nav.js +623 -0
- package/app/js/mobile-toolbar.js +476 -0
- package/app/js/modules/animation-module.js +497 -3
- package/app/js/modules/billing-module.js +724 -0
- package/app/js/modules/cam-module.js +507 -2
- package/app/js/modules/collaboration-module.js +513 -0
- package/app/js/modules/constraint-module.js +1266 -0
- package/app/js/modules/data-module.js +544 -1146
- package/app/js/modules/formats-module.js +438 -738
- package/app/js/modules/inspection-module.js +393 -0
- package/app/js/modules/mesh-module-enhanced.js +880 -0
- package/app/js/modules/plugin-module.js +597 -0
- package/app/js/modules/rendering-module.js +460 -0
- package/app/js/modules/scripting-module.js +593 -475
- package/app/js/modules/sketch-module.js +998 -2
- package/app/js/modules/step-module-enhanced.js +938 -0
- package/app/js/modules/surface-module.js +312 -0
- package/app/js/modules/version-module.js +420 -0
- package/app/js/offline-manager.js +705 -0
- package/app/js/responsive-init.js +360 -0
- package/app/js/touch-handler.js +429 -0
- package/app/manifest.json +211 -0
- package/app/offline.html +508 -0
- package/app/sw.js +571 -0
- package/app/tests/billing-tests.html +779 -0
- package/app/tests/brep-tests.html +980 -0
- package/app/tests/collab-tests.html +743 -0
- package/app/tests/mobile-tests.html +1299 -0
- package/app/tests/pwa-tests.html +1134 -0
- package/app/tests/step-tests.html +1042 -0
- package/app/tests/test-agent-v3.html +719 -0
- package/cycleCAD-Architecture-v2.pptx +0 -0
- package/docker-compose.yml +225 -0
- package/docs/BILLING-HELP.json +260 -0
- package/docs/BILLING-README.md +639 -0
- package/docs/BILLING-TUTORIAL.md +736 -0
- package/docs/BREP-HELP.json +326 -0
- package/docs/BREP-TUTORIAL.md +802 -0
- package/docs/COLLABORATION-HELP.json +228 -0
- package/docs/COLLABORATION-TUTORIAL.md +818 -0
- package/docs/DOCKER-HELP.json +224 -0
- package/docs/DOCKER-TUTORIAL.md +974 -0
- package/docs/MOBILE-HELP.json +243 -0
- package/docs/MOBILE-RESPONSIVE-README.md +378 -0
- package/docs/MOBILE-TUTORIAL.md +747 -0
- package/docs/PWA-HELP.json +228 -0
- package/docs/PWA-README.md +662 -0
- package/docs/PWA-TUTORIAL.md +757 -0
- package/docs/STEP-HELP.json +481 -0
- package/docs/STEP-IMPORT-TUTORIAL.md +824 -0
- package/docs/TESTING-GUIDE.md +528 -0
- package/docs/TESTING-HELP.json +182 -0
- package/fusion-vs-cyclecad.html +1771 -0
- package/nginx.conf +237 -0
- package/package.json +1 -1
- package/server/Dockerfile.converter +51 -0
- package/server/Dockerfile.signaling +28 -0
- package/server/billing-server.js +487 -0
- package/server/converter-enhanced.py +528 -0
- package/server/requirements-converter.txt +29 -0
- package/server/signaling-server.js +801 -0
- package/tests/docker-tests.sh +389 -0
- package/~$cycleCAD-Architecture-v2.pptx +0 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# cycleCAD Docker End-to-End Test Suite
|
|
4
|
+
# Comprehensive testing of all Docker services and functionality
|
|
5
|
+
#
|
|
6
|
+
# Usage: bash tests/docker-tests.sh
|
|
7
|
+
# Output: Test results with pass/fail status
|
|
8
|
+
#
|
|
9
|
+
# Tests:
|
|
10
|
+
# - Image building
|
|
11
|
+
# - Service startup
|
|
12
|
+
# - Health checks
|
|
13
|
+
# - API endpoints
|
|
14
|
+
# - STEP file conversion
|
|
15
|
+
# - Static asset serving
|
|
16
|
+
# - Headers and security
|
|
17
|
+
# - WebSocket connectivity
|
|
18
|
+
# - Resource cleanup
|
|
19
|
+
|
|
20
|
+
set -e
|
|
21
|
+
|
|
22
|
+
# Color codes for output
|
|
23
|
+
RED='\033[0;31m'
|
|
24
|
+
GREEN='\033[0;32m'
|
|
25
|
+
YELLOW='\033[1;33m'
|
|
26
|
+
BLUE='\033[0;34m'
|
|
27
|
+
NC='\033[0m' # No Color
|
|
28
|
+
|
|
29
|
+
# Test counters
|
|
30
|
+
TESTS_PASSED=0
|
|
31
|
+
TESTS_FAILED=0
|
|
32
|
+
TESTS_SKIPPED=0
|
|
33
|
+
|
|
34
|
+
# Configuration
|
|
35
|
+
BASE_URL="http://localhost:8080"
|
|
36
|
+
CONVERTER_URL="http://localhost:8787"
|
|
37
|
+
SIGNALING_URL="ws://localhost:8788"
|
|
38
|
+
TIMEOUT=10
|
|
39
|
+
|
|
40
|
+
# Helper functions
|
|
41
|
+
log_test() {
|
|
42
|
+
echo -e "${BLUE}[TEST]${NC} $1"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
log_pass() {
|
|
46
|
+
echo -e "${GREEN}[PASS]${NC} $1"
|
|
47
|
+
((TESTS_PASSED++))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
log_fail() {
|
|
51
|
+
echo -e "${RED}[FAIL]${NC} $1"
|
|
52
|
+
((TESTS_FAILED++))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
log_skip() {
|
|
56
|
+
echo -e "${YELLOW}[SKIP]${NC} $1"
|
|
57
|
+
((TESTS_SKIPPED++))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
log_info() {
|
|
61
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
assert_http_status() {
|
|
65
|
+
local url=$1
|
|
66
|
+
local expected_status=$2
|
|
67
|
+
local description=$3
|
|
68
|
+
|
|
69
|
+
log_test "$description (expecting $expected_status)"
|
|
70
|
+
|
|
71
|
+
local actual_status=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
72
|
+
--max-time $TIMEOUT \
|
|
73
|
+
-H "Connection: close" \
|
|
74
|
+
"$url" 2>/dev/null || echo "000")
|
|
75
|
+
|
|
76
|
+
if [ "$actual_status" = "$expected_status" ]; then
|
|
77
|
+
log_pass "$description"
|
|
78
|
+
return 0
|
|
79
|
+
else
|
|
80
|
+
log_fail "$description (got $actual_status, expected $expected_status)"
|
|
81
|
+
return 1
|
|
82
|
+
fi
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
assert_header_exists() {
|
|
86
|
+
local url=$1
|
|
87
|
+
local header=$2
|
|
88
|
+
local description=$3
|
|
89
|
+
|
|
90
|
+
log_test "$description"
|
|
91
|
+
|
|
92
|
+
local has_header=$(curl -s -I --max-time $TIMEOUT "$url" 2>/dev/null | grep -i "^${header}:" || echo "")
|
|
93
|
+
|
|
94
|
+
if [ ! -z "$has_header" ]; then
|
|
95
|
+
log_pass "$description"
|
|
96
|
+
return 0
|
|
97
|
+
else
|
|
98
|
+
log_fail "$description (header '$header' not found)"
|
|
99
|
+
return 1
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
wait_for_service() {
|
|
104
|
+
local url=$1
|
|
105
|
+
local max_attempts=30
|
|
106
|
+
local attempt=0
|
|
107
|
+
|
|
108
|
+
log_info "Waiting for $url to be ready..."
|
|
109
|
+
|
|
110
|
+
while [ $attempt -lt $max_attempts ]; do
|
|
111
|
+
if curl -s --max-time 2 "$url" > /dev/null 2>&1; then
|
|
112
|
+
log_info "$url is ready"
|
|
113
|
+
return 0
|
|
114
|
+
fi
|
|
115
|
+
echo -n "."
|
|
116
|
+
sleep 1
|
|
117
|
+
((attempt++))
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
log_fail "Timeout waiting for $url"
|
|
121
|
+
return 1
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# ============================================================================
|
|
125
|
+
# TEST SUITE
|
|
126
|
+
# ============================================================================
|
|
127
|
+
|
|
128
|
+
echo ""
|
|
129
|
+
echo "╔════════════════════════════════════════════════════════════════╗"
|
|
130
|
+
echo "║ cycleCAD Docker End-to-End Test Suite ║"
|
|
131
|
+
echo "║ $(date '+%Y-%m-%d %H:%M:%S') ║"
|
|
132
|
+
echo "╚════════════════════════════════════════════════════════════════╝"
|
|
133
|
+
echo ""
|
|
134
|
+
|
|
135
|
+
# Test 1: Check if docker-compose is available
|
|
136
|
+
log_test "docker-compose is installed and accessible"
|
|
137
|
+
if command -v docker-compose &> /dev/null; then
|
|
138
|
+
log_pass "docker-compose command found"
|
|
139
|
+
else
|
|
140
|
+
log_fail "docker-compose not found in PATH"
|
|
141
|
+
exit 1
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# Test 2: Check if Docker daemon is running
|
|
145
|
+
log_test "Docker daemon is running"
|
|
146
|
+
if docker info > /dev/null 2>&1; then
|
|
147
|
+
log_pass "Docker daemon is accessible"
|
|
148
|
+
else
|
|
149
|
+
log_fail "Cannot connect to Docker daemon"
|
|
150
|
+
exit 1
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# Test 3: Service startup verification
|
|
154
|
+
log_test "All services are running"
|
|
155
|
+
sleep 5 # Give services time to stabilize
|
|
156
|
+
|
|
157
|
+
RUNNING_SERVICES=$(docker-compose ps --format "{{.Name}}" | wc -l)
|
|
158
|
+
if [ $RUNNING_SERVICES -ge 3 ]; then
|
|
159
|
+
log_pass "Expected number of services running ($RUNNING_SERVICES)"
|
|
160
|
+
else
|
|
161
|
+
log_fail "Not enough services running (found $RUNNING_SERVICES, expected 3+)"
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Test 4: Wait for services to be ready
|
|
165
|
+
log_info "Waiting for services to become ready..."
|
|
166
|
+
wait_for_service "$BASE_URL/health" || exit 1
|
|
167
|
+
wait_for_service "$CONVERTER_URL/health" || exit 1
|
|
168
|
+
|
|
169
|
+
# ============================================================================
|
|
170
|
+
# cycleCAD Web App Tests (Port 8080)
|
|
171
|
+
# ============================================================================
|
|
172
|
+
|
|
173
|
+
echo ""
|
|
174
|
+
log_info "Testing cycleCAD Web Application..."
|
|
175
|
+
|
|
176
|
+
assert_http_status "$BASE_URL/health" "200" "Health check endpoint" || true
|
|
177
|
+
assert_http_status "$BASE_URL/" "200" "Landing page (index.html)" || true
|
|
178
|
+
assert_http_status "$BASE_URL/app/" "200" "CAD app (app/index.html)" || true
|
|
179
|
+
|
|
180
|
+
# Test header presence
|
|
181
|
+
assert_header_exists "$BASE_URL/" "Access-Control-Allow-Origin" "CORS header present" || true
|
|
182
|
+
assert_header_exists "$BASE_URL/" "Cross-Origin-Opener-Policy" "COOP header present" || true
|
|
183
|
+
assert_header_exists "$BASE_URL/" "Cross-Origin-Embedder-Policy" "COEP header present" || true
|
|
184
|
+
assert_header_exists "$BASE_URL/" "X-Content-Type-Options" "X-Content-Type-Options header" || true
|
|
185
|
+
|
|
186
|
+
# Test caching headers
|
|
187
|
+
log_test "Static assets have aggressive caching"
|
|
188
|
+
CACHE_HEADER=$(curl -s -I "$BASE_URL/screenshot.png" 2>/dev/null | grep -i "Cache-Control" | head -1)
|
|
189
|
+
if [[ "$CACHE_HEADER" =~ "public" ]]; then
|
|
190
|
+
log_pass "Static assets have Cache-Control header"
|
|
191
|
+
else
|
|
192
|
+
log_fail "Static assets missing Cache-Control header"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Test gzip compression
|
|
196
|
+
log_test "Gzip compression is enabled"
|
|
197
|
+
GZIP_TEST=$(curl -s -H "Accept-Encoding: gzip" -I "$BASE_URL/" 2>/dev/null | grep -i "Content-Encoding: gzip")
|
|
198
|
+
if [ ! -z "$GZIP_TEST" ]; then
|
|
199
|
+
log_pass "Gzip compression enabled for responses"
|
|
200
|
+
else
|
|
201
|
+
log_skip "Gzip compression (may not apply to small responses)"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# Test SPA routing
|
|
205
|
+
log_test "SPA routing works for /app/* paths"
|
|
206
|
+
for path in "/app/" "/app/project/test" "/app/edit/model"; do
|
|
207
|
+
assert_http_status "$BASE_URL$path" "200" "SPA route: $path" || true
|
|
208
|
+
done
|
|
209
|
+
|
|
210
|
+
# ============================================================================
|
|
211
|
+
# Converter Service Tests (Port 8787)
|
|
212
|
+
# ============================================================================
|
|
213
|
+
|
|
214
|
+
echo ""
|
|
215
|
+
log_info "Testing STEP Converter Service..."
|
|
216
|
+
|
|
217
|
+
assert_http_status "$CONVERTER_URL/health" "200" "Converter health check" || true
|
|
218
|
+
|
|
219
|
+
# Test OpenAPI documentation
|
|
220
|
+
assert_http_status "$CONVERTER_URL/docs" "200" "OpenAPI documentation" || true
|
|
221
|
+
|
|
222
|
+
# Test converter API endpoints
|
|
223
|
+
log_test "Converter API /convert endpoint exists"
|
|
224
|
+
assert_http_status "$CONVERTER_URL/convert" "405" "POST /convert expects POST (405 for GET)" || true
|
|
225
|
+
|
|
226
|
+
# Create a test STEP file if it doesn't exist
|
|
227
|
+
TEST_STEP_FILE="test-part.stp"
|
|
228
|
+
if [ ! -f "$TEST_STEP_FILE" ]; then
|
|
229
|
+
log_info "Creating minimal test STEP file..."
|
|
230
|
+
# Minimal valid STEP file
|
|
231
|
+
cat > "$TEST_STEP_FILE" << 'EOF'
|
|
232
|
+
ISO-10303-21;
|
|
233
|
+
HEADER;
|
|
234
|
+
FILE_DESCRIPTION(('Test part','Test'),
|
|
235
|
+
'2',2024,13,11,15,30,00,0,());
|
|
236
|
+
FILE_NAME('test-part.stp',
|
|
237
|
+
2024,13,11,15,30,00,0,(),
|
|
238
|
+
'','','');
|
|
239
|
+
FILE_SCHEMA(('IFC2X3'));
|
|
240
|
+
ENDSEC;
|
|
241
|
+
DATA;
|
|
242
|
+
#1=CARTESIAN_POINT('',(0.,0.,0.));
|
|
243
|
+
#2=CARTESIAN_POINT('',(1.,0.,0.));
|
|
244
|
+
#3=CARTESIAN_POINT('',(1.,1.,0.));
|
|
245
|
+
ENDSEC;
|
|
246
|
+
END-ISO-10303-21;
|
|
247
|
+
EOF
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
# Test file upload (may fail if converter not ready, that's OK)
|
|
251
|
+
log_test "STEP file upload and conversion"
|
|
252
|
+
if [ -f "$TEST_STEP_FILE" ]; then
|
|
253
|
+
RESPONSE=$(curl -s -X POST \
|
|
254
|
+
--max-time 30 \
|
|
255
|
+
-F "file=@$TEST_STEP_FILE" \
|
|
256
|
+
"$CONVERTER_URL/convert" 2>/dev/null || echo "")
|
|
257
|
+
|
|
258
|
+
if [ ! -z "$RESPONSE" ] && [[ "$RESPONSE" == *"glb"* ]] || [[ "$RESPONSE" == *"gltf"* ]]; then
|
|
259
|
+
log_pass "STEP conversion returns GLB/glTF response"
|
|
260
|
+
else
|
|
261
|
+
log_skip "STEP conversion (may require full OpenCASCADE.js setup)"
|
|
262
|
+
fi
|
|
263
|
+
else
|
|
264
|
+
log_skip "STEP file upload (test file not available)"
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
# ============================================================================
|
|
268
|
+
# Signaling Service Tests (Port 8788)
|
|
269
|
+
# ============================================================================
|
|
270
|
+
|
|
271
|
+
echo ""
|
|
272
|
+
log_info "Testing Signaling Service..."
|
|
273
|
+
|
|
274
|
+
assert_http_status "$SIGNALING_URL/health" "200" "Signaling health check" || true
|
|
275
|
+
|
|
276
|
+
# Test WebSocket upgrade
|
|
277
|
+
log_test "WebSocket endpoint accepts upgrades"
|
|
278
|
+
# This is a simple check; full WebSocket testing requires wscat or websocat
|
|
279
|
+
WS_TEST=$(curl -s -I -H "Upgrade: websocket" \
|
|
280
|
+
--max-time $TIMEOUT \
|
|
281
|
+
"$SIGNALING_URL/ws" 2>/dev/null | grep -i "upgrade" || echo "")
|
|
282
|
+
|
|
283
|
+
if [ ! -z "$WS_TEST" ]; then
|
|
284
|
+
log_pass "WebSocket upgrade headers present"
|
|
285
|
+
else
|
|
286
|
+
log_skip "WebSocket test (requires websocat or wscat)"
|
|
287
|
+
fi
|
|
288
|
+
|
|
289
|
+
# ============================================================================
|
|
290
|
+
# Docker-Specific Tests
|
|
291
|
+
# ============================================================================
|
|
292
|
+
|
|
293
|
+
echo ""
|
|
294
|
+
log_info "Testing Docker Configuration..."
|
|
295
|
+
|
|
296
|
+
# Test container resource limits
|
|
297
|
+
log_test "Container resource limits are configured"
|
|
298
|
+
CONVERTER_MEMORY=$(docker-compose inspect converter 2>/dev/null | grep -i '"Memory"' | head -1)
|
|
299
|
+
if [ ! -z "$CONVERTER_MEMORY" ]; then
|
|
300
|
+
log_pass "Converter has memory limits configured"
|
|
301
|
+
else
|
|
302
|
+
log_skip "Container memory limits (not visible in inspect output)"
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
# Test health checks
|
|
306
|
+
log_test "Services have health checks defined"
|
|
307
|
+
HEALTH_CHECKS=$(docker-compose inspect --format='{{.Config.Healthcheck}}' 2>/dev/null | grep -c "test" || echo "0")
|
|
308
|
+
if [ $HEALTH_CHECKS -gt 0 ]; then
|
|
309
|
+
log_pass "Health checks are configured"
|
|
310
|
+
else
|
|
311
|
+
log_fail "No health checks found in docker-compose"
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
# Test network
|
|
315
|
+
log_test "Services are connected to correct network"
|
|
316
|
+
NETWORK_NAME=$(docker network ls --filter "name=cyclecad" --format "{{.Name}}")
|
|
317
|
+
if [ ! -z "$NETWORK_NAME" ]; then
|
|
318
|
+
log_pass "cycleCAD network exists"
|
|
319
|
+
else
|
|
320
|
+
log_skip "Network verification (may need to inspect separately)"
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
# ============================================================================
|
|
324
|
+
# Integration Tests
|
|
325
|
+
# ============================================================================
|
|
326
|
+
|
|
327
|
+
echo ""
|
|
328
|
+
log_info "Running Integration Tests..."
|
|
329
|
+
|
|
330
|
+
# Test cross-service communication
|
|
331
|
+
log_test "Converter and signaling are accessible from main app"
|
|
332
|
+
for port in 8787 8788; do
|
|
333
|
+
assert_http_status "http://localhost:$port/health" "200" "Port $port is accessible" || true
|
|
334
|
+
done
|
|
335
|
+
|
|
336
|
+
# Test file size limits
|
|
337
|
+
log_test "Upload size limits are enforced"
|
|
338
|
+
# Check nginx max body size in config
|
|
339
|
+
if [ -f "nginx.conf" ]; then
|
|
340
|
+
MAX_SIZE=$(grep -i "client_max_body_size" nginx.conf | head -1)
|
|
341
|
+
if [[ "$MAX_SIZE" =~ "500M" ]]; then
|
|
342
|
+
log_pass "Max upload size set to 500MB"
|
|
343
|
+
else
|
|
344
|
+
log_skip "Max upload size check"
|
|
345
|
+
fi
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
# ============================================================================
|
|
349
|
+
# Cleanup Tests
|
|
350
|
+
# ============================================================================
|
|
351
|
+
|
|
352
|
+
echo ""
|
|
353
|
+
log_info "Testing Cleanup Operations..."
|
|
354
|
+
|
|
355
|
+
log_test "Services can be stopped and restarted"
|
|
356
|
+
# Just verify the commands would work without executing (too disruptive)
|
|
357
|
+
if docker-compose ps > /dev/null 2>&1; then
|
|
358
|
+
log_pass "docker-compose commands are functional"
|
|
359
|
+
else
|
|
360
|
+
log_fail "docker-compose is not responding"
|
|
361
|
+
fi
|
|
362
|
+
|
|
363
|
+
# ============================================================================
|
|
364
|
+
# Test Summary
|
|
365
|
+
# ============================================================================
|
|
366
|
+
|
|
367
|
+
echo ""
|
|
368
|
+
echo "╔════════════════════════════════════════════════════════════════╗"
|
|
369
|
+
echo "║ TEST SUMMARY ║"
|
|
370
|
+
echo "╚════════════════════════════════════════════════════════════════╝"
|
|
371
|
+
echo ""
|
|
372
|
+
echo -e "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
|
|
373
|
+
echo -e "Tests Failed: ${RED}$TESTS_FAILED${NC}"
|
|
374
|
+
echo -e "Tests Skipped: ${YELLOW}$TESTS_SKIPPED${NC}"
|
|
375
|
+
echo ""
|
|
376
|
+
|
|
377
|
+
TOTAL=$((TESTS_PASSED + TESTS_FAILED + TESTS_SKIPPED))
|
|
378
|
+
PASS_RATE=$((TESTS_PASSED * 100 / (TESTS_PASSED + TESTS_FAILED + 1)))
|
|
379
|
+
|
|
380
|
+
echo "Pass Rate: ${PASS_RATE}% ($TESTS_PASSED/$((TESTS_PASSED + TESTS_FAILED)))"
|
|
381
|
+
echo ""
|
|
382
|
+
|
|
383
|
+
if [ $TESTS_FAILED -eq 0 ]; then
|
|
384
|
+
echo -e "${GREEN}✓ All critical tests passed!${NC}"
|
|
385
|
+
exit 0
|
|
386
|
+
else
|
|
387
|
+
echo -e "${RED}✗ Some tests failed. Review output above.${NC}"
|
|
388
|
+
exit 1
|
|
389
|
+
fi
|
|
Binary file
|