managarten/services/mana-geocoding/scripts/smoke-test.sh
Till JS 2bbcf14aba chore(geocoding): remove Pelias + close 3 bypass paths to public Nominatim
Pelias was retired from the Mac mini on 2026-04-28; photon-self
(self-hosted Photon on mana-gpu) has been the live primary since then.
This removes the now-dead Pelias adapter, config, tests, and the
services/mana-geocoding/pelias/ stack — the entire compose file, the
geojsonify_place_details.js patch, the setup.sh import script.

Provider chain is now `photon-self → photon → nominatim`. The chain
keeps its `privacy: 'local' | 'public'` split, sensitive-query
blocking, coord quantization, and aggressive caching unchanged.

Three direct calls to nominatim.openstreetmap.org that bypassed
mana-geocoding now route through the wrapper:

- citycorners/add-city + citycorners/cities/[slug]/add use the shared
  searchAddress() client (browser → same-origin proxy → mana-geocoding
  → photon-self).
- memoro mobile drops its OSM reverse-geocoding fallback entirely;
  Expo's on-device reverse-geocoding stays as the sole path. Routing
  through the wrapper would require a memoro-server proxy endpoint —
  a follow-up if Expo's quality proves insufficient.

Other behavioral changes:

- CACHE_PUBLIC_TTL_MS dropped from 7d → 1h. The long TTL was a
  privacy-amplification trick from the Pelias era; with photon-self
  serving the bulk of traffic, a transient cross-LAN blip was pinning
  cached fallback answers for days. 1h gives quick recovery.
- /health/pelias renamed to /health/photon-self; prometheus blackbox
  config + status-page generator updated.
- mana-geocoding container no longer needs `extra_hosts:
  host.docker.internal:host-gateway` (was only there for the
  Pelias-on-host-network era).

113 tests passing. CLAUDE.md rewritten to reflect the post-Pelias
architecture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:12:26 +02:00

127 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Smoke test for a running mana-geocoding service.
#
# Runs a handful of real-world queries against the wrapper and asserts
# that each returns at least one result with sensible category mapping.
# Fails fast on the first unexpected response.
#
# Usage:
# ./scripts/smoke-test.sh # default http://localhost:3018
# ./scripts/smoke-test.sh http://mana-geocoding:3018
# BASE=http://mana-geocoding:3018 ./scripts/smoke-test.sh
#
# This is NOT a substitute for the unit tests in src/lib/__tests__/ — it
# requires a fully deployed Pelias stack with the DACH index already
# loaded. It's the test to run after a deploy to confirm the full pipeline
# is healthy.
set -euo pipefail
BASE="${1:-${BASE:-http://localhost:3018}}"
pass=0
fail=0
has() {
command -v "$1" >/dev/null 2>&1
}
if ! has jq; then
echo "error: jq is required for this script (brew install jq)" >&2
exit 2
fi
echo "=== mana-geocoding smoke test @ $BASE ==="
echo
check() {
local label="$1"
local url="$2"
local filter="$3"
local expected="$4"
local actual
actual=$(curl -sf --max-time 10 "$url" 2>/dev/null | jq -r "$filter" 2>/dev/null || echo "")
if [ "$actual" = "$expected" ]; then
printf " ✓ %-50s → %s\n" "$label" "$actual"
pass=$((pass + 1))
else
printf " ✗ %-50s → got %q, expected %q\n" "$label" "$actual" "$expected"
fail=$((fail + 1))
fi
}
urlenc() {
# POSIX-friendly URL-encode for the test queries.
# jq -Rr @uri is the easiest cross-platform path.
printf '%s' "$1" | jq -Rr @uri
}
# --- 1. Health checks ---
echo "--- Health ---"
check "wrapper health" "$BASE/health" '.status' 'ok'
check "photon-self health proxy" "$BASE/health/photon-self" '.status' 'ok'
echo
# --- 2. Forward geocoding ---
echo "--- Forward ---"
# Venue name queries (hit /autocomplete path)
check "restaurant search → food category" \
"$BASE/api/v1/geocode/search?q=$(urlenc 'Konzil Konstanz')&limit=1" \
'.results[0].category' 'food'
check "train station search → transit category" \
"$BASE/api/v1/geocode/search?q=$(urlenc 'Stuttgart Hauptbahnhof')&limit=1" \
'.results[0].category' 'transit'
# Street+locality query (falls back to /search path)
check "street+locality fallback returns a result" \
"$BASE/api/v1/geocode/search?q=$(urlenc 'Marktstätte Konstanz')&limit=1" \
'.results | length > 0' 'true'
# Focus point biasing
check "focus bias returns something near Konstanz" \
"$BASE/api/v1/geocode/search?q=$(urlenc 'Park')&limit=1&focus.lat=47.66&focus.lon=9.17" \
'.results | length > 0' 'true'
echo
# --- 3. Reverse geocoding ---
echo "--- Reverse ---"
# Konstanz city center
check "reverse Konstanz returns a result" \
"$BASE/api/v1/geocode/reverse?lat=47.663&lon=9.175" \
'.results | length > 0' 'true'
# München Marienplatz
check "reverse München Marienplatz resolves" \
"$BASE/api/v1/geocode/reverse?lat=48.137&lon=11.575" \
'.results | length > 0' 'true'
echo
# --- 4. Cache ---
echo "--- Cache ---"
# Prime the cache with a unique query
NONCE="smoke-$(date +%s)"
curl -sf --max-time 10 "$BASE/api/v1/geocode/search?q=$(urlenc "Konzil $NONCE")&limit=1" >/dev/null
check "same query comes back cached" \
"$BASE/api/v1/geocode/search?q=$(urlenc "Konzil $NONCE")&limit=1" \
'.cached' 'true'
echo
# --- Summary ---
total=$((pass + fail))
echo "=== Result: $pass/$total passed ==="
if [ "$fail" -gt 0 ]; then
exit 1
fi