mirror of
https://github.com/rustfs/rustfs.git
synced 2026-11-01 16:50:45 +00:00
4a63e53161
* test(validation): add pinned auto-testing manual lane * Install pinned ILM client for canonical validation lane * Prepare Python client for pool validation cases * Install validation client for replication cases * test(validation): provide the Python client for Heal cases * test(validation): build the candidate-bound Heal inspector artifact * test(validation): expose tool artifacts through the existing manual lane * test(validation): verify pinned Heal tools before fleet execution * test(validation): verify Heal tools against released shard captures * ci: audit retained validation environments before finalization * test(validation): add optional native Heal regression tooling * test(validation): route native tools through the existing driver * Run validation tool resolution on hosted Linux without acquiring the fleet lock * test(validation): bind C07 to pinned native authority evidence * test(validation): build optional C10 fixture codec on hosted Linux * test(ci): bind C10 execution to the verified shared codec * feat(ci): expose read-only validation fleet inventory * docs(ci): describe supported validation recovery * test(ci): add isolated manager native validation builds * test(ci): expose manager regressions through tools-only dispatch * ci(validation): consume pinned manager native prerequisites * fix(heal): preserve typed bucket errors for bounded retries * fix(heal): preserve typed errors and SSE-C response headers * ci(validation): publish isolated immutable candidate packages * test(validation): enforce private candidate manifest schema * test(validation): verify isolated package publication failures * ci(validation): dispatch isolated packages through the driver * fix(heal): deeply verify read repair payload failures * test(ecstore): verify incarnation fence at repair commit * ci(validation): verify C11 native storage evidence * fix(ci): isolate validation package publication credentials * test(ci): archive scoped F07 directory fsync evidence * fix(ecstore): retain typed quorum errors for missing parts * chore(ecstore): shrink typed-error ratchet baseline * fix(ecstore): retain below-quorum data during no-remove heal * fix(ci): allow recovery of completed cancelled validation runs * fix(heal): retain exhausted admin batch repair receipts * fix(observability): retain typed object error diagnostics * fix(s3): map typed RPC unavailability to service refusal * fix(filemeta): classify supported inline framing damage as corrupt * test(ecstore): exercise heal during committed overwrite cleanup * ci(validation): admit source-bound G01 native evidence before fleet execution * test(ecstore): fence version races and bind cleanup slots * ci(validation): require complete race native runtime preflight * test(ecstore): fence marker and batch deletes during heal * ci(validation): require G04 native and runtime admission * test(ecstore): fence multipart continue complete and abort during heal * test(ecstore): cover default heal owners and copy metadata races * ci(validation): admit source-bound owner and copy race proofs * test(scanner): assert typed corruption after metadata truncation * fix(ci): require complete native admission for multipart races * test(validation): wire I05 queued-successor native prerequisites * fix(scanner): bind object heals to the scanning disk scope * test(scanner): reuse storage boundary for scope regression * style: format RPC digest precedence assertion * fix(heal): query automatic tasks on their owning node * test(admin): reuse error facade in heal query regression * fix(heal): retain cancellation after successful bucket storage I/O * fix(ci): retain validation evidence outside runner temp * fix(heal): retain resolved object identity on terminal failures * test(scanner): adapt scope regression to admission receipts * ci(validation): inspect shared runner without fleet access * ci(validation): prepare Python before creating client environments * ci(validation): isolate each client virtual environment * ci(validation): retain interrupted evidence without fleet recovery * ci(validation): bind recovery to retained runner evidence * ci(validation): wire persistence and lock source plans * fix(validation): align read-only dispatch defaults --------- Co-authored-by: Chris <anzhengchao@gmail.com>
344 lines
14 KiB
YAML
344 lines
14 KiB
YAML
# Build source-bound helpers separately so live validation needs only artifacts.
|
|
name: RustFS Validation Tools
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
candidate_sha:
|
|
type: string
|
|
required: true
|
|
auto_testing_sha:
|
|
type: string
|
|
required: true
|
|
build_native_heal:
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
build_shared_heal:
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
build_manager_native:
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
secrets:
|
|
PF_TESTING_GH_TOKEN:
|
|
required: true
|
|
workflow_dispatch:
|
|
inputs:
|
|
candidate_sha:
|
|
description: Exact RustFS source SHA from the validation candidate manifest
|
|
type: string
|
|
required: true
|
|
auto_testing_sha:
|
|
description: Exact auto-testing SHA containing the Heal metadata inspector
|
|
type: string
|
|
required: true
|
|
build_native_heal:
|
|
description: Also compile and run separate exact-source native Heal regressions
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
build_shared_heal:
|
|
description: Build the controlled C10 shared-reference fixture encoder
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
build_manager_native:
|
|
description: Build and run exact candidate checkpoint/MRF/incarnation regressions
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
manager-native-regressions:
|
|
if: ${{ inputs.build_manager_native }}
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 180
|
|
env:
|
|
CANDIDATE_SHA: ${{ inputs.candidate_sha }}
|
|
AUTO_TESTING_SHA: ${{ inputs.auto_testing_sha }}
|
|
steps:
|
|
- name: Validate immutable manager native inputs
|
|
run: |
|
|
set -euo pipefail
|
|
[[ "${CANDIDATE_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "${AUTO_TESTING_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
|
|
- name: Checkout exact manager candidate source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
ref: ${{ inputs.candidate_sha }}
|
|
path: candidate
|
|
persist-credentials: false
|
|
|
|
- name: Checkout exact manager collector source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
repository: rustfs/auto-testing
|
|
ref: ${{ inputs.auto_testing_sha }}
|
|
token: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
path: auto-testing
|
|
persist-credentials: false
|
|
|
|
- name: Install manager native build dependencies
|
|
run: |
|
|
set -euo pipefail
|
|
sudo apt-get update
|
|
sudo apt-get install -y clang lld cmake pkg-config libssl-dev protobuf-compiler
|
|
df -h .
|
|
|
|
- name: Build exact unmodified candidate manager test executable
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(git -C auto-testing rev-parse HEAD)" = "${AUTO_TESTING_SHA}"
|
|
python3 -B auto-testing/scripts/validation_heal/manager_native.py build \
|
|
--source candidate --commit "${CANDIDATE_SHA}" --out manager-tools
|
|
|
|
- name: Run exact manager regressions independently
|
|
run: |
|
|
set -euo pipefail
|
|
python3 -B auto-testing/scripts/validation_heal/manager_native.py run \
|
|
--directory manager-tools --out manager-evidence
|
|
|
|
- name: Upload manager executable identities and original diagnostics
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustfs-validation-manager-native-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: |
|
|
manager-tools/heal-manager-native-tests
|
|
manager-tools/*.json
|
|
manager-tools/*.jsonl
|
|
manager-tools/*.stderr
|
|
manager-tools/*.log
|
|
manager-evidence/
|
|
if-no-files-found: warn
|
|
|
|
native-heal-regressions:
|
|
if: ${{ inputs.build_native_heal }}
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 180
|
|
env:
|
|
CANDIDATE_SHA: ${{ inputs.candidate_sha }}
|
|
AUTO_TESTING_SHA: ${{ inputs.auto_testing_sha }}
|
|
steps:
|
|
- name: Validate immutable native source inputs
|
|
run: |
|
|
set -euo pipefail
|
|
[[ "${CANDIDATE_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "${AUTO_TESTING_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
|
|
- name: Checkout exact native candidate source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
ref: ${{ inputs.candidate_sha }}
|
|
path: candidate
|
|
persist-credentials: false
|
|
|
|
- name: Checkout exact native collector source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
repository: rustfs/auto-testing
|
|
ref: ${{ inputs.auto_testing_sha }}
|
|
token: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
path: auto-testing
|
|
persist-credentials: false
|
|
|
|
- name: Install native build dependencies
|
|
run: |
|
|
set -euo pipefail
|
|
sudo apt-get update
|
|
sudo apt-get install -y clang lld cmake pkg-config libssl-dev protobuf-compiler
|
|
df -h .
|
|
|
|
- name: Build and enumerate the unmodified candidate test executable
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(git -C auto-testing rev-parse HEAD)" = "${AUTO_TESTING_SHA}"
|
|
use_race_native=false
|
|
if [[ -f auto-testing/scripts/validation_heal/race_native.py ]]; then
|
|
support_rc=0
|
|
python3 -B auto-testing/scripts/validation_heal/race_native.py supports \
|
|
--commit "${CANDIDATE_SHA}" || support_rc=$?
|
|
case "${support_rc}" in
|
|
0) use_race_native=true ;;
|
|
2) ;; # The original exact-source collector handles legacy candidates.
|
|
*) exit "${support_rc}" ;;
|
|
esac
|
|
fi
|
|
if [[ "${use_race_native}" == true ]]; then
|
|
python3 -B auto-testing/scripts/validation_heal/race_native.py build \
|
|
--source candidate --commit "${CANDIDATE_SHA}" --testing-commit "${AUTO_TESTING_SHA}" --out native-tools
|
|
else
|
|
python3 -B auto-testing/scripts/validation_heal/native_regressions.py build \
|
|
--source candidate --commit "${CANDIDATE_SHA}" --out native-tools
|
|
fi
|
|
|
|
- name: Run exact native regressions separately from fleet validation
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ -f native-tools/race-native.json ]]; then
|
|
test ! -e native-tools/native-regressions.json
|
|
python3 -B auto-testing/scripts/validation_heal/race_native.py run \
|
|
--directory native-tools --out native-evidence
|
|
else
|
|
python3 -B auto-testing/scripts/validation_heal/native_regressions.py run \
|
|
--directory native-tools --out native-evidence
|
|
fi
|
|
|
|
- name: Run existing F07 directory fsync failure regressions
|
|
if: ${{ inputs.candidate_sha == '1aa9be87d18cf941e5020f19e8622c26ba4b10ac' }}
|
|
run: |
|
|
set -euo pipefail
|
|
# Older immutable harness pins retain their original native suite;
|
|
# absence of this additive collector must never fabricate its proof.
|
|
if [[ ! -f auto-testing/scripts/validation_heal/persistence_native.py ]]; then
|
|
mkdir native-persistence-evidence
|
|
echo '{"complete":false,"reason":"pinned harness predates F07 directory-fsync collector","requiredNativeCoverageComplete":false,"canonicalCasePassClaimed":false}' \
|
|
> native-persistence-evidence/not-available.json
|
|
exit 0
|
|
fi
|
|
python3 -B auto-testing/scripts/validation_heal/persistence_native.py run \
|
|
--directory native-tools --native-evidence native-evidence --out native-persistence-evidence \
|
|
--testing-commit "${AUTO_TESTING_SHA}"
|
|
python3 -B auto-testing/scripts/validation_heal/persistence_native.py verify \
|
|
--directory native-tools --native-evidence native-evidence --out native-persistence-evidence \
|
|
--testing-commit "${AUTO_TESTING_SHA}"
|
|
|
|
- name: Upload native executable identities and original diagnostics
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustfs-validation-native-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: |
|
|
native-tools/ecstore-native-tests
|
|
native-tools/ecstore-race-native-tests
|
|
native-tools/*.json
|
|
native-tools/*.jsonl
|
|
native-tools/*.stderr
|
|
native-tools/*.log
|
|
native-evidence/
|
|
native-persistence-evidence/
|
|
if-no-files-found: warn
|
|
|
|
heal-metadata-inspector:
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 30
|
|
env:
|
|
CANDIDATE_SHA: ${{ inputs.candidate_sha }}
|
|
AUTO_TESTING_SHA: ${{ inputs.auto_testing_sha }}
|
|
steps:
|
|
- name: Validate immutable source inputs
|
|
run: |
|
|
set -euo pipefail
|
|
[[ "${CANDIDATE_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "${AUTO_TESTING_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
|
|
- name: Checkout exact candidate source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
ref: ${{ inputs.candidate_sha }}
|
|
path: candidate
|
|
persist-credentials: false
|
|
|
|
- name: Checkout exact inspector source
|
|
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7
|
|
with:
|
|
repository: rustfs/auto-testing
|
|
ref: ${{ inputs.auto_testing_sha }}
|
|
token: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
path: auto-testing
|
|
persist-credentials: false
|
|
|
|
- name: Build the read-only candidate metadata decoder
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(git -C candidate rev-parse HEAD)" = "${CANDIDATE_SHA}"
|
|
test "$(git -C auto-testing rev-parse HEAD)" = "${AUTO_TESTING_SHA}"
|
|
df -h .
|
|
python3 auto-testing/scripts/validation_heal/prepare_heal_meta_inspector.py \
|
|
--source candidate --commit "${CANDIDATE_SHA}" --out inspector-build
|
|
# Seed the helper's separate graph from the candidate's frozen graph.
|
|
# Cargo adds the helper package; both lock identities are retained.
|
|
cp candidate/Cargo.lock inspector-build/Cargo.lock
|
|
cargo build --release --manifest-path inspector-build/Cargo.toml
|
|
python3 auto-testing/scripts/validation_heal/check_bitrot_tool.py \
|
|
--binary inspector-build/target/release/heal-meta-inspect --source candidate
|
|
mkdir validation-tools
|
|
cp inspector-build/target/release/heal-meta-inspect validation-tools/
|
|
cp inspector-build/Cargo.lock validation-tools/inspector-Cargo.lock
|
|
python3 - <<'PY'
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
|
|
source = json.loads(Path("inspector-build/source.json").read_text())
|
|
binary = Path("validation-tools/heal-meta-inspect")
|
|
source.update(built=True, testingCommit=os.environ["AUTO_TESTING_SHA"],
|
|
binarySha256=hashlib.sha256(binary.read_bytes()).hexdigest(),
|
|
inspectorLockSha256=hashlib.sha256(Path("validation-tools/inspector-Cargo.lock").read_bytes()).hexdigest(),
|
|
toolchain=subprocess.check_output(["rustc", "-vV"], text=True),
|
|
target="x86_64-unknown-linux-gnu", runId=os.environ["GITHUB_RUN_ID"],
|
|
runAttempt=os.environ["GITHUB_RUN_ATTEMPT"])
|
|
Path("validation-tools/heal-meta-inspect.json").write_text(json.dumps(source, indent=2) + "\n")
|
|
PY
|
|
git -C candidate diff --exit-code
|
|
|
|
- name: Build and test the controlled C10 metadata encoder
|
|
if: ${{ inputs.build_shared_heal }}
|
|
run: |
|
|
set -euo pipefail
|
|
python3 -B auto-testing/scripts/validation_heal/prepare_heal_shared_fixture.py \
|
|
--source candidate --commit "${CANDIDATE_SHA}" --out shared-build
|
|
cp candidate/Cargo.lock shared-build/Cargo.lock
|
|
export CARGO_TARGET_DIR="${GITHUB_WORKSPACE}/inspector-build/target"
|
|
cargo build --release --manifest-path shared-build/Cargo.toml
|
|
mkdir shared-tools
|
|
if ! cargo test --release --manifest-path shared-build/Cargo.toml -- --test-threads=1 \
|
|
> shared-tools/shared-fixture-tests.log 2>&1; then
|
|
cat shared-tools/shared-fixture-tests.log
|
|
exit 1
|
|
fi
|
|
cp "${CARGO_TARGET_DIR}/release/heal-shared-fixture" shared-tools/
|
|
cp shared-build/Cargo.lock shared-tools/shared-Cargo.lock
|
|
python3 - <<'PY'
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
|
|
source = json.loads(Path("shared-build/source.json").read_text())
|
|
source.update(schemaVersion=1, built=True, sourceUnmodified=True,
|
|
candidateSourceTree=subprocess.check_output(["git", "-C", "candidate", "rev-parse", "HEAD^{tree}"], text=True).strip(),
|
|
testingCommit=os.environ["AUTO_TESTING_SHA"],
|
|
binarySha256=hashlib.sha256(Path("shared-tools/heal-shared-fixture").read_bytes()).hexdigest(),
|
|
sharedLockSha256=hashlib.sha256(Path("shared-tools/shared-Cargo.lock").read_bytes()).hexdigest(),
|
|
toolchain=subprocess.check_output(["rustc", "-vV"], text=True), target="x86_64-unknown-linux-gnu",
|
|
runId=os.environ["GITHUB_RUN_ID"], runAttempt=os.environ["GITHUB_RUN_ATTEMPT"])
|
|
Path("shared-tools/heal-shared-fixture.json").write_text(json.dumps(source, indent=2) + "\n")
|
|
PY
|
|
git -C candidate diff --exit-code
|
|
|
|
- name: Upload controlled C10 fixture encoder evidence
|
|
if: ${{ always() && inputs.build_shared_heal }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustfs-validation-shared-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: shared-tools/
|
|
if-no-files-found: warn
|
|
|
|
- name: Upload immutable validation tools
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustfs-validation-tools-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: validation-tools/
|
|
if-no-files-found: error
|