who_need_help/scripts/dev-scale-refresh.sh

160 lines
4.9 KiB
Bash
Executable File

#!/bin/sh
set -eu
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
if [ ! -f "$ROOT/.env" ]; then
echo "Missing $ROOT/.env." >&2
exit 1
fi
set -a
# shellcheck source=/dev/null
. "$ROOT/.env"
set +a
EXPECTED_DATABASE=${WNH_DEV_SCALE_EXPECTED_DATABASE:-who_need_help}
REQUESTS=${WNH_DEV_SCALE_REQUESTS:-1000000}
ACTIVITIES=${WNH_DEV_SCALE_ACTIVITIES:-1000000}
OUTPUT_DIR="$ROOT/output/dev-scale"
SUMMARY="$OUTPUT_DIR/refresh-summary.json"
CLUSTER_CONTAINER=who-need-help-control-plane
NAMESPACE=who-need-help
DATABASE_POD=postgis-0
if [ "${WNH_DEV_SCALE_REFRESH_CONFIRM:-}" != "refresh-persistent-dev-scale" ]; then
echo "WNH_DEV_SCALE_REFRESH_CONFIRM must equal refresh-persistent-dev-scale." >&2
exit 2
fi
case "$REQUESTS:$ACTIVITIES" in
*[!0-9:]*|:*|*:|0:*|*:0)
echo "The configured scale row counts must be positive integers." >&2
exit 2
;;
esac
if ! docker inspect "$CLUSTER_CONTAINER" >/dev/null 2>&1; then
echo "The project-owned kind control-plane container does not exist." >&2
exit 1
fi
if [ "$(docker inspect "$CLUSTER_CONTAINER" --format '{{.State.Running}}')" != true ]; then
echo "The project-owned kind control plane is not running." >&2
exit 1
fi
if [ "$(docker inspect "$CLUSTER_CONTAINER" --format '{{index .Config.Labels "io.x-k8s.kind.cluster"}}')" != "who-need-help" ]; then
echo "The running control plane is outside this project's kind cluster." >&2
exit 1
fi
kube() {
docker exec "$CLUSTER_CONTAINER" kubectl --namespace "$NAMESPACE" "$@"
}
if [ "$(kube get pod "$DATABASE_POD" -o jsonpath='{.status.phase}')" != "Running" ]; then
echo "The development PostGIS pod is not running." >&2
exit 1
fi
# Expansion is intentionally performed inside the database pod.
# shellcheck disable=SC2016
DB_USER=$(kube exec "$DATABASE_POD" -- sh -c 'printf %s "$POSTGRES_USER"')
# shellcheck disable=SC2016
DB_NAME=$(kube exec "$DATABASE_POD" -- sh -c 'printf %s "$POSTGRES_DB"')
if [ "$DB_NAME" != "$EXPECTED_DATABASE" ]; then
echo "Refusing refresh: expected database $EXPECTED_DATABASE, observed $DB_NAME." >&2
exit 1
fi
observed=$(
kube exec "$DATABASE_POD" -- psql -U "$DB_USER" -d "$DB_NAME" -At \
-c "SELECT (SELECT count(*) FROM help_requests WHERE structured_data @> '{\"scale_fixture\": true}'::jsonb)::text || ':' || (SELECT count(*) FROM activities WHERE structured_data @> '{\"scale_fixture\": true}'::jsonb)::text"
)
if [ "$observed" != "$REQUESTS:$ACTIVITIES" ]; then
echo "Refusing refresh: expected $REQUESTS:$ACTIVITIES synthetic rows, observed $observed." >&2
exit 1
fi
mkdir -p "$OUTPUT_DIR"
docker exec -i "$CLUSTER_CONTAINER" \
kubectl --namespace "$NAMESPACE" exec -i "$DATABASE_POD" -- \
psql -q -v ON_ERROR_STOP=1 -U "$DB_USER" -d "$DB_NAME" -At <<'SQL' >"$SUMMARY"
BEGIN;
UPDATE help_requests
SET status = 'open',
expires_at = date_trunc('second', now()) +
(mod(mod(hashtextextended(id::text, 0), 14) + 14, 14) + 1) * interval '1 day',
updated_at = date_trunc('second', now())
WHERE structured_data @> '{"scale_fixture": true}'::jsonb;
WITH refreshed AS (
SELECT
id,
date_trunc('second', now()) +
(mod(mod(hashtextextended(id::text, 0), 60) + 60, 60) + 2) * interval '1 day'
AS refreshed_starts_at
FROM activities
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
)
UPDATE activities
SET status = 'open',
starts_at = refreshed.refreshed_starts_at,
join_deadline = refreshed.refreshed_starts_at - interval '1 day',
updated_at = date_trunc('second', now())
FROM refreshed
WHERE activities.id = refreshed.id;
COMMIT;
ANALYZE help_requests, activities;
SELECT json_build_object(
'database', current_database(),
'synthetic_rows', json_build_object(
'help_requests', (
SELECT count(*) FROM help_requests
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
),
'activities', (
SELECT count(*) FROM activities
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
)
),
'public_open_rows', json_build_object(
'help_requests', (
SELECT count(*) FROM help_requests
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
AND status = 'open'
AND expires_at > now()
AND location_visibility <> 'hidden'
),
'activities', (
SELECT count(*) FROM activities
WHERE structured_data @> '{"scale_fixture": true}'::jsonb
AND status = 'open'
AND starts_at > now()
AND location_visibility = 'approximate_public'
)
),
'captured_at', date_trunc('second', now())
);
SQL
chmod 600 "$SUMMARY"
jq -e '
.database == $database and
.synthetic_rows.help_requests == ($requests | tonumber) and
.synthetic_rows.activities == ($activities | tonumber) and
.public_open_rows.help_requests > 0 and
.public_open_rows.activities > 0
' --arg database "$EXPECTED_DATABASE" \
--arg requests "$REQUESTS" \
--arg activities "$ACTIVITIES" \
"$SUMMARY" >/dev/null
printf 'Development scale refresh summary: %s\n' "$SUMMARY"