test: restructure container smoke tests for interactive use
Replaces the inner test script with an outer driver that runs individual podman/docker commands against a pre-built image. Tests sqlite-vec loading and store unit tests under both node and bun runtimes. Supports --build (image only), --shell (interactive), and -- CMD (arbitrary command) for debugging install issues in isolation.
This commit is contained in:
parent
0b57711d32
commit
c7e8ea02a5
@ -13,9 +13,17 @@ ENV PATH="/root/.local/bin:$PATH"
|
|||||||
# Pre-install node and bun
|
# Pre-install node and bun
|
||||||
RUN mise use -g node@latest bun@latest
|
RUN mise use -g node@latest bun@latest
|
||||||
|
|
||||||
# Copy the packed tarball and test script
|
# Copy the packed tarball and install via both package managers
|
||||||
COPY tobilu-qmd-*.tgz /tmp/
|
COPY tobilu-qmd-*.tgz /tmp/
|
||||||
COPY smoke-install-test.sh /tmp/
|
RUN mise exec node@latest -- npm install -g /tmp/tobilu-qmd-*.tgz
|
||||||
RUN chmod +x /tmp/smoke-install-test.sh
|
RUN mise exec bun@latest -- bun install -g /tmp/tobilu-qmd-*.tgz
|
||||||
|
|
||||||
CMD ["/tmp/smoke-install-test.sh"]
|
# Copy test project (src + test + configs) and install deps
|
||||||
|
COPY test-src/ /opt/qmd/
|
||||||
|
RUN cd /opt/qmd && mise exec node@latest -- npm install 2>/dev/null
|
||||||
|
RUN cd /opt/qmd && mise exec bun@latest -- bun install 2>/dev/null || true
|
||||||
|
|
||||||
|
# Put everything on PATH
|
||||||
|
ENV PATH="/root/.bun/bin:/root/.local/share/mise/shims:/root/.local/bin:$PATH"
|
||||||
|
|
||||||
|
CMD ["bash"]
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Smoke test: install @tobilu/qmd from tarball and verify it runs under node and bun.
|
|
||||||
# Both runtimes need node on PATH (the bin uses #!/usr/bin/env node shebang).
|
|
||||||
set -uo pipefail
|
|
||||||
|
|
||||||
TARBALL=$(ls /tmp/tobilu-qmd-*.tgz | head -1)
|
|
||||||
PASS=0
|
|
||||||
FAIL=0
|
|
||||||
TMP=$(mktemp)
|
|
||||||
|
|
||||||
ok() { printf " %-44s OK\n" "$1"; PASS=$((PASS + 1)); }
|
|
||||||
fail() { printf " %-44s FAIL\n" "$1"; FAIL=$((FAIL + 1)); cat "$TMP" | sed 's/^/ /'; }
|
|
||||||
|
|
||||||
NODE_BIN="$(mise where node@latest)/bin"
|
|
||||||
BUN_BIN="$(mise where bun@latest)/bin"
|
|
||||||
BASE_PATH="/root/.local/bin:/usr/local/bin:/usr/bin:/bin"
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Node: install via npm, runs with node (via shebang)
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
echo "=== Node $($NODE_BIN/node --version) ==="
|
|
||||||
export PATH="$NODE_BIN:$BASE_PATH"
|
|
||||||
|
|
||||||
if npm install -g "$TARBALL" >"$TMP" 2>&1; then ok "npm install -g"
|
|
||||||
else fail "npm install -g"; fi
|
|
||||||
|
|
||||||
timeout 10 qmd >"$TMP" 2>&1 || true
|
|
||||||
if grep -q "Usage:" "$TMP"; then ok "qmd shows help"
|
|
||||||
else fail "qmd shows help"; fi
|
|
||||||
|
|
||||||
if timeout 10 qmd collection list >"$TMP" 2>&1; then ok "qmd collection list"
|
|
||||||
else fail "qmd collection list"; fi
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Bun: install via bun, still runs with node (shebang)
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
echo ""
|
|
||||||
echo "=== Bun $($BUN_BIN/bun --version) ==="
|
|
||||||
export PATH="$BUN_BIN:$HOME/.bun/bin:$NODE_BIN:$BASE_PATH"
|
|
||||||
|
|
||||||
if bun install -g "$TARBALL" >"$TMP" 2>&1; then ok "bun install -g"
|
|
||||||
else fail "bun install -g"; fi
|
|
||||||
|
|
||||||
timeout 10 "$HOME/.bun/bin/qmd" >"$TMP" 2>&1 || true
|
|
||||||
if grep -q "Usage:" "$TMP"; then ok "qmd shows help (bun-installed)"
|
|
||||||
else fail "qmd shows help (bun-installed)"; fi
|
|
||||||
|
|
||||||
if timeout 10 "$HOME/.bun/bin/qmd" collection list >"$TMP" 2>&1; then ok "qmd collection list (bun-installed)"
|
|
||||||
else fail "qmd collection list (bun-installed)"; fi
|
|
||||||
|
|
||||||
rm -f "$TMP"
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Summary
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
echo ""
|
|
||||||
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
||||||
[[ $FAIL -eq 0 ]]
|
|
||||||
@ -1,6 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Build, pack, and smoke-test qmd in a container with mise + node + bun.
|
# Build a container image with qmd installed via npm and bun, then run smoke tests.
|
||||||
# Works with docker or podman (whichever is available).
|
# Works with docker or podman (whichever is available).
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# test/smoke-install.sh # build + run all smoke tests
|
||||||
|
# test/smoke-install.sh --build # build image only
|
||||||
|
# test/smoke-install.sh --shell # drop into container shell
|
||||||
|
# test/smoke-install.sh -- CMD... # run arbitrary command in container
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
@ -14,25 +20,150 @@ else
|
|||||||
echo "Error: neither podman nor docker found" >&2
|
echo "Error: neither podman nor docker found" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "Using: $CTR"
|
|
||||||
|
|
||||||
# Build TypeScript
|
IMAGE=qmd-smoke
|
||||||
echo "==> Building TypeScript..."
|
|
||||||
npm run build --silent
|
|
||||||
|
|
||||||
# Pack tarball into test/ (the build context)
|
build_image() {
|
||||||
echo "==> Packing tarball..."
|
echo "==> Building TypeScript..."
|
||||||
rm -f test/tobilu-qmd-*.tgz
|
npm run build --silent
|
||||||
TARBALL=$(npm pack --pack-destination test/ 2>/dev/null | tail -1)
|
|
||||||
echo " $TARBALL"
|
|
||||||
|
|
||||||
# Build container image
|
echo "==> Packing tarball..."
|
||||||
echo "==> Building container..."
|
rm -f test/tobilu-qmd-*.tgz
|
||||||
$CTR build -f test/Containerfile -t qmd-smoke test/
|
TARBALL=$(npm pack --pack-destination test/ 2>/dev/null | tail -1)
|
||||||
|
echo " $TARBALL"
|
||||||
|
|
||||||
# Run smoke tests
|
# Copy project files into build context so vitest/bun tests can run inside
|
||||||
echo "==> Running smoke tests..."
|
rm -rf test/test-src
|
||||||
$CTR run --rm qmd-smoke
|
mkdir -p test/test-src/src test/test-src/test
|
||||||
|
cp src/*.ts test/test-src/src/
|
||||||
|
cp -r dist test/test-src/
|
||||||
|
cp test/*.test.ts test/test-src/test/
|
||||||
|
cp package.json tsconfig.json tsconfig.build.json test/test-src/
|
||||||
|
|
||||||
# Clean up tarball
|
echo "==> Building container image ($CTR)..."
|
||||||
rm -f test/tobilu-qmd-*.tgz
|
$CTR build -f test/Containerfile -t "$IMAGE" test/
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -f test/tobilu-qmd-*.tgz
|
||||||
|
rm -rf test/test-src
|
||||||
|
echo "==> Image ready: $IMAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
$CTR run --rm "$IMAGE" bash -c "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
ok() { printf " %-50s OK\n" "$1"; PASS=$((PASS + 1)); }
|
||||||
|
fail() { printf " %-50s FAIL\n" "$1"; FAIL=$((FAIL + 1)); echo "$2" | sed 's/^/ /'; }
|
||||||
|
|
||||||
|
smoke_test() {
|
||||||
|
local label="$1"; shift
|
||||||
|
local out
|
||||||
|
if out=$(run "$@" 2>&1); then
|
||||||
|
ok "$label"
|
||||||
|
else
|
||||||
|
fail "$label" "$out"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
smoke_test_output() {
|
||||||
|
local label="$1"; local expect="$2"; shift 2
|
||||||
|
local out
|
||||||
|
out=$(run "$@" 2>&1) || true
|
||||||
|
if echo "$out" | grep -q "$expect"; then
|
||||||
|
ok "$label"
|
||||||
|
else
|
||||||
|
fail "$label" "$out"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_smoke_tests() {
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Node (npm-installed qmd)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
local NODE_BIN='$(mise where node@latest)/bin'
|
||||||
|
echo "=== Node (npm install) ==="
|
||||||
|
|
||||||
|
smoke_test_output "qmd shows help" "Usage:" \
|
||||||
|
"export PATH=$NODE_BIN:\$PATH; qmd"
|
||||||
|
|
||||||
|
smoke_test "qmd collection list" \
|
||||||
|
"export PATH=$NODE_BIN:\$PATH; qmd collection list"
|
||||||
|
|
||||||
|
smoke_test "qmd status" \
|
||||||
|
"export PATH=$NODE_BIN:\$PATH; qmd status"
|
||||||
|
|
||||||
|
smoke_test "sqlite-vec loads" \
|
||||||
|
"export PATH=$NODE_BIN:\$PATH;
|
||||||
|
NPM_GLOBAL=\$(npm root -g);
|
||||||
|
node -e \"
|
||||||
|
const {openDatabase, loadSqliteVec} = await import('\$NPM_GLOBAL/@tobilu/qmd/dist/db.js');
|
||||||
|
const db = openDatabase(':memory:');
|
||||||
|
loadSqliteVec(db);
|
||||||
|
const r = db.prepare('SELECT vec_version() as v').get();
|
||||||
|
console.log('sqlite-vec', r.v);
|
||||||
|
if (!r.v) process.exit(1);
|
||||||
|
\""
|
||||||
|
|
||||||
|
smoke_test "vitest (node)" \
|
||||||
|
"export PATH=$NODE_BIN:\$PATH; cd /opt/qmd && npx vitest run --reporter=verbose test/store.test.ts 2>&1 | tail -5"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Bun (bun-installed qmd)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
local BUN_BIN='$(mise where bun@latest)/bin'
|
||||||
|
echo ""
|
||||||
|
echo "=== Bun (bun install) ==="
|
||||||
|
|
||||||
|
smoke_test_output "qmd shows help" "Usage:" \
|
||||||
|
"export PATH=$BUN_BIN:$NODE_BIN:\$PATH; \$HOME/.bun/bin/qmd"
|
||||||
|
|
||||||
|
smoke_test "qmd collection list" \
|
||||||
|
"export PATH=$BUN_BIN:$NODE_BIN:\$PATH; \$HOME/.bun/bin/qmd collection list"
|
||||||
|
|
||||||
|
smoke_test "qmd status" \
|
||||||
|
"export PATH=$BUN_BIN:$NODE_BIN:\$PATH; \$HOME/.bun/bin/qmd status"
|
||||||
|
|
||||||
|
smoke_test "sqlite-vec loads (bun)" \
|
||||||
|
"export PATH=$BUN_BIN:\$PATH; bun -e \"
|
||||||
|
const {openDatabase, loadSqliteVec} = await import('\$HOME/.bun/install/global/node_modules/@tobilu/qmd/dist/db.js');
|
||||||
|
const db = openDatabase(':memory:');
|
||||||
|
loadSqliteVec(db);
|
||||||
|
const r = db.prepare('SELECT vec_version() as v').get();
|
||||||
|
console.log('sqlite-vec', r.v);
|
||||||
|
if (!r.v) process.exit(1);
|
||||||
|
\""
|
||||||
|
|
||||||
|
smoke_test "bun test store" \
|
||||||
|
"export PATH=$BUN_BIN:\$PATH; cd /opt/qmd && bun test --preload ./src/test-preload.ts --timeout 30000 test/store.test.ts 2>&1 | tail -10"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
echo ""
|
||||||
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
||||||
|
[[ $FAIL -eq 0 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
case "${1:-}" in
|
||||||
|
--build)
|
||||||
|
build_image
|
||||||
|
;;
|
||||||
|
--shell)
|
||||||
|
build_image
|
||||||
|
echo "==> Dropping into container shell..."
|
||||||
|
$CTR run --rm -it "$IMAGE" bash
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
run "$@"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
build_image
|
||||||
|
echo ""
|
||||||
|
echo "==> Running smoke tests..."
|
||||||
|
run_smoke_tests
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user