hubcio commented on code in PR #3749:
URL: https://github.com/apache/iggy/pull/3749#discussion_r3672608516


##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}

Review Comment:
   the artifact name embeds `github.run_attempt`, and the download at line 333 
uses the same expression. "re-run failed jobs" bumps run_attempt but does not 
re-execute an already-successful `needs` job, so `build-rust-tests` never 
uploads under the new attempt number and the partition goes looking for 
`rust-nextest-archive-<run_id>-2`, which never existed. it stays broken for 
attempts 3, 4 and so on - only "re-run all jobs" recovers, at the cost of a 
full rebuild. with `retries = 3` in `.config/nextest.toml` a flaky partition is 
routine, and re-running just that partition worked before this PR.
   
   the fix needs three parts, not two: drop `-${{ github.run_attempt }}` from 
both names, add `overwrite: true` to the upload, and raise `retention-days` 
from 1 at line 327. the `overwrite` part matters - artifacts are run-scoped and 
survive across attempts, so without it "re-run all jobs" hits a duplicate-name 
rejection on its upload. and github allows re-runs for 30 days, so a 1-day 
retention reopens the same hole from the other side.



##########
.github/workflows/_test.yml:
##########
@@ -262,3 +251,58 @@ jobs:
             codecov.json
           if-no-files-found: ignore
           retention-days: 7
+
+  build-rust-tests:
+    if: ${{ startsWith(inputs.component, 'rust') && inputs.task == 'test' }}
+    runs-on: ubuntu-latest
+    timeout-minutes: 60
+    steps:
+      - name: Checkout code
+        uses: actions/[email protected]
+
+      - name: Build and archive Rust tests
+        uses: ./.github/actions/rust/pre-merge
+        with:
+          task: test-build
+          component: ${{ inputs.component }}
+
+  run-rust-tests:
+    if: ${{ startsWith(inputs.component, 'rust') && inputs.task == 'test' }}
+    needs: build-rust-tests

Review Comment:
   worth stating this tradeoff in the PR description - the results tables only 
cover the first commit, and the archive split itself is unmeasured.
   
   `needs:` makes the gap between the build finishing and the partitions 
starting structural: 82s and 113s on this PR's run. on top of that the split 
adds roughly half a minute of tar and upload after the archive completes, plus 
a whole extra job setup - the disk reclaim alone was 49s in the build job and 
93s and 53s in the two run jobs. and it removes nothing from the critical path, 
because the old two jobs already built concurrently. so wall clock can only get 
worse. the job-minute saving is the real win and it is worth having.
   
   at 2 partitions that fixed overhead is paid to dedupe a single build. at 4 
it dedupes three for roughly the same cost and wins on both axes - which is the 
argument for unblocking the partition count, see the note on line 388 of the 
composite action.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+        compression-level: 0
+        if-no-files-found: error
+        retention-days: 1
+
+    - name: Download archived Rust tests
+      if: startsWith(inputs.task, 'test-run-')
+      uses: actions/download-artifact@v8
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+
+    - name: Run archived tests with coverage
+      if: startsWith(inputs.task, 'test-run-')
+      run: |
+        TASK="${{ inputs.task }}"
+        if [[ ! "$TASK" =~ ^test-run-([0-9]+)$ ]]; then
+          echo "::error::Invalid archived test task: $TASK"
+          exit 1
+        fi
+        PARTITION_INDEX="${BASH_REMATCH[1]}"
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        NEXTEST_FILTER=$(cat "$ARTIFACT_DIR/nextest-filter.txt")
+
+        mkdir -p target/debug
+        tar -C target/debug -xf "$ARTIFACT_DIR/connector-plugins.tar"
+        tar -C target/debug -xzf "$ARTIFACT_DIR/runtime-binaries.tar.gz"
+
+        RUNTIME_BINARIES=(
+          iggy
+          iggy-server
+          iggy-server-ng
+          iggy-connectors
+          iggy-mcp
+          iggy-bench
+        )
+        CARGO_BIN_ENV=()
+        for binary in "${RUNTIME_BINARIES[@]}"; do
+          binary_path="${GITHUB_WORKSPACE}/target/debug/${binary}"
+          if [[ ! -x "$binary_path" ]]; then
+            echo "::error::Required test runtime binary not found after 
extraction: ${binary_path}"
+            exit 1
+          fi
+          CARGO_BIN_ENV+=("CARGO_BIN_EXE_${binary}=${binary_path}")
+        done
+
+        source <(cargo llvm-cov show-env --sh)
+
+        if [[ "$RUNNER_OS" == "Linux" ]]; then
+          sudo sysctl -w vm.max_map_count=2000000 || true
+          eval "$(dbus-launch --sh-syntax)"
+          export DBUS_SESSION_BUS_ADDRESS
+          eval "$(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)"
+          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
+        fi
+
+        test_start=$(date +%s)
+        env "${CARGO_BIN_ENV[@]}" cargo nextest run \
+          --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst" \
+          --extract-to "$GITHUB_WORKSPACE" \
+          --extract-overwrite \
+          --workspace-remap "$GITHUB_WORKSPACE" \
+          --no-fail-fast \
+          --profile ci \
+          --partition "hash:${PARTITION_INDEX}/2" \
+          -E "$NEXTEST_FILTER"
+        test_end=$(date +%s)
+        test_duration=$((test_end - test_start))
+        echo "::notice::Partition ${PARTITION_INDEX}/2 executed in 
${test_duration}s ($(date -ud @${test_duration} +'%M:%S'))"
 
         cargo llvm-cov report --codecov --output-path codecov.json

Review Comment:
   `cargo llvm-cov report` only ever runs here, in `test-run-*`, and the build 
job has no reports-upload step - so the profraw written during `cargo build` 
and `cargo nextest archive` dies with that runner. that silently drops coverage 
for code which only executes at build time, i.e. proc-macro expansion inside 
rustc.
   
   measured on this PR's run against the previous flow, union of both 
partitions: `core/configs_derive/src/config_env.rs` goes from 222/237 regions 
hit to 0/237, and `core/configs_derive/src/lib.rs` from 4/4 to 0/4. region 
totals are identical across the two runs, so it is the same code with the 
counters zeroed. the control is inside the same crate family - files with real 
`#[test]`s keep their coverage, only the `#[proc_macro_*]` entry points go to 
zero. the new run also had a strictly larger scope, so it is not a DAG-filter 
artifact.
   
   nothing goes red, because codecov statuses here are `informational` - which 
is what makes it worth fixing. also emit `cargo llvm-cov report --codecov` in 
`test-build` and upload from there. don't ship the build-phase profraw inside 
the artifact instead, since both partitions would merge it and double-count.



##########
.github/workflows/_test.yml:
##########
@@ -38,6 +38,7 @@ permissions:
 
 jobs:
   run:
+    if: ${{ !(startsWith(inputs.component, 'rust') && inputs.task == 'test') }}

Review Comment:
   nothing fails closed on an unknown task name. every step in the composite 
action is an `if:` on a string literal, and this PR takes the number of 
literals that have to agree from one (`test-`) to several: `test` here and at 
lines 256 and 270, `test` in `components.yml`, plus `test-build` and 
`test-run-` inside the action.
   
   rename the task in `components.yml` and this negation flips true, the 
generic `run` job invokes the composite with a task matching zero steps, and 
the job passes green having done nothing. the one fail-closed check the PR does 
add - `::error::Invalid archived test task` - can never fire, since its only 
caller is `test-run-${{ matrix.partition }}`.
   
   a terminal step in the composite asserting `inputs.task` is in a known set 
would close it.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+        compression-level: 0
+        if-no-files-found: error
+        retention-days: 1
+
+    - name: Download archived Rust tests
+      if: startsWith(inputs.task, 'test-run-')
+      uses: actions/download-artifact@v8
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+
+    - name: Run archived tests with coverage
+      if: startsWith(inputs.task, 'test-run-')
+      run: |
+        TASK="${{ inputs.task }}"
+        if [[ ! "$TASK" =~ ^test-run-([0-9]+)$ ]]; then
+          echo "::error::Invalid archived test task: $TASK"
+          exit 1
+        fi
+        PARTITION_INDEX="${BASH_REMATCH[1]}"
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        NEXTEST_FILTER=$(cat "$ARTIFACT_DIR/nextest-filter.txt")
+
+        mkdir -p target/debug
+        tar -C target/debug -xf "$ARTIFACT_DIR/connector-plugins.tar"
+        tar -C target/debug -xzf "$ARTIFACT_DIR/runtime-binaries.tar.gz"
+
+        RUNTIME_BINARIES=(
+          iggy
+          iggy-server
+          iggy-server-ng
+          iggy-connectors
+          iggy-mcp
+          iggy-bench
+        )
+        CARGO_BIN_ENV=()
+        for binary in "${RUNTIME_BINARIES[@]}"; do
+          binary_path="${GITHUB_WORKSPACE}/target/debug/${binary}"
+          if [[ ! -x "$binary_path" ]]; then
+            echo "::error::Required test runtime binary not found after 
extraction: ${binary_path}"
+            exit 1
+          fi
+          CARGO_BIN_ENV+=("CARGO_BIN_EXE_${binary}=${binary_path}")
+        done
+
+        source <(cargo llvm-cov show-env --sh)
+
+        if [[ "$RUNNER_OS" == "Linux" ]]; then
+          sudo sysctl -w vm.max_map_count=2000000 || true
+          eval "$(dbus-launch --sh-syntax)"
+          export DBUS_SESSION_BUS_ADDRESS
+          eval "$(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)"
+          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
+        fi
+
+        test_start=$(date +%s)
+        env "${CARGO_BIN_ENV[@]}" cargo nextest run \
+          --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst" \
+          --extract-to "$GITHUB_WORKSPACE" \
+          --extract-overwrite \
+          --workspace-remap "$GITHUB_WORKSPACE" \

Review Comment:
   `--workspace-remap` covers less than the name suggests. compile-time 
`env!("CARGO_MANIFEST_DIR")` is baked into the archived test binaries and 
cannot be remapped - the flag only affects nextest's runtime cwd and the env 
var, so the runtime `std::env::var` form is fine but the macro form is not.
   
   two live users: `core/integration/src/harness/context.rs:54` and 
`core/integration/tests/server/http_tls.rs:46`. this works today only because 
both jobs are `ubuntu-latest` and land on the same 
`/home/runner/work/iggy/iggy` path. move either to a container, a different 
runner label or self-hosted and those tests break in a way the flag cannot fix. 
worth a comment on both `runs-on:` lines noting the coupling.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -259,52 +239,65 @@ runs:
         bins_duration=$((bins_end - bins_start))
         echo "::notice::Binaries and libraries built in ${bins_duration}s 
($(date -ud @${bins_duration} +'%M:%S'))"
 
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        mkdir -p "$ARTIFACT_DIR"
+
         compile_start=$(date +%s)
         if [[ -n "$PACKAGE_FLAGS" ]]; then
-          cargo test --locked --no-run $PACKAGE_FLAGS
+          cargo nextest archive --locked $PACKAGE_FLAGS \
+            --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst"
         else
-          cargo test --locked --no-run
+          cargo nextest archive --locked \
+            --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst"
         fi
         compile_end=$(date +%s)
         compile_duration=$((compile_end - compile_start))
-        echo "::notice::Tests compiled in ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
+        echo "::notice::Tests compiled and archived in ${compile_duration}s 
($(date -ud @${compile_duration} +'%M:%S'))"
 
-        # Start D-Bus and unlock keyring right before test execution to avoid
-        # gnome-keyring auto-locking the collection during the build phase.
-        # Previously this ran before `cargo build`, leaving a 7+ minute idle
-        # window that triggered org.freedesktop.Secret.Error.IsLocked ~10% of 
runs.
-        if [[ "$RUNNER_OS" == "Linux" ]]; then
-          eval $(dbus-launch --sh-syntax)
-          export DBUS_SESSION_BUS_ADDRESS
-          eval $(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)
-          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
+        if [[ -n "$NEXTEST_FILTER" ]]; then
+          printf '%s\n' "$NEXTEST_FILTER" > "$ARTIFACT_DIR/nextest-filter.txt"
+        else
+          printf '%s\n' 'all()' > "$ARTIFACT_DIR/nextest-filter.txt"
         fi
 
-        test_start=$(date +%s)
-        if command -v cargo-nextest &> /dev/null; then
-          if [[ -n "$NEXTEST_FILTER" ]]; then
-            cargo nextest run --locked --no-fail-fast --profile ci 
$PARTITION_FLAG $PACKAGE_FLAGS -E "$NEXTEST_FILTER"
-          else
-            cargo nextest run --locked --no-fail-fast --profile ci 
$PARTITION_FLAG
-          fi
+        PLUGIN_FILES=()
+        while IFS= read -r -d '' plugin_file; do
+          PLUGIN_FILES+=("${plugin_file##*/}")
+        done < <(
+          find target/debug -maxdepth 1 -type f \
+            -name 'libiggy_connector_*.so' -print0
+        )
+        if (( ${#PLUGIN_FILES[@]} > 0 )); then

Review Comment:
   this guard only catches zero plugins. 17 crates declare a cdylib, so a build 
producing 3 ships a partial 601 MB tarball and the failure surfaces two jobs 
later as a dlopen error inside the connector tests instead of here. the runtime 
binaries just below get checked name by name; the plugins don't. comparing 
against the cdylib count would make it symmetric.
   
   worth flagging that this guard is load-bearing beyond the obvious case: 
`cargo metadata ... || echo "{}"` and the `jq ... || true` above can silently 
leave the package list empty, and this is one of only two places that would 
notice. so don't let it get simplified away.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -259,52 +239,65 @@ runs:
         bins_duration=$((bins_end - bins_start))
         echo "::notice::Binaries and libraries built in ${bins_duration}s 
($(date -ud @${bins_duration} +'%M:%S'))"
 
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        mkdir -p "$ARTIFACT_DIR"
+
         compile_start=$(date +%s)
         if [[ -n "$PACKAGE_FLAGS" ]]; then
-          cargo test --locked --no-run $PACKAGE_FLAGS
+          cargo nextest archive --locked $PACKAGE_FLAGS \
+            --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst"
         else
-          cargo test --locked --no-run
+          cargo nextest archive --locked \
+            --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst"
         fi
         compile_end=$(date +%s)
         compile_duration=$((compile_end - compile_start))
-        echo "::notice::Tests compiled in ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
+        echo "::notice::Tests compiled and archived in ${compile_duration}s 
($(date -ud @${compile_duration} +'%M:%S'))"
 
-        # Start D-Bus and unlock keyring right before test execution to avoid
-        # gnome-keyring auto-locking the collection during the build phase.
-        # Previously this ran before `cargo build`, leaving a 7+ minute idle
-        # window that triggered org.freedesktop.Secret.Error.IsLocked ~10% of 
runs.
-        if [[ "$RUNNER_OS" == "Linux" ]]; then
-          eval $(dbus-launch --sh-syntax)
-          export DBUS_SESSION_BUS_ADDRESS
-          eval $(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)
-          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
+        if [[ -n "$NEXTEST_FILTER" ]]; then
+          printf '%s\n' "$NEXTEST_FILTER" > "$ARTIFACT_DIR/nextest-filter.txt"
+        else
+          printf '%s\n' 'all()' > "$ARTIFACT_DIR/nextest-filter.txt"
         fi
 
-        test_start=$(date +%s)
-        if command -v cargo-nextest &> /dev/null; then
-          if [[ -n "$NEXTEST_FILTER" ]]; then
-            cargo nextest run --locked --no-fail-fast --profile ci 
$PARTITION_FLAG $PACKAGE_FLAGS -E "$NEXTEST_FILTER"
-          else
-            cargo nextest run --locked --no-fail-fast --profile ci 
$PARTITION_FLAG
-          fi
+        PLUGIN_FILES=()
+        while IFS= read -r -d '' plugin_file; do
+          PLUGIN_FILES+=("${plugin_file##*/}")
+        done < <(
+          find target/debug -maxdepth 1 -type f \
+            -name 'libiggy_connector_*.so' -print0
+        )
+        if (( ${#PLUGIN_FILES[@]} > 0 )); then
+          tar -C target/debug -cf "$ARTIFACT_DIR/connector-plugins.tar" \

Review Comment:
   this tar is uncompressed (`-cf`) while the runtime binaries below use 
`-czf`, and the upload sets `compression-level: 0` - so 601 MB, roughly half 
the 1.3 GB artifact, crosses the wire raw once up and twice down.
   
   small in the scheme of things but nearly free. if you do it, use `-I 'zstd 
-T0'` rather than `-z`: the build job is on the critical path, so 
single-threaded gzip over 601 MB costs more there than the parallel downloads 
save. note `tar --zstd` on its own is also single-threaded, and `-caf` picks 
compression from the file extension, so the filename needs to change too.



##########
.github/actions/utils/setup-rust-with-cache/action.yml:
##########
@@ -19,6 +19,14 @@ name: setup-rust-with-cache
 description: Setup Rust toolchain with Swatinem/rust-cache
 
 inputs:
+  install-nextest:
+    description: "Whether to install cargo-nextest"
+    required: false
+    default: "false"
+  install-system-dependencies:
+    description: "Whether to install system packages required by Rust builds"

Review Comment:
   "required by Rust builds" undersells this - it is load-bearing at run time 
too. `hwlocality` links `libhwloc.so.15` dynamically (the vendored fallback is 
gated on `target_env = "musl"`), and the runner image doesn't ship it: the apt 
log on this PR's run shows `libhwloc15` being newly installed. so this step is 
the sole provider on the `test-run-*` legs, which compile nothing.
   
   as written the description invites the next person to switch it off for 
those legs as an obvious optimisation, and break CI at process load. worth 
rewording now while the input is new.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+        compression-level: 0
+        if-no-files-found: error
+        retention-days: 1
+
+    - name: Download archived Rust tests
+      if: startsWith(inputs.task, 'test-run-')
+      uses: actions/download-artifact@v8
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+
+    - name: Run archived tests with coverage
+      if: startsWith(inputs.task, 'test-run-')
+      run: |
+        TASK="${{ inputs.task }}"
+        if [[ ! "$TASK" =~ ^test-run-([0-9]+)$ ]]; then
+          echo "::error::Invalid archived test task: $TASK"
+          exit 1
+        fi
+        PARTITION_INDEX="${BASH_REMATCH[1]}"
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        NEXTEST_FILTER=$(cat "$ARTIFACT_DIR/nextest-filter.txt")
+
+        mkdir -p target/debug
+        tar -C target/debug -xf "$ARTIFACT_DIR/connector-plugins.tar"
+        tar -C target/debug -xzf "$ARTIFACT_DIR/runtime-binaries.tar.gz"
+
+        RUNTIME_BINARIES=(
+          iggy
+          iggy-server
+          iggy-server-ng
+          iggy-connectors
+          iggy-mcp
+          iggy-bench
+        )
+        CARGO_BIN_ENV=()
+        for binary in "${RUNTIME_BINARIES[@]}"; do
+          binary_path="${GITHUB_WORKSPACE}/target/debug/${binary}"
+          if [[ ! -x "$binary_path" ]]; then
+            echo "::error::Required test runtime binary not found after 
extraction: ${binary_path}"
+            exit 1
+          fi
+          CARGO_BIN_ENV+=("CARGO_BIN_EXE_${binary}=${binary_path}")
+        done
+
+        source <(cargo llvm-cov show-env --sh)
+
+        if [[ "$RUNNER_OS" == "Linux" ]]; then
+          sudo sysctl -w vm.max_map_count=2000000 || true

Review Comment:
   moving the sysctl from the build phase to here is right - doris boots at 
test time, not build time. but the six-line comment explaining why went with 
it. it named the kernel constraint and pointed at the testcontainers fixture, 
which is exactly what the next reader won't reconstruct from a bare `|| true`. 
worth carrying over.



##########
scripts/ci/sync-python-interpreter-version.sh:
##########
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash

Review Comment:
   unrelated to either commit in this PR, and incomplete - four other scripts 
under `scripts/ci` still use `#!/bin/bash`. either split it out or convert all 
of them.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -45,7 +51,7 @@ runs:
         # fmt/sort/machete never build into target/, so the multi-GB cache
         # restore is pure overhead. Compiling legs 
(check/clippy/doctest/test-*)
         # keep it; a cold cache there recompiles the whole dep tree.
-        read-cache: ${{ (inputs.task == 'fmt' || inputs.task == 'sort' || 
inputs.task == 'machete') && 'false' || 'true' }}
+        read-cache: ${{ (inputs.task == 'fmt' || inputs.task == 'sort' || 
inputs.task == 'machete' || startsWith(inputs.task, 'test-run-')) && 'false' || 
'true' }}

Review Comment:
   the comment two lines up still says compiling legs 
"(check/clippy/doctest/test-*)" keep the cache, which this line now contradicts 
for `test-run-*`.
   
   knock-on worth knowing: `Configure Cargo for CI` in `setup-rust-with-cache` 
is gated on `read-cache == 'true'`, so turning the cache off here also stops 
exporting `CARGO_INCREMENTAL=0` and the profile debug settings on those legs. 
harmless today since nothing compiles there, but it is an accidental coupling 
of two unrelated concerns rather than a decision - `read-cache` is now doing 
double duty as "is this a compiling job".



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -187,44 +191,30 @@ runs:
       shell: bash
 
     - name: Install dependencies for Rust tests
-      if: startsWith(inputs.task, 'test-') && runner.os == 'Linux'
+      if: startsWith(inputs.task, 'test-run-') && runner.os == 'Linux'
       run: |
         sudo apt-get install --yes musl-tools gnome-keyring keyutils dbus-x11 
libsecret-tools
         rm -f $HOME/.local/share/keyrings/*
       shell: bash
 
     - name: Install cargo-llvm-cov
-      if: startsWith(inputs.task, 'test-')
+      if: inputs.task == 'test-build' || startsWith(inputs.task, 'test-run-')
       uses: taiki-e/install-action@v2

Review Comment:
   splitting one job into two means the build job and the run jobs now resolve 
`cargo-llvm-cov` independently on separate runners, so a release landing 
between them is a producer/consumer skew that could not happen before. same for 
`cargo-nextest`, which `setup-rust-with-cache` curls from the floating 
`get.nexte.st/latest` url.
   
   no tool is version-pinned anywhere in this file, so the unpinned pattern is 
pre-existing - it is the split that turns it into a correctness risk. `tool: 
cargo-llvm-cov@<version>` in both jobs would close it.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+        compression-level: 0
+        if-no-files-found: error
+        retention-days: 1
+
+    - name: Download archived Rust tests
+      if: startsWith(inputs.task, 'test-run-')
+      uses: actions/download-artifact@v8
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+
+    - name: Run archived tests with coverage
+      if: startsWith(inputs.task, 'test-run-')
+      run: |
+        TASK="${{ inputs.task }}"
+        if [[ ! "$TASK" =~ ^test-run-([0-9]+)$ ]]; then
+          echo "::error::Invalid archived test task: $TASK"
+          exit 1
+        fi
+        PARTITION_INDEX="${BASH_REMATCH[1]}"
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        NEXTEST_FILTER=$(cat "$ARTIFACT_DIR/nextest-filter.txt")
+
+        mkdir -p target/debug
+        tar -C target/debug -xf "$ARTIFACT_DIR/connector-plugins.tar"
+        tar -C target/debug -xzf "$ARTIFACT_DIR/runtime-binaries.tar.gz"
+
+        RUNTIME_BINARIES=(
+          iggy
+          iggy-server
+          iggy-server-ng
+          iggy-connectors
+          iggy-mcp
+          iggy-bench
+        )
+        CARGO_BIN_ENV=()
+        for binary in "${RUNTIME_BINARIES[@]}"; do
+          binary_path="${GITHUB_WORKSPACE}/target/debug/${binary}"
+          if [[ ! -x "$binary_path" ]]; then
+            echo "::error::Required test runtime binary not found after 
extraction: ${binary_path}"
+            exit 1
+          fi
+          CARGO_BIN_ENV+=("CARGO_BIN_EXE_${binary}=${binary_path}")
+        done
+
+        source <(cargo llvm-cov show-env --sh)
+
+        if [[ "$RUNNER_OS" == "Linux" ]]; then
+          sudo sysctl -w vm.max_map_count=2000000 || true
+          eval "$(dbus-launch --sh-syntax)"
+          export DBUS_SESSION_BUS_ADDRESS
+          eval "$(echo -n "test" | gnome-keyring-daemon --unlock 
--components=secrets)"
+          echo -n "warmup" | secret-tool store --label="ci-warmup" ci-test 
warmup
+        fi
+
+        test_start=$(date +%s)
+        env "${CARGO_BIN_ENV[@]}" cargo nextest run \
+          --archive-file "$ARTIFACT_DIR/rust-tests.tar.zst" \
+          --extract-to "$GITHUB_WORKSPACE" \
+          --extract-overwrite \
+          --workspace-remap "$GITHUB_WORKSPACE" \
+          --no-fail-fast \
+          --profile ci \
+          --partition "hash:${PARTITION_INDEX}/2" \

Review Comment:
   the partition denominator `2` is hardcoded here, again in the notice at line 
392, in the matrix at `_test.yml:277`, and in the task description at line 23 - 
four places that have to stay in lockstep.
   
   growing the matrix fails loudly, since nextest rejects `hash:3/2`. shrinking 
it to `[1]` fails silently: partition 2's tests simply never run and the gate 
stays green. deriving the denominator from `strategy.job-total` would collapse 
all four.



##########
.github/workflows/_test.yml:
##########
@@ -262,3 +251,58 @@ jobs:
             codecov.json
           if-no-files-found: ignore
           retention-days: 7
+
+  build-rust-tests:
+    if: ${{ startsWith(inputs.component, 'rust') && inputs.task == 'test' }}

Review Comment:
   this gate is `startsWith(inputs.component, 'rust')` but the artifact name in 
the composite action carries no component segment. today only `rust` declares a 
`test` task, so exactly one job produces it - but give any other rust-prefixed 
component a `test` task and two build jobs upload the same name in one run. it 
fails loudly rather than silently mixing archives, so it is latent, but it is a 
one-line hardening either way: interpolate `inputs.component` into the name, or 
tighten this to `== 'rust'`.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -316,12 +309,87 @@ runs:
           echo "DAG scope:                     full workspace (${TOTAL_CRATES} 
crates)"
         fi
         echo "All targets build:             ${bins_duration}s ($(date -ud 
@${bins_duration} +'%M:%S'))"
-        echo "Tests compile:                 ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
-        echo "Tests execute:                 ${test_duration}s ($(date -ud 
@${test_duration} +'%M:%S'))"
+        echo "Tests compile and archive:     ${compile_duration}s ($(date -ud 
@${compile_duration} +'%M:%S'))"
         echo "-----------------------------------------"
         echo "Total build:                   ${build_duration}s ($(date -ud 
@${build_duration} +'%M:%S'))"
-        echo "Total time:                    ${total_duration}s ($(date -ud 
@${total_duration} +'%M:%S'))"
         echo "========================================="
+        du -h "$ARTIFACT_DIR"/*
+      shell: bash
+
+    - name: Upload archived Rust tests
+      if: inputs.task == 'test-build'
+      uses: actions/upload-artifact@v7
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+        compression-level: 0
+        if-no-files-found: error
+        retention-days: 1
+
+    - name: Download archived Rust tests
+      if: startsWith(inputs.task, 'test-run-')
+      uses: actions/download-artifact@v8
+      with:
+        name: rust-nextest-archive-${{ github.run_id }}-${{ github.run_attempt 
}}
+        path: ${{ runner.temp }}/rust-nextest-archive
+
+    - name: Run archived tests with coverage
+      if: startsWith(inputs.task, 'test-run-')
+      run: |
+        TASK="${{ inputs.task }}"
+        if [[ ! "$TASK" =~ ^test-run-([0-9]+)$ ]]; then
+          echo "::error::Invalid archived test task: $TASK"
+          exit 1
+        fi
+        PARTITION_INDEX="${BASH_REMATCH[1]}"
+        ARTIFACT_DIR="${RUNNER_TEMP}/rust-nextest-archive"
+        NEXTEST_FILTER=$(cat "$ARTIFACT_DIR/nextest-filter.txt")
+
+        mkdir -p target/debug
+        tar -C target/debug -xf "$ARTIFACT_DIR/connector-plugins.tar"
+        tar -C target/debug -xzf "$ARTIFACT_DIR/runtime-binaries.tar.gz"
+
+        RUNTIME_BINARIES=(
+          iggy
+          iggy-server
+          iggy-server-ng
+          iggy-connectors
+          iggy-mcp
+          iggy-bench
+        )
+        CARGO_BIN_ENV=()
+        for binary in "${RUNTIME_BINARIES[@]}"; do
+          binary_path="${GITHUB_WORKSPACE}/target/debug/${binary}"
+          if [[ ! -x "$binary_path" ]]; then
+            echo "::error::Required test runtime binary not found after 
extraction: ${binary_path}"
+            exit 1
+          fi
+          CARGO_BIN_ENV+=("CARGO_BIN_EXE_${binary}=${binary_path}")
+        done
+
+        source <(cargo llvm-cov show-env --sh)

Review Comment:
   `source <(cmd)` cannot fail. a failing command inside process substitution 
yields an empty fifo and `source` returns 0, so `set -e` never fires and the 
step continues without the env. same pattern at line 230, and in two more added 
lines just below - `eval "$(dbus-launch --sh-syntax)"` at 374 and the 
`gnome-keyring-daemon --unlock` eval at 376 swallow failures identically, so 
`export DBUS_SESSION_BUS_ADDRESS` exports nothing and the blame lands on 
`secret-tool store` at 377.
   
   worth knowing `eval "$(cmd)"` has the same hole - it receives an empty 
string and returns 0. the forms that actually propagate are `x=$(cmd)` or 
redirect-then-source:
   
       cargo llvm-cov show-env --sh > "$RUNNER_TEMP/llvm-cov-env.sh"
       source "$RUNNER_TEMP/llvm-cov-env.sh"
   
   not urgent: `cargo llvm-cov report` bails when it finds no profraw or object 
files, so these end red rather than green. they just end red pointing at the 
wrong step.



##########
.github/actions/rust/pre-merge/action.yml:
##########
@@ -187,44 +191,30 @@ runs:
       shell: bash
 
     - name: Install dependencies for Rust tests
-      if: startsWith(inputs.task, 'test-') && runner.os == 'Linux'
+      if: startsWith(inputs.task, 'test-run-') && runner.os == 'Linux'
       run: |
         sudo apt-get install --yes musl-tools gnome-keyring keyutils dbus-x11 
libsecret-tools

Review Comment:
   `musl-tools` provides the build-time `musl-gcc` linker, and the `if:` above 
narrows this step to `test-run-*`, which compiles nothing - so it is now 
installed only where it cannot be used, and absent from `test-build`, where 
compilation actually happens. the aarch64-musl job installs its own copy anyway 
and nothing on the test path links musl, so probably just delete it rather than 
move it back. the other four packages on this line are genuinely needed at test 
time.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to