#!/bin/bash # This script is used to test the program GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' BOLD='\033[1m' run_test_case() { # echo "Test case $1" MAX=0 MIN=10000000 AVG=0 SUM_SQUARES=0 ITER=$2 N=$1 MAX_ARGS="" ABOVE_5500_COUNT=0 # Create a temporary directory to store outputs TMP_DIR=$(mktemp -d) # Function to run a single test iteration run_iteration() { local iter=$1 local ARG=$(seq -1000 1000 | shuf -n $N) local OPS_OK=$(./push_swap $ARG | tee >(wc -l | tr -d '[:space:]' > "$TMP_DIR/ops_$iter") | ./checker $ARG | tr -d '[:space:]') local OPS=$(cat "$TMP_DIR/ops_$iter") local OK=$OPS_OK echo "$OPS" > "$TMP_DIR/ops_$iter" echo "$ARG" > "$TMP_DIR/arg_$iter" echo "$OK" > "$TMP_DIR/ok_$iter" } export -f run_iteration export TMP_DIR MAX MIN MAX_ARGS AVG N # Run the iterations in parallel seq 1 $ITER | xargs -n 1 -P 8 bash -c 'run_iteration "$@"' _ # Process results for file in $TMP_DIR/ops_*; do if [ -f "$file" ]; then local iter=$(basename $file | cut -d'_' -f2) local OPS=$(cat "$file") local ARG=$(cat "$TMP_DIR/arg_$iter") local OK=$(cat "$TMP_DIR/ok_$iter") AVG=$((AVG + OPS)) SUM_SQUARES=$((SUM_SQUARES + OPS * OPS)) if [ "$OPS" -gt "$MAX" ]; then MAX=$OPS MAX_ARGS="Max: $OPS | $(echo $ARG | tr -d '\n')" fi if [ "$OPS" -lt "$MIN" ]; then MIN=$OPS fi if [ "$OPS" -gt 5500 ]; then ABOVE_5500_COUNT=$((ABOVE_5500_COUNT + 1)) fi if [ "$OK" != "OK" ]; then echo "================================" echo "Error" echo "Args: $ARG" echo "Ops: $OPS" echo "Checker: $OK" echo "================================" fi fi done AVG=$((AVG / ITER)) VARIANCE=$((SUM_SQUARES / ITER - AVG * AVG)) STDDEV=$(echo "sqrt($VARIANCE)" | bc -l) echo -e "Testing\t $BOLD$N \telements $ITER times:$NC \t\tmax:$GREEN $MAX$NC\t\tmin:$RED $MIN$NC\t\tavg: $AVG\t\tstddev: $(printf "%.2f" $STDDEV)" # echo "Iterations: $ITER" # echo "Max: $MAX" # echo "Min: $MIN" # echo "Average: $AVG" # echo "--------------------------------" # echo "Max Args: $MAX_ARGS" # echo "--------------------------------" # if [ "$N" -eq 500 ]; then # echo "Number of tests with OPS > 5500: $ABOVE_5500_COUNT" # echo "--------------------------------" # fi # echo "" # Clean up rm -rf "$TMP_DIR" } check_output() { local output=$1 local expected=$2 local message=$3 if [ "$output" == "$expected" ]; then echo -e "${message}: ${GREEN}OK${NC}" else echo -e "${message}: ${RED}KO${NC}" fi } # Test push_swap with non-numeric arguments ARGS="a b c" OUTPUT=$(./push_swap $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "1. Test push_swap with non-numeric arguments" # Test push_swap with duplicate arguments ARGS="1 1 2 3" OUTPUT=$(./push_swap $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "2. Test push_swap with duplicate arguments" # Test push_swap with empty arguments OUTPUT=$(./push_swap 2>&1 >/dev/null) check_output "$OUTPUT" "" "3. Test push_swap with empty arguments" # Test push_swap with invalid arguments ARGS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 a" OUTPUT=$(./push_swap $ARGS 2>&1) check_output "$OUTPUT" "Error" "4. Test push_swap with invalid arguments" # Test push_swap with valid arguments ARGS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" OUTPUT=$(./push_swap $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "" "5. Test push_swap with valid arguments" # Run push_swap with only numeric parameters including one greater than MAXINT. The program must display "Error". OUTPUT=$(./push_swap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 999999999999999 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "6. Test push_swap with only numeric parameters including one greater than MAXINT" # Run the following command "$>./push_swap 42". The program should display nothing (0 instruction). OUTPUT=$(./push_swap 42 2>&1 >/dev/null) check_output "$OUTPUT" "" "7. Test push_swap with a single argument" # Run the following command "$>./push_swap 2 3". The program should display nothing (0 instruction). OUTPUT=$(./push_swap 2 3 2>&1 >/dev/null) check_output "$OUTPUT" "" "8. Test push_swap with two ordered arguments" # Run the following command "$>./push_swap 0 1 2 3". The program should display nothing (0 instruction). OUTPUT=$(./push_swap 0 1 2 3 2>&1 >/dev/null) check_output "$OUTPUT" "" "9. Test push_swap with four ordered arguments" # Run the following command "$>./push_swap 'Between 0 and 9 randomly sorted values chosen>'. The program should display nothing (0 instruction). OUTPUT=$(./push_swap 11 22 33 44 55 66 77 88 99 2>&1 >/dev/null) check_output "$OUTPUT" "" "10. Test push_swap with nine ordered arguments" # Run the following command "$>./push_swap 0 1 2 3 4 5 6 7 8 9". The program should display nothing (0 instruction). OUTPUT=$(./push_swap 0 1 2 3 4 5 6 7 8 9 2>&1 >/dev/null) check_output "$OUTPUT" "" "11. Test push_swap with ten ordered arguments" # Test checker with non-numeric arguments ARGS="a b c" OUTPUT=$(./checker $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "12. Test checker with non-numeric arguments" # Test checker with duplicate arguments ARGS="1 1 2 3" OUTPUT=$(./checker $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "13. Test checker with duplicate arguments" # Test checker with empty arguments OUTPUT=$(./checker 2>&1 >/dev/null) check_output "$OUTPUT" "" "14. Test checker with empty arguments" # Test checker with invalid arguments ARGS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 a" OUTPUT=$(./checker $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "15. Test checker with invalid arguments" # Test checker with valid arguments ARGS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" OUTPUT=$(./push_swap $ARGS | ./checker $ARGS) check_output "$OUTPUT" "OK" "16. Test push_swap and checker with ordered list" # Run "$>ARG="2 1 0"; ./push_swap $ARG | ./checker_OS $ARG". Check that the checker program displays "OK" and that the size of the list of instructions from push_swap is 2 OR 3. Otherwise the test fails. OUTPUT=$(ARG="2 1 0"; ./push_swap $ARG | ./checker $ARG) check_output "$OUTPUT" "OK" "17. Run \"$>ARG=\"2 1 0\"; ./push_swap \$ARG | ./checker_OS \$ARG\". Check that the checker program displays \"OK\"" OUTPUT=$(ARG="2 1 0"; ./push_swap $ARG | wc -l) if [ "$OUTPUT" -lt 3 ]; then echo -e "18. The size of the list of instructions from push_swap is less than 3: ${GREEN}OK${NC}" else echo -e "18. The size of the list of instructions from push_swap is less than 3: ${RED}KO${NC}" fi # Run "$>ARG="1 5 2 4 3"; ./push_swap $ARG | ./checker_OS $ARG". Check that the checker program displays "OK" and that the size of the list of instructions from push_swap is 12. Otherwise the test fails. OUTPUT=$(ARG="1 5 2 4 3"; ./push_swap $ARG | ./checker $ARG) check_output "$OUTPUT" "OK" "19. Run \"$>ARG=\"1 5 2 4 3\"; ./push_swap \$ARG | ./checker_OS \$ARG\". Check that the checker program displays \"OK\"" OUTPUT=$(ARG="1 5 2 4 3"; ./push_swap $ARG | wc -l) if [ "$OUTPUT" -lt 12 ]; then echo -e "20. The size of the list of instructions from push_swap is less than 12: ${GREEN}OK${NC}" else echo -e "20. The size of the list of instructions from push_swap is less than 12: ${RED}KO${NC}" fi # Run checker with valid parameters and an invalid action ARGS="1 2 3" ACTIONS="invalid_action" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "21. Run checker with valid parameters and an invalid action" # Run checker with valid parameters and an action with spaces ARGS="1 2 3" ACTIONS=" sa \npb\nrrr " OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS 2>&1 >/dev/null) check_output "$OUTPUT" "Error" "22. Run checker with valid parameters and an action with spaces" # Run checker with a specific command and action list ARGS="0 9 1 8 2 7 3 6 4 5" ACTIONS="sa\npb\nrrr\n" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "KO" "23. Run checker with specific command and action list" # Run checker with a valid list and a valid instruction list that doesn't order the integers ARGS="4 3 2 1" ACTIONS="sa\npb\nra\nrra\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "KO" "24. Run checker with valid list and invalid instruction list" ARGS="5 1 3 2 4" ACTIONS="pb\npb\nsa\npa\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "KO" "25. Run checker with valid list and invalid instruction list" ARGS="6 5 4 3 2 1" ACTIONS="pb\npb\npb\nsa\npa\npa\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "KO" "26. Run checker with valid list and invalid instruction list" # Run checker with no instructions ARGS="0 1 2" OUTPUT=$(echo -e "" | ./checker $ARGS) check_output "$OUTPUT" "OK" "27. Run checker with no instructions" # Run checker with a specific command and valid action list ARGS="0 9 1 8 2" ACTIONS="pb\nra\npb\nra\nsa\nra\npa\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "OK" "28. Run checker with specific command and valid action list" # Run checker with a valid list and a valid instruction list that orders the integers ARGS="3 2 1" ACTIONS="sa\nra\nsa\nrra" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "OK" "29. Run checker with valid list and valid instruction list" ARGS="4 1 3 2" ACTIONS="pb\npb\nsa\npa\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "OK" "30. Run checker with valid list and valid instruction list" ARGS="5 4 3 2 1" ACTIONS="pb\npb\npb\nsa\npa\npa\npa" OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "OK" "31. Run checker with valid list and valid instruction list" # Repeat the test with several permutations for i in {1..5}; do ARGS=$(seq 1 5 | shuf | tr '\n' ' ') ACTIONS=$(./push_swap $ARGS) OUTPUT=$(echo -e "$ACTIONS" | ./checker $ARGS) check_output "$OUTPUT" "OK" "32. Run checker with random permutation $i" done run_test_case 3 100 run_test_case 5 100 run_test_case 7 100 run_test_case 10 100 run_test_case 50 1 run_test_case 100 1 run_test_case 500 1