Skip to content

Add a way to bring up instances on ec2, benchmark them, and get profiles #71

Add a way to bring up instances on ec2, benchmark them, and get profiles

Add a way to bring up instances on ec2, benchmark them, and get profiles #71

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
# wal-rs is a git submodule at walshadow/wal-rs (see .gitmodules);
# the path dep in Cargo.toml points there. Submodule URL is SSH; the
# `Init wal-rs submodule` step in each job feeds a read-only deploy
# key (secrets.WAL_RS_DEPLOY_KEY) via GIT_SSH_COMMAND so the clone
# auths without disturbing the primary checkout's GITHUB_TOKEN path.
# Cancel superseded runs on the same ref.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: build + e2e (pg${{ matrix.pg-major }})
runs-on: ubuntu-latest
timeout-minutes: 60
# walshadow operationally supports PG 16+ (see PLAN.md "Supported
# PostgreSQL versions"). Matrix pins the on-PATH PG binaries to one
# specific major; tests + fixture-capture scripts pick up whichever
# `initdb` / `pg_ctl` / `postgres` lands first.
strategy:
fail-fast: false
matrix:
pg-major: [16, 17, 18]
steps:
- name: Checkout walshadow
uses: actions/checkout@v6
with:
path: walshadow
- name: Init wal-rs submodule
working-directory: walshadow
env:
WAL_RS_DEPLOY_KEY: ${{ secrets.WAL_RS_DEPLOY_KEY }}
run: |
install -d -m 700 ~/.ssh
printf '%s\n' "$WAL_RS_DEPLOY_KEY" > ~/.ssh/wal_rs_deploy
chmod 600 ~/.ssh/wal_rs_deploy
ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null
GIT_SSH_COMMAND='ssh -i ~/.ssh/wal_rs_deploy -o IdentitiesOnly=yes' \
git submodule update --init --recursive
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cargo cache
uses: Swatinem/rust-cache@v2
with:
workspaces: walshadow
# Key on PG major so a feature/test-config change for one
# major doesn't poison the others' caches.
key: pg${{ matrix.pg-major }}
- name: Install C deps (lz4 + zstd for clickhouse-c-rs)
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential liblz4-dev libzstd-dev curl gnupg lsb-release
# The runner's preinstalled postgresql-common ships only one major
# at a time; pull the requested major straight from PGDG so the
# matrix can pin any of 16 / 17 / 18 independently of the runner
# image's choice. `systemctl stop postgresql` parks any auto-
# started instance so tests own the unix-socket dirs cleanly.
- name: Install PostgreSQL ${{ matrix.pg-major }} (PGDG)
run: |
sudo systemctl stop postgresql 2>/dev/null || true
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/postgres-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/postgres-archive-keyring.gpg] https://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
postgresql-${{ matrix.pg-major }} \
postgresql-client-${{ matrix.pg-major }} \
postgresql-server-dev-${{ matrix.pg-major }}
sudo systemctl stop postgresql 2>/dev/null || true
PG_BIN=/usr/lib/postgresql/${{ matrix.pg-major }}/bin
"$PG_BIN/postgres" -V
"$PG_BIN/initdb" --version
echo "$PG_BIN" >> "$GITHUB_PATH"
# Official deb repo gives us both the `clickhouse` multitool (for
# `clickhouse local` tests) and `clickhouse-server` (for the
# readme_quickstart that connects to localhost:9000).
- name: Install ClickHouse (server + client)
run: |
sudo apt-get install -y apt-transport-https ca-certificates
curl -fsSL https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key \
| sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main" \
| sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
DEBIAN_FRONTEND=noninteractive sudo -E apt-get install -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
clickhouse-server clickhouse-client clickhouse-common-static
clickhouse --version
- name: Start ClickHouse server
run: |
sudo service clickhouse-server start
# Wait for native protocol on :9000 (readme_quickstart probes it).
for i in $(seq 1 60); do
if clickhouse-client --query "SELECT 1" >/dev/null 2>&1; then
echo "clickhouse-server up after ${i}s"
exit 0
fi
sleep 1
done
echo "clickhouse-server failed to come up" >&2
sudo tail -n 200 /var/log/clickhouse-server/clickhouse-server.err.log || true
exit 1
# classify / filter / xlog_switch / vacuum_full_pg_depend tests
# silently skip when no fixture bytes are present. Regenerate
# them against the matrix PG major so each job's
# filter_round_trip + classify_fixture + wal_stream_chunk_boundary
# actually runs against that major's WAL layout.
- name: Regenerate WAL fixtures (PG ${{ matrix.pg-major }})
working-directory: walshadow
env:
WALSHADOW_USE_LOCAL: "1"
run: |
fixtures/wal/classify/capture.sh
fixtures/wal/filter/capture.sh
fixtures/wal/xlog_switch/capture.sh
fixtures/wal/vacuum_full_pg_depend/capture.sh
- name: Build (workspace + tests)
working-directory: walshadow
run: cargo build --workspace --all-targets --locked
# All e2e tests run: shadow_lifecycle, shadow_catalog, catalog_seed,
# wal_stream_e2e (need initdb), classify_fixture + filter_round_trip
# + wal_stream_chunk_boundary (use the freshly regenerated fixtures),
# clickhouse-c-rs clickhouse_local + readme_quickstarts (need
# clickhouse binary + server on :9000).
- name: Test (workspace, single-threaded — each test owns a PG cluster)
working-directory: walshadow
env:
# Tests pick non-overlapping ports but PG cluster startup is heavy;
# avoid thrashing the runner by serializing.
RUST_TEST_THREADS: "1"
# Opts tests with `fx::dump_artifacts` into copying their tempdir
# here on failure. Empty on success; uploaded as a job artifact
# by the next step when present.
WALSHADOW_ARTIFACT_DIR: ${{ github.workspace }}/test-artifacts
run: cargo test --workspace --all-targets --locked -- --nocapture
- name: Upload test artifacts on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: test-artifacts-pg${{ matrix.pg-major }}
path: ${{ github.workspace }}/test-artifacts
if-no-files-found: ignore
retention-days: 7
# walshadow extension is a separate PGXS module (shipped to shadow PG).
# Build it against the matrix PG, install into that major's $libdir /
# share/extension, then run pg_regress under a private --temp-instance
# so we don't need an external server. Covers the C bridge function's
# varlena, fixed-width by-val, by-ref, NULL, and ereport paths.
- name: walshadow extension (build + pg_regress)
working-directory: walshadow/pgext
run: |
PG_BIN=/usr/lib/postgresql/${{ matrix.pg-major }}/bin
PG_CONFIG=$PG_BIN/pg_config
make PG_CONFIG=$PG_CONFIG
sudo make PG_CONFIG=$PG_CONFIG install
PG_REGRESS=/usr/lib/postgresql/${{ matrix.pg-major }}/lib/pgxs/src/test/regress/pg_regress
rm -rf /tmp/walshadow_pgext_tmpinst
"$PG_REGRESS" \
--inputdir=./ --outputdir=./ \
--bindir="$PG_BIN" \
--temp-instance=/tmp/walshadow_pgext_tmpinst \
--port=54329 \
walshadow
- name: walshadow extension regression diffs on failure
if: failure()
working-directory: walshadow/pgext
run: |
test -f regression.diffs && cat regression.diffs || true
test -d /tmp/walshadow_pgext_tmpinst/log && \
sudo tail -n 200 /tmp/walshadow_pgext_tmpinst/log/postmaster.log || true
- name: ClickHouse server logs on failure
if: failure()
run: sudo tail -n 500 /var/log/clickhouse-server/clickhouse-server.err.log || true
# Line-coverage baseline so future work can track movement. Runs the
# full e2e suite under `cargo llvm-cov` against the middle supported
# major (PG 17) — one major is enough for a coverage baseline; the
# matrix above proves cross-version behaviour separately. Uploads
# `lcov.info` + an HTML report as artifacts; summary lands in the
# job log.
coverage:
name: line coverage (pg17)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout walshadow
uses: actions/checkout@v6
with:
path: walshadow
- name: Init wal-rs submodule
working-directory: walshadow
env:
WAL_RS_DEPLOY_KEY: ${{ secrets.WAL_RS_DEPLOY_KEY }}
run: |
install -d -m 700 ~/.ssh
printf '%s\n' "$WAL_RS_DEPLOY_KEY" > ~/.ssh/wal_rs_deploy
chmod 600 ~/.ssh/wal_rs_deploy
ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null
GIT_SSH_COMMAND='ssh -i ~/.ssh/wal_rs_deploy -o IdentitiesOnly=yes' \
git submodule update --init --recursive
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
# cargo-llvm-cov needs `llvm-profdata` + `llvm-cov` shipped by
# this component.
components: llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Cargo cache
uses: Swatinem/rust-cache@v2
with:
workspaces: walshadow
# Instrumented builds differ from the test job's; pin a
# separate cache key so they don't collide.
key: coverage
- name: Install C deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential liblz4-dev libzstd-dev curl gnupg lsb-release
- name: Install PostgreSQL 17 (PGDG)
run: |
sudo systemctl stop postgresql 2>/dev/null || true
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/postgres-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/postgres-archive-keyring.gpg] https://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
postgresql-17 postgresql-client-17
sudo systemctl stop postgresql 2>/dev/null || true
echo "/usr/lib/postgresql/17/bin" >> "$GITHUB_PATH"
- name: Install ClickHouse (server + client)
run: |
sudo apt-get install -y apt-transport-https ca-certificates
curl -fsSL https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key \
| sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main" \
| sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
DEBIAN_FRONTEND=noninteractive sudo -E apt-get install -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
clickhouse-server clickhouse-client clickhouse-common-static
- name: Start ClickHouse server
run: |
sudo service clickhouse-server start
for i in $(seq 1 60); do
if clickhouse-client --query "SELECT 1" >/dev/null 2>&1; then
echo "clickhouse-server up after ${i}s"
exit 0
fi
sleep 1
done
sudo tail -n 200 /var/log/clickhouse-server/clickhouse-server.err.log || true
exit 1
- name: Regenerate WAL fixtures (PG 17)
working-directory: walshadow
env:
WALSHADOW_USE_LOCAL: "1"
run: |
fixtures/wal/classify/capture.sh
fixtures/wal/filter/capture.sh
fixtures/wal/xlog_switch/capture.sh
fixtures/wal/vacuum_full_pg_depend/capture.sh
# Single `--no-report` test pass so cargo only instruments &
# executes the suite once; subsequent `report` invocations re-read
# the cached profdata to emit lcov + html + summary.
- name: Run instrumented test suite (cargo llvm-cov)
working-directory: walshadow
env:
RUST_TEST_THREADS: "1"
WALSHADOW_ARTIFACT_DIR: ${{ github.workspace }}/test-artifacts
run: |
cargo llvm-cov clean --workspace
cargo llvm-cov --workspace --all-targets --locked --no-report \
-- --nocapture
- name: Upload test artifacts on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: test-artifacts-coverage
path: ${{ github.workspace }}/test-artifacts
if-no-files-found: ignore
retention-days: 7
- name: Coverage summary (job log)
working-directory: walshadow
run: cargo llvm-cov report --summary-only
- name: Coverage lcov.info
working-directory: walshadow
run: cargo llvm-cov report --lcov --output-path lcov.info
- name: Coverage HTML
working-directory: walshadow
run: cargo llvm-cov report --html
- name: Upload coverage artifacts
uses: actions/upload-artifact@v7
with:
name: coverage
path: |
walshadow/lcov.info
walshadow/target/llvm-cov/html
if-no-files-found: error
retention-days: 30
- name: Fail on any 0%-coverage file
working-directory: walshadow
run: |
zero=$(awk '
/^SF:/ { f = substr($0, 4) }
/^LF:/ { lf = substr($0, 4) + 0 }
/^LH:/ {
if (substr($0, 4) + 0 == 0 && lf > 0) {
i = index(f, "/src/"); if (i) f = substr(f, i + 1)
print f
}
}
' lcov.info)
if [ -n "$zero" ]; then
count=$(printf '%s\n' "$zero" | grep -c .)
echo "Files with 0% line coverage (every source file must be exercised by a test):"
printf '%s\n' "$zero" | sed 's/^/ /'
echo "::error::${count} file(s) have 0% line coverage"
exit 1
fi
echo "OK: all instrumented files have >0% line coverage."
- name: ClickHouse server logs on failure
if: failure()
run: sudo tail -n 500 /var/log/clickhouse-server/clickhouse-server.err.log || true
lint:
name: clippy + fmt
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout walshadow
uses: actions/checkout@v6
with:
path: walshadow
- name: Init wal-rs submodule
working-directory: walshadow
env:
WAL_RS_DEPLOY_KEY: ${{ secrets.WAL_RS_DEPLOY_KEY }}
run: |
install -d -m 700 ~/.ssh
printf '%s\n' "$WAL_RS_DEPLOY_KEY" > ~/.ssh/wal_rs_deploy
chmod 600 ~/.ssh/wal_rs_deploy
ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null
GIT_SSH_COMMAND='ssh -i ~/.ssh/wal_rs_deploy -o IdentitiesOnly=yes' \
git submodule update --init --recursive
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cargo cache
uses: Swatinem/rust-cache@v2
with:
workspaces: walshadow
key: lint
- name: Install C deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential liblz4-dev libzstd-dev
- name: cargo fmt
working-directory: walshadow
run: cargo fmt --all -- --check
- name: cargo clippy
working-directory: walshadow
run: cargo clippy --workspace --all-targets -- -D warnings