Skip to content

Integration Tests

Integration Tests #895

Workflow file for this run

name: Integration Tests
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
schedule:
- cron: "0 2 * * *"
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
TEST_S3_ENDPOINT: http://localhost:9000
TEST_S3_ACCESS_KEY: accesskey
TEST_S3_SECRET_KEY: secretkey
permissions:
contents: read
jobs:
cli-contract:
name: CLI Contract (Commands and Options)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Run CLI help contract tests
run: cargo test --package rustfs-cli --test help_contract
- name: Validate RustFS compatibility contract
run: |
python3 -m unittest scripts/tests/test_rustfs_compatibility.py
python3 scripts/rustfs_compatibility.py --check-repository
smoke-compatibility:
name: Smoke (RustFS ${{ matrix.version }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- version: 1.0.0-beta.9
image: rustfs/rustfs:1.0.0-beta.9
- version: 1.0.0-beta.10
image: rustfs/rustfs:1.0.0-beta.10
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Start RustFS ${{ matrix.version }}
run: |
set -euo pipefail
docker pull "${{ matrix.image }}"
tls_args=()
if [[ "${{ matrix.version }}" == "1.0.0-beta.10" ]]; then
mkdir -p "$PWD/tls"
openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
-keyout "$PWD/tls/ca_key.pem" \
-out "$PWD/tls/ca_cert.pem" \
-subj "/CN=RustFS integration test CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
openssl req -newkey rsa:2048 -nodes \
-keyout "$PWD/tls/rustfs_key.pem" \
-out "$PWD/tls/rustfs.csr" \
-subj "/CN=localhost"
printf '%s\n' \
"subjectAltName=DNS:localhost,IP:127.0.0.1" \
"basicConstraints=critical,CA:FALSE" \
"keyUsage=critical,digitalSignature,keyEncipherment" \
"extendedKeyUsage=serverAuth" > "$PWD/tls/rustfs.ext"
openssl x509 -req -days 1 \
-in "$PWD/tls/rustfs.csr" \
-CA "$PWD/tls/ca_cert.pem" \
-CAkey "$PWD/tls/ca_key.pem" \
-CAcreateserial \
-extfile "$PWD/tls/rustfs.ext" \
-out "$PWD/tls/rustfs_cert.pem"
chmod 0600 "$PWD/tls/ca_key.pem" "$PWD/tls/rustfs_key.pem"
chmod 0644 "$PWD/tls/ca_cert.pem" "$PWD/tls/rustfs_cert.pem"
sudo chown 10001:10001 "$PWD/tls/rustfs_key.pem"
tls_args+=(
-v "$PWD/tls:/opt/tls:ro"
-e RUSTFS_TLS_PATH=/opt/tls
)
{
echo "TEST_S3_ENDPOINT=https://localhost:9000"
echo "TEST_S3_CA_BUNDLE=$PWD/tls/ca_cert.pem"
} >> "$GITHUB_ENV"
fi
docker run -d --name rustfs \
-p 9000:9000 \
-p 9001:9001 \
-v rustfs-data:/data \
-e RUSTFS_ROOT_USER=accesskey \
-e RUSTFS_ROOT_PASSWORD=secretkey \
-e RUSTFS_ACCESS_KEY=accesskey \
-e RUSTFS_SECRET_KEY=secretkey \
-e RUSTFS_VOLUMES=/data \
-e RUSTFS_ADDRESS=":9000" \
-e RUSTFS_CONSOLE_ENABLE="true" \
-e RUSTFS_CONSOLE_ADDRESS=":9001" \
"${tls_args[@]}" \
"${{ matrix.image }}"
- name: Prove selected RustFS image
run: |
set -euo pipefail
actual_image="$(docker inspect --format '{{.Config.Image}}' rustfs)"
image_id="$(docker inspect --format '{{.Image}}' rustfs)"
test "$actual_image" = "${{ matrix.image }}"
printf 'version=%s\nimage=%s\nimage_id=%s\n' \
"${{ matrix.version }}" "$actual_image" "$image_id" \
| tee rustfs-image.txt
- name: Wait for RustFS
run: |
for i in {1..60}; do
curl_args=(-sf)
if [[ -n "${TEST_S3_CA_BUNDLE:-}" ]]; then
curl_args+=(--cacert "$TEST_S3_CA_BUNDLE")
fi
if curl "${curl_args[@]}" "$TEST_S3_ENDPOINT/health" > /dev/null 2>&1; then
echo "RustFS is ready"
exit 0
fi
sleep 1
done
echo "RustFS failed to start"
docker logs rustfs
exit 1
- name: Run smoke compatibility tests
run: |
set -euo pipefail
TESTS=(
"object_operations::test_upload_and_download_small_file"
"admin_operations::test_admin_info_cluster"
"object_operations::test_move_recursive_prefix_s3_to_s3"
"quota_operations::test_bucket_quota_set_info_clear"
"option_behavior_operations::test_cp_dry_run_does_not_create_target_object"
"option_behavior_operations::test_head_bytes_returns_prefix_bytes"
"option_behavior_operations::test_find_print_outputs_full_remote_path"
"option_behavior_operations::test_find_exec_rejects_json_output"
"option_behavior_operations::test_mirror_parallel_zero_returns_usage_error"
)
if [[ "${{ matrix.version }}" == "1.0.0-beta.10" ]]; then
TESTS+=(
"checksum_operations::test_beta10_checksum_put_multipart_and_rejection"
"atomic_object_lock_operations::test_beta10_atomic_object_lock_put_copy_and_multipart"
"sse_customer_operations::test_beta10_sse_customer_put_head_get_wrong_key_and_multipart"
"multipart_operations::test_multipart_server_side_copy_direct_primitive"
"recursive_operations::test_recursive_copy"
)
fi
for test_name in "${TESTS[@]}"; do
echo "==> Running $test_name"
cargo test \
--package rustfs-cli \
--test integration \
--features integration \
"$test_name" \
-- \
--exact \
--test-threads=1
done
- name: Probe and report RustFS capabilities
run: |
image_id="$(docker inspect --format '{{.Image}}' rustfs)"
scripts/probe-rustfs-compatibility.sh \
"${{ matrix.version }}" \
"rustfs-compatibility-${{ matrix.version }}.json" \
"$image_id"
- name: Publish compatibility report
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: rustfs-compatibility-${{ matrix.version }}
path: |
rustfs-compatibility-${{ matrix.version }}.json
rustfs-image.txt
- name: Show RustFS logs on failure
if: failure()
run: docker logs rustfs 2>&1 | tail -200
full-target:
name: Full Integration (RustFS 1.0.0-beta.10)
runs-on: ubuntu-latest
timeout-minutes: 90
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Start RustFS 1.0.0-beta.10
run: |
docker pull rustfs/rustfs:1.0.0-beta.10
docker run -d --name rustfs \
-p 9000:9000 \
-p 9001:9001 \
-v rustfs-data:/data \
-e RUSTFS_ROOT_USER=accesskey \
-e RUSTFS_ROOT_PASSWORD=secretkey \
-e RUSTFS_ACCESS_KEY=accesskey \
-e RUSTFS_SECRET_KEY=secretkey \
-e RUSTFS_VOLUMES=/data \
-e RUSTFS_ADDRESS=":9000" \
-e RUSTFS_CONSOLE_ENABLE="true" \
-e RUSTFS_CONSOLE_ADDRESS=":9001" \
rustfs/rustfs:1.0.0-beta.10
- name: Prove selected RustFS image
run: |
set -euo pipefail
actual_image="$(docker inspect --format '{{.Config.Image}}' rustfs)"
test "$actual_image" = "rustfs/rustfs:1.0.0-beta.10"
docker inspect --format 'image={{.Config.Image}} image_id={{.Image}}' rustfs
- name: Wait for RustFS
run: |
for i in {1..60}; do
if curl -sf http://localhost:9000/health > /dev/null 2>&1; then
echo "RustFS is ready"
exit 0
fi
sleep 1
done
echo "RustFS failed to start"
docker logs rustfs
exit 1
- name: Run full integration suite
run: cargo test --package rustfs-cli --test integration --features integration -- --test-threads=1
- name: Run S3 golden tests
run: cargo test --package rustfs-cli --test golden --features golden,integration -- --test-threads=1
- name: Show RustFS logs on failure
if: failure()
run: docker logs rustfs 2>&1 | tail -200
golden:
name: Golden Tests
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Run golden tests
run: cargo test --package rustfs-cli --test golden --features golden
env:
RC_CONFIG_DIR: ${{ runner.temp }}/rc-test-config