fetch_ml/scripts/dev/smoke-test.sh
Jeremie Fraeys d3a861063f
fix(smoke-test): add Colima-specific file sharing instructions
Detect if user is running Colima and provide appropriate fix instructions:

- Check for colima command presence
- If Colima detected: suggest virtiofs/sshfs mount options
- Show colima.yaml mount configuration example
- Include verification command: colima ssh -- ls ...

Maintains Docker Desktop instructions for non-Colima users.
2026-02-24 11:35:58 -05:00

212 lines
No EOL
7.2 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail;
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
export FETCHML_REPO_ROOT="$repo_root"
# Parse arguments
env="dev"
native_mode=false
while [[ $# -gt 0 ]]; do
case "$1" in
--native)
native_mode=true
shift
;;
dev|prod)
env="$1"
shift
;;
--help|-h)
echo "Usage: $0 [dev|prod] [--native]"
echo ""
echo "Options:"
echo " dev|prod Environment to test (default: dev)"
echo " --native Also test native libraries (C++ integration)"
echo " --help Show this help"
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [dev|prod] [--native]" >&2
exit 2
;;
esac
done
# Native library smoke test (merged from smoke-test-native.sh)
if [[ "$native_mode" == true ]]; then
echo "=== FetchML Native Libraries Smoke Test ==="
echo ""
cd "$repo_root"
# Build native libraries
echo "1. Building native libraries..."
if [[ -d native/build ]]; then
cd native/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_ASAN=OFF >/dev/null 2>&1 || true
make -j4 2>&1 | grep -E "(Built|Error|error)" || true
cd ../..
echo " Native libraries built"
else
echo " ⚠ native/build not found, skipping native build"
fi
echo ""
# Run C++ unit tests
echo "2. Running C++ smoke tests..."
local tests_run=0
for test_bin in ./native/build/test_*; do
if [[ -x "$test_bin" ]]; then
local test_name=$(basename "$test_bin")
echo " Running $test_name..."
"$test_bin" 2>/dev/null && echo "$test_name passed" || echo "$test_name skipped/failed"
((tests_run++))
fi
done
if [[ $tests_run -eq 0 ]]; then
echo " ⚠ No C++ tests found"
else
echo " Ran $tests_run C++ test(s)"
fi
echo ""
echo "3. Building Go applications with native libs..."
go build -tags native_libs -o /dev/null ./cmd/api-server 2>&1 | grep -v "ignoring duplicate" || true
echo " api-server builds"
go build -tags native_libs -o /dev/null ./cmd/worker 2>&1 | grep -v "ignoring duplicate" || true 2>/dev/null || echo " (worker optional)"
echo ""
fi
probe_https_health_openssl() {
host="$1"
port="$2"
path="$3"
req="GET ${path} HTTP/1.1\r\nHost: ${host}\r\nConnection: close\r\n\r\n"
resp=$(printf "%b" "$req" | openssl s_client -connect "127.0.0.1:${port}" -servername "${host}" -tls1_2 -quiet 2>/dev/null || true)
printf "%s" "$resp" | tr -d '\r' | head -n 1 | grep -Eq '^HTTP/1\.[01] 200'
}
compose_cmd="docker-compose";
if ! command -v docker-compose >/dev/null 2>&1; then
compose_cmd="docker compose";
fi
compose_files=()
compose_project_args=("--project-directory" "$repo_root")
api_base=""
prometheus_base=""
stack_name=""
api_wait_seconds=90
prometheus_wait_seconds=90
if [ "$env" = "dev" ]; then
mkdir -p \
"$repo_root/data/dev/redis" \
"$repo_root/data/dev/minio" \
"$repo_root/data/dev/prometheus" \
"$repo_root/data/dev/grafana" \
"$repo_root/data/dev/loki" \
"$repo_root/data/dev/logs" \
"$repo_root/data/dev/experiments" \
"$repo_root/data/dev/active" \
"$repo_root/data/dev/workspaces"
# Verify Docker can access the data directory (macOS file sharing check)
if ! docker run --rm -v "$repo_root/data/dev:/test-data:ro" alpine:3.19 ls /test-data >/dev/null 2>&1; then
echo "ERROR: Docker cannot access $repo_root/data/dev"
echo ""
if command -v colima >/dev/null 2>&1; then
echo "You are using Colima. To fix:"
echo "1. Stop Colima: colima stop"
echo "2. Start with host mounts enabled: colima start --mount-type=virtiofs"
echo " OR: colima start --mount-type=sshfs --mount-writable"
echo "3. Verify the mount: colima ssh -- ls $repo_root/data/dev"
echo ""
echo "If using Colima template, ensure your ~/.colima/default/colima.yaml has:"
echo " mounts:"
echo " - location: $repo_root"
echo " writable: true"
else
echo "This is a Docker Desktop file sharing issue. To fix:"
echo "1. Open Docker Desktop -> Settings -> Resources -> File sharing"
echo "2. Add or verify: $repo_root"
echo "3. Click 'Apply & Restart'"
fi
echo ""
echo "Alternatively, run: mkdir -p $repo_root/data/dev/{redis,minio,prometheus,grafana,loki,logs,experiments,active,workspaces}"
exit 1
fi
stack_name="dev"
api_wait_seconds=180
prometheus_wait_seconds=180
compose_files=("-f" "$repo_root/deployments/docker-compose.dev.yml")
api_base="https://localhost:9101"
if ! curl -skf "$api_base/health" >/dev/null 2>&1; then
api_base="http://localhost:9101"
fi
prometheus_base="http://localhost:9090"
else
mkdir -p \
"$repo_root/data/prod-smoke/caddy/data" \
"$repo_root/data/prod-smoke/caddy/config" \
"$repo_root/data/prod-smoke/redis" \
"$repo_root/data/prod-smoke/logs" \
"$repo_root/data/prod-smoke/experiments" \
"$repo_root/data/prod-smoke/active"
stack_name="prod"
compose_files=("-f" "$repo_root/deployments/docker-compose.prod.smoke.yml")
api_base="https://localhost:8443"
export FETCHML_DOMAIN=localhost
export CADDY_EMAIL=smoke@example.invalid
fi
cleanup() {
status=$?;
if [ "$status" -ne 0 ]; then
$compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" logs --no-color || true;
fi
if [ "${KEEP_STACK:-0}" != "1" ]; then
$compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" down -v >/dev/null 2>&1 || true;
fi
exit "$status";
}
trap cleanup EXIT;
echo "Starting $stack_name stack for smoke test...";
$compose_cmd "${compose_project_args[@]}" "${compose_files[@]}" up -d --build >/dev/null;
echo "Waiting for API to become healthy...";
deadline=$(($(date +%s) + $api_wait_seconds));
while true; do
if [ "$env" = "dev" ]; then
if curl -skf "$api_base/health" >/dev/null 2>&1; then break; fi;
else
if probe_https_health_openssl "localhost" "8443" "/health"; then break; fi;
fi
if [ $(date +%s) -ge $deadline ]; then echo "Timed out waiting for $api_base/health"; exit 1; fi;
sleep 2;
done;
if [ "$env" = "dev" ]; then
echo "Checking metrics endpoint...";
curl -skf "$api_base/metrics" >/dev/null;
echo "Waiting for Prometheus target api-server to be up...";
deadline=$(($(date +%s) + $prometheus_wait_seconds));
query_url="$prometheus_base/api/v1/query?query=up%7Bjob%3D%22api-server%22%7D";
while true; do
resp=$(curl -sf "$query_url" || true);
resp_compact=$(printf "%s" "$resp" | tr -d '\n' | tr -d '\r');
if echo "$resp_compact" | grep -Fq '"instance":"api-server:9101"' && echo "$resp_compact" | grep -Fq ',"1"]'; then break; fi;
if [ $(date +%s) -ge $deadline ]; then echo "Timed out waiting for Prometheus api-server target to be up"; echo "$resp"; exit 1; fi;
sleep 2;
done;
fi