From 951c3605b89f43a228cd6573e84d413617eb77b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Just?= Date: Fri, 6 Sep 2024 11:18:49 -0700 Subject: [PATCH] Consolidate version-3 and Java-11 branches (#594) --------- Co-authored-by: Michael Ernst --- .github/workflows/ci.yml | 3 + .../lib/test_generation/bin/_tool.source | 32 ++++---- .../lib/test_generation/bin/_tool.template | 18 ++--- framework/lib/test_generation/bin/evosuite.sh | 12 +-- framework/lib/test_generation/bin/randoop.sh | 2 + .../compile-errors/test-111-112.diff | 13 ++++ .../compile-errors/test-93-97.diff | 13 ++++ .../compile-errors/test-99-109.diff | 13 ++++ .../Mockito/chooseDepedencyVersion.sh | 6 +- .../projects/Mockito/setMutationCompiler.sh | 12 +-- framework/test/get_klocs.sh | 15 ++-- framework/test/test.include | 3 +- framework/test/test_bug_mining.sh | 77 +++++++++---------- framework/test/test_cp.sh | 14 ++-- framework/test/test_d4j_query.sh | 34 ++++---- framework/test/test_export_command.sh | 29 ++++--- framework/test/test_fix_test_suite.sh | 15 ++-- framework/test/test_gen_tests.sh | 36 ++++----- framework/test/test_mutation_analysis.sh | 8 +- framework/test/test_style.sh | 22 ++++++ framework/test/test_tutorial.sh | 10 +-- framework/test/test_verify_bugs.sh | 29 ++++--- init.sh | 4 +- 23 files changed, 247 insertions(+), 173 deletions(-) mode change 100644 => 100755 framework/lib/test_generation/bin/_tool.template create mode 100644 framework/projects/JacksonDatabind/compile-errors/test-111-112.diff create mode 100644 framework/projects/JacksonDatabind/compile-errors/test-93-97.diff create mode 100644 framework/projects/JacksonDatabind/compile-errors/test-99-109.diff create mode 100755 framework/test/test_style.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f9e5e6e2..8b42759e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,6 +62,9 @@ jobs: - run: carton exec ./test_bug_mining.sh name: test_bug_mining.sh working-directory: "./framework/test" + - run: carton exec ./test_style.sh + name: test_style.sh + working-directory: "./framework/test" # Verify a few select bugs to detect serious breakages early. - run: carton exec ./test_verify_bugs.sh -p Collections -b 10 -A diff --git a/framework/lib/test_generation/bin/_tool.source b/framework/lib/test_generation/bin/_tool.source index bd8d36fe5..991ac7f3c 100755 --- a/framework/lib/test_generation/bin/_tool.source +++ b/framework/lib/test_generation/bin/_tool.source @@ -1,3 +1,4 @@ +#!/bin/bash # # This file provides helper functions for the wrapper shell scripts of the test # generation tools. This file should be included in each wrapper shell script: @@ -22,7 +23,8 @@ die() { # Check whether an environment variable is set -- if not, die with an error message check_env() { local var="$1" - local val=$(eval echo \$$var) + local val + val="$(eval echo \$$var)" [ -z "$val" ] && die "Variable $var not set!" } @@ -30,48 +32,48 @@ check_env() { # source file of the provided class name. get_rel_src_path() { local class="$1" - local src_dir=$($D4J_HOME/framework/bin/defects4j \ - export -p dir.src.classes -w $D4J_DIR_WORKDIR 2> /dev/null) - echo "$src_dir/$(echo $class | tr '.' '/').java" + local src_dir; src_dir=$("$D4J_HOME"/framework/bin/defects4j \ + export -p dir.src.classes -w "$D4J_DIR_WORKDIR" 2> /dev/null) + echo "$src_dir/$(echo "$class" | tr '.' '/').java" } # Get the absolute path to the source file of the provided class name. get_abs_src_path() { local class="$1" - echo "$D4J_DIR_WORKDIR/$(get_rel_src_path $class)" + echo "$D4J_DIR_WORKDIR/$(get_rel_src_path "$class")" } # Get the project classpath -- that is, the classpath to compile and run the # checked-out Defects4J project version. get_project_cp() { - $D4J_HOME/framework/bin/defects4j \ - export -p cp.compile -w $D4J_DIR_WORKDIR 2> /dev/null + "$D4J_HOME"/framework/bin/defects4j \ + export -p cp.compile -w "$D4J_DIR_WORKDIR" 2> /dev/null } # Parse a tool's config file: ignore comments and replace newlines with spaces. parse_config() { local file=$1 - grep -v "\s*#" $file | tr '\n' ' ' + grep -v "\s*#" "$file" | tr '\n' ' ' } # Returns the list of all classes for the current bug get_all_classes() { - local src_dir=$($D4J_HOME/framework/bin/defects4j \ - export -p dir.src.classes -w $D4J_DIR_WORKDIR 2> /dev/null) - (cd $D4J_DIR_WORKDIR/$src_dir && \ + local src_dir; src_dir=$("$D4J_HOME"/framework/bin/defects4j \ + export -p dir.src.classes -w "$D4J_DIR_WORKDIR" 2> /dev/null) + (cd "$D4J_DIR_WORKDIR/$src_dir" && \ find . -name "*.java" | tr '/' '.' | sed -e 's/^\.*//g' | sed -e 's/\.java//g') } # Returns the list of all relevant classes for the current bug get_relevant_classes() { - $D4J_HOME/framework/bin/defects4j \ - export -p classes.relevant -w $D4J_DIR_WORKDIR 2> /dev/null + "$D4J_HOME"/framework/bin/defects4j \ + export -p classes.relevant -w "$D4J_DIR_WORKDIR" 2> /dev/null } # Returns the list of all modified classes for the current bug get_modified_classes() { - $D4J_HOME/framework/bin/defects4j \ - export -p classes.modified -w $D4J_DIR_WORKDIR 2> /dev/null + "$D4J_HOME"/framework/bin/defects4j \ + export -p classes.modified -w "$D4J_DIR_WORKDIR" 2> /dev/null } # Output a command, execute it, and print whether it succeeded or failed. diff --git a/framework/lib/test_generation/bin/_tool.template b/framework/lib/test_generation/bin/_tool.template old mode 100644 new mode 100755 index 7e86d3218..7be46cf81 --- a/framework/lib/test_generation/bin/_tool.template +++ b/framework/lib/test_generation/bin/_tool.template @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Wrapper script for # @@ -26,25 +26,25 @@ if [ -z "$D4J_DIR_TESTGEN_BIN" ]; then fi # General helper functions -source $D4J_DIR_TESTGEN_BIN/_tool.source +source "$D4J_DIR_TESTGEN_BIN"/_tool.source # The classpath to compile and run the project -project_cp=$(get_project_cp) +project_cp="$(get_project_cp)" # Read all additional configuration parameters -add_config=$(parse_config $D4J_DIR_TESTGEN_BIN/.config) +add_config=$(parse_config "$D4J_DIR_TESTGEN_BIN"/.config) # Make sure the provided test mode is supported -if [ $D4J_TEST_MODE == "regression" ]; then - ... -elif [ $D4J_TEST_MODE == "error-revealing" ]; then - ... +if [ "$D4J_TEST_MODE" = "regression" ]; then + : # TODO ... +elif [ "$D4J_TEST_MODE" = "error-revealing" ]; then + : # TODO ... else die "Unsupported test mode: $D4J_TEST_MODE" fi # The command that invokes the test generator -cmd="... $add_config" +cmd="... $add_config ... $project_cp ..." # Run the test-generation command if ! exec_cmd "$cmd"; then diff --git a/framework/lib/test_generation/bin/evosuite.sh b/framework/lib/test_generation/bin/evosuite.sh index e44d3b048..3a1a3fafc 100755 --- a/framework/lib/test_generation/bin/evosuite.sh +++ b/framework/lib/test_generation/bin/evosuite.sh @@ -26,16 +26,16 @@ if [ -z "$D4J_DIR_TESTGEN_BIN" ]; then fi # General helper functions -source $D4J_DIR_TESTGEN_BIN/_tool.source +source "$D4J_DIR_TESTGEN_BIN"/_tool.source # The classpath to compile and run the project project_cp=$(get_project_cp) # Read all additional configuration parameters -add_config=$(parse_config $D4J_DIR_TESTGEN_BIN/evosuite.config) +add_config=$(parse_config "$D4J_DIR_TESTGEN_BIN"/evosuite.config) # Make sure the provided test mode is supported -if [ $D4J_TEST_MODE != "regression" ]; then +if [ "$D4J_TEST_MODE" != "regression" ]; then die "Unsupported test mode: $D4J_TEST_MODE" fi @@ -47,10 +47,12 @@ if [[ $(tail -c1 "$D4J_FILE_TARGET_CLASSES" | wc -l) -eq 0 ]]; then fi # Compute the budget per target class; evenly split the time for search and assertions -num_classes=$(cat $D4J_FILE_TARGET_CLASSES | wc -l) +num_classes=$(wc -l < "$D4J_FILE_TARGET_CLASSES") budget=$(echo "$D4J_TOTAL_BUDGET/2/$num_classes" | bc) -for class in $(cat $D4J_FILE_TARGET_CLASSES); do +# shellcheck disable=SC2013 # reading words rather than lines, I suppose +for class in $(cat "$D4J_FILE_TARGET_CLASSES"); do + #shellcheck disable=SC2153 # D4J_DIR_TESTGEN_LIB is not a typo of D4J_DIR_TESTGEN_BIN cmd="java -cp $D4J_DIR_TESTGEN_LIB/evosuite-current.jar org.evosuite.EvoSuite \ -class $class \ -projectCP $project_cp \ diff --git a/framework/lib/test_generation/bin/randoop.sh b/framework/lib/test_generation/bin/randoop.sh index e296e477d..e5562199b 100755 --- a/framework/lib/test_generation/bin/randoop.sh +++ b/framework/lib/test_generation/bin/randoop.sh @@ -62,8 +62,10 @@ REG_BASE_NAME=RegressionTest ERR_BASE_NAME=ErrorTest # Print Randoop version +#shellcheck disable=SC2153 # D4J_DIR_TESTGEN_LIB is not a typo of D4J_DIR_TESTGEN_BIN version=$(java -cp "$D4J_DIR_TESTGEN_LIB/randoop-current.jar" randoop.main.Main | head -1) printf "\n(%s)" "$version" >&2 +# shellcheck disable=SC1083 printf ".%.0s" {1..expr 73 - length "$version"} >&2 printf " " >&2 diff --git a/framework/projects/JacksonDatabind/compile-errors/test-111-112.diff b/framework/projects/JacksonDatabind/compile-errors/test-111-112.diff new file mode 100644 index 000000000..f35630aa9 --- /dev/null +++ b/framework/projects/JacksonDatabind/compile-errors/test-111-112.diff @@ -0,0 +1,13 @@ +diff --git a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +index f7d1517ed..0fc5e357d 100644 +--- a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java ++++ b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +@@ -80,7 +80,7 @@ public class IllegalTypesCheckTest extends BaseMapTest + public void testJDKTypes1855() throws Exception + { + // apparently included by JDK? +- _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); ++// _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); + + // also: we can try some form of testing, even if bit contrived... + _testIllegalType(BogusPointcutAdvisor.class); diff --git a/framework/projects/JacksonDatabind/compile-errors/test-93-97.diff b/framework/projects/JacksonDatabind/compile-errors/test-93-97.diff new file mode 100644 index 000000000..f35630aa9 --- /dev/null +++ b/framework/projects/JacksonDatabind/compile-errors/test-93-97.diff @@ -0,0 +1,13 @@ +diff --git a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +index f7d1517ed..0fc5e357d 100644 +--- a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java ++++ b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +@@ -80,7 +80,7 @@ public class IllegalTypesCheckTest extends BaseMapTest + public void testJDKTypes1855() throws Exception + { + // apparently included by JDK? +- _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); ++// _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); + + // also: we can try some form of testing, even if bit contrived... + _testIllegalType(BogusPointcutAdvisor.class); diff --git a/framework/projects/JacksonDatabind/compile-errors/test-99-109.diff b/framework/projects/JacksonDatabind/compile-errors/test-99-109.diff new file mode 100644 index 000000000..f35630aa9 --- /dev/null +++ b/framework/projects/JacksonDatabind/compile-errors/test-99-109.diff @@ -0,0 +1,13 @@ +diff --git a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +index f7d1517ed..0fc5e357d 100644 +--- a/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java ++++ b/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java +@@ -80,7 +80,7 @@ public class IllegalTypesCheckTest extends BaseMapTest + public void testJDKTypes1855() throws Exception + { + // apparently included by JDK? +- _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); ++// _testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader"); + + // also: we can try some form of testing, even if bit contrived... + _testIllegalType(BogusPointcutAdvisor.class); diff --git a/framework/projects/Mockito/chooseDepedencyVersion.sh b/framework/projects/Mockito/chooseDepedencyVersion.sh index 6df30386f..490f70bb2 100755 --- a/framework/projects/Mockito/chooseDepedencyVersion.sh +++ b/framework/projects/Mockito/chooseDepedencyVersion.sh @@ -4,10 +4,10 @@ # $1 = workDir # $2 = D4J_HOME -cd $1 +cd "$1" || (echo "cannot cd to workdir $1" && exit 1) ./gradlew dependencies >> tmpDepend.txt if grep -q buddy tmpDepend.txt; then - version=`cat tmpDepend.txt | grep buddy | cut -d: -f 3 | head -1` - cp $2/framework/projects/Mockito/byte-buddy/byte-buddy-$version.jar $1/compileLib/ + version=$(grep buddy tmpDepend.txt | head -1 | cut -d: -f 3) + cp "$2/framework/projects/Mockito/byte-buddy/byte-buddy-$version.jar" "$1/compileLib/" fi rm tmpDepend.txt diff --git a/framework/projects/Mockito/setMutationCompiler.sh b/framework/projects/Mockito/setMutationCompiler.sh index 1073c1fe1..f598b9810 100755 --- a/framework/projects/Mockito/setMutationCompiler.sh +++ b/framework/projects/Mockito/setMutationCompiler.sh @@ -2,11 +2,13 @@ # $1 = working directory # $2 = location of Defects4J (D4J_HOME) -WORK_DIR=$1 -D4J_HOME=$2 +WORK_DIR="$1" +D4J_HOME="$2" BUILD_FILE="build.gradle" -echo >> $WORK_DIR/$BUILD_FILE -echo "compileJava.options.fork = true" >> $WORK_DIR/$BUILD_FILE -echo "compileJava.options.forkOptions.executable = '$D4J_HOME/major/bin/major'" >> $WORK_DIR/$BUILD_FILE +{ + echo; + echo "compileJava.options.fork = true"; + echo "compileJava.options.forkOptions.executable = '$D4J_HOME/major/bin/major'"; +} >> "$WORK_DIR/$BUILD_FILE" diff --git a/framework/test/get_klocs.sh b/framework/test/get_klocs.sh index 4f50cf5af..431546ecc 100755 --- a/framework/test/get_klocs.sh +++ b/framework/test/get_klocs.sh @@ -8,8 +8,9 @@ ################################################################################ # Must use Java version 8. -JAVA_VERSION_STRING=`java -version 2>&1 | head -1` -JAVA_RELEASE_NUMBER=`echo $JAVA_VERSION_STRING | sed 's/^.*1\.\(.\).*/\1/'` +JAVA_VERSION_STRING=$(java -version 2>&1 | head -1) +# shellcheck disable=SC2001 # variable substitution does not suffice; needs sed. +JAVA_RELEASE_NUMBER=$(echo "$JAVA_VERSION_STRING" | sed 's/^.*1\.\(.\).*/\1/') if [[ "$JAVA_RELEASE_NUMBER" != "8" ]]; then echo Must use Java version 8 exit @@ -37,18 +38,20 @@ if [ -z "$1" ] ; then bids=( 1 2 3 4 5 ) else # Generate tests for supplied project list + # shellcheck disable=SC2206 projects=( $1 ) if [ -z "$2" ] ; then # Generate tests for all bids bids=( 1 2 3 4 5 ) else # Generate tests for supplied bid list + # shellcheck disable=SC2206 bids=( $2 ) fi fi -echo "Projects: ${projects[@]}" -echo "Bug ids: ${bids[@]}" +echo "Projects: " "${projects[@]}" +echo "Bug ids: " "${bids[@]}" # We want the 'fixed' version of the sample. type=f @@ -57,9 +60,9 @@ for pid in "${projects[@]}"; do for bid in "${bids[@]}"; do vid=${bid}$type - run_klocs.pl -p $pid -v $vid -n 1 -o $randoop_dir || die "run klocs on $pid-$vid" + run_klocs.pl -p "$pid" -v "$vid" -n 1 -o "$randoop_dir" || die "run klocs on $pid-$vid" done done # delete tmp file directory -rm -rf $randoop_dir +rm -rf "$randoop_dir" diff --git a/framework/test/test.include b/framework/test/test.include index 5dcc15e32..8a573058a 100755 --- a/framework/test/test.include +++ b/framework/test/test.include @@ -65,7 +65,8 @@ print_result() { printf "\n$text\n" 1>&2 } -# Print and log error message, and terminate script if HALT_ON_ERROR is set +# Print and log error message, and set ERROR. +# Terminate script if HALT_ON_ERROR is set. # die die() { echo "Error: $1" 1>&2 diff --git a/framework/test/test_bug_mining.sh b/framework/test/test_bug_mining.sh index 8daa6df98..bfe68a795 100755 --- a/framework/test/test_bug_mining.sh +++ b/framework/test/test_bug_mining.sh @@ -7,7 +7,7 @@ set -e -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -31,8 +31,7 @@ _check_output() { sort "$actual" > "$actual.sorted" sort "$expected" > "$expected.sorted" - cmp --silent "$expected.sorted" "$actual.sorted" - if [ $? -ne 0 ]; then + if ! cmp --silent "$expected.sorted" "$actual.sorted" ; then rm -f "$actual.sorted" "$expected.sorted" die "'$actual' is not equal to '$expected'!" fi @@ -49,11 +48,11 @@ fi # remote resource is newer. Works around connections that hang. Takes a # single command-line argument, a URL. download_url() { - BASENAME=`basename ${@: -1}` + BASENAME=$(basename "${@: -1}") if [ "$(uname)" = "Darwin" ] ; then wget -nv -N "$@" else - timeout 300 curl -s -S -R -L -O -z "$BASENAME" "$@" || (echo "retrying curl $@" && rm -f "$BASENAME" && curl -R -L -O -z "$BASENAME" "$@") + timeout 300 curl -s -S -R -L -O -z "$BASENAME" "$@" || (echo "retrying curl $*" && rm -f "$BASENAME" && curl -R -L -O -z "$BASENAME" "$@") fi } @@ -69,8 +68,8 @@ test_create_project() { local repository_url="$4" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./create-project.pl -p $project_id -n $project_name -w $work_dir -r $repository_url || die "Create project script has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./create-project.pl -p "$project_id" -n "$project_name" -w "$work_dir" -r "$repository_url" || die "Create project script has failed" popd > /dev/null 2>&1 # Check whether expected directories exist @@ -114,8 +113,8 @@ test_download_issues() { local issues_file="$work_dir/issues.txt" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./download-issues.pl -g $issue_tracker_name -t $issue_tracker_project_id -o $issues_dir -f $issues_file || die "Download of all issues from the issue tracker has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./download-issues.pl -g "$issue_tracker_name" -t "$issue_tracker_project_id" -o "$issues_dir" -f "$issues_file" || die "Download of all issues from the issue tracker has failed" popd > /dev/null 2>&1 # Check whether expected files exist @@ -138,11 +137,11 @@ test_crossref_commmit_issue() { local issues_file="$work_dir/issues.txt" local commit_db_file="$work_dir/framework/projects/$project_id/$BUGS_CSV_ACTIVE" - git --git-dir=$repository_dir log --reverse > $git_log_file || die "Git log has failed" + git --git-dir="$repository_dir" log --reverse > "$git_log_file" || die "Git log has failed" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./vcs-log-xref.pl -e $regex -l $git_log_file -r $repository_dir -i $issues_file -f $commit_db_file || die "Crossreference of commits and issues ids has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./vcs-log-xref.pl -e "$regex" -l "$git_log_file" -r "$repository_dir" -i "$issues_file" -f "$commit_db_file" || die "Crossreference of commits and issues ids has failed" popd > /dev/null 2>&1 # Check whether expected files exist @@ -171,16 +170,16 @@ test_initialize_revisions() { mkdir -p "$lib_dir" mkdir -p "$lib_dir/junit/junit/4.12" - (cd "$lib_dir/junit/junit/4.12" && download_url https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar || die "Failed to download junit-4.12.jar") + (cd "$lib_dir/junit/junit/4.12" && download_url https://repo1.maven.org/maven2/junit/junit/4.12/junit-4.12.jar) || die "Failed to download junit-4.12.jar" mkdir -p "$lib_dir/org/apache/commons/commons-lang3/3.4" - (cd "$lib_dir/org/apache/commons/commons-lang3/3.4" && download_url https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar || die "Failed to download commons-lang3-3.4.jar") + (cd "$lib_dir/org/apache/commons/commons-lang3/3.4" && download_url https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar) || die "Failed to download commons-lang3-3.4.jar" mkdir -p "$lib_dir/org/hamcrest/hamcrest-core/1.3" - (cd "$lib_dir/org/hamcrest/hamcrest-core/1.3" && download_url https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar || die "Failed to download hamcrest-core-1.3.jar") + (cd "$lib_dir/org/hamcrest/hamcrest-core/1.3" && download_url https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar) || die "Failed to download hamcrest-core-1.3.jar" # End of fix for Java-7 pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./initialize-revisions.pl -p $project_id -w $work_dir -b $bug_id || die "Initialize revisions script has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./initialize-revisions.pl -p "$project_id" -w "$work_dir" -b "$bug_id" || die "Initialize revisions script has failed" popd > /dev/null 2>&1 local analyzer_output_dir="framework/projects/$project_id/analyzer_output/$bug_id" @@ -191,10 +190,10 @@ test_initialize_revisions() { _check_output "$work_dir/$analyzer_output_dir/info" "$RESOURCES_OUTPUT_DIR/$analyzer_output_dir/info" local commit_db_file="$work_dir/framework/projects/$project_id/$BUGS_CSV_ACTIVE" - local rev_v1=$(grep "^$bug_id," "$commit_db_file" | cut -f2 -d',') - local rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') - local rev_v1_build_dir="$work_dir/framework/projects/$project_id/build_files/$rev_v1" - local rev_v2_build_dir="$work_dir/framework/projects/$project_id/build_files/$rev_v2" + local rev_v1; rev_v1=$(grep "^$bug_id," "$commit_db_file" | cut -f2 -d',') + local rev_v2; rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') + local rev_v1_build_dir; rev_v1_build_dir="$work_dir/framework/projects/$project_id/build_files/$rev_v1" + local rev_v2_build_dir; rev_v2_build_dir="$work_dir/framework/projects/$project_id/build_files/$rev_v2" [ -s "$rev_v1_build_dir/build.xml" ] || die "$rev_v1_build_dir/build.xml does not exist or it is empty" [ -s "$rev_v1_build_dir/maven-build.properties" ] || die "$rev_v1_build_dir/maven-build.properties does not exist or it is empty" [ -s "$rev_v1_build_dir/maven-build.xml" ] || die "$rev_v1_build_dir/maven-build.xml does not exist or it is empty" @@ -224,18 +223,18 @@ test_analyze_project() { local bug_id="$5" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./analyze-project.pl -p $project_id -w $work_dir -g $issue_tracker_name -t $issue_tracker_project_id -b $bug_id || die "Analyze project script has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./analyze-project.pl -p "$project_id" -w "$work_dir" -g "$issue_tracker_name" -t "$issue_tracker_project_id" -b "$bug_id" || die "Analyze project script has failed" popd > /dev/null 2>&1 local commit_db_file="$work_dir/framework/projects/$project_id/$BUGS_CSV_ACTIVE" - local rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') + local rev_v2; rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') local failing_tests="framework/projects/$project_id/failing_tests/$rev_v2" [ -s "$work_dir/$failing_tests" ] || die "No failing test cases has been reported" # Same number of failing tests - local actual_num_failing_tests=$(grep -a "^--- " "$work_dir/$failing_tests" | wc -l) - local expected_num_failing_tests=$(grep -a "^--- " "$RESOURCES_OUTPUT_DIR/$failing_tests" | wc -l) + local actual_num_failing_tests; actual_num_failing_tests=$(grep -a "^--- " "$work_dir/$failing_tests" | wc -l) + local expected_num_failing_tests; expected_num_failing_tests=$(grep -a "^--- " "$RESOURCES_OUTPUT_DIR/$failing_tests" | wc -l) if [ "$actual_num_failing_tests" -ne "$expected_num_failing_tests" ]; then echo "Expected failing tests:" grep -a "^--- " "$RESOURCES_OUTPUT_DIR/$failing_tests" @@ -263,16 +262,16 @@ test_get_trigger() { local bug_id="$3" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./get-trigger.pl -p $project_id -w $work_dir -b $bug_id || die "Get list of triggering test cases has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./get-trigger.pl -p "$project_id" -w "$work_dir" -b "$bug_id" || die "Get list of triggering test cases has failed" popd > /dev/null 2>&1 local trigger_tests="framework/projects/$project_id/trigger_tests/$bug_id" [ -s "$work_dir/$trigger_tests" ] || die "List of triggering test cases is empty or does not exist" # Same number of trigger tests - local actual_num_trigger_tests=$(grep -a "^--- " "$work_dir/$trigger_tests" | wc -l) - local expected_num_trigger_tests=$(grep -a "^--- " "$RESOURCES_OUTPUT_DIR/$trigger_tests" | wc -l) + local actual_num_trigger_tests; actual_num_trigger_tests=$(grep -c -a "^--- " "$work_dir/$trigger_tests") + local expected_num_trigger_tests; expected_num_trigger_tests=$(grep -c -a "^--- " "$RESOURCES_OUTPUT_DIR/$trigger_tests") [ "$actual_num_trigger_tests" -eq "$expected_num_trigger_tests" ] || die "Expected $expected_num_trigger_tests trigger tests and got $actual_num_trigger_tests" # Same trigger tests @@ -292,8 +291,8 @@ test_get_metadata() { local bug_id="$3" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./get-metadata.pl -p $project_id -w $work_dir -b $bug_id || die "Metadata extraction has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./get-metadata.pl -p "$project_id" -w "$work_dir" -b "$bug_id" || die "Metadata extraction has failed" popd > /dev/null 2>&1 local relevant_tests="framework/projects/$project_id/relevant_tests/$bug_id" @@ -324,8 +323,8 @@ test_promote_to_db() { local repository_dir="$work_dir/project_repos/$project_name.git" pushd . > /dev/null 2>&1 - cd $BUG_MINING_FRAMEWORK_DIR - ./promote-to-db.pl -p $project_id -w $work_dir -r $repository_dir -b $bug_id || die "Promotion of $project_id-$bug_id has failed" + cd "$BUG_MINING_FRAMEWORK_DIR" + ./promote-to-db.pl -p "$project_id" -w "$work_dir" -r "$repository_dir" -b "$bug_id" || die "Promotion of $project_id-$bug_id has failed" popd > /dev/null 2>&1 _check_output "$HERE/../core/Project/$project_id.pm" "$work_dir/framework/core/Project/$project_id.pm" @@ -333,17 +332,17 @@ test_promote_to_db() { [ -d "$HERE/../projects/$project_id" ] || die "Project directory does not exist" local commit_db_file="$work_dir/framework/projects/$project_id/$BUGS_CSV_ACTIVE" - local rev_v1=$(grep "^$bug_id," "$commit_db_file" | cut -f2 -d',') - local rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') + local rev_v1; rev_v1=$(grep "^$bug_id," "$commit_db_file" | cut -f2 -d',') + local rev_v2; rev_v2=$(grep "^$bug_id," "$commit_db_file" | cut -f3 -d',') local failing_tests="projects/$project_id/failing_tests/$rev_v2" _check_output "$HERE/../$failing_tests" "$work_dir/framework/$failing_tests" for dir in "build_files/$rev_v1" "build_files/$rev_v2"; do while read -r f; do - f_name=$(basename $f) + f_name=$(basename "$f") _check_output "$HERE/../projects/$project_id/$dir/$f_name" "$f" - done < <(find "$(cd $work_dir/framework/projects/$project_id/$dir; pwd)" -type f) + done < <(find "$(cd "$work_dir/framework/projects/$project_id/$dir"; pwd)" -type f) done local loaded_classes="projects/$project_id/loaded_classes" @@ -426,7 +425,7 @@ if [ "$ERROR" -ne "0" ]; then printf '=%.s' $(seq 1 80) 1>&2 echo 1>&2 echo "The following errors occurred:" 1>&2 - cat $LOG 1>&2 + cat "$LOG" 1>&2 fi # Indicate whether an error occurred diff --git a/framework/test/test_cp.sh b/framework/test/test_cp.sh index f13c9488d..f91c3ae26 100755 --- a/framework/test/test_cp.sh +++ b/framework/test/test_cp.sh @@ -5,7 +5,7 @@ # ################################################################################ -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -13,7 +13,7 @@ init # Print usage message usage() { - local known_pids=$(defects4j pids) + local known_pids; known_pids=$(defects4j pids) echo "usage: $0 [-p ]" echo "Project ids:" for pid in $known_pids; do @@ -50,21 +50,21 @@ main() { echo "Temporary directory: $TMP_ROOT" >"$LOG" for PID in $PIDS; do - for BID in $(defects4j bids -p $PID); do + for BID in $(defects4j bids -p "$PID"); do DIR="$TMP_ROOT/$PID-$BID" - defects4j checkout -p $PID -v${BID}f -w "$DIR" + defects4j checkout -p "$PID" -v"${BID}"f -w "$DIR" defects4j compile -w "$DIR" echo "$PID-$BID: start" >> "$LOG" for cp in "cp.compile" "cp.test"; do key="$PID-$BID-$cp" echo " - $key: $(defects4j export -p $cp -w "$DIR")" >> "$LOG" - check_cp_entries $key $(defects4j export -p $cp -w "$DIR") || ERROR=1 + check_cp_entries "$key" "$(defects4j export -p $cp -w "$DIR")" || ERROR=1 done echo "$PID-$BID: done" >> "$LOG" done done - rm -rf $TMP_ROOT + rm -rf "$TMP_ROOT" exit $ERROR } @@ -73,7 +73,7 @@ main() { check_cp_entries() { local KEY=$1 local CP=$2 - for entry in $(echo $CP | tr ':' '\n'); do + for entry in $(echo "$CP" | tr ':' '\n'); do [[ -e "$entry" ]] || echo "!!! Invalid CP entry ($KEY): $entry" >> "$LOG" done } diff --git a/framework/test/test_d4j_query.sh b/framework/test/test_d4j_query.sh index 6ed5cdfb5..ccc5d43ac 100755 --- a/framework/test/test_d4j_query.sh +++ b/framework/test/test_d4j_query.sh @@ -5,7 +5,7 @@ # ################################################################################ -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -16,39 +16,39 @@ result=`diff $HERE/temp $HERE/resources/output/d4j-query/1` [ "$result" == "" ] || die "query \"-p Collections\" -H failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp -$BASE_DIR/framework/bin/defects4j query -p Collections >> $HERE"/temp" -result=`diff $HERE/temp $HERE/resources/output/d4j-query/2` +"$BASE_DIR"/framework/bin/defects4j query -p Collections >> "$HERE"/temp +result=$(diff "$HERE"/temp "$HERE"/resources/output/d4j-query/2) [ "$result" == "" ] || die "query \"-p Collections\" failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp -$BASE_DIR/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" >> $HERE"/temp" -result=`diff $HERE/temp $HERE/resources/output/d4j-query/3` +"$BASE_DIR"/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" >> "$HERE"/temp +result=$(diff "$HERE"/temp "$HERE"/resources/output/d4j-query/3) [ "$result" == "" ] || die "query \"-p Collections -q \"revision.id.buggy,classes.modified\"\" failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp -$BASE_DIR/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" -D >> $HERE"/temp" -result=`diff $HERE/temp $HERE/resources/output/d4j-query/4` +"$BASE_DIR"/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" -D >> "$HERE"/temp +result=$(diff "$HERE"/temp "$HERE"/resources/output/d4j-query/4) [ "$result" == "" ] || die "query \"-p Collections -q \"revision.id.buggy,classes.modified\" -D\" failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp -$BASE_DIR/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" -A >> $HERE"/temp" -result=`diff $HERE/temp $HERE/resources/output/d4j-query/5` +"$BASE_DIR"/framework/bin/defects4j query -p Collections -q "revision.id.buggy,classes.modified" -A >> "$HERE"/temp +result=$(diff "$HERE"/temp "$HERE"/resources/output/d4j-query/5) [ "$result" == "" ] || die "query \"-p Collections -q \"revision.id.buggy,classes.modified\" -A\" failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp -$BASE_DIR/framework/bin/defects4j query -p Collections -q "deprecated.reason" -A >> $HERE"/temp" -result=`diff $HERE/temp $HERE/resources/output/d4j-query/6` +"$BASE_DIR"/framework/bin/defects4j query -p Collections -q "deprecated.reason" -A >> "$HERE"/temp +result=$(diff "$HERE"/temp "$HERE"/resources/output/d4j-query/6) [ "$result" == "" ] || die "query \"-p Collections -q \"deprecated.reason\" -A\" failed: $result" -rm $HERE"/temp" +rm "$HERE"/temp diff --git a/framework/test/test_export_command.sh b/framework/test/test_export_command.sh index b8f4f2103..ab36b358e 100755 --- a/framework/test/test_export_command.sh +++ b/framework/test/test_export_command.sh @@ -10,7 +10,7 @@ # ################################################################################ -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -25,14 +25,12 @@ _run_export_command() { local exp_cmp="$2" local exp_out="" - pushd . > /dev/null 2>&1 - cd "$work_dir" - exp_out=$(defects4j export -p "$exp_cmp") - if [ $? -ne 0 ]; then - popd > /dev/null 2>&1 + pushd "$work_dir" > /dev/null 2>&1 || (echo "Cannot pushd to $work_dir" && exit 1) + if ! defects4j export -p "$exp_cmp" ; then + popd > /dev/null 2>&1 || (echo "Cannot popd" && exit 1) return 1 fi - popd > /dev/null 2>&1 + popd > /dev/null 2>&1 || (echo "Cannot popd" && exit 1) echo "$exp_out" return 0 @@ -48,7 +46,8 @@ test_export_properties() { ################################################################# # Iterate over all bugs ################################################################# - local bids="$(get_bug_ids $BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE)" + local bids + bids="$(get_bug_ids "$BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE")" for bid in $bids; do local work_dir="$test_dir/$pid/$bid" mkdir -p "$work_dir" @@ -58,9 +57,8 @@ test_export_properties() { ################################################################# # Check "dir.bin.tests" ################################################################# - local test_classes_dir="" - test_classes_dir=$(_run_export_command "$work_dir" "dir.bin.tests") - if [ $? -ne 0 ]; then + local test_classes_dir=""; + if ! test_classes_dir=$(_run_export_command "$work_dir" "dir.bin.tests") ; then die "Export command of $pid-$bid has failed" fi @@ -134,8 +132,7 @@ test_export_properties() { # Check "dir.bin.classes" ################################################################# local classes_dir="" - classes_dir=$(_run_export_command "$work_dir" "dir.bin.classes") - if [ $? -ne 0 ]; then + if ! classes_dir=$(_run_export_command "$work_dir" "dir.bin.classes") ; then die "Export command of $pid-$bid has failed" fi @@ -181,7 +178,7 @@ test_export_properties() { # Print usage message and exit usage() { - local known_pids=$(defects4j pids) + local known_pids; known_pids=$(defects4j pids) echo "usage: $0 -p " echo "Project ids:" for pid in $known_pids; do @@ -214,7 +211,7 @@ fi for PID in $PIDS; do HALT_ON_ERROR=0 # Run all test cases (and log all results), regardless of whether errors occur - test_export_properties $PID || die "Test 'test_export_properties' has failed!" + test_export_properties "$PID" || die "Test 'test_export_properties' has failed!" done # Print a summary of what went wrong @@ -222,7 +219,7 @@ if [ "$ERROR" -ne "0" ]; then printf '=%.s' $(seq 1 80) 1>&2 echo 1>&2 echo "The following errors occurred:" 1>&2 - cat $LOG 1>&2 + cat "$LOG" 1>&2 fi # Indicate whether an error occurred diff --git a/framework/test/test_fix_test_suite.sh b/framework/test/test_fix_test_suite.sh index adeaff0f9..9960c7a40 100755 --- a/framework/test/test_fix_test_suite.sh +++ b/framework/test/test_fix_test_suite.sh @@ -5,7 +5,7 @@ # ################################################################################ -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -39,11 +39,11 @@ _check_fix_db() { [ -s "$fix_db_file" ] || die "Database file 'fix' doesn't exist or is empty!" - local num_rows=$(cat "$fix_db_file" | wc -l) + local num_rows; num_rows=$(wc -l < "$fix_db_file") [ "$num_rows" -eq 2 ] || die "Database file 'fix' does not have 2 rows!" # Convert DOS (\r\n) to Unix (\n) line ending and check data of last row - local actual_db_data=$(tr -d '\r' < "$fix_db_file" | tail -n1) + local actual_db_data; actual_db_data=$(tr -d '\r' < "$fix_db_file" | tail -n1) [ "$actual_db_data" == "$expected_db_data" ] || die "Unexpected result (expected: '$expected_db_data'; actual: '$actual_db_data')!" return 0 @@ -62,11 +62,12 @@ _create_tar_bz2_file() { local suites_dir="$4" # Create a .tar.bz2 file with all test suites - pushd . > /dev/null 2>&1 - cd "$HERE/resources/input" + pushd . > /dev/null 2>&1 || (echo "cannot pushd ." && exit 1) + cd "$HERE/resources/input" || (echo "cannot cd to $HERE/resources/input" && exit 1) tar_bz2_file="$suites_dir/$pid-$bid-test.0.tar.bz2" + # shellcheck disable=SC2086 # $input_files contains multiple files tar -jcvf "$tar_bz2_file" $input_files || return 1 - popd > /dev/null 2>&1 + popd > /dev/null 2>&1 || (echo "cannot popd" && exit 1) return 0 } @@ -205,6 +206,7 @@ test_MultipleUnitTestsWithMultipleCompilationIssues() { local pid="Gson" local bid="18f" + #shellcheck disable=SC2016 # Literal $ in single-quoted string. run_fix_test_suite_test_case "$pid" "$bid" \ 'com/google/gson/internal/$Gson$Types_ESTest.java com/google/gson/internal/$Gson$Types_ESTest_scaffolding.java' \ 'com/google/gson/internal/$Gson$Types_ESTest.java com/google/gson/internal/$Gson$Types_ESTest.java.bak com/google/gson/internal/$Gson$Types_ESTest_scaffolding.java' \ @@ -215,6 +217,7 @@ test_MultipleUnitTestsWithMultipleCompilationIssues() { return 0 fi + #shellcheck disable=SC2016 # Literal $ in single-quoted string. run_fix_test_suite_test_case "$pid" "$bid" \ 'com/google/gson/internal/$Gson$Types_ESTest.java com/google/gson/internal/$Gson$Types_ESTest_scaffolding.java' \ 'com/google/gson/internal/$Gson$Types_ESTest.java com/google/gson/internal/$Gson$Types_ESTest.java.bak com/google/gson/internal/$Gson$Types_ESTest_scaffolding.java' \ diff --git a/framework/test/test_gen_tests.sh b/framework/test/test_gen_tests.sh index ed728da88..1a43e66d1 100755 --- a/framework/test/test_gen_tests.sh +++ b/framework/test/test_gen_tests.sh @@ -20,7 +20,7 @@ init # Print usage message and exit usage() { - local known_pids=$(defects4j pids) + local known_pids; known_pids=$(defects4j pids) echo "usage: $0 -p [-b ... | -b ... ]" echo "Project ids:" for pid in $known_pids; do @@ -35,7 +35,7 @@ while getopts ":p:b:" opt; do p) PID="$OPTARG" ;; b) if [[ "$OPTARG" =~ ^[0-9]*\.\.[0-9]*$ ]]; then - BUGS="$BUGS $(eval echo {$OPTARG})" + BUGS="$BUGS $(eval echo "{$OPTARG}")" else BUGS="$BUGS $OPTARG" fi @@ -63,12 +63,12 @@ init # Run all bugs, unless otherwise specified if [ "$BUGS" == "" ]; then - BUGS="$(get_bug_ids $BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE)" + BUGS="$(get_bug_ids "$BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE")" fi # Create log file -script_name=$(echo $script | sed 's/\.sh$//') -LOG="$TEST_DIR/${script_name}$(printf '_%s_%s' $PID $$).log" +script_name_without_sh=${script//.sh/} +LOG="$TEST_DIR/${script_name_without_sh}$(printf '_%s_%s' "$PID" $$).log" ################################################################################ # Run all generators on the specified bugs, and determine bug detection, @@ -79,12 +79,12 @@ LOG="$TEST_DIR/${script_name}$(printf '_%s_%s' $PID $$).log" HALT_ON_ERROR=0 work_dir="$TMP_DIR/$PID" -mkdir -p $work_dir +mkdir -p "$work_dir" # Clean working directory -rm -rf "$work_dir/*" +rm -rf "${work_dir:?}/*" -for bid in $(echo $BUGS); do +for bid in $BUGS ; do # Skip all bug ids that do not exist in the active-bugs csv if ! grep -q "^$bid," "$BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE"; then warn "Skipping bug ID that is not listed in active-bugs csv: $PID-$bid" @@ -95,9 +95,9 @@ for bid in $(echo $BUGS); do target_classes="$BASE_DIR/framework/projects/$PID/modified_classes/$bid.src" # Iterate over all supported generators and generate regression tests - for tool in $($BASE_DIR/framework/bin/gen_tests.pl -g help | grep \- | tr -d '-'); do + for tool in $("$BASE_DIR"/framework/bin/gen_tests.pl -g help | grep - | tr -d '-'); do # Directory for generated test suites - suite_src="$tool" + # suite_src="$tool" suite_num=1 suite_dir="$work_dir/$tool/$suite_num" @@ -105,28 +105,28 @@ for bid in $(echo $BUGS); do vid=${bid}f # Run generator and the fix script on the generated test suite - if ! gen_tests.pl -g "$tool" -p $PID -v $vid -n 1 -o "$TMP_DIR" -b 30 -c "$target_classes"; then + if ! gen_tests.pl -g "$tool" -p "$PID" -v "$vid" -n 1 -o "$TMP_DIR" -b 30 -c "$target_classes"; then die "run $tool (regression) on $PID-$vid" # Skip any remaining analyses (cannot be run), even if halt-on-error is false continue fi - fix_test_suite.pl -p $PID -d "$suite_dir" || die "fix test suite" + fix_test_suite.pl -p "$PID" -d "$suite_dir" || die "fix test suite" # Run test suite and determine bug detection - test_bug_detection $PID "$suite_dir" + test_bug_detection "$PID" "$suite_dir" # Run test suite and determine mutation score - test_mutation $PID "$suite_dir" + test_mutation "$PID" "$suite_dir" # Run test suite and determine code coverage - test_coverage $PID "$suite_dir" 0 + test_coverage "$PID" "$suite_dir" 0 - rm -rf $work_dir/$tool + rm -rf "${work_dir:?}/$tool" done vid=${bid}b # Run Randoop to generate error-revealing tests (other tools cannot do so) - gen_tests.pl -g randoop -p $PID -v $vid -n 1 -o "$TMP_DIR" -b 30 -c "$target_classes" -E + gen_tests.pl -g randoop -p "$PID" -v "$vid" -n 1 -o "$TMP_DIR" -b 30 -c "$target_classes" -E # We expect Randoop to not crash; it may or may not create an error-revealing test for this version ret=$? [ $ret -eq 0 ] || [ $ret -eq 127 ] || die "run $tool (error-revealing) on $PID-$vid" @@ -139,7 +139,7 @@ if [ $ERROR != 0 ]; then printf '=%.s' $(seq 1 80) 1>&2 echo 1>&2 echo "The following errors occurred:" 1>&2 - cat $LOG 1>&2 + cat "$LOG" 1>&2 fi # Indicate whether an error occurred diff --git a/framework/test/test_mutation_analysis.sh b/framework/test/test_mutation_analysis.sh index 1b688b277..d2579711c 100755 --- a/framework/test/test_mutation_analysis.sh +++ b/framework/test/test_mutation_analysis.sh @@ -7,7 +7,7 @@ # TODO: There is some code duplication in this test script, which we can avoid # by extracting the mutation analysis workflow into a parameterized function. -HERE=$(cd `dirname $0` && pwd) +HERE=$(cd "$(dirname "$0")" && pwd) || (echo "cannot cd to $(dirname "$0")" && exit 1) # Import helper subroutines and variables, and init Defects4J source "$HERE/test.include" || exit 1 @@ -51,7 +51,7 @@ _check_mutation_result() { # The last row of 'summary.csv' does not have an end of line character. # Otherwise, using wc would be more intuitive. - local num_rows=$(grep -c "^" "$summary_file") + local num_rows; num_rows=$(grep -c "^" "$summary_file") [ "$num_rows" -eq "2" ] || die "Unexpected number of lines in '$summary_file'!" # Columns of summary (csv) file: @@ -143,7 +143,7 @@ _set_vars "Chart" "12f" # Remove temporary directory if it already exists rm -rf "$pid_vid_dir" # Checkout project-version -defects4j checkout -p $pid -v $vid -w "$pid_vid_dir" || die "It was not possible to checkout $pid-$vid to '$pid_vid_dir'!" +defects4j checkout -p "$pid" -v "$vid" -w "$pid_vid_dir" || die "It was not possible to checkout $pid-$vid to '$pid_vid_dir'!" # Remove the summary file to ensure it is regenerated rm -f "$summary_file" defects4j mutation -w "$pid_vid_dir" -r || die "Mutation analysis (including all mutants) failed!" @@ -156,7 +156,7 @@ _set_vars "Mockito" "12f" # Remove temporary directory if it already exists rm -rf "$pid_vid_dir" # Checkout project-version -defects4j checkout -p $pid -v $vid -w "$pid_vid_dir" || die "It was not possible to checkout $pid-$vid to '$pid_vid_dir'!" +defects4j checkout -p "$pid" -v "$vid" -w "$pid_vid_dir" || die "It was not possible to checkout $pid-$vid to '$pid_vid_dir'!" # Remove the summary file to ensure it is regenerated rm -f "$summary_file" defects4j mutation -w "$pid_vid_dir" -r || die "Mutation analysis (including all mutants) failed!" diff --git a/framework/test/test_style.sh b/framework/test/test_style.sh new file mode 100755 index 000000000..45631b40b --- /dev/null +++ b/framework/test/test_style.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +TOPLEVEL="$(git rev-parse --show-toplevel)" + +cd "$TOPLEVEL" || (echo "Cannot cd to $TOPLEVEL" && exit 1) + +# Check style of sh scripts. +grep -r -l '^\#! \?\(/bin/\|/usr/bin/env \)sh' --exclude=\*~ "$TOPLEVEL"/framework | while read -r line +do + shellcheck -x -P SCRIPTDIR --format=gcc "$line" + checkbashisms "$line" +done + +# Check style of bash scripts. +grep -r -l '^\#! \?\(/bin/\|/usr/bin/env \)bash' --exclude=\*~ "$TOPLEVEL"/framework | while read -r line +do + shellcheck -x -P SCRIPTDIR --format=gcc "$line" +done +for file in "$TOPLEVEL"/init.sh "$TOPLEVEL"/framework/lib/test_generation/bin/_tool.source ; do + shellcheck -x -P SCRIPTDIR --format=gcc "$file" +done + diff --git a/framework/test/test_tutorial.sh b/framework/test/test_tutorial.sh index dd071fd68..06fa6fb49 100755 --- a/framework/test/test_tutorial.sh +++ b/framework/test/test_tutorial.sh @@ -23,15 +23,15 @@ vid=${bid}b work_dir=$TMP_DIR/$pid-$vid # Checkout buggy version -defects4j checkout -p $pid -v $vid -w $work_dir || die "checkout program version $pid-$vid" +defects4j checkout -p $pid -v $vid -w "$work_dir" || die "checkout program version $pid-$vid" # Verify that defects4j's config file exists -[ -e $work_dir/.defects4j.config ] || die "read config file" +[ -e "$work_dir"/.defects4j.config ] || die "read config file" # Verify that defects4j's config file provides the correct data -grep -q "pid=$pid" $work_dir/.defects4j.config || die "verify pid in config file" -grep -q "vid=$vid" $work_dir/.defects4j.config || die "verify vid in config file" +grep -q "pid=$pid" "$work_dir"/.defects4j.config || die "verify pid in config file" +grep -q "vid=$vid" "$work_dir"/.defects4j.config || die "verify vid in config file" -cd $work_dir +cd "$work_dir" || (echo "cannot cd to $work_dir" && exit 1) # Compile buggy version defects4j compile || die "compile program version $pid-$vid" diff --git a/framework/test/test_verify_bugs.sh b/framework/test/test_verify_bugs.sh index e7faa081b..65e94946f 100755 --- a/framework/test/test_verify_bugs.sh +++ b/framework/test/test_verify_bugs.sh @@ -49,7 +49,7 @@ while getopts ":p:b:AD" opt; do p) PID="$OPTARG" ;; b) if [[ "$OPTARG" =~ ^[0-9]*\.\.[0-9]*$ ]]; then - BUGS="$BUGS $(eval echo {$OPTARG})" + BUGS="$BUGS $(eval echo "{$OPTARG}")" else BUGS="$BUGS $OPTARG" fi @@ -75,7 +75,7 @@ fi # Run all bugs, unless otherwise specified if [ "$BUGS" == "" ]; then - BUGS="$(get_bug_ids $BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE)" + BUGS="$(get_bug_ids "$BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE")" fi if [ "$DEBUG" == "-D" ]; then @@ -83,9 +83,9 @@ if [ "$DEBUG" == "-D" ]; then fi # Create log file -script_name=$(echo $script | sed 's/\.sh$//') -LOG="$TEST_DIR/${script_name}$(printf '_%s_%s' $PID $$).log" -DIR_FAILING="$TEST_DIR/${script_name}$(printf '_%s_%s' $PID $$).failing_tests" +script_name_without_sh=${script//.sh/} +LOG="$TEST_DIR/${script_name_without_sh}$(printf '_%s_%s' "$PID" $$).log" +DIR_FAILING="$TEST_DIR/${script_name_without_sh}$(printf '_%s_%s' "$PID" $$).failing_tests" ################################################################################ # Run developer-written tests on all buggy and fixed program versions, and @@ -96,15 +96,15 @@ DIR_FAILING="$TEST_DIR/${script_name}$(printf '_%s_%s' $PID $$).failing_tests" HALT_ON_ERROR=0 test_dir="$TMP_DIR/test_trigger" -mkdir -p $test_dir +mkdir -p "$test_dir" -mkdir -p $DIR_FAILING +mkdir -p "$DIR_FAILING" work_dir="$test_dir/$PID" # Clean working directory -rm -rf $work_dir -for bid in $(echo $BUGS); do +rm -rf "$work_dir" +for bid in $BUGS ; do # Skip all bug ids that do not exist in the active-bugs csv if ! grep -q "^$bid," "$BASE_DIR/framework/projects/$PID/$BUGS_CSV_ACTIVE"; then warn "Skipping bug ID that is not listed in active-bugs csv: $PID-$bid" @@ -113,8 +113,7 @@ for bid in $(echo $BUGS); do for v in "b" "f"; do vid=${bid}$v - defects4j checkout -p $PID -v "$vid" -w "$work_dir" || die "checkout: $PID-$vid" - + defects4j checkout -p "$PID" -v "$vid" -w "$work_dir" || die "checkout: $PID-$vid" defects4j compile -w "$work_dir" || die "compile: $PID-$vid" defects4j test $TEST_FLAG -w "$work_dir" || die "run relevant tests: $PID-$vid" @@ -123,7 +122,7 @@ for bid in $(echo $BUGS); do triggers=$(num_triggers "$work_dir/failing_tests") # Expected number of failing tests for each fixed version is 0! if [ $v == "f" ]; then - [ $triggers -eq 0 ] \ + [ "$triggers" -eq 0 ] \ || die "verify number of triggering tests: $PID-$vid (expected: 0, actual: $triggers)" continue fi @@ -133,9 +132,9 @@ for bid in $(echo $BUGS); do expected=$(num_triggers "$BASE_DIR/framework/projects/$PID/trigger_tests/$bid") # Fail if there are no trigger tests - [ $expected -gt 0 ] || die "Metadata error: There are no trigger tests for $PID-$vid" + [ "$expected" -gt 0 ] || die "Metadata error: There are no trigger tests for $PID-$vid" - [ $triggers -eq $expected ] \ + [ "$triggers" -eq "$expected" ] \ || die "verify number of triggering tests: $PID-$vid (expected: $expected, actual: $triggers)" for t in $(get_triggers "$BASE_DIR/framework/projects/$PID/trigger_tests/$bid"); do grep -q "$t" "$work_dir/failing_tests" || die "expected triggering test $t did not fail" @@ -153,7 +152,7 @@ if [ $ERROR != 0 ]; then printf '=%.s' $(seq 1 80) 1>&2 echo 1>&2 echo "The following errors occurred:" 1>&2 - cat $LOG 1>&2 + cat "$LOG" 1>&2 fi # Indicate whether an error occurred diff --git a/init.sh b/init.sh index 8d345458e..cdb7acdde 100755 --- a/init.sh +++ b/init.sh @@ -80,7 +80,7 @@ download_url() { else ZBASENAME="" fi - (timeout 300 curl -s -S -R -L -O $ZBASENAME "$URL" || (echo "retrying curl $URL" && rm -f "$BASENAME" && curl -R -L -O "$URL")) && echo "Downloaded $URL" + (timeout 300 curl -s -S -R -L -O "$ZBASENAME" "$URL" || (echo "retrying curl $URL" && rm -f "$BASENAME" && curl -R -L -O "$URL")) && echo "Downloaded $URL" fi } @@ -121,7 +121,7 @@ get_modification_timestamp() { cmd="stat -f %m $f" fi - local ts=$($cmd) + local ts; ts=$($cmd) echo "$ts" }