databuild/tests/end_to_end/lib/service_utils.sh
2025-07-07 19:20:45 -07:00

285 lines
No EOL
7.1 KiB
Bash
Executable file

#!/bin/bash
# Service utilities for DataBuild end-to-end tests
set -euo pipefail
# Source test utilities
source "$(dirname "${BASH_SOURCE[0]}")/test_utils.sh"
# Start a DataBuild service with test configuration
start_test_service() {
local service_binary="$1"
local db_path="$2"
local port="${3:-$(find_available_port)}"
local host="${4:-127.0.0.1}"
# Set environment variables for the service
export DATABUILD_BUILD_EVENT_LOG="sqlite:///$db_path"
# Start the service in the background
log_info "Starting service: $service_binary --port=$port --host=$host" >&2
"$service_binary" --port="$port" --host="$host" > /dev/null 2>&1 &
local service_pid=$!
# Wait for service to be ready
local health_url="http://$host:$port/health"
if ! wait_for_service "$health_url" 30; then
kill_and_wait "$service_pid"
test_fail "Service failed to start"
fi
log_info "Service started with PID: $service_pid on port: $port" >&2
echo "$service_pid:$port"
}
# Stop a DataBuild service
stop_test_service() {
local service_info="$1"
local service_pid=$(echo "$service_info" | cut -d: -f1)
if [[ -n "$service_pid" ]]; then
log_info "Stopping service with PID: $service_pid"
kill_and_wait "$service_pid"
log_info "Service stopped"
fi
}
# Make a build request via HTTP API
make_build_request() {
local host="$1"
local port="$2"
local partitions="$3"
local url="http://$host:$port/api/v1/builds"
local data="{\"partitions\": $partitions}"
log_info "Making build request to $url with partitions: $partitions"
local response=$(http_request "POST" "$url" "$data")
local build_id=$(extract_json_value "$response" ".build_id")
if [[ -z "$build_id" || "$build_id" == "null" ]]; then
log_error "Failed to get build ID from response: $response"
return 1
fi
log_info "Build request created with ID: $build_id"
echo "$build_id"
}
# Get build status via HTTP API
get_build_status() {
local host="$1"
local port="$2"
local build_id="$3"
local url="http://$host:$port/api/v1/builds/$build_id"
local response=$(http_request "GET" "$url")
local status=$(extract_json_value "$response" ".status")
echo "$status"
}
# Wait for build to complete
wait_for_build_completion() {
local host="$1"
local port="$2"
local build_id="$3"
local timeout="${4:-60}"
local count=0
while [[ $count -lt $timeout ]]; do
local status=$(get_build_status "$host" "$port" "$build_id")
case "$status" in
"COMPLETED")
log_info "Build $build_id completed successfully"
return 0
;;
"FAILED")
log_error "Build $build_id failed"
return 1
;;
"RUNNING"|"PENDING")
log_info "Build $build_id status: $status"
;;
*)
log_warn "Unknown build status: $status"
;;
esac
sleep 2
((count += 2))
done
log_error "Build $build_id did not complete within $timeout seconds"
return 1
}
# Get partition status via HTTP API
get_partition_status_api() {
local host="$1"
local port="$2"
local partition_ref="$3"
local url="http://$host:$port/api/v1/partitions/$partition_ref"
local response=$(http_request "GET" "$url")
local status=$(extract_json_value "$response" ".status")
echo "$status"
}
# Check service health
check_service_health() {
local host="$1"
local port="$2"
local url="http://$host:$port/health"
if curl -sf "$url" > /dev/null 2>&1; then
log_info "Service health check passed"
return 0
else
log_error "Service health check failed"
return 1
fi
}
# Get service metrics
get_service_metrics() {
local host="$1"
local port="$2"
local output_file="$3"
local url="http://$host:$port/metrics"
if ! http_request "GET" "$url" > "$output_file"; then
log_error "Failed to get service metrics"
return 1
fi
log_info "Service metrics saved to: $output_file"
}
# List all builds via HTTP API
list_builds() {
local host="$1"
local port="$2"
local output_file="$3"
local url="http://$host:$port/api/v1/builds"
if ! http_request "GET" "$url" > "$output_file"; then
log_error "Failed to list builds"
return 1
fi
log_info "Build list saved to: $output_file"
}
# Get build events via HTTP API
get_build_events_api() {
local host="$1"
local port="$2"
local output_file="$3"
local limit="${4:-100}"
local url="http://$host:$port/api/v1/events?limit=$limit"
if ! http_request "GET" "$url" > "$output_file"; then
log_error "Failed to get build events"
return 1
fi
log_info "Build events saved to: $output_file"
}
# Test service API endpoints
test_service_endpoints() {
local host="$1"
local port="$2"
local base_url="http://$host:$port"
# Test health endpoint
if ! curl -sf "$base_url/health" > /dev/null; then
log_error "Health endpoint failed"
return 1
fi
# Test API endpoints
local endpoints=(
"/api/v1/builds"
"/api/v1/events"
"/metrics"
)
for endpoint in "${endpoints[@]}"; do
if ! curl -sf "$base_url$endpoint" > /dev/null; then
log_error "Endpoint $endpoint failed"
return 1
fi
done
log_info "All service endpoints are accessible"
return 0
}
# Execute full build workflow via service
execute_service_build() {
local service_info="$1"
local partitions="$2"
local timeout="${3:-120}"
local service_pid=$(echo "$service_info" | cut -d: -f1)
local port=$(echo "$service_info" | cut -d: -f2)
local host="127.0.0.1"
# Check if service is still running
if ! kill -0 "$service_pid" 2>/dev/null; then
log_error "Service is not running"
return 1
fi
# Make build request
local build_id=$(make_build_request "$host" "$port" "$partitions")
if [[ -z "$build_id" ]]; then
log_error "Failed to create build request"
return 1
fi
# Wait for build completion
if ! wait_for_build_completion "$host" "$port" "$build_id" "$timeout"; then
log_error "Build failed to complete"
return 1
fi
log_info "Service build completed successfully"
return 0
}
# Start service and run build, then stop service
run_service_build() {
local service_binary="$1"
local db_path="$2"
local partitions="$3"
local timeout="${4:-120}"
# Start service
local service_info=$(start_test_service "$service_binary" "$db_path")
# Ensure service is stopped on exit
trap "stop_test_service '$service_info'" EXIT
# Execute build
execute_service_build "$service_info" "$partitions" "$timeout"
local result=$?
# Stop service
stop_test_service "$service_info"
return $result
}