Repository navigation
Expand file tree
/
Copy pathDockerfile.test
More file actions
285 lines (235 loc) Β· 7.33 KB
/
Copy pathDockerfile.test
File metadata and controls
285 lines (235 loc) Β· 7.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# Multi-stage Docker build for testing environment
# This Dockerfile creates a comprehensive testing environment with all necessary tools
FROM node:24-bookworm AS node-deps
WORKDIR /app
COPY package.json bun.lock* ./
RUN npm install -g bun && bun install --frozen-lockfile
# Use rustup nightly directly so the cached deps build matches the
# nightly pinned in rust-toolchain.toml (otherwise stable rust builds
# the dummy crate and the real build re-fetches nightly, busting cache).
FROM rust:1.93-slim-bookworm AS rust-deps
WORKDIR /app
COPY Cargo.toml Cargo.lock rust-toolchain.toml ./
ARG SKIP_MODEL_BUILD=1
ENV SKIP_MODEL_BUILD=${SKIP_MODEL_BUILD}
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release && rm -rf src
# Test execution environment β aligned with production polyglot Dockerfile.
FROM rust:1.93-slim-bookworm
# Install system dependencies for testing
RUN apt-get update && apt-get install -y \
curl \
wget \
gnupg \
ca-certificates \
postgresql-client \
redis-tools \
jq \
python3 \
python3-pip \
build-essential \
git \
&& rm -rf /var/lib/apt/lists/*
# Install Node.js 24 LTS and Bun for TypeScript testing (aligned with
# production Dockerfile's `NODE_MAJOR=24`).
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g bun
# Install Playwright and dependencies
RUN npx playwright install-deps
RUN npx playwright install chromium
# Install Rust toolchain components for testing and coverage
RUN rustup component add rustfmt clippy
RUN cargo install grcov
RUN cargo install cargo-tarpaulin
# Set up work directory
WORKDIR /app
# Copy dependency files
COPY --from=node-deps /app/node_modules ./node_modules
COPY --from=rust-deps /app/target ./target
# Copy source code
COPY . .
# Create directories for test results and coverage
RUN mkdir -p /test-results /coverage /reports
# Set environment variables for testing
ENV RUST_LOG=debug
ENV CARGO_INCREMENTAL=0
ENV RUSTFLAGS="-C instrument-coverage"
ENV LLVM_PROFILE_FILE="/coverage/rust-%p-%m.profraw"
ENV NODE_ENV=test
ENV CI=true
ENV SKIP_MODEL_BUILD=1
# Install additional test utilities
RUN pip3 install --no-cache-dir \
pytest \
pytest-html \
requests \
beautifulsoup4
# Create test scripts directory
RUN mkdir -p /scripts
# Create comprehensive test runner script
RUN cat > /scripts/run-tests.sh << 'EOF'
#!/bin/bash
set -e
echo "π§ͺ Starting comprehensive test suite..."
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test results directory
RESULTS_DIR="/test-results"
COVERAGE_DIR="/coverage"
REPORTS_DIR="/reports"
# Ensure directories exist
mkdir -p "$RESULTS_DIR" "$COVERAGE_DIR" "$REPORTS_DIR"
# Function to run with timing
run_with_timing() {
local name="$1"
shift
echo -e "${BLUE}π Running: $name${NC}"
local start_time=$(date +%s)
if "$@"; then
local end_time=$(date +%s)
local duration=$((end_time - start_time))
echo -e "${GREEN}β
$name completed in ${duration}s${NC}"
return 0
else
local end_time=$(date +%s)
local duration=$((end_time - start_time))
echo -e "${RED}β $name failed after ${duration}s${NC}"
return 1
fi
}
# 1. Rust unit tests with coverage
echo -e "${YELLOW}π Phase 1: Rust Unit Tests${NC}"
run_with_timing "Rust unit tests" \
cargo test --lib --bins --tests \
--exclude-from-test integration \
--exclude-from-test e2e
# 2. TypeScript unit tests with coverage
echo -e "${YELLOW}π Phase 2: TypeScript Unit Tests${NC}"
run_with_timing "TypeScript tests" \
bun test --coverage --reporter json > "$RESULTS_DIR/typescript-results.json"
# 3. Rust integration tests
echo -e "${YELLOW}π Phase 3: Rust Integration Tests${NC}"
run_with_timing "Rust integration tests" \
cargo test --test '*_integration' \
--test-threads 1
# 4. API integration tests
echo -e "${YELLOW}π Phase 4: API Integration Tests${NC}"
run_with_timing "API tests" \
cargo test tests::api \
--test-threads 1
# 5. End-to-end tests with Playwright
echo -e "${YELLOW}π Phase 5: End-to-End Tests${NC}"
run_with_timing "E2E tests" \
npx playwright test --reporter=json --output-dir="$RESULTS_DIR/playwright"
# 6. Performance tests (if enabled)
if [[ "${RUN_PERFORMANCE_TESTS:-false}" == "true" ]]; then
echo -e "${YELLOW}β‘ Phase 6: Performance Tests${NC}"
run_with_timing "Performance tests" \
cargo test --test performance --release
fi
# 7. Generate coverage reports
echo -e "${YELLOW}π Phase 7: Coverage Report Generation${NC}"
# Rust coverage
run_with_timing "Rust coverage report" \
grcov . --binary-path ./target/debug/deps/ \
-s . \
-t html,lcov,json,cobertura \
--branch \
--ignore-not-existing \
--ignore '../*' \
--ignore "/*" \
--ignore "tests/*" \
--ignore "target/*" \
-o "$COVERAGE_DIR/rust"
# TypeScript coverage (handled by c8/nyc via bun test)
echo -e "${GREEN}π Coverage reports generated${NC}"
# 8. Generate unified test report
echo -e "${YELLOW}π Phase 8: Unified Report Generation${NC}"
cat > "$REPORTS_DIR/test-summary.json" << REPORT_EOF
{
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)",
"test_run_id": "$(uuidgen)",
"environment": {
"rust_version": "$(rustc --version)",
"node_version": "$(node --version)",
"bun_version": "$(bun --version)",
"os": "$(uname -a)"
},
"phases": {
"rust_unit": {"status": "completed"},
"typescript_unit": {"status": "completed"},
"rust_integration": {"status": "completed"},
"api_integration": {"status": "completed"},
"e2e": {"status": "completed"},
"coverage": {"status": "completed"}
},
"artifacts": {
"coverage_dir": "$COVERAGE_DIR",
"results_dir": "$RESULTS_DIR",
"reports_dir": "$REPORTS_DIR"
}
}
REPORT_EOF
echo -e "${GREEN}π Test suite completed successfully!${NC}"
echo -e "${BLUE}π Results: $RESULTS_DIR${NC}"
echo -e "${BLUE}π Coverage: $COVERAGE_DIR${NC}"
echo -e "${BLUE}π Reports: $REPORTS_DIR${NC}"
EOF
# Make script executable
RUN chmod +x /scripts/run-tests.sh
# Create health check script
RUN cat > /scripts/healthcheck.sh << 'EOF'
#!/bin/bash
set -e
# Check if all required services are available
echo "π Checking service dependencies..."
# Check PostgreSQL
if ! pg_isready -h postgres -p 5432 -U postgres -d uar_test -q; then
echo "β PostgreSQL not ready"
exit 1
fi
# Check Redis
if ! redis-cli -h redis -p 6379 ping >/dev/null 2>&1; then
echo "β Redis not ready"
exit 1
fi
# Check SurrealDB
if ! curl -sf http://surreal:8000/health >/dev/null 2>&1; then
echo "β SurrealDB not ready"
exit 1
fi
# Check main application
if ! curl -sf http://app:3001/health >/dev/null 2>&1; then
echo "β Main application not ready"
exit 1
fi
echo "β
All services ready"
exit 0
EOF
RUN chmod +x /scripts/healthcheck.sh
# Create quick smoke test script
RUN cat > /scripts/smoke-test.sh << 'EOF'
#!/bin/bash
set -e
echo "π Running smoke tests..."
# Quick connectivity tests
curl -f http://app:3001/health || exit 1
pg_isready -h postgres -p 5432 -U postgres -d uar_test || exit 1
redis-cli -h redis -p 6379 ping || exit 1
# Quick compilation check
cargo check --all-targets || exit 1
# Quick TypeScript check
bun run check || exit 1
echo "β
Smoke tests passed"
EOF
RUN chmod +x /scripts/smoke-test.sh
# Set default command
CMD ["/scripts/run-tests.sh"]
# Add healthcheck
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD /scripts/healthcheck.sh