#!/usr/bin/env bash # ============================================================================= # Training Infrastructure Consistency Tests # ============================================================================= # Validates that Dockerfile.training, train.sh, build_docker_images.sh, and # job-template.yaml all agree on binary names and model mappings. # # Run: bash infra/scripts/tests/test_training_infra_consistency.sh # ============================================================================= set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" PASS=0 FAIL=0 pass() { echo " PASS: $1"; PASS=$((PASS + 1)); } fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); } echo "=== Training Infrastructure Consistency Tests ===" echo "" # --- Test 1: Dockerfile.training builds all expected binaries ---------------- echo "[1] Dockerfile.training binary list" DOCKERFILE="$REPO_ROOT/infra/docker/Dockerfile.training" EXPECTED_BINS=(train_baseline_rl train_baseline_supervised evaluate_baseline hyperopt_baseline_rl hyperopt_baseline_supervised) for bin in "${EXPECTED_BINS[@]}"; do if grep -q "$bin" "$DOCKERFILE"; then pass "Dockerfile builds $bin" else fail "Dockerfile missing $bin" fi done # --- Test 2: build_docker_images.sh EXPECTED_BINARIES matches ---------------- echo "" echo "[2] build_docker_images.sh EXPECTED_BINARIES" BUILD_SCRIPT="$REPO_ROOT/scripts/build_docker_images.sh" # Only check the hyperopt binaries (that's what EXPECTED_BINARIES validates) for bin in hyperopt_baseline_rl hyperopt_baseline_supervised; do if grep -q "\"$bin\"" "$BUILD_SCRIPT"; then pass "build_docker_images.sh validates $bin" else fail "build_docker_images.sh missing $bin from EXPECTED_BINARIES" fi done # --- Test 3: train.sh MODEL_BINARY covers all 10 models --------------------- echo "" echo "[3] train.sh MODEL_BINARY mapping completeness" TRAIN_SCRIPT="$REPO_ROOT/infra/scripts/train.sh" ALL_MODELS=(dqn ppo tft mamba2 tggn tlob liquid kan xlstm diffusion) for model in "${ALL_MODELS[@]}"; do if grep -q "\\[$model\\]=" "$TRAIN_SCRIPT"; then pass "train.sh maps model=$model" else fail "train.sh missing mapping for model=$model" fi done # --- Test 4: train.sh maps RL models to train_baseline_rl ------------------- echo "" echo "[4] train.sh RL model mapping" RL_MODELS=(dqn ppo) for model in "${RL_MODELS[@]}"; do if grep "\\[$model\\]=" "$TRAIN_SCRIPT" | grep -q "train_baseline_rl"; then pass "$model maps to train_baseline_rl" else fail "$model should map to train_baseline_rl" fi done # --- Test 5: train.sh maps supervised models to train_baseline_supervised ---- echo "" echo "[5] train.sh supervised model mapping" SUPERVISED_MODELS=(tft mamba2 tggn tlob liquid kan xlstm diffusion) for model in "${SUPERVISED_MODELS[@]}"; do if grep "\\[$model\\]=" "$TRAIN_SCRIPT" | grep -q "train_baseline_supervised"; then pass "$model maps to train_baseline_supervised" else fail "$model should map to train_baseline_supervised" fi done # --- Test 6: Dockerfile COPY and strip loop are consistent ------------------- echo "" echo "[6] Dockerfile build-and-copy consistency" # Check the for loop that copies binaries matches the cargo build --example list CARGO_EXAMPLES=$(grep -oP '(?<=--example )\S+' "$DOCKERFILE" | sort) COPY_BINS=$(grep -oP '(?<=for bin in )\S.*?(?=;)' "$DOCKERFILE" | tr ' ' '\n' | sort) if [ "$CARGO_EXAMPLES" = "$COPY_BINS" ]; then pass "Dockerfile cargo build examples match copy loop" else fail "Dockerfile cargo build examples don't match copy loop" echo " Build: $CARGO_EXAMPLES" echo " Copy: $COPY_BINS" fi # --- Test 7: job-template.yaml references valid binary ----------------------- echo "" echo "[7] job-template.yaml binary reference" JOB_TEMPLATE="$REPO_ROOT/infra/k8s/training/job-template.yaml" if grep -q "train_baseline_supervised\|train_baseline_rl" "$JOB_TEMPLATE"; then pass "job-template.yaml references unified binary" else fail "job-template.yaml doesn't reference unified binaries" fi # --- Test 8: No references to deleted binaries in infra ---------------------- echo "" echo "[8] No stale binary references in infra/" DELETED_BINS=(train_dqn train_tft train_ppo_parquet train_tft_parquet train_mamba2_parquet train_dqn_production train_rainbow train_ppo_extended train_continuous_ppo_parquet hyperopt_dqn_demo hyperopt_ppo_demo hyperopt_tft_demo hyperopt_mamba2_demo hyperopt_continuous_ppo_demo hyperopt_baseline) STALE_FOUND=0 for bin in "${DELETED_BINS[@]}"; do # Search infra/ and scripts/ (excluding this test and docs/) if grep -rq --include='*.sh' --include='*.yaml' --include='*.yml' "$bin" \ "$REPO_ROOT/infra/" "$REPO_ROOT/scripts/" 2>/dev/null | grep -v "test_training_infra" | grep -v "docs/" | head -1; then fail "Stale reference to deleted binary: $bin" STALE_FOUND=$((STALE_FOUND + 1)) fi done if [ "$STALE_FOUND" -eq 0 ]; then pass "No stale binary references in infra/ or scripts/" fi # --- Test 9: Cargo.toml has example entries for all unified binaries --------- echo "" echo "[9] Cargo.toml example entries" CARGO_TOML="$REPO_ROOT/crates/ml/Cargo.toml" for bin in train_baseline_rl train_baseline_supervised hyperopt_baseline_rl hyperopt_baseline_supervised evaluate_baseline; do if grep -q "name = \"$bin\"" "$CARGO_TOML"; then pass "Cargo.toml has example entry: $bin" else fail "Cargo.toml missing example entry: $bin" fi done # --- Summary ------------------------------------------------------------------ echo "" echo "=== Results: $PASS passed, $FAIL failed ===" if [ "$FAIL" -gt 0 ]; then exit 1 fi