Files
minerops/scripts/test-agent-zones-migration.sh
2026-08-26 15:48:59 +00:00

187 lines
8.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${repo_root}"
project_name="${MINEROPS_AGENT_ZONES_MIGRATION_PROJECT:-minerops-agent-zones-migration-$$}"
compose=(docker compose --project-name "${project_name}" --env-file .env.dev -f compose.dev.yaml)
cleanup() {
status=$?
if (( status != 0 )); then
"${compose[@]}" logs --no-color --tail 160 postgres || true
fi
"${compose[@]}" down --volumes --remove-orphans >/dev/null 2>&1 || true
exit "${status}"
}
trap cleanup EXIT
run_alembic() { "${compose[@]}" run --rm --no-deps backend alembic "$@"; }
psql_db() {
"${compose[@]}" exec -T postgres sh -ec \
'exec psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" "$@"' sh "$@"
}
[[ -f .env.dev ]] || { echo "Missing .env.dev" >&2; exit 1; }
"${compose[@]}" up --detach postgres
for attempt in $(seq 1 60); do
"${compose[@]}" exec -T postgres sh -ec \
'pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"' >/dev/null 2>&1 && break
(( attempt < 60 )) || { echo "PostgreSQL did not become ready" >&2; exit 1; }
sleep 1
done
"${compose[@]}" build backend
site_a="00000000-0000-4000-8000-000000001690"
site_b="00000000-0000-4000-8000-000000001691"
miner_a="00000000-0000-4000-8000-000000001692"
echo "Testing production path 0014 -> 0015 -> 0016 and truthful unassigned data..."
run_alembic upgrade 0014_repair_parts_tracking
psql_db -c "INSERT INTO minerops_site_agents (agent_id, site_name) VALUES ('legacy-zone-unassigned', 'Legacy Display')"
run_alembic upgrade 0015_miner_control_foundation
psql_db <<SQL
INSERT INTO sites (id, name) VALUES
('${site_a}', 'Agent Zone Site A'),
('${site_b}', 'Agent Zone Site B');
INSERT INTO miners (id, site_id, asset_tag, first_seen_at, last_seen_at)
VALUES ('${miner_a}', '${site_a}', 'AGENT-ZONE-MIGRATION', NULL, NULL);
INSERT INTO minerops_site_agents (agent_id, site_id, site_name)
VALUES ('zone-agent-a', '${site_a}', 'Agent Zone Site A');
INSERT INTO minerops_agent_snapshots (agent_id, site_name, miner_count, payload)
VALUES ('zone-agent-a', 'Agent Zone Site A', 0, '{}');
INSERT INTO minerops_agent_discoveries (
id, agent_id, site_name, ip_address, raw_payload, discovery_status
) VALUES (
'agent-zone-discovery', 'zone-agent-a', 'Agent Zone Site A',
'192.0.2.90', '{}', 'new'
);
SQL
run_alembic upgrade 0016_agent_zones
[[ "$(run_alembic current 2>/dev/null)" == *"0016_agent_zones"* ]]
psql_db <<SQL
DO \$\$
DECLARE zone_a uuid;
BEGIN
SELECT id INTO zone_a FROM agent_zones
WHERE site_id = '${site_a}' AND name = 'Default Zone';
IF zone_a IS NULL THEN
RAISE EXCEPTION 'Default Zone was not created for Site A';
END IF;
IF (SELECT agent_zone_id FROM miners WHERE id = '${miner_a}') IS DISTINCT FROM zone_a THEN
RAISE EXCEPTION 'Miner was not backfilled to its Site default Zone';
END IF;
IF (SELECT agent_zone_id FROM minerops_site_agents WHERE agent_id = 'zone-agent-a')
IS DISTINCT FROM zone_a THEN
RAISE EXCEPTION 'Agent was not backfilled to its Site default Zone';
END IF;
IF (SELECT agent_zone_id FROM minerops_agent_snapshots WHERE agent_id = 'zone-agent-a' LIMIT 1)
IS DISTINCT FROM zone_a THEN
RAISE EXCEPTION 'Snapshot Zone backfill failed';
END IF;
IF (SELECT agent_zone_id FROM minerops_agent_discoveries WHERE id = 'agent-zone-discovery')
IS DISTINCT FROM zone_a THEN
RAISE EXCEPTION 'Discovery Zone backfill failed';
END IF;
IF (SELECT agent_zone_id FROM minerops_site_agents
WHERE agent_id = 'legacy-zone-unassigned') IS NOT NULL THEN
RAISE EXCEPTION 'Legacy Agent without a durable Site was guessed into a Zone';
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_indexes
WHERE indexname = 'uq_minerops_site_agents_agent_zone_id') THEN
RAISE EXCEPTION 'One-Agent-per-Zone index missing';
END IF;
IF EXISTS (SELECT 1 FROM pg_indexes
WHERE indexname = 'uq_minerops_site_agents_site_id') THEN
RAISE EXCEPTION 'One-Agent-per-Site index was not removed';
END IF;
END \$\$;
SQL
echo "Testing CIDR, active-name, cross-Site, and one-Agent-per-Zone integrity..."
psql_db <<SQL
INSERT INTO agent_zone_network_ranges (agent_zone_id, network)
SELECT id, '10.30.0.0/24'::cidr FROM agent_zones
WHERE site_id = '${site_a}' AND name = 'Default Zone';
DO \$\$
DECLARE zone_a uuid;
BEGIN
SELECT id INTO zone_a FROM agent_zones
WHERE site_id = '${site_a}' AND name = 'Default Zone';
IF (SELECT network::text FROM agent_zone_network_ranges
WHERE agent_zone_id = zone_a) <> '10.30.0.0/24' THEN
RAISE EXCEPTION 'CIDR was not stored canonically';
END IF;
BEGIN
INSERT INTO agent_zones (site_id, name) VALUES ('${site_a}', 'default zone');
RAISE EXCEPTION 'Case-insensitive active Zone duplicate was accepted';
EXCEPTION WHEN unique_violation THEN NULL;
END;
BEGIN
INSERT INTO minerops_site_agents (agent_id, site_id, agent_zone_id, site_name)
VALUES ('duplicate-zone-agent', '${site_a}', zone_a, 'Duplicate');
RAISE EXCEPTION 'Second Agent in one Zone was accepted';
EXCEPTION WHEN unique_violation THEN NULL;
END;
BEGIN
UPDATE miners SET site_id = '${site_b}' WHERE id = '${miner_a}';
RAISE EXCEPTION 'Cross-Site miner Zone combination was accepted';
EXCEPTION WHEN foreign_key_violation THEN NULL;
END;
END \$\$;
SQL
echo "Confirming CIDR values with host bits are rejected..."
if psql_db -c "INSERT INTO agent_zone_network_ranges (agent_zone_id, network) SELECT id, '10.30.0.7/24'::cidr FROM agent_zones WHERE site_id = '${site_a}' AND name = 'Default Zone'"; then
echo "Host-address CIDR unexpectedly passed PostgreSQL validation" >&2
exit 1
fi
echo "Testing downgrade refusal for irreducible network configuration..."
if output="$(run_alembic downgrade 0015_miner_control_foundation 2>&1)"; then
echo "Downgrade unexpectedly accepted Agent Zone network ranges" >&2
exit 1
fi
[[ "${output}" == *"cannot be represented by the one-Agent-per-Site model"* ]]
[[ "$(run_alembic current 2>/dev/null)" == *"0016_agent_zones"* ]]
[[ "$(psql_db -Atc "SELECT count(*) FROM agent_zone_network_ranges")" == "1" ]]
psql_db -c "DELETE FROM agent_zone_network_ranges"
echo "Testing downgrade refusal with multiple Agents at one Site..."
psql_db <<SQL
WITH created AS (
INSERT INTO agent_zones (site_id, name)
VALUES ('${site_a}', 'Room 2') RETURNING id
)
INSERT INTO minerops_site_agents (agent_id, site_id, agent_zone_id, site_name)
SELECT 'zone-agent-b', '${site_a}', id, 'Agent Zone Site A' FROM created;
SQL
if output="$(run_alembic downgrade 0015_miner_control_foundation 2>&1)"; then
echo "Downgrade unexpectedly accepted multiple Agents at one Site" >&2
exit 1
fi
[[ "${output}" == *"multiple Agent installations are assigned"* ]]
[[ "${output}" == *"${site_a}"* ]]
[[ "$(run_alembic current 2>/dev/null)" == *"0016_agent_zones"* ]]
[[ "$(psql_db -Atc "SELECT count(*) FROM minerops_site_agents WHERE site_id='${site_a}'")" == "2" ]]
psql_db -c "DELETE FROM minerops_site_agents WHERE agent_id = 'zone-agent-b'; DELETE FROM agent_zones WHERE site_id = '${site_a}' AND name = 'Room 2'"
echo "Testing legal downgrade, data preservation, and re-upgrade..."
run_alembic downgrade 0015_miner_control_foundation
[[ "$(run_alembic current 2>/dev/null)" == *"0015_miner_control_foundation"* ]]
[[ "$(psql_db -Atc "SELECT count(*) FROM miners WHERE id='${miner_a}'")" == "1" ]]
[[ "$(psql_db -Atc "SELECT count(*) FROM minerops_site_agents WHERE agent_id='zone-agent-a'")" == "1" ]]
[[ "$(psql_db -Atc "SELECT count(*) FROM information_schema.tables WHERE table_name='agent_zones'")" == "0" ]]
run_alembic upgrade 0016_agent_zones
[[ "$(run_alembic current 2>/dev/null)" == *"0016_agent_zones"* ]]
echo "Testing empty database through head..."
"${compose[@]}" exec -T postgres sh -ec 'createdb -U "$POSTGRES_USER" minerops_agent_zones_empty'
"${compose[@]}" run --rm --no-deps -e POSTGRES_DB=minerops_agent_zones_empty backend alembic upgrade head
empty_revision="$("${compose[@]}" exec -T postgres sh -ec \
'psql -U "$POSTGRES_USER" -d minerops_agent_zones_empty -Atc "SELECT version_num FROM alembic_version"')"
[[ "${empty_revision}" == "0016_agent_zones" ]]
echo "Agent Zones migration lifecycle checks passed."