nigig-org/tools/test-mpesa-store-clean.sh
Arena Bot 33dbece7d8
Some checks failed
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
Payment domain and storage / isolated-payment-tests (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
fix(ui): use valid syntax for assigning ids to metric values
2026-07-29 01:56:41 +00:00

133 lines
4.3 KiB
Bash

#!/usr/bin/env bash
# Isolated, self-cleaning test runner for nigig-core's M-Pesa observation code.
#
# Why this exists
# ---------------
# `nigig-core` is commented out of the workspace: it depends on git-hosted
# Makepad and Robius crates that are not available in a standalone checkout, so
# `cargo test -p nigig-core` cannot run here. That was previously used to argue
# the parser/store defects (B1, B4, B6) could not be fixed safely.
#
# They can. The three files that hold those defects — `parser.rs`,
# `classifier.rs` and `store.rs` — depend only on `serde`, `chrono`, one
# `log!` macro and one `app_data_dir()` helper. This script copies those files
# into a temporary crate, supplies the two shims, and runs their tests under
# the toolchain declared in `rust-toolchain.toml`.
#
# It is a verification harness, not a build target: it proves the pure
# parsing/persistence logic is correct without waiting for the whole
# application graph to become buildable.
#
# Usage:
# ./tools/test-mpesa-store-clean.sh
# KEEP_TEST_ENV=1 ./tools/test-mpesa-store-clean.sh # debugging only
set -Eeuo pipefail
IFS=$'\n\t'
REPO_ROOT="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
MPESA_DIR="$REPO_ROOT/crates/nigig-core/src/persistence/mpesa"
KEEP_TEST_ENV="${KEEP_TEST_ENV:-0}"
declared_toolchain() {
sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
"$REPO_ROOT/rust-toolchain.toml" | head -n 1
}
TOOLCHAIN="${RUST_TOOLCHAIN:-$(declared_toolchain)}"
if [[ -z "$TOOLCHAIN" ]]; then
echo "error: could not read channel from rust-toolchain.toml" >&2
exit 2
fi
for required in parser.rs classifier.rs store.rs; do
if [[ ! -f "$MPESA_DIR/$required" ]]; then
echo "error: expected $MPESA_DIR/$required" >&2
exit 2
fi
done
WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/nigig-mpesa-test.XXXXXXXX")"
cleanup() {
local status=$?
if [[ "$KEEP_TEST_ENV" == "1" ]]; then
echo "test environment retained for debugging: $WORK_DIR" >&2
else
rm -rf -- "$WORK_DIR"
echo "cleaned isolated M-Pesa store test environment" >&2
fi
exit "$status"
}
trap cleanup EXIT HUP INT TERM
export RUSTUP_HOME="$WORK_DIR/rustup"
export CARGO_HOME="$WORK_DIR/cargo"
export CARGO_TARGET_DIR="$WORK_DIR/target"
export PATH="$CARGO_HOME/bin:$PATH"
RUSTUP_INIT="$WORK_DIR/rustup-init"
echo "creating isolated Rust toolchain ($TOOLCHAIN) in $WORK_DIR" >&2
curl --fail --location --proto '=https' --tlsv1.2 \
https://sh.rustup.rs -o "$RUSTUP_INIT"
chmod 700 "$RUSTUP_INIT"
"$RUSTUP_INIT" -y --profile minimal --default-toolchain "$TOOLCHAIN" \
--component rustfmt --no-modify-path
CRATE="$WORK_DIR/mpesa-store-harness"
mkdir -p "$CRATE/src"
cat > "$CRATE/Cargo.toml" <<'MANIFEST'
[package]
name = "mpesa-store-harness"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
[dependencies]
serde = { version = "1", features = ["derive"] }
chrono = { version = "0.4", features = ["serde"] }
MANIFEST
cat > "$CRATE/src/lib.rs" <<'SHIM'
//! Test shim for nigig-core's M-Pesa observation modules.
//!
//! These modules take exactly two things from the wider application: the
//! `log!` macro from Makepad, and `app_data_dir()` from nigig-core. Both are
//! replaced here so the pure logic can be compiled and tested standalone.
macro_rules! log {
($($arg:tt)*) => {{ let _ = format!($($arg)*); }};
}
pub(crate) use log;
pub mod dir {
use std::path::PathBuf;
pub fn app_data_dir() -> PathBuf {
std::env::temp_dir().join("nigig-mpesa-store-harness")
}
}
pub mod classifier;
pub mod parser;
pub mod store;
SHIM
cp "$MPESA_DIR/parser.rs" "$MPESA_DIR/classifier.rs" "$MPESA_DIR/store.rs" \
"$CRATE/src/"
# Rewrite the in-crate module paths to the flat harness layout and point the
# two external references at the shims above.
sed -i \
-e 's#use crate::persistence::mpesa::classifier::#use crate::classifier::#' \
-e 's#use crate::persistence::mpesa::parser::#use crate::parser::#' \
-e 's#use makepad_widgets::log;#use crate::log;#' \
"$CRATE/src/parser.rs" "$CRATE/src/classifier.rs" "$CRATE/src/store.rs"
cargo --version
rustc --version
# Single-threaded: the store writes to one fixed path, so parallel tests would
# race on the same file.
cargo test --manifest-path "$CRATE/Cargo.toml" -- --test-threads=1
echo "isolated M-Pesa parser/classifier/store tests passed" >&2