#!/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