The durable service's documents join the version contract. A set's result (wai.quantum.set/1) and a result's provenance (wai.quantum.provenance/1) are engine schemas; the service's receipt key set (wai.quantum.receipt-keys/1, with its signed transitions) and the command line's scheduler lease (wai.quantum.lease/1) are their hosts'. The job request names programs, sweep and dry_run, a job's result may be a set's, an energy figure may be the processor packages', and a job names its store digests. A set's head now names the engine and its schema, inside what its receipt seals, as every other result does. A result's provenance names the gate set its compile wrote as basis (it read the compile summary's old target field, which the rename left empty). run_quantum_set and dry_run_quantum_job answer to output schemas, each with its verdict whether refused or not, and run_quantum_circuit asked as a dry run answers as one. The strict tests call both and hold every answer, the job's set form and the key set after a rotation to their schemas; the contract workflow requires the new tests by name, and check_schemas.py reads the new files and holds a set's run to its schema. The service's store stays at ~/.local/share/wai-quantum-service/store by default; the Python check and its tests start the service with a store in their own scratch, as the service workflow's legs already do. Co-Authored-By: Claude Opus 5.5 <[email protected]>
94 lines
5 KiB
Shell
94 lines
5 KiB
Shell
#!/usr/bin/env bash
|
|
# The Python package's whole check, as CI runs it (.github/workflows/wai-quantum-py.yml)
|
|
# and as a person runs it on a build host:
|
|
#
|
|
# bash wai/wai-quantum-py/ci/check.sh [--write-notebooks]
|
|
#
|
|
# 1. builds the command line and the job service from this checkout (the surfaces
|
|
# the package is held to);
|
|
# 2. clippy on the extension module, warnings as errors;
|
|
# 3. builds the wheel with maturin (pinned), and installs it in a fresh venv with
|
|
# the pinned, hashed test requirements (tests/requirements.lock);
|
|
# 4. pytest, every test required (none may skip: WAI_QUANTUM_REQUIRE_ALL=1);
|
|
# 5. runs the doc notebooks against a job service started here, each held to its
|
|
# stored outputs (--write-notebooks stores them instead);
|
|
# 6. installs the same wheel alone on Python 3.9 and runs tests/smoke.py.
|
|
#
|
|
# Needs cargo (the toolchain rust-toolchain.toml names), uv and node (or WAI_QUANTUM_NODE). Scratch goes
|
|
# under $WORK (default: $RUNNER_TEMP/wai-quantum-py, or a new temporary directory);
|
|
# cargo builds into $CARGO_TARGET_DIR (default: $WORK/target).
|
|
set -euo pipefail
|
|
PKG="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
WAI="$(cd "$PKG/.." && pwd)"
|
|
WRITE=0
|
|
[ "${1:-}" = "--write-notebooks" ] && WRITE=1
|
|
WORK="${WORK:-${RUNNER_TEMP:-$(mktemp -d)}/wai-quantum-py}"
|
|
mkdir -p "$WORK"
|
|
export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORK/target}"
|
|
PY="${WAI_QUANTUM_PYTHON:-3.12}"
|
|
MATURIN=1.15.0
|
|
step() { echo; echo "== $*"; }
|
|
|
|
step "the command line and the job service, from this checkout"
|
|
(cd "$WAI/wai-quantum-cli" && cargo build --locked --release)
|
|
(cd "$WAI/wai-quantum-service" && cargo build --locked --release)
|
|
CLI="$CARGO_TARGET_DIR/release/wai-quantum"
|
|
SVC="$CARGO_TARGET_DIR/release/wai-quantum-service"
|
|
"$CLI" --version
|
|
|
|
step "clippy on the extension module"
|
|
(cd "$PKG" && cargo clippy --locked --release --all-targets -- -D warnings)
|
|
|
|
step "the wheel (maturin $MATURIN)"
|
|
rm -rf "$WORK/tools" "$WORK/dist" "$WORK/test" "$WORK/py39"
|
|
uv venv -q --python "$PY" "$WORK/tools"
|
|
uv pip install -q --python "$WORK/tools/bin/python" "maturin==$MATURIN"
|
|
(cd "$PKG" && "$WORK/tools/bin/maturin" build --release --locked -o "$WORK/dist")
|
|
WHEEL="$(ls "$WORK"/dist/wai_quantum-*.whl)"
|
|
echo "built $(basename "$WHEEL")"
|
|
case "$(basename "$WHEEL")" in *-cp39-abi3-*) ;; *) echo "::error::the wheel is not abi3 from Python 3.9: $WHEEL"; exit 1 ;; esac
|
|
|
|
step "a fresh venv: the wheel and the pinned test requirements"
|
|
uv venv -q --python "$PY" "$WORK/test"
|
|
uv pip install -q --python "$WORK/test/bin/python" --require-hashes -r "$PKG/tests/requirements.lock"
|
|
uv pip install -q --python "$WORK/test/bin/python" --no-deps "$WHEEL"
|
|
"$WORK/test/bin/python" -I -c 'import wai_quantum, wai_quantum.widgets as w; assert w.HAVE_WIDGETS; print("wai_quantum", wai_quantum.__version__, "from", wai_quantum.__file__)'
|
|
|
|
step "node: the widgets' front ends parse"
|
|
NODE="${WAI_QUANTUM_NODE:-$(command -v node || true)}"
|
|
[ -n "$NODE" ] || { echo "::error::no node (or WAI_QUANTUM_NODE): the widgets' front ends are tested with it"; exit 1; }
|
|
export WAI_QUANTUM_NODE="$NODE"
|
|
"$NODE" --version
|
|
for f in "$PKG"/python/wai_quantum/static/*.js "$PKG"/tests/front_ends.mjs; do "$NODE" --check "$f"; done
|
|
|
|
step "pytest"
|
|
export WAI_QUANTUM_CLI="$CLI" WAI_QUANTUM_SERVICE_BIN="$SVC" WAI_QUANTUM_REQUIRE_ALL=1
|
|
export IPYTHONDIR="$WORK/ipython" JUPYTER_PLATFORM_DIRS=1
|
|
(cd "$PKG" && "$WORK/test/bin/pytest" -q -p no:cacheprovider tests 2>&1 | tee "$WORK/pytest.log")
|
|
grep -qE '^[0-9]+ passed' "$WORK/pytest.log" || { echo "::error::pytest did not report passes"; exit 1; }
|
|
if grep -qE '[0-9]+ (failed|skipped|error)' "$WORK/pytest.log"; then echo "::error::a test failed, erred or skipped"; exit 1; fi
|
|
|
|
step "the doc notebooks, against a job service started here"
|
|
port=$(( 18300 + RANDOM % 500 ))
|
|
cfg="$WORK/qsvc"; rm -rf "$cfg"; mkdir -p "$cfg"
|
|
WAI_QSVC_KEY="$cfg/service.key" WAI_QSVC_STORE="$cfg/store" WAI_QSVC_ADDR="127.0.0.1:$port" WAI_QSVC_BUDGET_GB=4 WAI_QSVC_JOB_GB=2 WAI_QSVC_WORKERS=1 \
|
|
WAI_QSVC_MIN_FREE_PCT=0 WAI_QSVC_CLIENT_BURST=10000 "$SVC" serve > "$cfg/service.log" 2>&1 &
|
|
pid=$!
|
|
trap 'kill $pid 2>/dev/null || true' EXIT
|
|
for _ in $(seq 1 100); do curl -fs -o /dev/null "http://127.0.0.1:$port/v1/health" && break; sleep 0.2; done
|
|
nb=(getting-started bell-receipt equivalence noisy-run service-job)
|
|
files=(); for n in "${nb[@]}"; do files+=("$PKG/notebooks/$n.ipynb"); done
|
|
# (An empty array expands under set -u only this way in the bash macOS ships.)
|
|
args=(); [ "$WRITE" = 1 ] && args=(--write)
|
|
(cd "$PKG" && XDG_CONFIG_HOME="$WORK/nbconfig" WAI_QUANTUM_SERVICE="http://127.0.0.1:$port" "$WORK/test/bin/python" tests/run_notebooks.py ${args[@]+"${args[@]}"} "${files[@]}")
|
|
kill $pid 2>/dev/null || true
|
|
wait $pid 2>/dev/null || true
|
|
trap - EXIT
|
|
|
|
step "the same wheel alone on Python 3.9"
|
|
uv venv -q --python 3.9 "$WORK/py39"
|
|
uv pip install -q --python "$WORK/py39/bin/python" --no-deps "$WHEEL"
|
|
(cd "$WORK" && "$WORK/py39/bin/python" -I "$PKG/tests/smoke.py")
|
|
|
|
echo
|
|
echo "wai-quantum-py: every check passed ($(grep -E '^[0-9]+ passed' "$WORK/pytest.log"))"
|