chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Mirrors the Ubuntu CI environment exactly:
|
||||
# - Ubuntu 24.04 (same as GitHub Actions ubuntu-latest / ubuntu-24.04-arm)
|
||||
# - GCC (system default) with ASan + UBSan + LeakSanitizer
|
||||
# - libsqlite3-dev + zlib1g-dev (same as CI "Install deps" step)
|
||||
#
|
||||
# Build: docker build -t cbm-test test-infrastructure/
|
||||
# Run: docker run --rm -v $(pwd):/src cbm-test
|
||||
|
||||
FROM ubuntu:noble
|
||||
|
||||
# Minimal: gcc + zlib only. sqlite3 is vendored (compiled from source with ASan).
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc g++ make \
|
||||
zlib1g-dev \
|
||||
pkg-config \
|
||||
python3 \
|
||||
git \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Default: run test.sh with GCC (mirrors CI exactly)
|
||||
ENTRYPOINT ["scripts/test.sh"]
|
||||
CMD ["CC=gcc", "CXX=g++"]
|
||||
@@ -0,0 +1,26 @@
|
||||
# Mirrors the Alpine CI environment for portable (musl static) builds.
|
||||
# - Alpine 3.21 with musl libc
|
||||
# - GCC + static zlib for fully static binaries
|
||||
# - Produces portable Linux binaries that run on any distro
|
||||
#
|
||||
# Build: docker build -f test-infrastructure/Dockerfile.alpine -t cbm-alpine test-infrastructure/
|
||||
# Run: docker run --rm -v $(pwd):/src cbm-alpine
|
||||
|
||||
FROM alpine:3.21@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
||||
|
||||
RUN apk add --no-cache \
|
||||
build-base \
|
||||
linux-headers \
|
||||
zlib-dev \
|
||||
zlib-static \
|
||||
bash \
|
||||
git \
|
||||
python3 \
|
||||
nodejs \
|
||||
npm \
|
||||
ca-certificates
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
ENTRYPOINT ["bash", "scripts/build.sh"]
|
||||
CMD ["CC=gcc", "CXX=g++", "STATIC=1"]
|
||||
@@ -0,0 +1,32 @@
|
||||
# Lint environment — mirrors CI lint job exactly:
|
||||
# - clang-format-20 (from LLVM apt repo)
|
||||
# - cppcheck 2.20.0 (built from source, same as CI)
|
||||
#
|
||||
# Build: docker build -t cbm-lint -f test-infrastructure/Dockerfile.lint test-infrastructure/
|
||||
# Run: docker run --rm -v $(pwd):/src cbm-lint
|
||||
|
||||
FROM ubuntu:noble
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc g++ make cmake \
|
||||
libsqlite3-dev zlib1g-dev \
|
||||
pkg-config wget gnupg git ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# clang-format-20 (same version as CI)
|
||||
RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc \
|
||||
&& echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main" > /etc/apt/sources.list.d/llvm-20.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends clang-format-20 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# cppcheck 2.20.0 (same version as CI)
|
||||
RUN git clone --depth 1 --branch 2.20.0 https://github.com/danmar/cppcheck.git /tmp/cppcheck \
|
||||
&& cmake -S /tmp/cppcheck -B /tmp/cppcheck/build -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=OFF -DCMAKE_INSTALL_PREFIX=/usr/local \
|
||||
&& cmake --build /tmp/cppcheck/build -j$(nproc) \
|
||||
&& cmake --install /tmp/cppcheck/build \
|
||||
&& rm -rf /tmp/cppcheck
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
ENTRYPOINT ["scripts/lint.sh"]
|
||||
CMD ["CLANG_FORMAT=clang-format-20"]
|
||||
@@ -0,0 +1,53 @@
|
||||
# Cross-compile AND run Windows tests locally using llvm-mingw + Wine.
|
||||
#
|
||||
# llvm-mingw: LLVM/Clang-based MinGW toolchain
|
||||
# Wine: runs the resulting .exe for actual test execution
|
||||
#
|
||||
# Usage:
|
||||
# docker compose -f test-infrastructure/docker-compose.yml run --rm build-windows
|
||||
# docker compose -f test-infrastructure/docker-compose.yml run --rm test-windows
|
||||
|
||||
FROM mstorsjo/llvm-mingw:latest
|
||||
|
||||
# Install Wine + binfmt support for transparent .exe execution
|
||||
RUN dpkg --add-architecture i386 && \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
wine64 curl zstd \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install zlib into the llvm-mingw sysroot (from MSYS2 CLANG64 repo)
|
||||
RUN mkdir -p /tmp/zlib-pkg && \
|
||||
curl -sL "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-zlib-1.3.1-1-any.pkg.tar.zst" \
|
||||
| zstd -d | tar xf - -C /tmp/zlib-pkg && \
|
||||
cp -rn /tmp/zlib-pkg/clang64/include/* /opt/llvm-mingw/x86_64-w64-mingw32/include/ && \
|
||||
cp -rn /tmp/zlib-pkg/clang64/lib/* /opt/llvm-mingw/x86_64-w64-mingw32/lib/ && \
|
||||
rm -rf /tmp/zlib-pkg
|
||||
|
||||
# Add Wine to PATH (Ubuntu noble puts it in /usr/lib/wine/)
|
||||
ENV PATH="/usr/lib/wine:${PATH}"
|
||||
|
||||
# Verify all tools are installed
|
||||
RUN echo "=== Tool check ===" && \
|
||||
x86_64-w64-mingw32-clang --version | head -1 && \
|
||||
x86_64-w64-mingw32-clang++ --version | head -1 && \
|
||||
make --version | head -1 && \
|
||||
ls /opt/llvm-mingw/x86_64-w64-mingw32/include/zlib.h && \
|
||||
(wine64 --version 2>/dev/null || echo "WARN: wine64 not on PATH, checking alternatives...") && \
|
||||
(which wine64 || which wine || find / -name "wine64" -type f 2>/dev/null | head -1 || echo "ERROR: wine not found") && \
|
||||
echo "=== All tools OK ==="
|
||||
|
||||
# Pre-init Wine to avoid first-run prompts during test
|
||||
RUN WINEDEBUG=-all wine64 wineboot --init 2>/dev/null || \
|
||||
WINEDEBUG=-all wine wineboot --init 2>/dev/null || \
|
||||
echo "WARN: Wine init skipped"
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "-c"]
|
||||
|
||||
# Default: cross-compile production build
|
||||
CMD ["make -j4 -f Makefile.cbm clean-c && \
|
||||
make -j4 -f Makefile.cbm cbm \
|
||||
CC=x86_64-w64-mingw32-clang \
|
||||
CXX=x86_64-w64-mingw32-clang++ \
|
||||
&& echo '=== Windows cross-compile: OK ==='"]
|
||||
@@ -0,0 +1,174 @@
|
||||
# Local test environment — mirrors GitHub Actions CI for ALL platforms.
|
||||
#
|
||||
# Coverage:
|
||||
# Linux arm64: native test + build (mirrors CI ubuntu-24.04-arm)
|
||||
# Linux amd64: QEMU test + build (mirrors CI ubuntu-latest)
|
||||
# Windows: cross-compile with mingw-w64 (catches all compile errors)
|
||||
# macOS: run natively — scripts/test.sh CC=cc && scripts/build.sh CC=cc
|
||||
|
||||
services:
|
||||
# ── Linux test (ASan + UBSan + LeakSanitizer) ──────────────
|
||||
test:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
command: ["CC=gcc", "CXX=g++"]
|
||||
|
||||
test-amd64:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
command: ["CC=gcc", "CXX=g++"]
|
||||
|
||||
# ── Linux production build (-O2 -Werror) ───────────────────
|
||||
build:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["scripts/build.sh"]
|
||||
command: ["CC=gcc", "CXX=g++"]
|
||||
|
||||
build-amd64:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["scripts/build.sh"]
|
||||
command: ["CC=gcc", "CXX=g++"]
|
||||
|
||||
# ── Windows cross-compile + test (llvm-mingw + Wine) ────────
|
||||
build-windows:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.mingw
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
|
||||
test-windows:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.mingw
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
command: >-
|
||||
make -j4 -f Makefile.cbm clean-c &&
|
||||
make -j4 -f Makefile.cbm build/c/test-runner
|
||||
CC=x86_64-w64-mingw32-clang
|
||||
CXX=x86_64-w64-mingw32-clang++ &&
|
||||
echo '=== Running tests under Wine ===' &&
|
||||
WINEDEBUG=-all wine64 build/c/test-runner.exe &&
|
||||
echo '=== Windows test: OK ==='
|
||||
|
||||
# ── Smoke test (build + run smoke-test.sh) ──────────────────
|
||||
smoke:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
scripts/build.sh CC=gcc CXX=g++ &&
|
||||
scripts/smoke-test.sh ./build/c/codebase-memory-mcp
|
||||
|
||||
smoke-amd64:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
scripts/build.sh CC=gcc CXX=g++ &&
|
||||
scripts/smoke-test.sh ./build/c/codebase-memory-mcp
|
||||
|
||||
# ── Windows smoke (cross-compile + Wine) ──────────────────
|
||||
smoke-windows:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.mingw
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
scripts/build.sh CC=x86_64-w64-mingw32-clang CXX=x86_64-w64-mingw32-clang++ &&
|
||||
mv build/c/codebase-memory-mcp build/c/codebase-memory-mcp.exe 2>/dev/null || true &&
|
||||
WINEDEBUG=-all scripts/smoke-test.sh ./build/c/codebase-memory-mcp.exe
|
||||
|
||||
# ── Windows soak (cross-compile + Wine) ───────────────────
|
||||
soak-windows:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.mingw
|
||||
platform: linux/amd64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["/bin/bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
scripts/build.sh CC=x86_64-w64-mingw32-clang CXX=x86_64-w64-mingw32-clang++ &&
|
||||
mv build/c/codebase-memory-mcp build/c/codebase-memory-mcp.exe 2>/dev/null || true &&
|
||||
CBM_DIAGNOSTICS=1 WINEDEBUG=-all scripts/soak-test.sh ./build/c/codebase-memory-mcp.exe 10
|
||||
|
||||
# ── Linux portable (Alpine musl static) ────────────────────
|
||||
test-portable:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.alpine
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["bash", "scripts/test.sh"]
|
||||
command: ["CC=gcc", "CXX=g++"]
|
||||
|
||||
build-portable:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.alpine
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["bash", "scripts/build.sh"]
|
||||
command: ["CC=gcc", "CXX=g++", "STATIC=1"]
|
||||
|
||||
smoke-portable:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.alpine
|
||||
platform: linux/arm64
|
||||
volumes:
|
||||
- ..:/src
|
||||
entrypoint: ["bash", "-c"]
|
||||
command:
|
||||
- |
|
||||
scripts/build.sh CC=gcc CXX=g++ STATIC=1 &&
|
||||
file build/c/codebase-memory-mcp | grep -q "statically linked" &&
|
||||
echo "=== Verified: statically linked ===" &&
|
||||
scripts/smoke-test.sh ./build/c/codebase-memory-mcp
|
||||
|
||||
# ── Lint ────────────────────────────────────────────────────
|
||||
lint:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: test-infrastructure/Dockerfile.lint
|
||||
volumes:
|
||||
- ..:/src
|
||||
Executable
+112
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env bash
|
||||
# Local CI — test all platforms before pushing.
|
||||
#
|
||||
# Coverage:
|
||||
# Linux arm64: test (ASan+LeakSan) + build (-O2) [native, fast]
|
||||
# Linux amd64: test + build [QEMU, slower]
|
||||
# Linux portable: Alpine musl static build + smoke [portable binary]
|
||||
# Windows: cross-compile with mingw-w64 [compile-check]
|
||||
# macOS: run natively (not in Docker)
|
||||
#
|
||||
# Usage:
|
||||
# ./test-infrastructure/run.sh # arm64 test+build + portable + Windows
|
||||
# ./test-infrastructure/run.sh all # above + amd64
|
||||
# ./test-infrastructure/run.sh portable # Alpine portable build + smoke only
|
||||
# ./test-infrastructure/run.sh windows # Windows cross-compile only
|
||||
# ./test-infrastructure/run.sh test # Linux arm64 test only (no perf)
|
||||
# ./test-infrastructure/run.sh perf # Linux arm64 perf/incremental only
|
||||
# ./test-infrastructure/run.sh build # Linux arm64 build only
|
||||
# ./test-infrastructure/run.sh lint # clang-format + cppcheck
|
||||
# ./test-infrastructure/run.sh shell # debug shell
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
COMPOSE="docker compose -f $ROOT/test-infrastructure/docker-compose.yml"
|
||||
|
||||
case "${1:-full}" in
|
||||
full)
|
||||
echo "=== Linux arm64: test + build ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test
|
||||
$COMPOSE run --rm build
|
||||
echo "=== Linux arm64: smoke test ==="
|
||||
$COMPOSE run --rm smoke
|
||||
echo "=== Linux portable: Alpine static build + smoke ==="
|
||||
$COMPOSE run --rm smoke-portable
|
||||
echo "=== Windows: cross-compile ==="
|
||||
$COMPOSE run --rm build-windows
|
||||
echo "=== All passed ==="
|
||||
;;
|
||||
test)
|
||||
echo "=== Linux arm64: test (ASan + LeakSanitizer, no perf) ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test
|
||||
;;
|
||||
perf)
|
||||
echo "=== Linux arm64: perf/incremental tests ==="
|
||||
$COMPOSE run --rm test
|
||||
;;
|
||||
build)
|
||||
echo "=== Linux arm64: production build (-O2 -Werror) ==="
|
||||
$COMPOSE run --rm build
|
||||
;;
|
||||
smoke)
|
||||
echo "=== Linux arm64: smoke test (build + run all phases) ==="
|
||||
$COMPOSE run --rm smoke
|
||||
;;
|
||||
portable)
|
||||
echo "=== Linux portable: Alpine static build + smoke ==="
|
||||
$COMPOSE run --rm smoke-portable
|
||||
;;
|
||||
portable-test)
|
||||
echo "=== Linux portable: Alpine test (ASan + LeakSan) ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test-portable
|
||||
;;
|
||||
windows)
|
||||
echo "=== Windows: cross-compile + smoke (Wine) ==="
|
||||
$COMPOSE run --rm smoke-windows
|
||||
;;
|
||||
smoke-windows)
|
||||
echo "=== Windows: smoke test (cross-compile + Wine) ==="
|
||||
$COMPOSE run --rm smoke-windows
|
||||
;;
|
||||
soak-windows)
|
||||
echo "=== Windows: soak test (cross-compile + Wine, 10 min) ==="
|
||||
$COMPOSE run --rm soak-windows
|
||||
;;
|
||||
amd64)
|
||||
echo "=== Linux amd64: test + build ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test-amd64
|
||||
$COMPOSE run --rm build-amd64
|
||||
;;
|
||||
all)
|
||||
echo "=== Linux arm64: test + build + smoke ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test
|
||||
$COMPOSE run --rm build
|
||||
$COMPOSE run --rm smoke
|
||||
echo "=== Linux portable: Alpine static build + smoke ==="
|
||||
$COMPOSE run --rm smoke-portable
|
||||
echo "=== Linux amd64: test + build + smoke ==="
|
||||
$COMPOSE run --rm -e CBM_SKIP_PERF=1 test-amd64
|
||||
$COMPOSE run --rm build-amd64
|
||||
$COMPOSE run --rm smoke-amd64
|
||||
echo "=== Windows: cross-compile + smoke (Wine) ==="
|
||||
$COMPOSE run --rm smoke-windows
|
||||
echo "=== All platforms passed ==="
|
||||
;;
|
||||
lint)
|
||||
echo "=== Linters (clang-format-20 + cppcheck 2.20.0) ==="
|
||||
$COMPOSE run --rm lint
|
||||
;;
|
||||
shell)
|
||||
echo "=== Debug shell (Linux arm64) ==="
|
||||
$COMPOSE run --rm --entrypoint bash test
|
||||
;;
|
||||
shell-alpine)
|
||||
echo "=== Debug shell (Alpine) ==="
|
||||
$COMPOSE run --rm --entrypoint bash test-portable
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {full|test|build|smoke|portable|portable-test|windows|amd64|all|lint|shell|shell-alpine}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user