- Implemented CanonJson class for deterministic JSON serialization and hashing. - Added unit tests for CanonJson functionality, covering various scenarios including key sorting, handling of nested objects, arrays, and special characters. - Created project files for the Canonical JSON library and its tests, including necessary package references. - Added README.md for library usage and API reference. - Introduced RabbitMqIntegrationFactAttribute for conditional RabbitMQ integration tests.
134 lines
3.6 KiB
Bash
134 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
||
# run-replay.sh
|
||
# Deterministic Replay Benchmark
|
||
# Sprint: SPRINT_3850_0001_0001
|
||
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
RESULTS_DIR="$SCRIPT_DIR/results/$(date -u +%Y%m%d_%H%M%S)"
|
||
|
||
# Parse arguments
|
||
MANIFEST_FILE=""
|
||
RUNS=5
|
||
VERBOSE=false
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--manifest)
|
||
MANIFEST_FILE="$2"
|
||
shift 2
|
||
;;
|
||
--runs)
|
||
RUNS="$2"
|
||
shift 2
|
||
;;
|
||
--verbose|-v)
|
||
VERBOSE=true
|
||
shift
|
||
;;
|
||
*)
|
||
echo "Unknown option: $1"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
echo "╔════════════════════════════════════════════════╗"
|
||
echo "║ Deterministic Replay Benchmark ║"
|
||
echo "╚════════════════════════════════════════════════╝"
|
||
echo ""
|
||
echo "Configuration:"
|
||
echo " Manifest: ${MANIFEST_FILE:-<default sample>}"
|
||
echo " Runs: $RUNS"
|
||
echo " Results dir: $RESULTS_DIR"
|
||
echo ""
|
||
|
||
mkdir -p "$RESULTS_DIR"
|
||
|
||
# Use sample manifest if none provided
|
||
if [ -z "$MANIFEST_FILE" ] && [ -f "$SCRIPT_DIR/fixtures/sample-manifest.json" ]; then
|
||
MANIFEST_FILE="$SCRIPT_DIR/fixtures/sample-manifest.json"
|
||
fi
|
||
|
||
declare -a HASHES
|
||
|
||
echo "Running $RUNS iterations..."
|
||
echo ""
|
||
|
||
for i in $(seq 1 $RUNS); do
|
||
echo -n " Run $i: "
|
||
|
||
OUTPUT_FILE="$RESULTS_DIR/run_$i.json"
|
||
|
||
if command -v dotnet &> /dev/null; then
|
||
# Run the replay service
|
||
dotnet run --project "$SCRIPT_DIR/../../src/Scanner/StellaOps.Scanner.WebService" -- \
|
||
replay \
|
||
--manifest "$MANIFEST_FILE" \
|
||
--output "$OUTPUT_FILE" \
|
||
--format json 2>/dev/null || {
|
||
echo "⊘ Skipped (replay command not available)"
|
||
continue
|
||
}
|
||
|
||
if [ -f "$OUTPUT_FILE" ]; then
|
||
HASH=$(sha256sum "$OUTPUT_FILE" | cut -d' ' -f1)
|
||
HASHES+=("$HASH")
|
||
echo "sha256:${HASH:0:16}..."
|
||
else
|
||
echo "⊘ No output generated"
|
||
fi
|
||
else
|
||
echo "⊘ Skipped (dotnet not available)"
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
|
||
# Verify all hashes match
|
||
if [ ${#HASHES[@]} -gt 1 ]; then
|
||
FIRST_HASH="${HASHES[0]}"
|
||
ALL_MATCH=true
|
||
|
||
for hash in "${HASHES[@]}"; do
|
||
if [ "$hash" != "$FIRST_HASH" ]; then
|
||
ALL_MATCH=false
|
||
break
|
||
fi
|
||
done
|
||
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo "Results"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
||
if $ALL_MATCH; then
|
||
echo "✓ PASS: All $RUNS runs produced identical output"
|
||
echo " Hash: sha256:$FIRST_HASH"
|
||
else
|
||
echo "✗ FAIL: Outputs differ between runs"
|
||
echo ""
|
||
echo "Hashes:"
|
||
for i in "${!HASHES[@]}"; do
|
||
echo " Run $((i+1)): ${HASHES[$i]}"
|
||
done
|
||
fi
|
||
else
|
||
echo "ℹ️ Insufficient runs to verify determinism"
|
||
fi
|
||
|
||
# Create summary JSON
|
||
cat > "$RESULTS_DIR/summary.json" <<EOF
|
||
{
|
||
"benchmark": "determinism-replay",
|
||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||
"manifest": "$MANIFEST_FILE",
|
||
"runs": $RUNS,
|
||
"hashes": [$(printf '"%s",' "${HASHES[@]}" | sed 's/,$//')],
|
||
"deterministic": ${ALL_MATCH:-null}
|
||
}
|
||
EOF
|
||
|
||
echo ""
|
||
echo "Results saved to: $RESULTS_DIR"
|