Skip to content

[chaos] Record puffin blob deleted rows (#1773) #22

[chaos] Record puffin blob deleted rows (#1773)

[chaos] Record puffin blob deleted rows (#1773) #22

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Cancel superseded runs for the same branch / PR
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-Dwarnings"
defaults:
run:
shell: bash
# ---------------------------------------------------------------------------
# Jobs
# ---------------------------------------------------------------------------
jobs:
# ────────────────────────────── 1 · FORMAT + CLIPPY ─────────────────────────
lint:
name: Format & Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
id: toolchain
with:
components: rustfmt,clippy
- uses: taiki-e/install-action@v2
with:
tool: cargo-deny
- uses: taiki-e/install-action@v2
with:
tool: cargo-sort
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- name: rustfmt check
run: cargo fmt --check
- name: clippy lint
run: cargo clippy --all-targets --all-features -- -D warnings
- name: cargo deny check
run: cargo deny check
- name: cargo dependency format
run: cargo sort --workspace
# ──────────────────────── 2 · GCS test (feature, chaos) ─────────────────
gcs_test:
name: GCS tests (feature, chaos)
runs-on: ubuntu-latest
strategy:
matrix:
type: [feature, chaos]
include:
- type: feature
name: GCS feature test
timeout-minutes: 10
cmd: |
cargo test --lib --features=storage-gcs
- type: chaos
name: GCS chaos test
timeout-minutes: 10
cmd: |
RUST_BACKTRACE=1 cargo test test_gcs_chaos --features=chaos-test,storage-gcs -p moonlink -- --nocapture
steps:
- uses: actions/checkout@v5
# ─────────────────────── Start Fake GCS Server ──────────────────────────
- name: Start Fake GCS Server
timeout-minutes: 2
run: |
docker run -d \
--name fake-gcs \
-p 4443:4443 \
-e STORAGE_DIR=/data \
fsouza/fake-gcs-server:latest \
-scheme http -port 4443
# ─────────────── Add hostnames to /etc/hosts ──────────────────────────
- name: Add gcs.local to /etc/hosts
run: |
echo "127.0.0.1 gcs.local" | sudo tee -a /etc/hosts
# ───────────────────── Wait for Fake GCS to be ready ───────────────────
- name: Wait for Fake GCS ready
timeout-minutes: 2
run: |
for i in {1..10}; do
if curl -sf http://gcs.local:4443/storage/v1/b; then
echo "Fake GCS is ready!"
break
fi
echo "Waiting for Fake GCS..."
sleep 2
done
# ────────────────────── Toolchain + Test Tools ─────────────────────────
- name: Run ${{ matrix.name }}
timeout-minutes: ${{ matrix.timeout-minutes }}
run: |
${{ matrix.cmd }}
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ──────────────────────── 3 · S3 test (feature, chaos) ───────────────────
s3_test:
name: S3 tests (feature, chaos)
runs-on: ubuntu-latest
strategy:
matrix:
type: [feature, chaos]
include:
- type: feature
name: S3 feature test
timeout-minutes: 10
cmd: |
cargo test --lib --features=storage-s3
- type: chaos
name: S3 chaos test
timeout-minutes: 10
cmd: |
cargo test storage::filesystem::accessor -p moonlink --features=chaos-test
RUST_BACKTRACE=1 cargo test test_s3_chaos --features=chaos-test,storage-s3 -p moonlink -- --nocapture
steps:
- uses: actions/checkout@v5
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
# ─────────────────────── Start Fake S3 Server ──────────────────────────
- name: Start Fake S3 Server
timeout-minutes: 2
run: |
docker run -d \
--name minio \
-p 9000:9000 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
minio/minio:latest server /data
# ─────────────── Add hostnames to /etc/hosts ──────────────────────────
- name: Add s3.local to /etc/hosts
run: |
echo "127.0.0.1 s3.local" | sudo tee -a /etc/hosts
# ───────────────────── Wait for Fake S3 to be ready ───────────────────
- name: Wait for Fake S3
timeout-minutes: 2
run: |
for i in {1..10}; do
if curl -sf http://minio:9000/minio/health/ready; then
echo "Fake S3 is ready!"
break
fi
echo "Waiting for Fake GCS..."
sleep 2
done
# ────────────────────── Toolchain + Test Tools ─────────────────────────
- name: Run ${{ matrix.name }}
timeout-minutes: ${{ matrix.timeout-minutes }}
run: |
${{ matrix.cmd }}
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────────────────── 4 · TEST & COVERAGE ────────────────────────────
coverage:
name: Unit Tests + Coverage (llvm-cov + nextest)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# ────────────────────── Toolchain + Test Tools ─────────────────────────
- uses: dtolnay/rust-toolchain@stable
id: toolchain
with:
components: llvm-tools-preview
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- uses: taiki-e/install-action@v2
with: { tool: cargo-llvm-cov }
- uses: taiki-e/install-action@v2
with: { tool: nextest }
- name: Run tests via llvm-cov/nextest
timeout-minutes: 10
# Remove moonlink_datafusion from unit test pipeline, since it takes long to build (2x longer than all other crates), and it doesn't contain any unit tests.
run: |
cargo llvm-cov \
--locked \
--lib \
--workspace \
--exclude moonlink_datafusion \
--lcov --output-path lcov.info \
nextest \
--profile ci \
--no-fail-fast
# ---------- Upload JUnit test results to Codecov ----------
- name: Upload test results (JUnit)
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: target/nextest/ci/junit.xml
fail_ci_if_error: true
# ---------- Upload coverage report to Codecov ----------
- name: Upload coverage (lcov)
if: ${{ !cancelled() }}
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: lcov.info
fail_ci_if_error: true
# ──────────────────────── 5 · Chaos test ────────────────────────────
chaos_test:
name: Chaos test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- name: Start chaos test
timeout-minutes: 10
run: |
RUST_BACKTRACE=1 cargo test table_handler::chaos_test::test_chaos_on_local_fs --features=chaos-test -p moonlink -- --nocapture
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────── 6 · Chaos test with local fs optimization ─────────────
chaos_test_with_local_fs_optimization:
name: Chaos test with local filesystem optimization
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Start chaos test
timeout-minutes: 10
run: |
RUST_BACKTRACE=1 cargo test table_handler::chaos_test::test_local_system_optimization_chaos --features=chaos-test -p moonlink -- --nocapture
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────── 7 · Chaos test with chaos injection ─────────────
chaos_test_with_chaos_injection:
name: Chaos test with chaos injection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- name: Start chaos test
timeout-minutes: 10
run: |
RUST_BACKTRACE=1 cargo test table_handler::chaos_test::test_chaos_injection --features=chaos-test -p moonlink -- --nocapture
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────── 8 · Chaos test for disk slice write ─────────────
disk_slice_write_with_chaos:
name: Chaos test for disk slice write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- name: Start chaos test
timeout-minutes: 10
run: |
RUST_BACKTRACE=1 cargo test table_handler::chaos_test::test_disk_slice_chaos --features=chaos-test -p moonlink -- --nocapture
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────── 9 · Chaos test for append only operation ─────────────
append_only_chaos:
name: Chaos test for append only operation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- name: Start chaos test
timeout-minutes: 10
run: |
RUST_BACKTRACE=1 cargo test table_handler::chaos_test::test_append_only_chaos --features=chaos-test -p moonlink -- --nocapture
# ────────────────────── Upload chaos dump ────────────────────────────
- name: Upload chaos dumps
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-dumps-${{ github.run_id }}-${{ github.job }}-${{ matrix.target || 'no-matrix' }}
path: /tmp/chaos_test_*
retention-days: 3
if-no-files-found: warn
# ───────────── 10 · PostgreSQL Integration Tests ─────────────
postgres_tests:
name: PostgreSQL Integration Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:latest
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: >-
--name postgres
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
id: toolchain
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
- name: Wait for PostgreSQL
run: |
for i in {1..10}; do
if pg_isready -h localhost -p 5432 -U postgres; then
echo "PostgreSQL is ready!"
break
fi
echo "Waiting for PostgreSQL..."
sleep 2
done
- name: Configure PostgreSQL for logical replication
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c "ALTER SYSTEM SET wal_level = 'logical';"
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c "SELECT pg_reload_conf();"
- name: Restart PostgreSQL to apply wal_level
run: |
docker restart postgres
for i in {1..10}; do
if pg_isready -h localhost -p 5432 -U postgres; then
echo "PostgreSQL restarted and ready!"
break
fi
echo "Waiting for PostgreSQL after restart..."
sleep 2
done
- name: Run PostgreSQL integration tests
timeout-minutes: 10
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
run: |
cargo test --package moonlink_connectors --lib --features connector-pg
# want to test storing and retrieving different types of storage configs
cargo test --package moonlink_metadata_store --tests --features "metadata-all test-utils storage-s3 storage-gcs"
# ───────────── 11 · Moonlink Service Integration Tests ─────────────
moonlink_service_tests:
name: Moonlink Service Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
id: toolchain
- uses: swatinem/rust-cache@v2
with:
shared-key: ${{ steps.toolchain.outputs.cachekey }}
- uses: rui314/setup-mold@v1
with:
mold-version: 2.40.3
make-default: true
# ────────────────────── Create backend directory ─────────────────────────
- name: Create backend directory
run: |
mkdir -p ${{ github.workspace }}/.shared-nginx
chmod 777 ${{ github.workspace }}/.shared-nginx
# ─────────────────────── Start nginx manually ──────────────────────────
- name: Start nginx
timeout-minutes: 2
run: |
docker run -d \
--name nginx \
-p 80:80 \
-v ${{ github.workspace }}/.shared-nginx:/usr/share/nginx/html:ro \
nginx:latest
# ─────────────── Add hostnames to /etc/hosts ──────────────────────────
- name: Add nginx.local to /etc/hosts
run: |
echo "127.0.0.1 nginx.local" | sudo tee -a /etc/hosts
# ───────────────────── Wait for nginx to be ready ───────────────────
- name: Wait for nginx
timeout-minutes: 2
run: |
for i in {1..10}; do
if curl -sf http://localhost:80; then
echo "Nginx is ready!"
break
fi
echo "Waiting for nginx..."
sleep 2
done
- name: Run moonlink_service integration tests
timeout-minutes: 10
env:
MOONLINK_BACKEND_DIR: ${{ github.workspace }}/.shared-nginx
run: |
RUST_BACKTRACE=1 cargo test --package moonlink_service --lib --features standalone-test -- --nocapture