- Migrate Paper loader from sunset v2 API to v3 (fill.papermc.io) - Fix NeoForge: fall back to beta versions when no stable exists (set -e + grep) - Fix setEula/setperms ordering (was writing eula.txt before /data was writable) - Fix setEula/serverInfoWrite to use absolute paths (/data/server/) - Add VOLUME directive removal (was shadowing bind mounts) - Add comprehensive API test suite (110 tests across 6 suites) - Move test.sh to tests/integration.sh, switch to named volumes - Add Docker build cache to CI workflows - Add .editorconfig, expand .gitignore, improve README docs
253 lines
8.5 KiB
Bash
Executable File
253 lines
8.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Tests for Bedrock Dedicated Server download API
|
|
# Covers: Primary API, fallback API, version parsing
|
|
# Usage: ./tests/test_bedrock.sh
|
|
|
|
source "$(dirname "$0")/test_utils.sh"
|
|
|
|
echo -e "\n${BOLD}Bedrock API Tests${NC}"
|
|
echo ""
|
|
|
|
BEDROCK_API_URL="https://net.web.minecraft-services.net/api/v1.0/download/links"
|
|
BEDROCK_FALLBACK_URL="https://raw.githubusercontent.com/kittizz/bedrock-server-downloads/refs/heads/main/bedrock-server-downloads.json"
|
|
|
|
# ---------- Primary API (minecraft-services.net) ---------------------------
|
|
|
|
test_bedrock_primary_api_reachable() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
assert_not_empty "$body" "Bedrock primary API body should not be empty"
|
|
}
|
|
|
|
test_bedrock_primary_api_is_json() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
assert_json_valid "$body" "Primary API response should be valid JSON"
|
|
}
|
|
|
|
test_bedrock_primary_api_has_result() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
assert_json_field "$body" '.result' "Should have .result field"
|
|
}
|
|
|
|
test_bedrock_primary_api_has_links() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
assert_json_field "$body" '.result.links' "Should have .result.links array"
|
|
}
|
|
|
|
test_bedrock_primary_api_links_is_array() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local type
|
|
type=$(echo "$body" | jq -r '.result.links | type')
|
|
assert_equals "$type" "array" ".result.links should be an array"
|
|
}
|
|
|
|
test_bedrock_primary_has_linux_entry() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local found
|
|
found=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
|
|
|
|
if [[ -n "$found" && "$found" != "null" ]]; then
|
|
return 0
|
|
else
|
|
echo "ASSERT FAILED: No serverBedrockLinux entry found"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
test_bedrock_primary_linux_url_format() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local url
|
|
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
|
|
|
|
assert_matches "$url" "bedrock-server-.*\.zip$" \
|
|
"Linux download URL should end with bedrock-server-{version}.zip"
|
|
}
|
|
|
|
test_bedrock_primary_linux_url_reachable() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local url
|
|
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
|
|
|
|
if [[ -z "$url" ]]; then
|
|
echo "No Linux download URL found"
|
|
return 1
|
|
fi
|
|
|
|
# Just check HTTP HEAD to avoid downloading the full zip
|
|
local http_code
|
|
http_code=$(curl -sL -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 30 \
|
|
-A "Mozilla/5.0 (X11; Linux x86_64)" -I "$url") || true
|
|
assert_equals "$http_code" "200" "Bedrock download URL should return HTTP 200"
|
|
}
|
|
|
|
test_bedrock_primary_has_windows_entry() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local found
|
|
found=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockWin") | .downloadUrl // empty')
|
|
|
|
if [[ -n "$found" && "$found" != "null" ]]; then
|
|
return 0
|
|
else
|
|
echo "No serverBedrockWin entry found (may be expected on some API versions)"
|
|
return 77 # skip
|
|
fi
|
|
}
|
|
|
|
test_bedrock_primary_download_type_values() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local types
|
|
types=$(echo "$body" | jq -r '.result.links[].downloadType' | sort -u)
|
|
|
|
assert_not_empty "$types" "Should have at least one download type"
|
|
}
|
|
|
|
# ---------- Version parsing from URL ---------------------------------------
|
|
|
|
test_bedrock_version_from_url() {
|
|
local body
|
|
body=$(api_get_ua "$BEDROCK_API_URL")
|
|
local url
|
|
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
|
|
|
|
if [[ -z "$url" ]]; then
|
|
echo "No Linux download URL found"
|
|
return 1
|
|
fi
|
|
|
|
# Extract version from URL (same regex as bedrock.sh)
|
|
local ver
|
|
ver=$(echo "$url" | grep -oP 'bedrock-server-\K[\d.]+(?=\.zip)')
|
|
assert_not_empty "$ver" "Should extract version from URL"
|
|
assert_matches "$ver" "^[0-9]+\.[0-9]+\.[0-9]+" \
|
|
"Version '${ver}' should look like x.y.z"
|
|
}
|
|
|
|
# ---------- Fallback API (GitHub) ------------------------------------------
|
|
|
|
test_bedrock_fallback_api_reachable() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
assert_not_empty "$body" "Bedrock fallback API body should not be empty"
|
|
}
|
|
|
|
test_bedrock_fallback_api_is_json() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
assert_json_valid "$body" "Fallback API response should be valid JSON"
|
|
}
|
|
|
|
test_bedrock_fallback_has_release() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
assert_json_field "$body" '.release' "Should have .release field"
|
|
}
|
|
|
|
test_bedrock_fallback_release_is_object() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
local type
|
|
type=$(echo "$body" | jq -r '.release | type')
|
|
assert_equals "$type" "object" ".release should be a JSON object"
|
|
}
|
|
|
|
test_bedrock_fallback_release_has_entries() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
local count
|
|
count=$(echo "$body" | jq '.release | length')
|
|
if [[ "$count" -gt 0 ]]; then
|
|
return 0
|
|
else
|
|
echo "ASSERT FAILED: .release should have entries, got ${count}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
test_bedrock_fallback_entry_has_linux_url() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
local first_key
|
|
first_key=$(echo "$body" | jq -r '.release | keys | .[0]')
|
|
local url
|
|
url=$(echo "$body" | jq -r ".release[\"${first_key}\"].linux.url // empty")
|
|
|
|
assert_not_empty "$url" "First release entry should have .linux.url"
|
|
}
|
|
|
|
test_bedrock_fallback_linux_url_format() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
local first_key
|
|
first_key=$(echo "$body" | jq -r '.release | keys | .[0]')
|
|
local url
|
|
url=$(echo "$body" | jq -r ".release[\"${first_key}\"].linux.url // empty")
|
|
|
|
assert_matches "$url" "bedrock-server-.*\.zip$" \
|
|
"Fallback URL should end with bedrock-server-{version}.zip"
|
|
}
|
|
|
|
test_bedrock_fallback_highest_version() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
# The script sorts by version and takes the last (highest) entry
|
|
local highest
|
|
highest=$(echo "$body" | jq -r '
|
|
.release | to_entries | sort_by(.key | split(".") | map(tonumber)) | last | .key
|
|
')
|
|
|
|
assert_not_empty "$highest" "Should find a highest version"
|
|
assert_matches "$highest" "^[0-9]+\.[0-9]+\.[0-9]+" \
|
|
"Highest version '${highest}' should look like x.y.z"
|
|
}
|
|
|
|
# ---------- Preview entry --------------------------------------------------
|
|
|
|
test_bedrock_fallback_has_preview() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
assert_json_field "$body" '.preview' "Should have .preview field"
|
|
}
|
|
|
|
test_bedrock_fallback_preview_is_object() {
|
|
local body
|
|
body=$(api_get "$BEDROCK_FALLBACK_URL")
|
|
local type
|
|
type=$(echo "$body" | jq -r '.preview | type')
|
|
assert_equals "$type" "object" ".preview should be a JSON object"
|
|
}
|
|
|
|
# ---------- Run all tests --------------------------------------------------
|
|
|
|
run_test "Primary API is reachable" test_bedrock_primary_api_reachable
|
|
run_test "Primary API response is valid JSON" test_bedrock_primary_api_is_json
|
|
run_test "Primary API has .result field" test_bedrock_primary_api_has_result
|
|
run_test "Primary API has .result.links" test_bedrock_primary_api_has_links
|
|
run_test ".result.links is an array" test_bedrock_primary_api_links_is_array
|
|
run_test "Has serverBedrockLinux entry" test_bedrock_primary_has_linux_entry
|
|
run_test "Linux download URL has correct format" test_bedrock_primary_linux_url_format
|
|
run_test "Linux download URL returns HTTP 200" test_bedrock_primary_linux_url_reachable
|
|
run_test "Has serverBedrockWin entry" test_bedrock_primary_has_windows_entry
|
|
run_test "Download types are present" test_bedrock_primary_download_type_values
|
|
run_test "Version can be parsed from download URL" test_bedrock_version_from_url
|
|
run_test "Fallback API (GitHub) is reachable" test_bedrock_fallback_api_reachable
|
|
run_test "Fallback API response is valid JSON" test_bedrock_fallback_api_is_json
|
|
run_test "Fallback has .release field" test_bedrock_fallback_has_release
|
|
run_test ".release is a JSON object" test_bedrock_fallback_release_is_object
|
|
run_test ".release has entries" test_bedrock_fallback_release_has_entries
|
|
run_test "First release entry has .linux.url" test_bedrock_fallback_entry_has_linux_url
|
|
run_test "Fallback URL has correct format" test_bedrock_fallback_linux_url_format
|
|
run_test "Fallback has a highest version" test_bedrock_fallback_highest_version
|
|
run_test "Fallback has .preview field" test_bedrock_fallback_has_preview
|
|
run_test ".preview is a JSON object" test_bedrock_fallback_preview_is_object
|
|
|
|
print_summary
|