|
|
@@ -1,6 +1,12 @@
|
|
|
#!/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).
|
|
|
+#
|
|
|
+# 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
|
|
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
@@ -14,25 +20,150 @@ else
|
|
|
echo "Error: neither podman nor docker found" >&2
|
|
|
exit 1
|
|
|
fi
|
|
|
-echo "Using: $CTR"
|
|
|
|
|
|
-# Build TypeScript
|
|
|
-echo "==> Building TypeScript..."
|
|
|
-npm run build --silent
|
|
|
+IMAGE=qmd-smoke
|
|
|
|
|
|
-# Pack tarball into test/ (the build context)
|
|
|
-echo "==> Packing tarball..."
|
|
|
-rm -f test/tobilu-qmd-*.tgz
|
|
|
-TARBALL=$(npm pack --pack-destination test/ 2>/dev/null | tail -1)
|
|
|
-echo " $TARBALL"
|
|
|
+build_image() {
|
|
|
+ echo "==> Building TypeScript..."
|
|
|
+ npm run build --silent
|
|
|
|
|
|
-# Build container image
|
|
|
-echo "==> Building container..."
|
|
|
-$CTR build -f test/Containerfile -t qmd-smoke test/
|
|
|
+ echo "==> Packing tarball..."
|
|
|
+ rm -f test/tobilu-qmd-*.tgz
|
|
|
+ TARBALL=$(npm pack --pack-destination test/ 2>/dev/null | tail -1)
|
|
|
+ echo " $TARBALL"
|
|
|
|
|
|
-# Run smoke tests
|
|
|
-echo "==> Running smoke tests..."
|
|
|
-$CTR run --rm qmd-smoke
|
|
|
+ # Copy project files into build context so vitest/bun tests can run inside
|
|
|
+ rm -rf test/test-src
|
|
|
+ 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
|
|
|
-rm -f test/tobilu-qmd-*.tgz
|
|
|
+ echo "==> Building container image ($CTR)..."
|
|
|
+ $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
|