חזור לתיקייה: גליון 1

tester

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה

    tester

    02340124

    מבוא לתכנות מערכות

    רשימות הרצאה לקריאה בשבת

    tester

    הופק מתוך תקיית התואר של שקד

    uni-folder.vercel.app

    tester.sh

    הערה (קובץ קוד)

    קובץ זה הוא קובץ קוד מסוג BASH.

    #!/bin/bash
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    NC='\033[0m' # No Color
    
    show_help() {
        echo "Usage: $0 -e <executable> -i <input_dir> -o <expected_dir>"
        echo ""
        echo "This script runs an executable on each input file (.in) in the input directory, compares the output with the expected file (.expected), and checks for memory leaks. Ensure each input file has a corresponding expected output file with the same name and a (.expected) extension."
        echo "The script also supports pretest and posttest scripts, such as a shell script to compile the executable. Simply provide a script with the same name as the executable, ending in _pre.sh for pretest and _post.sh for posttest."
    
        echo ""
        echo -n
        echo "Options:"
        echo "  -h                Show this help message"
        echo "Arguments:"
        echo "  -e <executable>   The executable to run the tests on"
        echo "  -i <input_dir>    The directory containing the test input files"
        echo "  -o <expected_dir> The directory containing the expected output files"
    }
    
    run_test() {
        local test_type=$2
        local test_script="${1%.*}_${test_type}.sh"
        
        if [ -f "$test_script" ]; then
            echo -n "Running ${test_type}: "
            ./"$test_script"
            
            if [ $? -eq 0 ]; then
                printf "${GREEN}done${NC}\n"
            else
                printf "${RED}error${NC}\n"
                exit 1
            fi
        fi
    }
    
    run_pretest() {
        run_test "$1" "pre"
    }
    
    run_posttest() {
        run_test "$1" "post"
    }
    
    check_memory_leaks() {
        local log_file=$1
        local check_str=$2
    
        if grep -q "$check_str" "$log_file"; then
            printf "Leak: ${GREEN}pass${NC}\n"
        else
            printf "Leak: ${RED}fail${NC}\n"
            # cat "$log_file"
            RET=1
        fi
    }
    
    while getopts ":he:i:o:" opt; do
        case ${opt} in
            h )
                show_help
                exit 0
                ;;
            e )
                executable=$OPTARG
                ;;
            i )
                input_dir=$OPTARG
                ;;
            o )
                expected_output_dir=$OPTARG
                ;;
            \? )
                echo "Error: Invalid option '-$OPTARG'" 1>&2
                show_help
                exit 1
                ;;
            : )
                echo "Error: Option '-$OPTARG' requires an argument" 1>&2
                show_help
                exit 1
                ;;
        esac
    done
    shift $((OPTIND -1))
    
    # Check if required arguments are provided
    if [ -z "${executable}" ] || [ -z "${input_dir}" ] || [ -z "${expected_output_dir}" ]; then
        echo "Error: Missing required arguments"
        show_help
        exit 1
    fi
    
    # Ensure all files in input_dir have .in extension and corresponding .expected files in expected_output_dir
    for file in "${input_dir}"/*; do
        if  ! "${file}" == *.in ; then
            echo "Error: All files in ${input_dir} must have a .in extension"
            exit 1
        fi
        basefile=$(basename "${file}" .in)
        expected_file="${expected_output_dir}/${basefile}.expected"
        if  ! -f "${expected_file}" ; then
            echo "Error: Missing corresponding expected output file for ${file}"
            exit 1
        fi
    done
    
    # Check if running on macOS
    IS_MAC=0
    if  "$(uname)" == "Darwin" ; then
        IS_MAC=1
    fi
    
    shopt -s nullglob
    RET=0
    
    for i in ${input_dir}/*.in
    do
        printf "test $i >>>  \n"
    
        # Run pretest script if it exists
        run_pretest $i
        
        base_filename=$(basename "$i" .in)
        # Execute the main executable with the input file and create an output file
        ./${executable} < $i > ${base_filename}.out
        # Compare the output file with the expected output file
        diff ${base_filename}.out ${expected_output_dir}/${base_filename}.expected
        if [ $? -ne 0 ]; then
            printf "${RED}Diff failed${NC}\n"
            RET=1
        else
            printf "Diff: ${GREEN}pass${NC}\n"
        fi
    
        rm ${base_filename}.out
    
        
        if [ $IS_MAC -eq 0 ]; then
            # Perform memory leak check using valgrind if not on macOS
            valgrind_command="valgrind --leak-check=full ./${executable} < $i &> ${base_filename}.valgrind_log"
            eval $valgrind_command > /dev/null 2>&1
            check_memory_leaks "${base_filename}.valgrind_log" "ERROR SUMMARY: 0"
            rm "${base_filename}.valgrind_log"
        else
            # Perform memory leak check on macOS
            leaks_command="MallocStackLogging=1 leaks -quiet --atExit -- ./${executable} < $i &> ${base_filename}.leaks_log"
            # Execute the command and redirect both stdout and stderr to /dev/null to suppress all output
            eval $leaks_command > /dev/null 2>&1
            check_memory_leaks "${base_filename}.leaks_log" "0 leaks for 0 total leaked bytes"
            rm "${base_filename}.leaks_log"
        fi
    
        # Run posttest script if it exists
        run_posttest $i
    done
    
    exit $RET