#!/bin/bash # This script was automatically generated: Sat Mar 19 22:08:41 AEST 2022 # by uqpsutto OUTPUT_DIR=$(date +"/tmp/2310test%Y%m%d-%H%M%S") # Environment Variables: export LD_LIBRARY_PATH='/local/courses/csse2310/lib' # Common functions # Error handling backtrace code (modified from # https://stackoverflow.com/questions/25492953) function backtrace () { local deptn=${#FUNCNAME[@]} for ((i=2; i<$deptn; i++)); do local func="${FUNCNAME[$i]}" local line="${BASH_LINENO[$((i-1))]}" local src="${BASH_SOURCE[$i]}" printf '%*s' $i '' >&2 # indent echo "at: $func(), $src, line $line" >&2 done } set -o errtrace # Usage: error_exit # Prints message to stderr and exits with the given code function error_exit() { code="$1" shift echo "${bold}$@${normal}" >&2 backtrace exit ${code} } # Usage assert [-code ] [-m ] ... # Checks that the execution of the given command results in a "true" result # If not, prints the given message (or the command that failed) and # exits with the given code (or 1) function assert() { unset message code=1 # Default exit code while true; do case "$1" in "-code") code="$2"; shift 2;; "-m") message="$2"; shift 2;; *) break;; esac done # Run the command to check if ! "$@" &>/dev/null ; then if isset message ; then error_exit "${code}" "$message" else error_exit "${code}" "Assertion failed (${code}): ${*@Q}" fi fi } # Usage: isset # Returns true if variable name is set, false otherwise function isset() { #!1 does indirection - name replaced by $1 #+x will substitute variable value (if set) by x, if unset no change test -n "${!1+x}" } # Usage: is_integer # Returns true if the given string is a non-negative integer, false otherwise function is_integer() { [[ $1 =~ ^[0-9]+$ ]] } # Usage: is_number # Returns true if the given string is a non-negative integer or a floating # point number expressed with a decimal point and optional digits after the # decimal point. Returns false otherwise. function is_number() { [[ $1 =~ ^[0-9]+(\.[0-9]*)?$ ]] } # Usage: is_testid # Returns true if the given string is of the form category-num.test-num. # (No leading zeroes permitted.) # Returns false otherwise. function is_testid() { [[ $1 =~ ^[1-9][0-9]*\.[1-9][0-9]*$ ]] } # Usage: is_command # Checks whether the given string is an executable command function is_command() { type "$1" &>/dev/null } # Usage: get_test_num_from_id # testid should be of the form category-number.test-number. (If not, this # function exits the program.) Prints the test-number component after the # decimal point. function get_test_num_from_id() { assert is_testid $1 echo "$1" | cut -d . -f 2 } # Usage: get_category_num_from_id # testid should be of the form category-number.test-number. (If not, this # function exits the program.) Prints the category-number component before # the decimal point. function get_category_num_from_id() { assert is_testid $1 echo "$1" | cut -d . -f 1 } # Usage: indent # Reads stdin, and echoes to stdout with 4 spaces at the start of each line function indent() { sed 's/^/ /' } # Definitions of terminal colour and styling constants # #Based on the Stack Overflow answer at # https://unix.stackexchange.com/questions/9957/how-to-check-if-bash-can-print-colors if test -t 1 ; then # stdout is a tty normal="$(tput sgr0)" bold="$(tput bold)" underline="$(tput smul)" # Foreground colours black="$(tput setaf 0)" red="$(tput setaf 1)" green="$(tput setaf 2)" yellow="$(tput setaf 3)" blue="$(tput setaf 4)" magenta="$(tput setaf 5)" cyan="$(tput setaf 6)" white="$(tput setaf 7)" else normal="" bold="" underline="" black="" red="" green="" yellow="" blue="" magenta="" cyan="" white="" fi # Functions and definitions used by testing scripts # By default we send fd 100 to /dev/null. (Sent elsewhere in autograde scripts.) jsonfd=100 eval "exec ${jsonfd}>/dev/null" # Usage: cleanup # Function is called on exit function cleanup() { echo "Cleaning up ..." rm -f -r ${OUTPUT_DIR} echo "Done" } /local/courses/csse2310/bin/csse2310logusage 2>/dev/null trap cleanup EXIT # Usage: check_usage command-line-arguments # Prints the action to be taken: run_test or explain_test or mark_test # (mark_test is the default if the command name begins with mark or autograde) # Overwrites TESTS_TO_RUN if tests are listed on the command line function check_usage() { if [[ $(basename "$0") =~ ^(mark|repmark|autograde).* ]] ; then action=mark_test extrausagetext='|mark' else action=run_test fi if [ "$1" ] ; then # At least one argument supplied - it must be "run", "explain" or "mark" case "$1" in run) action="run_test";; explain) action="explain_test";; mark) action="mark_test";; *) echo "Usage: $0 [run|explain${extrausagetext} [testid ...]]" >&2 exit 1 ;; esac if [ "$2" ] ; then # Have one or more arguments - tests to run shift # expand any single numbers to all subtests rm -f /tmp/tests_to_run touch /tmp/tests_to_run for i in "$@" ; do if is_integer "$i" ; then echo $TESTS_TO_RUN | tr ' ' '\n' | grep "^${i}\." >> /tmp/tests_to_run else echo $i >> /tmp/tests_to_run fi done TESTS_TO_RUN=$(cat /tmp/tests_to_run) rm -f /tmp/tests_to_run fi fi } # Usage: setup_for_testing # Creates a symlink to the testfiles and creates the output directory function setup_for_testing() { assert isset TESTFILES_DIR assert isset OUTPUT_DIR echo "Setting up for tests" echo "Time: $(TZ=AEST-10 date)" if [ -f .username ] ; then echo "User: $(cat .username)" fi if [ -L testfiles ] ; then rm testfiles || error_exit 1 "Unable to remove existing testfiles link" fi ln -s -T "${TESTFILES_DIR}" testfiles &>/dev/null || error_exit 1 "Unable to create symbolic link 'testfiles'" mkdir -p "${OUTPUT_DIR}" || error_exit 1 "Unable to create temporary output directory" } # Usage: do_svn_checkout function do_svn_checkout() { echo "${bold}Checking out code from SVN repo to $2 ...${normal}" if [ ! "${SVN_REVISION}" ] ; then SVN_REVISION=head fi if ! svn checkout --depth files "$1" -r ${SVN_REVISION} "$2"; then error_exit 2 "Failed to checkout repository" fi } # Usage: do_make function do_make() { echo "${bold}Running make...${normal}" if ! make ; then error_exit 3 "Make failed" fi } # Usage: run_cmd_and_save_output ... # Stdout is saved to /.stdout # Stderr is saved to /.stderr # Exit code is returned # cmd may include environment variable definitions function run_cmd_and_save_output() { # Check timeout value is valid assert -code 11 is_number "$1" timeout="$1" # Check testid has valid format (num.num) assert -code 12 is_testid "$2" testid="$2" # Make sure the output directory already exists assert -code 13 test -d "$3" outputdir="$3" shift 3 # Consume the first three arguments # Run the command - with a timeout # We run in a subshell and send shell error messages to /dev/null # We first determine whether any of the arguments are setting envirovnment # variables and we set those ( if isset FILESIZELIMIT ; then ulimit -f ${FILESIZELIMIT} fi while [[ "$1" =~ ^[A-Za-z][A-Za-z0-9_]*=.*$ ]] ; do export ${1%%=*}=${1#*=} shift done exec 2>/dev/null; timeout ${timeout} "${@}" \ > "${outputdir}/${testid}.stdout" \ 2> "${outputdir}/${testid}.stderr" ) # Will return with exit code of this last command } # Usage: compare_files stdout|stderr|filename \ # # Compares the given files and outputs summary line if differ # Returns true (0) if files both match, false otherwise function compare_files() { assert -code 16 test -f "$2" if [ ! -f "$3" ] ; then echo "Expected output file $1 not found" return 1 elif ! diff -q "$2" "$3" &>/dev/null; then if [ "$1" = "stdout" -o "$1" = "stderr" ] ; then echo "Mismatch on $1" else echo "Mismatch in file $1" fi return 1 else return 0 fi } # Usage: check_program_output command stdout-file stderr-file # Expect the command to return true - print message if not. # The given file containing stdout from the test will be supplied as stdin # for program. The given file containing stderr from the test will be supplied # on file desciptor 3. function check_program_output() { if ! "$1" <"$2" 3<"$3"&>/dev/null; then echo "Program '$1' returned false" return 1; else return 0; fi } # Usage: explain_exitcode # Prints an explanation of an erroneous code with a preceding space - or # no explanation if the code is not erroneous function explain_exitcode() { assert -code 20 is_integer "$1" actual="$1" if [[ $actual -eq 124 ]] ; then explanation=" (Timeout)" elif [[ $actual -eq 126 ]] ; then explanation=" (Command not executable)" elif [[ $actual -eq 127 ]] ; then explanation=" (Command not found)" elif [[ $actual -eq 135 ]] ; then explanation=" (Bus Error)" elif [[ $actual -eq 139 ]] ; then explanation=" (Segmentation fault)" elif [[ $actual -eq 153 ]] ; then explanation=" (File size limit (${FILESIZELIMIT}k) exceeded)" elif [[ $actual -ge 129 && $actual -le 160 ]] ; then explanation=" (SIG"$(kill -l $(($actual - 128)) 2>/dev/null)" signal)" else explanation="" fi echo ${explanation} } # Usage: compare_exitcodes # Compares the two exit codes - outputs a summary if they differ # Returns true (0) if they match, false otherwise function compare_exitcodes() { assert -code 20 is_integer "$1" assert -code 21 is_integer "$2" expected=$1 actual=$2 # Expected exit code should be less than 124 assert -code 22 test $expected -lt 124 if [[ $actual -ne $expected ]] ; then explanation=$(explain_exitcode $actual) echo "Got exitcode ${actual}${explanation} - but expected ${expected}" return 1 else return 0 fi } # Usage run_test # [-exit ] # [-stdout ] # [-stderr ] # [-file ] # [-prog command] ... # ... # Note argument format is the same as for explain_test below so that they # can be called with the one command. function run_test() { assert -code 25 is_testid "$1" testid="$1" testname="$2" testdescription="$3" # Not needed in this function shift 3 assert -code 28 is_number "$TIMEOUT" unset check expected progs declare -a check declare -A expected declare -a progs while [ "${1:0:1}" = "-" ] ; do case "$1" in "-exit" ) expected[exit]="$2" assert -code 26 is_integer "$2" assert -code 29 [ "$2" -lt 124 ] shift 2 ;; "-stdout" ) check+=(stdout) expected[stdout]="$2" assert -code 27 test -f "$2" shift 2 ;; "-stderr" ) check+=(stderr) expected[stderr]="$2" assert -code 27 test -f "$2" shift 2 ;; "-file" ) check+=("$2") expected["$2"]="$3" assert -code 27 test -f "$3" shift 3 ;; "-prog" ) progs+=("$2") assert -code 27 is_command "$2" shift 2 ;; *) error_exit 1 "Illegal argument to run_test: $1" esac done outputdir="$1" shift printf "%-5s - %-52s" "${testid}" "${testname}" run_cmd_and_save_output ${TIMEOUT} ${testid} "${outputdir}" "$@" actual_exitcode=$? rm -f "${outputdir}/.details" touch "${outputdir}/.details" declare -i result=0 # Declare result to be an integer if [ "${expected[exit]}" ] ; then compare_exitcodes ${expected[exit]} ${actual_exitcode} \ >> "${outputdir}/.details" result+=$? elif [[ "$actual_exitcode" -ge 124 ]] ; then error_explanation=$(explain_exitcode "$actual_exitcode") if [ "${error_explanation}" ] ; then # We didn't have to check an exit code - but we got a # timeout or command not found or signal... result+=1 echo "Got unexpected exitcode ${actual_exitcode}${error_explanation}" \ >> "${outputdir}/.details" fi fi if [[ "$actual_exitcode" -lt 124 ]] ; then # Check files as required for file in "${check[@]}" ; do if [ "$file" = "stdout" -o "$file" = "stderr" ] ; then # Check stdout or stderr compare_files $file "${expected[$file]}" \ "${outputdir}/${testid}.${file}" >> "${outputdir}/.details" result+=$? else # Check file compare_files $file "${expected[$file]}" \ "${file}" >> "${outputdir}/.details" result+=$? fi done # Check programs for prog in "${progs[@]}" ; do check_program_output "${prog}" "${outputdir}/${testid}.stdout" \ "${outputdir}/${testid}.stderr" >> "${outputdir}/.details" result+=$? done fi if [[ "$result" -eq 0 ]] ; then echo "${bold}${green}PASS${normal}" else echo "${bold}${red}FAIL${normal}" cat "${outputdir}/.details" | indent fi rm -f "${outputdir}/.details" } # Usage: explain_test # [-exit ] # [-stdout ] # [-stderr ] # [-file ] # [-prog command] # ... function explain_test() { assert -code 30 is_testid "$1" testid="$1" testname="$2" test_description="$3" shift 3 echo "${green}${bold}=== ${testid} - ${testname} ===${normal}" echo "${bold}Description:${normal} ${test_description}" | fmt msg="" while [ "${1:0:1}" = "-" ] ; do case "$1" in "-exit" ) msg+=" Expect exit code: $2"$'\n'; assert -code 31 is_integer "$2" shift 2;; "-stdout" ) msg+=" Standard output (${testid}.stdout) should match $2"$'\n' shift 2;; "-stderr" ) msg+=" Standard error (${testid}.stderr) should match $2"$'\n' shift 2;; "-file" ) msg+=" Contents of file '$2' should match $3"$'\n' shift 3;; "-prog" ) msg+=" Result of running '$2' should be true (exit status 0)"$'\n' shift 2;; * ) error_exit 1 "Illegal argument to explain_test: $1" esac done outputdir="$1" cmd="$2" shift 2 echo "${bold}What the test runs:${normal}" echo " ${cmd} ${*@Q} > ${testid}.stdout 2>" \ "${testid}.stderr" echo "${bold}What the test checks:${normal}" echo "${msg}" echo } # Usage: do_tests function do_tests() { if [[ "${action}" =~ ^(run|mark).* ]] ; then # Action is to run or mark tests, not explain tests - make sure we have a # program to test do_make echo "${bold}Running tests ... ${normal}" fi echo "----------------------------------------------------------------------" for i in $TESTS_TO_RUN ; do cmd="test${i}" if [[ $(type -t ${cmd}) = "function" ]]; then "${cmd}" "${action}" else error_exit 4 "Test ${i} is not known" fi done echo "----------------------------------------------------------------------" } # Tests for category 1 - invalid_usage # Details for test 1.1. ($1 will be run_test or explain_test) function test1.1() { "$1" 1.1 "invalid_usage01" "Check that args 'one two' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'one' 'two' } # Details for test 1.2. ($1 will be run_test or explain_test) function test1.2() { "$1" 1.2 "invalid_usage02" "Check that args 'one two three' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'one' 'two' 'three' } # Details for test 1.3. ($1 will be run_test or explain_test) function test1.3() { "$1" 1.3 "invalid_usage03" "Check that args 'one two three four' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'one' 'two' 'three' 'four' } # Details for test 1.4. ($1 will be run_test or explain_test) function test1.4() { "$1" 1.4 "invalid_usage04" "Check that args 'one two three four five' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'one' 'two' 'three' 'four' 'five' } # Details for test 1.5. ($1 will be run_test or explain_test) function test1.5() { "$1" 1.5 "invalid_usage05" "Check that args 'one two three four five six' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'one' 'two' 'three' 'four' 'five' 'six' } # Details for test 1.6. ($1 will be run_test or explain_test) function test1.6() { "$1" 1.6 "invalid_usage06" "Check that args '-max' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' } # Details for test 1.7. ($1 will be run_test or explain_test) function test1.7() { "$1" 1.7 "invalid_usage07" "Check that args '-len' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' } # Details for test 1.8. ($1 will be run_test or explain_test) function test1.8() { "$1" 1.8 "invalid_usage08" "Check that args '-max nonnumber' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' 'nonnumber' } # Details for test 1.9. ($1 will be run_test or explain_test) function test1.9() { "$1" 1.9 "invalid_usage09" "Check that args '-len nonnumber' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' 'nonnumber' } # Details for test 1.10. ($1 will be run_test or explain_test) function test1.10() { "$1" 1.10 "invalid_usage10" "Check that args '-max 5 -len' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '5' '-len' } # Details for test 1.11. ($1 will be run_test or explain_test) function test1.11() { "$1" 1.11 "invalid_usage11" "Check that args '-max 2' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '2' } # Details for test 1.12. ($1 will be run_test or explain_test) function test1.12() { "$1" 1.12 "invalid_usage12" "Check that args '-max 10' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '10' } # Details for test 1.13. ($1 will be run_test or explain_test) function test1.13() { "$1" 1.13 "invalid_usage13" "Check that args '-max 3abc' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '3abc' } # Details for test 1.14. ($1 will be run_test or explain_test) function test1.14() { "$1" 1.14 "invalid_usage14" "Check that args '-max 3 dictionary extra-arg' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '3' 'dictionary' 'extra-arg' } # Details for test 1.15. ($1 will be run_test or explain_test) function test1.15() { "$1" 1.15 "invalid_usage15" "Check that args '-max 8 -len nonnumber' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '8' '-len' 'nonnumber' } # Details for test 1.16. ($1 will be run_test or explain_test) function test1.16() { "$1" 1.16 "invalid_usage16" "Check that args '-max 8 -max 8' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '8' '-max' '8' } # Details for test 1.17. ($1 will be run_test or explain_test) function test1.17() { "$1" 1.17 "invalid_usage17" "Check that args '-guess' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-guess' } # Details for test 1.18. ($1 will be run_test or explain_test) function test1.18() { "$1" 1.18 "invalid_usage18" "Check that args '-max 3 -max 5 /usr/share/dict/words' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '3' '-max' '5' '/usr/share/dict/words' } # Details for test 1.19. ($1 will be run_test or explain_test) function test1.19() { "$1" 1.19 "invalid_usage19" "Check that args '-max 5 -len 5 /usr/share/dict/words extra' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-max' '5' '-len' '5' '/usr/share/dict/words' 'extra' } # Details for test 1.20. ($1 will be run_test or explain_test) function test1.20() { "$1" 1.20 "invalid_usage20" "Check that args '-guess 8' considered invalid" \ -exit 1 \ -stdout "testfiles/empty" \ -stderr "testfiles/1.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-guess' '8' } # Tests for category 2 - invalid_file # Details for test 2.1. ($1 will be run_test or explain_test) function test2.1() { "$1" 2.1 "invalid_file01" "Dictionary 'hello.there.csse2310' unable to be opened with program args ''" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.1.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" 'hello.there.csse2310' } # Details for test 2.2. ($1 will be run_test or explain_test) function test2.2() { "$1" 2.2 "invalid_file02" "Dictionary '/does/not/exist' unable to be opened with program args ''" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.2.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '/does/not/exist' } # Details for test 2.3. ($1 will be run_test or explain_test) function test2.3() { "$1" 2.3 "invalid_file03" "Dictionary '/var/log/cron' unable to be opened with program args ''" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.3.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '/var/log/cron' } # Details for test 2.4. ($1 will be run_test or explain_test) function test2.4() { "$1" 2.4 "invalid_file04" "Dictionary '../nope' unable to be opened with program args ''" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.4.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '../nope' } # Details for test 2.5. ($1 will be run_test or explain_test) function test2.5() { "$1" 2.5 "invalid_file05" "Dictionary 'hello.there.csse2310' unable to be opened with program args '-len 4'" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.5.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' '4' 'hello.there.csse2310' } # Details for test 2.6. ($1 will be run_test or explain_test) function test2.6() { "$1" 2.6 "invalid_file06" "Dictionary '/does/not/exist' unable to be opened with program args '-len 4'" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.6.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' '4' '/does/not/exist' } # Details for test 2.7. ($1 will be run_test or explain_test) function test2.7() { "$1" 2.7 "invalid_file07" "Dictionary '/var/log/cron' unable to be opened with program args '-len 4'" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.7.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' '4' '/var/log/cron' } # Details for test 2.8. ($1 will be run_test or explain_test) function test2.8() { "$1" 2.8 "invalid_file08" "Dictionary '../nope' unable to be opened with program args '-len 4'" \ -exit 2 \ -stdout "testfiles/empty" \ -stderr "testfiles/2.8.stderr" \ "${OUTPUT_DIR}" \ "./wordle-debug" '-len' '4' '../nope' } # Tests for category 3 - prompt # Details for test 3.1. ($1 will be run_test or explain_test) function test3.1() { "$1" 3.1 "prompt01" "Check for welcome and prompt" \ -stdout "testfiles/3.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' '/dev/null' '-lines' '2' } # Details for test 3.2. ($1 will be run_test or explain_test) function test3.2() { "$1" 3.2 "prompt02" "Check for welcome and prompt 2" \ -stdout "testfiles/3.2.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' '/dev/null' '-lines' '2' '-max' '3' } # Tests for category 4 - wrong_len # Details for test 4.1. ($1 will be run_test or explain_test) function test4.1() { "$1" 4.1 "wrong_len01" "Check guess of length 4 with default word length" \ -stdout "testfiles/4.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/wronglen.1' } # Details for test 4.2. ($1 will be run_test or explain_test) function test4.2() { "$1" 4.2 "wrong_len02" "Check guess of length 0 with default word length" \ -stdout "testfiles/4.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/wronglen.2' } # Details for test 4.3. ($1 will be run_test or explain_test) function test4.3() { "$1" 4.3 "wrong_len03" "Check guesses that are too long (word length 4)" \ -stdout "testfiles/4.3.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'word' 'testfiles/wronglen.3' '-len' '4' } # Tests for category 5 - non_letters # Details for test 5.1. ($1 will be run_test or explain_test) function test5.1() { "$1" 5.1 "non_letters01" "Check program handles guesses with non letters - with args '-len 6 -max 7'" \ -stdout "testfiles/5.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/nonletters.1' } # Details for test 5.2. ($1 will be run_test or explain_test) function test5.2() { "$1" 5.2 "non_letters02" "Check program handles guesses with non letters - with args '-len 6 -max 7'" \ -stdout "testfiles/5.2.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'there' 'testfiles/nonletters.2' } # Details for test 5.3. ($1 will be run_test or explain_test) function test5.3() { "$1" 5.3 "non_letters03" "Check program handles guesses with non letters - with args '-len 6 -max 7'" \ -stdout "testfiles/5.3.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'cat' 'testfiles/nonletters.3' '-len' '3' } # Tests for category 6 - incorrect_guesses # Details for test 6.1. ($1 will be run_test or explain_test) function test6.1() { "$1" 6.1 "incorrect_guesses01" "Single invalid guess, default dictionary and other options" \ -stdout "testfiles/6.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'lines' 'testfiles/invalid.1' } # Details for test 6.2. ($1 will be run_test or explain_test) function test6.2() { "$1" 6.2 "incorrect_guesses02" "Multiple invalid guesses, default dictionary and other options" \ -stdout "testfiles/6.2.stdout" \ -exit 3 \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'guess' 'testfiles/invalid.2' } # Details for test 6.3. ($1 will be run_test or explain_test) function test6.3() { "$1" 6.3 "incorrect_guesses03" "Multiple invalid guesses, supplied dictionary and default other options" \ -stdout "testfiles/6.2.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'marks' 'testfiles/invalid.3' '/local/courses/csse2310/etc/common-words' } # Details for test 6.4. ($1 will be run_test or explain_test) function test6.4() { "$1" 6.4 "incorrect_guesses04" "Multiple invalid guesses, default dictionary, other args given" \ -stdout "testfiles/6.4.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'answer' 'testfiles/invalid.4' '-len' '6' } # Tests for category 7 - various_capitalisation # Details for test 7.1. ($1 will be run_test or explain_test) function test7.1() { "$1" 7.1 "various_capitalisation01" "Single incorrect guess, default dictionary and other options" \ -stdout "testfiles/7.1.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'hands' 'testfiles/incorrect.1' } # Details for test 7.2. ($1 will be run_test or explain_test) function test7.2() { "$1" 7.2 "various_capitalisation02" "Multiple incorrect guesses, default dictionary and other options" \ -stdout "testfiles/7.2.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'guess' 'testfiles/incorrect.2' } # Details for test 7.3. ($1 will be run_test or explain_test) function test7.3() { "$1" 7.3 "various_capitalisation03" "Multiple incorrect guesses, supplied dictionary and default other options" \ -stdout "testfiles/7.3.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'marks' 'testfiles/incorrect.3' '/local/courses/csse2310/etc/common-words' } # Details for test 7.4. ($1 will be run_test or explain_test) function test7.4() { "$1" 7.4 "various_capitalisation04" "Multiple incorrect guesses, default dictionary, other args given" \ -stdout "testfiles/7.4.stdout" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'answer' 'testfiles/incorrect.4' '-len' '6' } # Tests for category 8 - running_out_of_attempts # Details for test 8.1. ($1 will be run_test or explain_test) function test8.1() { "$1" 8.1 "running_out_of_attempts01" "Multiple incorrect guesses, default dictionary and other options" \ -exit 3 \ -stdout "testfiles/8.1.stdout" \ -stderr "testfiles/8.1.stderr" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'guess' 'testfiles/incorrect.2' } # Details for test 8.2. ($1 will be run_test or explain_test) function test8.2() { "$1" 8.2 "running_out_of_attempts02" "Multiple incorrect guesses, supplied dictionary and max 3 guesses" \ -exit 3 \ -stdout "testfiles/8.2.stdout" \ -stderr "testfiles/8.2.stderr" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'marks' 'testfiles/incorrect.3' '-max' '3' '/local/courses/csse2310/etc/common-words' } # Details for test 8.3. ($1 will be run_test or explain_test) function test8.3() { "$1" 8.3 "running_out_of_attempts03" "Multiple incorrect guesses, default dictionary, word length 6" \ -exit 3 \ -stdout "testfiles/8.3.stdout" \ -stderr "testfiles/8.3.stderr" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'answer' 'testfiles/incorrect.4' '-len' '6' } # Tests for category 9 - handles_eof # Details for test 9.1. ($1 will be run_test or explain_test) function test9.1() { "$1" 9.1 "handles_eof01" "Single blank line input before EOF" \ -exit 3 \ -stdout "testfiles/9.1.stdout" \ -stderr "testfiles/9.1.stderr" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/eof.1' } # Details for test 9.2. ($1 will be run_test or explain_test) function test9.2() { "$1" 9.2 "handles_eof02" "EOF after second guess (before newline)" \ -exit 3 \ -stdout "testfiles/9.2.stdout" \ -stderr "testfiles/9.1.stderr" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/eof.2' } # Tests for category 10 - right_answer # Details for test 10.1. ($1 will be run_test or explain_test) function test10.1() { "$1" 10.1 "right_answer01" "Correct answer on third guess" \ -exit 0 \ -stdout "testfiles/10.1.stdout" \ -stderr "testfiles/empty" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/right.1' } # Details for test 10.2. ($1 will be run_test or explain_test) function test10.2() { "$1" 10.2 "right_answer02" "Correct answer on third guess - mixed capitalisation" \ -exit 0 \ -stdout "testfiles/10.1.stdout" \ -stderr "testfiles/empty" \ "${OUTPUT_DIR}" \ "testfiles-custom/run_wordle.sh" 'right' 'testfiles/right.2' } # Tests for category 11 - repeated_letters # Tests for category 12 - memory TIMEOUT=10 TESTS_TO_RUN=' 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 3.1 3.2 4.1 4.2 4.3 5.1 5.2 5.3 6.1 6.2 6.3 6.4 7.1 7.2 7.3 7.4 8.1 8.2 8.3 9.1 9.2 10.1 10.2 ' check_usage "$@" # Now have defined 'action' and 'TESTS_TO_RUN' # 'action' will be one of 'run_test', 'explain_test' or 'mark_test' TESTFILES_DIR='/local/courses/csse2310/resources/a1/testfiles.public' # If we're running tests or marking then get setup to do so if [ $action = run_test -o $action = mark_test ] ; then setup_for_testing fi do_tests