Add test.sh
This commit is contained in:
173
test.sh
Normal file
173
test.sh
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test push_swap with multiple sizes, memory leak check, and sorting verification
|
||||
|
||||
COUNT=${1:-5} # Number of tests per size, default 5
|
||||
|
||||
# Detect OS and architecture
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
OS="linux"
|
||||
CHECKER="./checker/checker_linux"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
OS="mac"
|
||||
CHECKER="./checker/checker_Mac"
|
||||
else
|
||||
echo "Unsupported OS: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ARCH=$(uname -m)
|
||||
echo "Detected OS: $OS ($ARCH)"
|
||||
echo "Using checker: $CHECKER"
|
||||
|
||||
# Test if checker works (x86_64 checker on arm64 may hang)
|
||||
CHECKER_WORKS=true
|
||||
if [ -x "$CHECKER" ]; then
|
||||
test_result=$(echo "" | timeout 2 $CHECKER 1 2>/dev/null; echo $?)
|
||||
if [ "$test_result" == "124" ]; then
|
||||
echo "⚠ Checker timeout - may have architecture mismatch (x86_64 on arm64)"
|
||||
CHECKER_WORKS=false
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test sizes and their targets (official: 5->12, 100->700, 500->5500)
|
||||
SIZES=(2 5 10 100 200 500)
|
||||
TARGETS=(1 12 50 700 2000 5500)
|
||||
|
||||
# Generate random numbers based on OS
|
||||
generate_random() {
|
||||
local size=$1
|
||||
if [[ "$OS" == "mac" ]]; then
|
||||
jot $size 1 $size | sort -R | tr '\n' ' '
|
||||
else
|
||||
shuf -i 1-$size | tr '\n' ' '
|
||||
fi
|
||||
}
|
||||
|
||||
# Run tests for each size
|
||||
overall_pass=true
|
||||
|
||||
for idx in "${!SIZES[@]}"; do
|
||||
SIZE=${SIZES[$idx]}
|
||||
TARGET=${TARGETS[$idx]}
|
||||
|
||||
echo "============================================"
|
||||
echo "Testing with $SIZE numbers (target: <= $TARGET ops)"
|
||||
echo "============================================"
|
||||
|
||||
total=0
|
||||
min=999999
|
||||
max=0
|
||||
all_sorted=true
|
||||
|
||||
for i in $(seq 1 $COUNT); do
|
||||
# Generate unique random numbers
|
||||
ARG=$(generate_random $SIZE)
|
||||
|
||||
# Run push_swap and capture output
|
||||
OPS_OUTPUT=$(./push_swap $ARG 2>/dev/null)
|
||||
ops=$(echo "$OPS_OUTPUT" | wc -l | tr -d ' ')
|
||||
|
||||
# Handle empty output (already sorted)
|
||||
if [ -z "$OPS_OUTPUT" ]; then
|
||||
ops=0
|
||||
fi
|
||||
|
||||
# Verify sorting with checker
|
||||
if [ "$CHECKER_WORKS" = true ] && [ -x "$CHECKER" ]; then
|
||||
# Handle empty operations (already sorted case) - use printf for true empty
|
||||
if [ -z "$OPS_OUTPUT" ]; then
|
||||
result=$(printf '' | timeout 5 $CHECKER $ARG 2>/dev/null)
|
||||
else
|
||||
result=$(printf '%s\n' "$OPS_OUTPUT" | timeout 5 $CHECKER $ARG 2>/dev/null)
|
||||
fi
|
||||
if [ "$result" == "OK" ]; then
|
||||
sorted_status="✓"
|
||||
else
|
||||
sorted_status="✗"
|
||||
all_sorted=false
|
||||
fi
|
||||
else
|
||||
sorted_status="-" # Checker not available
|
||||
fi
|
||||
|
||||
# Update stats
|
||||
total=$((total + ops))
|
||||
if [ $ops -lt $min ]; then min=$ops; fi
|
||||
if [ $ops -gt $max ]; then max=$ops; fi
|
||||
|
||||
echo "Run $i: $ops ops $sorted_status"
|
||||
done
|
||||
|
||||
avg=$((total / COUNT))
|
||||
echo "--------------------------------------------"
|
||||
echo "Min: $min | Max: $max | Avg: $avg | Target: $TARGET"
|
||||
|
||||
if [ $max -le $TARGET ]; then
|
||||
echo "✓ PASS - Operations within benchmark"
|
||||
else
|
||||
echo "✗ FAIL - Max ($max) exceeds target ($TARGET)"
|
||||
overall_pass=false
|
||||
fi
|
||||
|
||||
if [ "$CHECKER_WORKS" = true ]; then
|
||||
if [ "$all_sorted" = true ]; then
|
||||
echo "✓ PASS - All sorts verified correct"
|
||||
else
|
||||
echo "✗ FAIL - Some sorts incorrect"
|
||||
overall_pass=false
|
||||
fi
|
||||
else
|
||||
echo "- SKIP - Checker not available"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Memory leak check
|
||||
echo "============================================"
|
||||
echo "Memory Leak Check"
|
||||
echo "============================================"
|
||||
|
||||
ARG=$(generate_random 100)
|
||||
|
||||
if [[ "$OS" == "mac" ]]; then
|
||||
# macOS: use leaks command
|
||||
echo "Running: leaks --atExit -- ./push_swap ..."
|
||||
leaks_output=$(leaks --atExit -- ./push_swap $ARG 2>&1)
|
||||
if echo "$leaks_output" | grep -q "0 leaks"; then
|
||||
echo "✓ PASS - No memory leaks detected"
|
||||
elif echo "$leaks_output" | grep -q "cannot examine"; then
|
||||
echo "⚠ SKIP - leaks tool cannot examine process (SIP restriction)"
|
||||
else
|
||||
leak_count=$(echo "$leaks_output" | grep -o "[0-9]* leak" | head -1)
|
||||
echo "✗ FAIL - Memory leaks detected: $leak_count"
|
||||
overall_pass=false
|
||||
fi
|
||||
else
|
||||
# Linux: use valgrind
|
||||
if command -v valgrind &> /dev/null; then
|
||||
echo "Running: valgrind --leak-check=full ./push_swap ..."
|
||||
valgrind_output=$(valgrind --leak-check=full --error-exitcode=1 ./push_swap $ARG 2>&1 >/dev/null)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ PASS - No memory leaks detected"
|
||||
else
|
||||
echo "✗ FAIL - Memory leaks detected"
|
||||
overall_pass=false
|
||||
fi
|
||||
else
|
||||
echo "⚠ SKIP - valgrind not installed"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "Final Result"
|
||||
echo "============================================"
|
||||
if [ "$overall_pass" = true ]; then
|
||||
echo "✓ ALL TESTS PASSED"
|
||||
exit 0
|
||||
else
|
||||
echo "✗ SOME TESTS FAILED"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user