Files
clean-architecture-backend-…/scripts/verify-mongodb-advanced.sh
T

165 lines
7.3 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# The MongoDB Advanced capability gate (advanced plan Task 15).
#
# Advanced capabilities are opt-in modules. This script verifies the contracts that can be verified
# without provider infrastructure, and then reports -- explicitly -- which promotion evidence it
# could NOT produce.
#
# Required promotion categories (MongoAdvancedPromotionEvidence.REQUIRED):
#
# stable-platform, actual-topology, security, migration, failure, runbook
#
# `actual-topology` is the one that cannot be substituted. A container gives a functional pass for
# sharding, search, vector and encryption while exercising none of the behaviour that makes them
# Advanced rather than Stable: real shard distribution, a real analyzer, a real KMS. Atlas Local is
# a pull-request convenience and is not release evidence -- see
# MongoAtlasCapabilityContractSuite.Environment.
#
# Usage:
# bash scripts/verify-mongodb-advanced.sh
# MONGODB_DOCKER=1 bash scripts/verify-mongodb-advanced.sh
# MONGODB_SHARDED_URI=... MONGODB_ATLAS_URI=... MONGODB_KMS=... bash scripts/verify-mongodb-advanced.sh
#
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
GRADLE_DIR="${REPO_ROOT}/src"
MODULE=':adapter:outbound:persistence-mongo'
GRADLE=(./gradlew --console=plain)
FAILED=()
MISSING_EVIDENCE=()
echo "MongoDB Advanced capability gate"
echo "repository: ${REPO_ROOT}"
# --- stable-platform -------------------------------------------------------------------------
# An Advanced capability cannot be promoted over a Stable platform that does not itself pass.
echo ""
echo "=== [stable-platform] Stable gate"
if bash "${REPO_ROOT}/scripts/verify-mongodb-platform.sh"; then
echo "stable-platform: supplied"
else
status=$?
if (( status == 2 )); then
echo "stable-platform: INCOMPLETE (the Stable gate skipped lanes)"
MISSING_EVIDENCE+=("stable-platform (Stable gate incomplete)")
else
FAILED+=("stable-platform")
fi
fi
# --- failure + runbook (hermetic) -------------------------------------------------------------
# Every Advanced refusal contract: disabled capability refuses construction, CSFLE/QE cannot share a
# collection, QE substring/prefix/suffix unsupported on 8.0, a non-READY search index cannot serve,
# undeclared scatter-gather is rejected, a dimension mismatch is refused.
echo ""
echo "=== [failure] Advanced contract tests"
if (cd "${GRADLE_DIR}" && "${GRADLE[@]}" "${MODULE}:test" --tests '*advanced*'); then
echo "failure: supplied"
else
FAILED+=("failure")
fi
echo ""
echo "=== [runbook] capability documentation"
for doc in sharding time-series encryption search-vector multi-tenancy gridfs-migration; do
path="${REPO_ROOT}/docs/mongodb/advanced/${doc}.md"
if [[ -f "${path}" ]]; then
echo " + ${doc}.md"
else
echo " - ${doc}.md MISSING"
FAILED+=("runbook:${doc}")
fi
done
if [[ ! -f "${REPO_ROOT}/docs/adr/ADR-MONGO-ADV-001-capability-promotion.md" ]]; then
echo " - ADR-MONGO-ADV-001 MISSING"
FAILED+=("runbook:ADR-MONGO-ADV-001")
fi
# --- actual-topology -------------------------------------------------------------------------
echo ""
echo "=== [actual-topology] provider environments"
# The URI travels in the environment, never as a JVM argument. `-Dmongodb.sharded.uri=mongodb://
# user:pass@host` is visible in `ps` to every user on the machine, in the Gradle failure output and
# in any CI log that echoes the command.
#
# The selector names the contract's class. `--tests '*Shard*'` was satisfied by the hermetic
# ShardKeyAnalyzerTest, so "sharded topology" was certified by a unit test that never opened a
# connection. Which classes count is `src/config/mongodb/release-contracts.json`, and
# MongoReleaseEvidenceVerifier checks the JUnit XML rather than the exit code.
if [[ -n "${MONGODB_SHARDED_URI:-}" ]]; then
# Not promoted. `mongoShardedTest` is declared in release-contracts.json under
# experimental_contracts and is registered by no build file, so invoking it here could only ever
# fail — and before the demotion it made this script unrunnable while the manifest still reported
# the capability as a blocking gate. Supplying the URI is therefore an explicit error rather than
# a silent skip: an operator who set it expected a qualification to run.
echo "sharded topology is experimental and has no registered lane;" >&2
echo " MONGODB_SHARDED_URI was set but mongoShardedTest does not exist." >&2
echo " See experimental_contracts in src/config/mongodb/release-contracts.json." >&2
FAILED+=("actual-topology:sharded-not-promoted")
else
echo "actual-topology(sharded): no MONGODB_SHARDED_URI"
MISSING_EVIDENCE+=("actual-topology: sharded cluster")
fi
# Present is not exercised. An environment variable proves somebody exported a string; the
# contract is satisfied by a lane that ran against the deployment it names, which is why this
# records the variable as *not yet* evidence until MONGO-REL-011's class has run.
if [[ -n "${MONGODB_ATLAS_URI:-}" ]]; then
echo "actual-topology(search/vector): MONGODB_ATLAS_URI present (lane not yet implemented)"
MISSING_EVIDENCE+=("actual-topology: MONGO-REL-011 has no lane; an exported URI is not a run")
else
echo "actual-topology(search/vector): no MONGODB_ATLAS_URI"
MISSING_EVIDENCE+=("actual-topology: search/vector on the actual target deployment")
fi
if [[ -n "${MONGODB_KMS:-}" ]]; then
echo "actual-topology(encryption): MONGODB_KMS present (lane not yet implemented)"
MISSING_EVIDENCE+=("actual-topology: MONGO-REL-012 has no lane; an exported KMS is not a run")
else
echo "actual-topology(encryption): no MONGODB_KMS"
MISSING_EVIDENCE+=("actual-topology: real KMS and key vault")
fi
# --- security + migration ---------------------------------------------------------------------
# Review artefacts, not test runs: a role review and a documented migration path per capability.
# These used to be appended unconditionally, so the gate could never reach PROMOTABLE no matter what
# anybody did — a gate with no passing state is a gate nobody can act on. They are now satisfied by
# a committed sign-off file, which is the artefact the review actually produces.
for signoff in security migration; do
path="${REPO_ROOT}/docs/mongodb/advanced/signoff/${signoff}.md"
if [[ -f "${path}" ]]; then
echo "${signoff}: sign-off recorded at docs/mongodb/advanced/signoff/${signoff}.md"
else
MISSING_EVIDENCE+=("${signoff}: per-capability sign-off (docs/mongodb/advanced/signoff/${signoff}.md)")
fi
done
# --- Report ------------------------------------------------------------------------------------
echo ""
echo "---------------------------------------------------------------"
if (( ${#FAILED[@]} > 0 )); then
echo "ADVANCED GATE: FAILED"
for entry in "${FAILED[@]}"; do echo " - ${entry}"; done
echo "---------------------------------------------------------------"
exit 1
fi
echo "verifiable contracts: PASSED"
if (( ${#MISSING_EVIDENCE[@]} > 0 )); then
echo ""
echo "ADVANCED GATE: NOT PROMOTABLE -- missing evidence:"
for entry in "${MISSING_EVIDENCE[@]}"; do echo " ~ ${entry}"; done
echo ""
echo "A capability stays opt-in until every category in"
echo "MongoAdvancedPromotionEvidence.REQUIRED is supplied. See"
echo "docs/adr/ADR-MONGO-ADV-001-capability-promotion.md."
echo "---------------------------------------------------------------"
exit 2
fi
echo "ADVANCED GATE: PASSED"
echo "---------------------------------------------------------------"