mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
feat(get): consolidate GET performance optimization (#3972)
* feat(get): consolidate GET performance optimization Consolidated implementation of all GET performance optimizations into a single, well-organized commit replacing the previous patch-on-patch approach. ## Changes ### Configuration (set_disk/mod.rs) - Consolidated all GET optimization flags into a single organized section - Enabled by default: codec streaming, metadata early-stop, page cache reclaim - Added codec streaming multipart flag (default: disabled) - Added version-aware early-stop flag (default: disabled) - Added adaptive duplex buffer sizing based on object size - All flags use OnceLock caching with rollout percentage support ### Metadata Early-Stop (set_disk/read.rs) - Delete marker early-stop when quorum agrees - Version-aware early-stop for versioned GET requests - MetadataQuorumAccumulator enhanced with: - delete_marker_votes tracking - requested_version_id and matching_version_votes tracking - version_early_stop_decision() method - 6 new tests for version early-stop scenarios ### Codec Streaming (erasure/coding/decode_reader.rs) - DualInFlight (2-stripe lookahead) enabled by default ### Decode Pipeline (erasure/coding/decode.rs) - Stripe prefetch count configuration - Bitrot-decode overlap configuration ### Disk Layer (disk/local.rs) - O_DIRECT read configuration constants (preparation) ### Metrics (io-metrics/lib.rs) - BytesPool acquisition/return metrics - Metadata phase duration with early-stop label - Total duration with reader_path label ### Diagnostics (diagnostics/) - Early-stop reason constants - Pool tier/outcome label constants ### Observability (.docker/observability/) - 3 Grafana dashboards for GET optimization monitoring - Prometheus alert rules (6 alerts: 3 critical, 3 warning) - Updated README.md and README_ZH.md with usage docs ### Config (config/src/constants/runtime.rs) - Page cache reclaim read enabled by default ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | RUSTFS_GET_CODEC_STREAMING_ENABLE | true | Codec streaming base flag | | RUSTFS_GET_CODEC_STREAMING_ROLLOUT_PCT | 100 | Codec streaming rollout % | | RUSTFS_GET_CODEC_STREAMING_MULTIPART_ENABLE | false | Multipart codec streaming | | RUSTFS_GET_METADATA_EARLY_STOP_ENABLE | true | Early-stop base flag | | RUSTFS_GET_METADATA_EARLY_STOP_ROLLOUT_PCT | 100 | Early-stop rollout % | | RUSTFS_GET_METADATA_VERSION_EARLY_STOP_ENABLE | false | Version-aware early-stop | | RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE | true | Page cache reclaim | | RUSTFS_OBJECT_DIRECT_IO_READ_ENABLE | false | O_DIRECT (preparation) | | RUSTFS_GET_DECODE_STRIPE_PREFETCH_COUNT | 1 | Stripe prefetch | | RUSTFS_GET_BITROT_DECODE_OVERLAP_ENABLE | false | Bitrot-decode overlap | | RUSTFS_GET_CODEC_STREAMING_MAX_INFLIGHT | 2 | DualInFlight stripes | ## Rollback All optimizations can be disabled via environment variables: RUSTFS_GET_CODEC_STREAMING_ENABLE=false RUSTFS_GET_METADATA_EARLY_STOP_ENABLE=false RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE=false Co-Authored-By: heihutu <heihutu@gmail.com> * test(get): add stress test scripts for GET optimization validation - quick-validate-get-optimization.sh: Quick 5-minute validation - stress-test-get-optimization.sh: Full 30+ minute stress test - README-stress-test.md: Usage documentation Co-Authored-By: heihutu <heihutu@gmail.com> * test(ecstore): align file cache reclaim defaults * chore(deps): update redis and erasure codec * test(ecstore): align decode fill policy default * test(ecstore): align metadata early-stop default * fix(ecstore): keep metadata early stop opt-in --------- Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# GET Optimization Stress Test Scripts
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- `warp` installed (https://github.com/minio/warp)
|
||||
- `mc` configured with access to the RustFS server
|
||||
- RustFS server running with GET optimizations enabled
|
||||
|
||||
### Quick Validation (5 minutes)
|
||||
|
||||
```bash
|
||||
./scripts/quick-validate-get-optimization.sh localhost:9000
|
||||
```
|
||||
|
||||
This runs basic functional tests:
|
||||
- Data integrity verification
|
||||
- Concurrent GET stability
|
||||
- Early-stop behavior validation
|
||||
|
||||
### Full Stress Test (30+ minutes)
|
||||
|
||||
```bash
|
||||
./scripts/stress-test-get-optimization.sh localhost:9000 ./stress-results
|
||||
```
|
||||
|
||||
This runs comprehensive tests:
|
||||
- Data correctness validation (1KB, 1MB, 10MB objects)
|
||||
- Concurrent GET stress test (16, 64, 256 concurrency)
|
||||
- Mixed read/write workload
|
||||
- Early-stop behavior under load
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `WARP_ACCESS_KEY` | rustfsadmin | S3 access key |
|
||||
| `WARP_SECRET_KEY` | rustfsadmin | S3 secret key |
|
||||
| `MC_ALIAS` | rustfs | mc alias for the server |
|
||||
| `TEST_BUCKET` | auto-generated | Test bucket name |
|
||||
| `TEST_DURATION` | 300s | Duration for stress tests |
|
||||
| `CONCURRENCY` | 64 | Default concurrency level |
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### 1. Data Correctness Validation
|
||||
|
||||
Verifies that GET returns correct data with early-stop enabled:
|
||||
- Uploads random data
|
||||
- Downloads and compares MD5 hash
|
||||
- Tests different object sizes (1KB, 1MB, 10MB)
|
||||
|
||||
### 2. Concurrent GET Stress Test
|
||||
|
||||
Tests performance under high concurrency:
|
||||
- Object sizes: 1KiB, 1MiB, 4MiB, 10MiB
|
||||
- Concurrency levels: 16, 64, 256
|
||||
- Duration: configurable (default 300s)
|
||||
|
||||
### 3. Mixed Read/Write Stress Test
|
||||
|
||||
Tests stability under concurrent read/write:
|
||||
- 50% reads, 50% writes
|
||||
- 1MB objects
|
||||
- 64 concurrent operations
|
||||
|
||||
### 4. Early-Stop Behavior Validation
|
||||
|
||||
Verifies early-stop works correctly:
|
||||
- 100 sequential reads of the same object
|
||||
- Verifies data size matches expected
|
||||
- Checks for any download failures
|
||||
|
||||
## Expected Results
|
||||
|
||||
### Success Criteria
|
||||
|
||||
- **Data Correctness**: 100% pass rate (no data corruption)
|
||||
- **Concurrent GET**: No errors, consistent latency
|
||||
- **Mixed Workload**: No deadlocks or data corruption
|
||||
- **Early-Stop**: All reads return correct data size
|
||||
|
||||
### Performance Baselines
|
||||
|
||||
| Object Size | Expected Throughput | Expected p95 Latency |
|
||||
|-------------|--------------------|--------------------|
|
||||
| 1KiB | > 5 MiB/s | < 10ms |
|
||||
| 1MiB | > 500 MiB/s | < 20ms |
|
||||
| 4MiB | > 1000 MiB/s | < 30ms |
|
||||
| 10MiB | > 2000 MiB/s | < 50ms |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **warp not found**: Install with `go install github.com/minio/warp@latest`
|
||||
2. **mc not configured**: Run `mc alias set rustfs http://localhost:9000 admin password`
|
||||
3. **Connection refused**: Verify RustFS is running and accessible
|
||||
4. **Permission denied**: Check S3 credentials
|
||||
|
||||
### Debug Mode
|
||||
|
||||
Enable debug logging:
|
||||
```bash
|
||||
RUST_LOG=rustfs_ecstore::bucket::lifecycle=debug ./scripts/stress-test-get-optimization.sh
|
||||
```
|
||||
|
||||
## Output Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `test-config.txt` | Test configuration |
|
||||
| `correctness-results.txt` | Data correctness results |
|
||||
| `early-stop-results.txt` | Early-stop validation results |
|
||||
| `get-*.json` | Concurrent GET performance (warp JSON) |
|
||||
| `mixed-*.json` | Mixed workload performance (warp JSON) |
|
||||
| `correctness-errors.log` | Data correctness errors (if any) |
|
||||
| `early-stop-errors.log` | Early-stop errors (if any) |
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env bash
|
||||
# Quick Validation Script for GET Optimization
|
||||
# Usage: ./scripts/quick-validate-get-optimization.sh [TARGET_HOST]
|
||||
#
|
||||
# Runs quick functional tests to validate GET optimization changes:
|
||||
# 1. Basic GET correctness
|
||||
# 2. Concurrent GET stability
|
||||
# 3. Early-stop behavior
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TARGET_HOST="${1:-localhost:9000}"
|
||||
MC_ALIAS="${MC_ALIAS:-rustfs}"
|
||||
TEST_BUCKET="quick-validate-$(date +%s)"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Quick GET Optimization Validation"
|
||||
echo "=========================================="
|
||||
echo "Target: $TARGET_HOST"
|
||||
echo ""
|
||||
|
||||
# Create test bucket
|
||||
mc mb "${MC_ALIAS}/${TEST_BUCKET}" 2>/dev/null || true
|
||||
|
||||
# ============================================================================
|
||||
# Test 1: Basic GET Correctness
|
||||
# ============================================================================
|
||||
echo "[1/3] Basic GET Correctness"
|
||||
|
||||
# Upload test file
|
||||
dd if=/dev/urandom of=/tmp/quick-test.bin bs=1048576 count=1 2>/dev/null
|
||||
original_hash=$(md5 -q /tmp/quick-test.bin 2>/dev/null || md5sum /tmp/quick-test.bin | awk '{print $1}')
|
||||
|
||||
mc cp /tmp/quick-test.bin "${MC_ALIAS}/${TEST_BUCKET}/test.bin" >/dev/null 2>&1
|
||||
|
||||
# Download and verify
|
||||
mc cp "${MC_ALIAS}/${TEST_BUCKET}/test.bin" /tmp/quick-test-download.bin >/dev/null 2>&1
|
||||
download_hash=$(md5 -q /tmp/quick-test-download.bin 2>/dev/null || md5sum /tmp/quick-test-download.bin | awk '{print $1}')
|
||||
|
||||
if [ "$original_hash" = "$download_hash" ]; then
|
||||
echo " PASS: Data integrity verified"
|
||||
else
|
||||
echo " FAIL: Data mismatch (original=$original_hash, download=$download_hash)"
|
||||
fi
|
||||
|
||||
rm -f /tmp/quick-test.bin /tmp/quick-test-download.bin
|
||||
|
||||
# ============================================================================
|
||||
# Test 2: Concurrent GET Stability
|
||||
# ============================================================================
|
||||
echo "[2/3] Concurrent GET Stability"
|
||||
|
||||
# Upload multiple test files
|
||||
for i in $(seq 1 10); do
|
||||
dd if=/dev/urandom of="/tmp/quick-test-${i}.bin" bs=1048576 count=1 2>/dev/null
|
||||
mc cp "/tmp/quick-test-${i}.bin" "${MC_ALIAS}/${TEST_BUCKET}/test-${i}.bin" >/dev/null 2>&1
|
||||
rm -f "/tmp/quick-test-${i}.bin"
|
||||
done
|
||||
|
||||
# Concurrent download
|
||||
passed=0
|
||||
failed=0
|
||||
|
||||
for i in $(seq 1 10); do
|
||||
if mc cp "${MC_ALIAS}/${TEST_BUCKET}/test-${i}.bin" "/tmp/quick-download-${i}.bin" >/dev/null 2>&1; then
|
||||
size=$(stat -f%z "/tmp/quick-download-${i}.bin" 2>/dev/null || stat -c%s "/tmp/quick-download-${i}.bin" 2>/dev/null)
|
||||
if [ "$size" = "1048576" ]; then
|
||||
passed=$((passed + 1))
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
rm -f "/tmp/quick-download-${i}.bin"
|
||||
done
|
||||
|
||||
echo " Result: $passed passed, $failed failed"
|
||||
|
||||
# ============================================================================
|
||||
# Test 3: Early-Stop Behavior
|
||||
# ============================================================================
|
||||
echo "[3/3] Early-Stop Behavior"
|
||||
|
||||
# Upload a larger test file
|
||||
dd if=/dev/urandom of=/tmp/quick-test-large.bin bs=1048576 count=10 2>/dev/null
|
||||
mc cp /tmp/quick-test-large.bin "${MC_ALIAS}/${TEST_BUCKET}/test-large.bin" >/dev/null 2>&1
|
||||
|
||||
# Multiple reads to trigger early-stop
|
||||
passed=0
|
||||
failed=0
|
||||
|
||||
for i in $(seq 1 20); do
|
||||
if mc cp "${MC_ALIAS}/${TEST_BUCKET}/test-large.bin" "/tmp/quick-large-${i}.bin" >/dev/null 2>&1; then
|
||||
size=$(stat -f%z "/tmp/quick-large-${i}.bin" 2>/dev/null || stat -c%s "/tmp/quick-large-${i}.bin" 2>/dev/null)
|
||||
if [ "$size" = "10485760" ]; then
|
||||
passed=$((passed + 1))
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
rm -f "/tmp/quick-large-${i}.bin"
|
||||
done
|
||||
|
||||
echo " Result: $passed passed, $failed failed"
|
||||
|
||||
rm -f /tmp/quick-test-large.bin
|
||||
|
||||
# ============================================================================
|
||||
# Cleanup
|
||||
# ============================================================================
|
||||
echo ""
|
||||
echo "Cleaning up..."
|
||||
mc rm --recursive --force "${MC_ALIAS}/${TEST_BUCKET}" >/dev/null 2>&1 || true
|
||||
mc rb "${MC_ALIAS}/${TEST_BUCKET}" >/dev/null 2>&1 || true
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Quick Validation Complete"
|
||||
echo "=========================================="
|
||||
Executable
+242
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env bash
|
||||
# GET Optimization Stress Test Script
|
||||
# Usage: ./scripts/stress-test-get-optimization.sh [TARGET_HOST] [OUTPUT_DIR]
|
||||
#
|
||||
# Validates:
|
||||
# 1. Data correctness with early-stop enabled
|
||||
# 2. Concurrent GET performance
|
||||
# 3. Mixed read/write stability
|
||||
# 4. Early-stop behavior under slow disk conditions
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TARGET_HOST="${1:-localhost:9000}"
|
||||
OUTPUT_DIR="${2:-./stress-test-results/$(date +%Y%m%d-%H%M%S)}"
|
||||
MC_ALIAS="${MC_ALIAS:-rustfs}"
|
||||
TEST_BUCKET="${TEST_BUCKET:-stress-test-$(date +%s)}"
|
||||
TEST_DURATION="${TEST_DURATION:-300s}"
|
||||
CONCURRENCY="${CONCURRENCY:-64}"
|
||||
|
||||
# S3 credentials
|
||||
export WARP_ACCESS_KEY="${WARP_ACCESS_KEY:-rustfsadmin}"
|
||||
export WARP_SECRET_KEY="${WARP_SECRET_KEY:-rustfsadmin}"
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
echo "=========================================="
|
||||
echo "GET Optimization Stress Test"
|
||||
echo "=========================================="
|
||||
echo "Target: $TARGET_HOST"
|
||||
echo "Output: $OUTPUT_DIR"
|
||||
echo "Bucket: $TEST_BUCKET"
|
||||
echo "Duration: $TEST_DURATION"
|
||||
echo "Concurrency: $CONCURRENCY"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Save test configuration
|
||||
cat > "$OUTPUT_DIR/test-config.txt" <<EOF
|
||||
Date: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
Target: $TARGET_HOST
|
||||
Bucket: $TEST_BUCKET
|
||||
Duration: $TEST_DURATION
|
||||
Concurrency: $CONCURRENCY
|
||||
|
||||
Environment Variables:
|
||||
RUSTFS_GET_METADATA_EARLY_STOP_ENABLE=${RUSTFS_GET_METADATA_EARLY_STOP_ENABLE:-true}
|
||||
RUSTFS_GET_CODEC_STREAMING_ENABLE=${RUSTFS_GET_CODEC_STREAMING_ENABLE:-false}
|
||||
RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE=${RUSTFS_OBJECT_FILE_CACHE_RECLAIM_READ_ENABLE:-true}
|
||||
EOF
|
||||
|
||||
# ============================================================================
|
||||
# Test 1: Data Correctness Validation
|
||||
# ============================================================================
|
||||
echo "[1/4] Data Correctness Validation"
|
||||
echo "=================================="
|
||||
|
||||
test_data_correctness() {
|
||||
local size=$1
|
||||
local count=$2
|
||||
local passed=0
|
||||
local failed=0
|
||||
|
||||
echo " Testing $count objects of size $size..."
|
||||
|
||||
for i in $(seq 1 $count); do
|
||||
# Generate test file
|
||||
local testfile="/tmp/stress-test-${size}-${i}.bin"
|
||||
if [ "$size" = "1KB" ]; then
|
||||
dd if=/dev/urandom of="$testfile" bs=1024 count=1 2>/dev/null
|
||||
elif [ "$size" = "1MB" ]; then
|
||||
dd if=/dev/urandom of="$testfile" bs=1048576 count=1 2>/dev/null
|
||||
elif [ "$size" = "10MB" ]; then
|
||||
dd if=/dev/urandom of="$testfile" bs=1048576 count=10 2>/dev/null
|
||||
fi
|
||||
|
||||
# Calculate original hash
|
||||
local original_hash
|
||||
original_hash=$(md5 -q "$testfile" 2>/dev/null || md5sum "$testfile" | awk '{print $1}')
|
||||
|
||||
# Upload
|
||||
mc cp "$testfile" "${MC_ALIAS}/${TEST_BUCKET}/correctness-${size}-${i}.bin" >/dev/null 2>&1
|
||||
|
||||
# Download and verify
|
||||
local downloadfile="/tmp/stress-test-${size}-${i}-download.bin"
|
||||
mc cp "${MC_ALIAS}/${TEST_BUCKET}/correctness-${size}-${i}.bin" "$downloadfile" >/dev/null 2>&1
|
||||
|
||||
local download_hash
|
||||
download_hash=$(md5 -q "$downloadfile" 2>/dev/null || md5sum "$downloadfile" | awk '{print $1}')
|
||||
|
||||
if [ "$original_hash" = "$download_hash" ]; then
|
||||
passed=$((passed + 1))
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
echo " MISMATCH: correctness-${size}-${i}.bin (original=$original_hash, download=$download_hash)" >> "$OUTPUT_DIR/correctness-errors.log"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm -f "$testfile" "$downloadfile"
|
||||
done
|
||||
|
||||
echo " Result: $passed passed, $failed failed"
|
||||
echo "correctness_${size}: passed=$passed failed=$failed" >> "$OUTPUT_DIR/correctness-results.txt"
|
||||
}
|
||||
|
||||
# Test different object sizes
|
||||
mc mb "${MC_ALIAS}/${TEST_BUCKET}" 2>/dev/null || true
|
||||
|
||||
test_data_correctness "1KB" 100
|
||||
test_data_correctness "1MB" 50
|
||||
test_data_correctness "10MB" 10
|
||||
|
||||
echo ""
|
||||
|
||||
# ============================================================================
|
||||
# Test 2: Concurrent GET Stress Test
|
||||
# ============================================================================
|
||||
echo "[2/4] Concurrent GET Stress Test"
|
||||
echo "================================="
|
||||
|
||||
# Prepare test objects
|
||||
echo " Preparing test objects..."
|
||||
for size in 1KiB 1MiB 4MiB 10MiB; do
|
||||
warp put --obj.size="$size" --num.objects=100 --host="$TARGET_HOST" --bucket="$TEST_BUCKET" --concurrent=16 >/dev/null 2>&1
|
||||
done
|
||||
|
||||
echo " Running concurrent GET tests..."
|
||||
|
||||
for size in 1KiB 1MiB 4MiB 10MiB; do
|
||||
for conc in 16 64 256; do
|
||||
echo " GET size=$size concurrency=$conc duration=$TEST_DURATION"
|
||||
output_file="$OUTPUT_DIR/get-${size}-c${conc}.json"
|
||||
|
||||
if warp get \
|
||||
--host="$TARGET_HOST" \
|
||||
--obj.size="$size" \
|
||||
--concurrent="$conc" \
|
||||
--duration="$TEST_DURATION" \
|
||||
--bucket="$TEST_BUCKET" \
|
||||
--json \
|
||||
> "$output_file" 2>/dev/null; then
|
||||
echo " OK"
|
||||
else
|
||||
echo " FAILED (see $output_file)"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# ============================================================================
|
||||
# Test 3: Mixed Read/Write Stress Test
|
||||
# ============================================================================
|
||||
echo "[3/4] Mixed Read/Write Stress Test"
|
||||
echo "==================================="
|
||||
|
||||
echo " Running mixed workload for $TEST_DURATION..."
|
||||
|
||||
warp mixed \
|
||||
--host="$TARGET_HOST" \
|
||||
--obj.size=1MiB \
|
||||
--concurrent="$CONCURRENCY" \
|
||||
--duration="$TEST_DURATION" \
|
||||
--bucket="$TEST_BUCKET" \
|
||||
--json \
|
||||
> "$OUTPUT_DIR/mixed-1MiB-c${CONCURRENCY}.json" 2>/dev/null || echo " MIXED TEST FAILED"
|
||||
|
||||
echo " Mixed test complete"
|
||||
echo ""
|
||||
|
||||
# ============================================================================
|
||||
# Test 4: Early-Stop Behavior Validation
|
||||
# ============================================================================
|
||||
echo "[4/4] Early-Stop Behavior Validation"
|
||||
echo "====================================="
|
||||
|
||||
# This test verifies that early-stop works correctly by checking:
|
||||
# 1. All GET requests return correct data
|
||||
# 2. No timeouts or errors under normal conditions
|
||||
# 3. Performance is consistent
|
||||
|
||||
echo " Running early-stop validation with concurrent reads..."
|
||||
|
||||
# Create a test object
|
||||
dd if=/dev/urandom of=/tmp/early-stop-test.bin bs=1048576 count=10 2>/dev/null
|
||||
mc cp /tmp/early-stop-test.bin "${MC_ALIAS}/${TEST_BUCKET}/early-stop-test.bin" >/dev/null 2>&1
|
||||
|
||||
# Concurrent read test
|
||||
local_passed=0
|
||||
local_failed=0
|
||||
|
||||
for i in $(seq 1 100); do
|
||||
downloadfile="/tmp/early-stop-download-${i}.bin"
|
||||
if mc cp "${MC_ALIAS}/${TEST_BUCKET}/early-stop-test.bin" "$downloadfile" >/dev/null 2>&1; then
|
||||
# Verify file size
|
||||
local_size=$(stat -f%z "$downloadfile" 2>/dev/null || stat -c%s "$downloadfile" 2>/dev/null)
|
||||
if [ "$local_size" = "10485760" ]; then
|
||||
local_passed=$((local_passed + 1))
|
||||
else
|
||||
local_failed=$((local_failed + 1))
|
||||
echo " SIZE MISMATCH: expected 10485760, got $local_size" >> "$OUTPUT_DIR/early-stop-errors.log"
|
||||
fi
|
||||
else
|
||||
local_failed=$((local_failed + 1))
|
||||
echo " DOWNLOAD FAILED: iteration $i" >> "$OUTPUT_DIR/early-stop-errors.log"
|
||||
fi
|
||||
rm -f "$downloadfile"
|
||||
done
|
||||
|
||||
echo " Early-stop validation: $local_passed passed, $local_failed failed"
|
||||
echo "early_stop_validation: passed=$local_passed failed=$local_failed" >> "$OUTPUT_DIR/early-stop-results.txt"
|
||||
|
||||
# Cleanup
|
||||
rm -f /tmp/early-stop-test.bin
|
||||
mc rm "${MC_ALIAS}/${TEST_BUCKET}/early-stop-test.bin" >/dev/null 2>&1 || true
|
||||
|
||||
echo ""
|
||||
|
||||
# ============================================================================
|
||||
# Summary
|
||||
# ============================================================================
|
||||
echo "=========================================="
|
||||
echo "Stress Test Summary"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Results saved to: $OUTPUT_DIR"
|
||||
echo ""
|
||||
echo "Files:"
|
||||
ls -la "$OUTPUT_DIR"
|
||||
echo ""
|
||||
echo "Review:"
|
||||
echo " - correctness-results.txt: Data correctness validation"
|
||||
echo " - early-stop-results.txt: Early-stop behavior validation"
|
||||
echo " - get-*.json: Concurrent GET performance results"
|
||||
echo " - mixed-*.json: Mixed workload results"
|
||||
echo ""
|
||||
|
||||
# Cleanup test bucket
|
||||
echo "Cleaning up test bucket..."
|
||||
mc rm --recursive --force "${MC_ALIAS}/${TEST_BUCKET}" >/dev/null 2>&1 || true
|
||||
mc rb "${MC_ALIAS}/${TEST_BUCKET}" >/dev/null 2>&1 || true
|
||||
|
||||
echo "Done!"
|
||||
Reference in New Issue
Block a user