|
261 | 261 | export SUBBOOST_DOCTOR_HEALTH_INTERVAL_SECONDS=0 |
262 | 262 | source local/scripts/subboost.sh |
263 | 263 | sudo_do() { "$@"; } |
| 264 | + docker_calls_file="$home/docker-calls" |
264 | 265 | docker() { |
265 | 266 | if [ "$1" = "info" ]; then return 0; fi |
266 | 267 | if [ "$1" = "compose" ]; then |
| 268 | + printf '%s\\n' "$*" >> "$docker_calls_file" |
267 | 269 | case "$*" in |
268 | 270 | "compose version"*) return 0 ;; |
269 | 271 | *" config --services") printf 'app\\ndb\\ncron\\n'; return 0 ;; |
|
302 | 304 | } |
303 | 305 | update_cmd |
304 | 306 | printf 'curl_count=%s\\n' "$(cat "$curl_count_file")" |
| 307 | + cat "$docker_calls_file" |
305 | 308 | `; |
306 | 309 |
|
307 | 310 | const result = runBash(script); |
|
311 | 314 | expect(result.stdout).not.toContain("健康检查: 异常"); |
312 | 315 | // wait_for_health checks live once per attempt, then status_cmd performs one final live+ready check. |
313 | 316 | expect(result.stdout).toContain("curl_count=8"); |
| 317 | + expect(result.stdout).toContain("up -d --no-deps cron"); |
| 318 | + }, 10_000); |
| 319 | + |
| 320 | + it("restarts rollback cron without recreating the healthy old app", () => { |
| 321 | + const script = ` |
| 322 | + set -Eeuo pipefail |
| 323 | + home="$(mktemp -d)" |
| 324 | + trap 'rm -rf "$home"' EXIT |
| 325 | + mkdir -p "$home/bin" |
| 326 | + cat > "$home/.env" <<'ENV' |
| 327 | +SUBBOOST_IMAGE=image |
| 328 | +POSTGRES_DB=subboost |
| 329 | +POSTGRES_USER=subboost |
| 330 | +POSTGRES_PASSWORD=password |
| 331 | +DATABASE_URL=postgresql://subboost:password@db:5432/subboost?schema=public |
| 332 | +ENCRYPTION_KEY=key |
| 333 | +JWT_SECRET=jwt |
| 334 | +CRON_SECRET=cron |
| 335 | +APP_URL=http://127.0.0.1:31000 |
| 336 | +SUBBOOST_PORT=31000 |
| 337 | +ENV |
| 338 | + : > "$home/docker-compose.yml" |
| 339 | + export SUBBOOST_SCRIPT_SOURCE_ONLY=1 |
| 340 | + export SUBBOOST_HOME="$home" |
| 341 | + export SUBBOOST_BIN="$home/bin/subboost" |
| 342 | + export SUBBOOST_DOCTOR_HEALTH_ATTEMPTS=1 |
| 343 | + export SUBBOOST_DOCTOR_HEALTH_INTERVAL_SECONDS=0 |
| 344 | + source local/scripts/subboost.sh |
| 345 | + sudo_do() { "$@"; } |
| 346 | + docker_calls_file="$home/docker-calls" |
| 347 | + docker() { |
| 348 | + if [ "$1" = "info" ]; then return 0; fi |
| 349 | + if [ "$1" = "compose" ]; then |
| 350 | + printf '%s\\n' "$*" >> "$docker_calls_file" |
| 351 | + case "$*" in |
| 352 | + "compose version"*) return 0 ;; |
| 353 | + *" config --services") printf 'app\\ndb\\ncron\\n'; return 0 ;; |
| 354 | + *" config" | *" pull" | *" stop cron app") return 0 ;; |
| 355 | + *"pg_dump -Fc"*) printf 'custom-dump'; return 0 ;; |
| 356 | + *"pg_restore --list"* | *"pg_restore --clean"*) cat >/dev/null; return 0 ;; |
| 357 | + *"candidate-compose.yml up -d --no-deps cron") return 1 ;; |
| 358 | + *" up -d "*) return 0 ;; |
| 359 | + *" ps -q app") printf 'app-id\\n'; return 0 ;; |
| 360 | + esac |
| 361 | + fi |
| 362 | + if [ "$1" = "inspect" ] && [ "$2" = "-f" ]; then |
| 363 | + printf 'sha256:old-image\\n' |
| 364 | + fi |
| 365 | + return 0 |
| 366 | + } |
| 367 | + curl() { return 0; } |
| 368 | + update_status=0 |
| 369 | + if update_cmd; then |
| 370 | + : |
| 371 | + else |
| 372 | + update_status=$? |
| 373 | + fi |
| 374 | + printf 'update_status=%s\\n' "$update_status" |
| 375 | + cat "$docker_calls_file" |
| 376 | + [ "$update_status" -eq 1 ] |
| 377 | + `; |
| 378 | + |
| 379 | + const result = runBash(script); |
| 380 | + |
| 381 | + expect(result.status, `stdout:\n${result.stdout}\nstderr:\n${result.stderr}`).toBe(0); |
| 382 | + expect(result.stdout).toContain("Candidate update failed: candidate cron startup failed"); |
| 383 | + expect(result.stdout).toContain("Previous version restored successfully."); |
| 384 | + expect(result.stdout).toMatch(/candidate-compose\.yml.*up -d --no-deps cron/); |
| 385 | + expect(result.stdout).toMatch(/old-compose\.yml.*up -d --no-deps cron/); |
| 386 | + expect(result.stdout).not.toMatch(/old-compose\.yml.*up -d cron(?:\s|$)/); |
314 | 387 | }, 10_000); |
315 | 388 |
|
316 | 389 | it("uses refreshed release metadata before pulling during update", () => { |
|
0 commit comments