#!/usr/bin/env bash # Disposable, headless smoke check for the incomplete 26.3 runtime Age backend. set -euo pipefail repo_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) smoke_dir=$(mktemp -d "${TMPDIR:-/tmp}/rivencraft-263-smoke.XXXXXX") server_dir="$smoke_dir/server" server_pid= input_fd= cleanup() { if [[ -n "$server_pid" ]] && kill -0 "$server_pid" 2>/dev/null; then if [[ -n "$input_fd" ]]; then printf 'stop\n' >&"$input_fd" || true; fi wait "$server_pid" 2>/dev/null || true fi if [[ -n "$input_fd" ]]; then exec {input_fd}>&-; fi rm -rf -- "$smoke_dir" } trap cleanup EXIT mkdir -p "$server_dir" printf 'eula=true\n' > "$server_dir/eula.txt" printf 'server-port=0\nonline-mode=false\nwhite-list=false\n' > "$server_dir/server.properties" wait_for_log() { local log_file=$1 pattern=$2 seconds=$3 local tries=$((seconds * 4)) for ((i = 0; i < tries; i++)); do if grep -Fq -- "$pattern" "$log_file" 2>/dev/null; then return 0; fi if ! kill -0 "$server_pid" 2>/dev/null; then printf 'Server exited before: %s\n' "$pattern" >&2 tail -80 "$log_file" >&2 return 1 fi sleep 0.25 done printf 'Timed out waiting for: %s\n' "$pattern" >&2 tail -80 "$log_file" >&2 return 1 } start_server() { local phase=$1 log_file="$smoke_dir/$phase.log" fifo="$smoke_dir/$phase.stdin" mkfifo "$fifo" exec {input_fd}<>"$fifo" "$repo_dir/gradlew" -p "$repo_dir/ports/mc263" runServer \ -PserverRunDir="$server_dir" --no-daemon < "$fifo" > "$log_file" 2>&1 & server_pid=$! wait_for_log "$log_file" 'Done (' 120 } stop_server() { printf 'stop\n' >&"$input_fd" wait "$server_pid" server_pid= exec {input_fd}>&- rm -- "$fifo" } send_and_wait() { local command=$1 result=$2 printf '%s\n' "$command" >&"$input_fd" wait_for_log "$log_file" "$result" 60 } start_server first send_and_wait 'rivencraft_port compat' 'Registered biomes by namespace:' send_and_wait 'rivencraft_port age create smoke_alpha 123456789' 'Created rivencraft:age/smoke_alpha with seed 123456789' send_and_wait 'rivencraft_port age create smoke_beta 987654321' 'Created rivencraft:age/smoke_beta with seed 987654321' # The index must reach disk while the server is still running. A graceful # shutdown would hide the interrupted-save regression this checks. index_file="$server_dir/world/dimensions/minecraft/overworld/data/rivencraft/runtime_ages.dat" [[ -s "$index_file" ]] || { printf 'Age index was not persisted before shutdown: %s\n' "$index_file" >&2 exit 1 } gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_alpha' gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_beta' send_and_wait 'rivencraft_port age sample smoke_alpha' 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' alpha_before=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//') beta_before=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//') if [[ "$alpha_before" == "$beta_before" ]]; then printf 'Different Age seeds produced the same terrain probe: %s\n' "$alpha_before" >&2 exit 1 fi stop_server start_server restart send_and_wait 'rivencraft_port age list' 'smoke_alpha' send_and_wait 'rivencraft_port age sample smoke_alpha' 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' alpha_after=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//') beta_after=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//') [[ "$alpha_before" == "$alpha_after" && "$beta_before" == "$beta_after" ]] || { printf 'Age terrain changed across restart: %s/%s -> %s/%s\n' \ "$alpha_before" "$beta_before" "$alpha_after" "$beta_after" >&2 exit 1 } stop_server printf '26.3 dedicated-server smoke passed: two distinct Ages persisted across restart.\n'