Files
obikmer/scripts/smoke_test_index2.sh
T

127 lines
4.4 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# smoke_test_index2.sh — end-to-end smoke test of `obikmer2 index` (this
# working tree) + `obikmer query` (the release binary already on PATH).
#
# obikmer2 is being rebuilt incrementally from obikmer (see DevDocMD) and
# for now only implements `index`. This script checks that an index it
# produces is readable by an already-released, PATH-installed `obikmer`
# binary — the cross-binary counterpart to scripts/smoke_test_index.sh,
# which builds and queries with the same (in-tree) `obikmer`.
#
# What it does:
# 1. builds `obikmer2` (debug, via `cargo run`)
# 2. generates a small deterministic random FASTA
# 3. runs `obikmer2 index` on it
# 4. picks a real k-mer from the source sequence, avoiding low-complexity
# substrings (see scripts/smoke_test_index.sh's own note on this)
# 5. runs `obikmer query` (PATH binary, not built from this tree) and
# checks the k-mer round-trips
# 6. prints total-kmers-indexed and a clear PASS/FAIL, exit code matches
#
# Usage:
# scripts/smoke_test_index2.sh [-k KMER_SIZE] [-m MINIMIZER_SIZE] [-p PARTITIONS] [--keep]
#
# --keep leaves the temp directory in place (path printed) instead of
# deleting it on exit, for manual inspection of a failure.
set -euo pipefail
K=11
M=5
PARTITIONS=4
KEEP=0
while [ $# -gt 0 ]; do
case "$1" in
-k) K="$2"; shift 2 ;;
-m) M="$2"; shift 2 ;;
-p) PARTITIONS="$2"; shift 2 ;;
--keep) KEEP=1; shift ;;
*) echo "unknown argument: $1" >&2; exit 2 ;;
esac
done
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WORK="$(mktemp -d -t obikmer2_smoke.XXXXXX)"
cleanup() {
if [ "$KEEP" -eq 1 ]; then
echo "kept: $WORK"
else
rm -rf "$WORK"
fi
}
trap cleanup EXIT
fail() {
echo "FAIL: $1" >&2
exit 1
}
command -v obikmer >/dev/null 2>&1 || fail "obikmer not found on PATH"
# ── 1. generate a small deterministic random FASTA ─────────────────────────
python3 - "$WORK/test.fasta" "$K" <<'EOF'
import random, sys
path, k = sys.argv[1], int(sys.argv[2])
random.seed(1234)
bases = "ACGT"
with open(path, "w") as f:
for i in range(3):
seq = "".join(random.choice(bases) for _ in range(300))
f.write(f">seq{i}\n{seq}\n")
EOF
# ── 2. build + run index (obikmer2, in-tree) ────────────────────────────────
cd "$REPO_ROOT/src"
INDEX_LOG="$WORK/index.log"
if ! cargo run -q -p obikmer2 --bin obikmer2 -- \
index -k "$K" -m "$M" --theta 0 -p "$PARTITIONS" \
-o "$WORK/out.idx" "$WORK/test.fasta" > "$INDEX_LOG" 2>&1
then
cat "$INDEX_LOG" >&2
fail "obikmer2 index exited non-zero"
fi
N_KMERS="$(grep -o '[0-9]* total kmers indexed' "$INDEX_LOG" | grep -o '^[0-9]*' || true)"
[ -n "$N_KMERS" ] || { cat "$INDEX_LOG" >&2; fail "could not find 'N total kmers indexed' in index log"; }
[ "$N_KMERS" -gt 0 ] || fail "index reports 0 kmers indexed"
# ── 3+4. try candidate k-mers spread across the source sequence until one
# round-trips — see scripts/smoke_test_index.sh's own note: query's
# entropy filter can reject a genuinely-indexed low-complexity
# window, that's not a bug, just try the next candidate.
readarray -t CANDIDATES < <(python3 - "$WORK/test.fasta" "$K" <<'EOF'
import sys
path, k = sys.argv[1], int(sys.argv[2])
with open(path) as f:
seq = "".join(l.strip() for l in f if not l.startswith(">"))
for start in range(0, len(seq) - k, 17):
print(seq[start:start+k])
EOF
)
[ "${#CANDIDATES[@]}" -gt 0 ] || fail "could not extract any candidate k-mer from the source FASTA"
QUERY_LOG="$WORK/query.log"
FOUND=0
for QUERY_KMER in "${CANDIDATES[@]}"; do
printf ">q1\n%s\n" "$QUERY_KMER" > "$WORK/query.fasta"
# PATH binary, deliberately not built from this tree.
if ! obikmer query "$WORK/out.idx" "$WORK/query.fasta" > "$QUERY_LOG" 2>&1
then
cat "$QUERY_LOG" >&2
fail "obikmer query exited non-zero"
fi
if grep -q '"kmer_count":1' "$QUERY_LOG"; then
FOUND=1
break
fi
done
if [ "$FOUND" -ne 1 ]; then
cat "$QUERY_LOG" >&2
fail "no candidate k-mer round-tripped (tried ${#CANDIDATES[@]}) — likely a real regression, not a low-complexity fixture"
fi
echo "PASS: obikmer2 index + PATH obikmer query round-trip OK — $N_KMERS kmers indexed, query k-mer '$QUERY_KMER' found"