# 在 Linux 中設定 Defects4j (以v1.2.0為例) > 引用 Defects4J github https://github.com/rjust/defects4j > 引用 TingWei 學長寫的 "[新的虛擬機 Defects4j 設定](https://hackmd.io/@saID5sq_QhCsFgtxP02KkA/Defects4J_Set#%E6%96%B0%E7%9A%84%E8%99%9B%E6%93%AC%E6%A9%9FDefects4j%E8%A8%AD%E5%AE%9A%E3%80%82)" ## 環境要求 (Requirements) 創建新的虛擬機後先更新。 ``` sudo apt update sudo apt upgrade -y ``` > 有些linux版本沒有unzip,需要自己下載 > `sudo apt install unzip` ### 1. 下載 Java 1.7 (僅適用 Defects4j v1.5.0 以前的版本) 因為新版ubuntu可能已經不再適用Java 7,所以透過這樣的步驟實現。 ( 如果要其他已經無法下載的java版本,可從Oracle上找 ) 下載 [Java 1.7.10.tar.gz](https://drive.google.com/file/d/18hfujRsl0yO7DYTcl87-32CVzA1P6bJX/view?pli=1) > 若用到 Defects4j v2.0.0 以後,請下載 Java 1.8。 > 補充1.8的檔案 [Java 1.8.tar.gz](https://drive.google.com/file/d/1q90flX7bUSYJZdHsR589ric4lgRv_nRU/view) 建立一個存放 Java 7 的資料夾,輸入下列指令。 ``` cd ../.. cd opt sudo mkdir JDK ``` 回到 Downloads 資料夾,並將剛剛下載的檔案解壓縮到建立的資料夾。 ``` cd ~ cd Downloads sudo tar -zxvf jdk-7u80-linux-x64.tar.gz -C /opt/JDK ``` 設定環境變數。 ``` sudo nano ~/.bashrc ``` 在環境變數設定檔案最後面加上,加入完成之後Ctrl+O儲存。 (注意: 這是我存 Java 7 的資料夾位置,若存的位置不一樣要自己改。) ``` export JAVA_HOME=/opt/JDK/jdk1.7.0_80 export PATH=$JAVA_HOME/bin:$PATH ``` 執行環境設定。 ``` source ~/.bashrc ``` 確認有成功安裝。 ``` java -version javac -version ``` ### 2. 安裝 Git >= 1.9 ``` sudo apt-get install git -y git --version ``` ### 3. 安裝 SVN >= 1.8 ``` sudo apt install subversion -y svn --version ``` ### 4. 安裝 Perl >= 5.0.10 ``` sudo apt install perl -y sudo apt list --installed | grep -i perl ``` > 若之後實驗遇到 "Can't locate DBI.pm in @INC" 的錯誤 > 再執行以下命令以安裝 DBI 模組: > `sudo apt-get install libdbi-perl` ### 5. 安裝 cpanminus ``` sudo apt-get install cpanminus -y ``` ### 6. 安裝 curl ``` sudo apt install curl -y ``` ### 7. 安裝 maven ``` sudo apt install maven -y ``` ### 8. 安裝 ANT 下載 ANT 的壓縮檔案。 [ant 1.9.16](https://drive.google.com/file/d/1A-sRvJlBbAfhznxUTfsQlB4KF3jl8Gzq/view) 建立一個給ANT的資料夾。 ``` cd ../../.. cd opt sudo mkdir ANT ``` 回到Downloads,並解壓縮,之後設定環境變數。 ``` cd ~ cd Downloads sudo tar -zxvf apache-ant-1.9.16-bin.tar.gz -C /opt/ANT/ ``` 設定環境變數。 ``` sudo nano ~/.bashrc ``` 在環境變數設定檔案最後面加上,加入完成之後Ctrl+O儲存。 ``` export ANT_HOME=/opt/ANT/apache-ant-1.9.16 export PATH=$ANT_HOME/bin:$PATH ``` 執行環境設定,並確認有安裝成功。 ``` source ~/.bashrc ant -version ``` ## Getting started ### 1. 下載 Defects4J,並切換到需要的版本 ``` git clone https://github.com/rjust/defects4j.git cd defects4j git checkout v1.2.0 ``` 確認切換版本成功。 ``` git describe --tags ``` ### 2. 初始化 Defects4J 在初始化之前,需先修改2個檔案內容(get_repos.sh 和 init.sh)。 > 因為原本的內容有些網址已被刪除,若直接按原檔案執行會出現404。 1. project_repos 資料夾中的 `get_repos.sh` 修改內容如下(可直接整個複製貼上) :::spoiler get_repos.sh ``` #!/usr/bin/env bash set -e # The name of the archive that contains all project repos ARCHIVE=defects4j-repos.zip main() { # The BSD version of stat does not support --version or -c if stat --version &> /dev/null; then # GNU version cmd="stat -c %Y $ARCHIVE" else # BSD version cmd="stat -f %m $ARCHIVE" fi if [ -e $ARCHIVE ]; then old=$($cmd) else old=0 fi # Only download repos if the server has a newer file download_url "https://defects4j.org/downloads/$ARCHIVE" new=$($cmd) # Exit if no newer file is available [ "$old" == "$new" ] && exit 0 # Remove old files clean # Extract new repos unzip -q -u $ARCHIVE && mv defects4j/project_repos/* . && rm -r defects4j } clean() { rm -rf \ closure-compiler.git \ commons-lang.git \ commons-math.git \ jfreechart \ joda-time.git \ README } # MacOS does not install the timeout command by default. if [ "$(uname)" = "Darwin" ] ; then function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; } fi # Download the remote resource to a local file of the same name, if the # remote resource is newer. Works around connections that hang. Takes a # single command-line argument, a URL. download_url() { 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" "$@") fi } main ``` ::: 2. `init.sh` 修改內容如下(可直接整個複製貼上) :::spoiler init.sh ``` #!/usr/bin/env bash # # Exit the shell script immediately if any of the subsequent commands fails. # immediately set -e # # TODO: Major and the coverage tools should be moved to framework/lib ################################################################################ # This script initializes Defects4J. In particular, it downloads and sets up: # - the project's version control repositories # - the Major mutation framework # - the supported test generation tools # - the supported code coverage tools (TODO) ################################################################################ HOST_URL="https://defects4j.org/downloads" # Directories for project repositories and external libraries BASE="$(cd "$(dirname "$0")"; pwd)" DIR_REPOS="$BASE/project_repos" DIR_LIB_GEN="$BASE/framework/lib/test_generation/generation" DIR_LIB_RT="$BASE/framework/lib/test_generation/runtime" DIR_LIB_GRADLE="$BASE/framework/lib/build_systems/gradle" ################################################################################ main() { echo "Checking system configuration ... " # Check whether wget is available on OSX if [ "$(uname)" = "Darwin" ] ; then if ! wget --version > /dev/null 2>&1; then print_error_and_exit "Couldn't find wget to download dependencies. Please install wget and re-run this script." fi fi # Check whether curl is available if ! curl --version > /dev/null 2>&1; then print_error_and_exit "Couldn't find curl to download dependencies. Please install curl and re-run this script." fi # Check whether unzip is available if ! unzip -v > /dev/null 2>&1; then print_error_and_exit "Couldn't find unzip to extract dependencies. Please install unzip and re-run this script." fi # Create lib folders if necessary mkdir -p "$DIR_LIB_GEN" && mkdir -p "$DIR_LIB_RT" && mkdir -p "$DIR_LIB_GRADLE" ############################################################################ # # Download project repositories if necessary # echo "Setting up project repositories ... " cd "$DIR_REPOS" && ./get_repos.sh ############################################################################ # # Download Major # # Adapt Major's default wrapper scripts: # - set headless to true to support Chart on machines without X. # - do not mutate code unless an MML is specified (for historical reasons, # major v1 was sometimes called without specifying an MML to simply act as # javac; Major v2+'s default is to generate all mutants as opposed to none). # echo echo "Setting up Major ... " MAJOR_VERSION="3.0.1" MAJOR_URL="https://mutation-testing.org/downloads" MAJOR_ZIP="major-${MAJOR_VERSION}_jre11.zip" cd "$BASE" && rm -rf major \ && download_url_and_unzip "$MAJOR_URL/$MAJOR_ZIP" \ && rm "$MAJOR_ZIP" \ && perl -pi -e '$_ .= qq( -Djava.awt.headless=true \\\n) if /CodeCacheSize/' \ major/bin/ant \ && perl -pi -e '$_ .= qq(\nif [ -z "\$MML" ]; then javac \$*; exit \$?; fi\n) if /^REFACTOR=/' \ major/bin/major \ && perl -pi -e '$_ = qq(REFACTOR=\${REFACTOR:-"enable.decl.refactor enable.method.refactor"}\n) if /^REFACTOR=/' \ major/bin/major \ ############################################################################ # # Download EvoSuite # echo echo "Setting up EvoSuite ... " EVOSUITE_VERSION="0.2.0" EVOSUITE_URL="https://github.com/EvoSuite/evosuite/releases/download/v${EVOSUITE_VERSION}" EVOSUITE_JAR="evosuite-${EVOSUITE_VERSION}.jar" EVOSUITE_RT_JAR="evosuite-standalone-runtime-${EVOSUITE_VERSION}.jar" cd "$DIR_LIB_GEN" && download_url "$EVOSUITE_URL/$EVOSUITE_JAR" cd "$DIR_LIB_RT" && download_url "$EVOSUITE_URL/$EVOSUITE_RT_JAR" # Set symlinks for the supported version of EvoSuite (cd "$DIR_LIB_GEN" && ln -sf "$EVOSUITE_JAR" "evosuite-current.jar") (cd "$DIR_LIB_RT" && ln -sf "$EVOSUITE_RT_JAR" "evosuite-rt.jar") ############################################################################ # # Download Randoop # echo echo "Setting up Randoop ... " RANDOOP_VERSION="4.0.4" RANDOOP_URL="https://github.com/randoop/randoop/releases/download/v${RANDOOP_VERSION}" RANDOOP_ZIP="randoop-${RANDOOP_VERSION}.zip" RANDOOP_JAR="randoop-all-${RANDOOP_VERSION}.jar" REPLACECALL_JAR="replacecall-${RANDOOP_VERSION}.jar" COVEREDCLASS_JAR="covered-class-${RANDOOP_VERSION}.jar" (cd "$DIR_LIB_GEN" && download_url_and_unzip "$RANDOOP_URL/$RANDOOP_ZIP") # Set symlink for the supported version of Randoop (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$RANDOOP_JAR" "randoop-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$REPLACECALL_JAR" "replacecall-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$COVEREDCLASS_JAR" "covered-class-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/jacocoagent.jar" "jacocoagent.jar") ############################################################################ # # Download build system dependencies # echo echo "Setting up Gradle dependencies ... " cd "$DIR_LIB_GRADLE" GRADLE_DISTS_ZIP=defects4j-gradle-dists.zip GRADLE_DEPS_ZIP=defects4j-gradle-deps.zip old_dists_ts=0 old_deps_ts=0 if [ -e $GRADLE_DISTS_ZIP ]; then old_dists_ts=$(get_modification_timestamp $GRADLE_DISTS_ZIP) fi if [ -e $GRADLE_DEPS_ZIP ]; then old_deps_ts=$(get_modification_timestamp $GRADLE_DEPS_ZIP) fi # Only download archive if the server has a newer file download_url $HOST_URL/$GRADLE_DISTS_ZIP download_url $HOST_URL/$GRADLE_DEPS_ZIP new_dists_ts=$(get_modification_timestamp $GRADLE_DISTS_ZIP) new_deps_ts=$(get_modification_timestamp $GRADLE_DEPS_ZIP) # Update gradle distributions/dependencies if a newer archive was available [ "$old_dists_ts" != "$new_dists_ts" ] && mkdir "dists" && unzip -q -u $GRADLE_DISTS_ZIP -d "dists" [ "$old_deps_ts" != "$new_deps_ts" ] && unzip -q -u $GRADLE_DEPS_ZIP cd "$BASE" ############################################################################ # # Download utility programs # echo echo "Setting up utility programs ... " BUILD_ANALYZER_VERSION="0.0.1" BUILD_ANALYZER_JAR=build-analyzer-$BUILD_ANALYZER_VERSION.jar BUILD_ANALYZER_URL="https://github.com/jose/build-analyzer/releases/download/v$BUILD_ANALYZER_VERSION/$BUILD_ANALYZER_JAR" BUILD_ANALYZER_JAR_LOCAL="analyzer.jar" cd "$BASE/framework/lib" && download_url "$BUILD_ANALYZER_URL" rm -f "$BUILD_ANALYZER_JAR_LOCAL" ln -s "$BUILD_ANALYZER_JAR" "$BUILD_ANALYZER_JAR_LOCAL" echo echo "Defects4J successfully initialized." } ################################################################################ # # Utility functions # # Print an error message and terminate the script. # Takes one argument, a custom error message. # Prints the supplied error message and a script termination notice to stderr. # Terminates the script with exit code 1. print_error_and_exit() { echo -e "${1} \nTerminating initialization... " >&2 exit 1 } # MacOS does not install the timeout command by default. if [ "$(uname)" = "Darwin" ] ; then function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; } fi # Download the remote resource to a local file of the same name. # Takes a single argument, a URL. # Skips the download if the remote resource is newer. # Works around connections that hang. download_url() { if [ "$#" -ne 1 ]; then echo "Illegal number of arguments" fi URL=$1 echo "Downloading ${URL}" if [ "$(uname)" = "Darwin" ] ; then wget -nv -N "$URL" || print_error_and_exit "Could not download $URL" echo "Downloaded $URL" else BASENAME="$(basename "$URL")" if [ -f "$BASENAME" ]; then ZBASENAME="-z $BASENAME" 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" fi } # Download the remote resource and unzip it. # Takes a single argument, a URL. # Skips the download if the local file of the same name is newer. # Works around connections that hang and corrupted downloads. download_url_and_unzip() { if [ "$#" -ne 1 ]; then echo "Illegal number of arguments" fi URL=$1 BASENAME="$(basename "$URL")" download_url "$URL" if ! unzip -o "$BASENAME" > /dev/null ; then echo "retrying download and unzip" rm -rf "$BASENAME" download_url "$URL" unzip -o "$BASENAME" fi } # Get time of last data modification of a file get_modification_timestamp() { local USAGE="Usage: get_modification_timestamp <file>" if [ "$#" != 1 ]; then print_error_and_exit "$USAGE" fi local f="$1" # The BSD version of stat does not support --version or -c if stat --version &> /dev/null; then # GNU version cmd="stat -c %Y $f" else # BSD version cmd="stat -f %m $f" fi local ts; ts=$($cmd) echo "$ts" } main ``` ::: 修改完成後即可執行初始化。 ``` ./init.sh ``` > 若初始化結果仍有錯誤,請詳讀錯誤內容, > 重新確認 sh檔中對應的網址是否存在,以及網址的內容是否與版本相符合。 > 例如: 確認Major網址https://mutation-testing.org/downloads/ 是否為version 3.0.1 補充說明: 上面init.sh檔案中的工具可能有些版本不相容,所以請自行確認你要使用到的工具是否有版本問題,並切換。 更新: 我要用到major做mutation(人工植入bug),但上面major v3.0.1 和 defects4j v1.2.0 不相容,所以我會用下面init_fixed.sh (將 major 改成 v1.3.2) :::spoiler init_fixed.sh ``` #!/usr/bin/env bash # # Exit the shell script immediately if any of the subsequent commands fails. # immediately set -e # # TODO: Major and the coverage tools should be moved to framework/lib ################################################################################ # This script initializes Defects4J. In particular, it downloads and sets up: # - the project's version control repositories # - the Major mutation framework # - the supported test generation tools # - the supported code coverage tools (TODO) ################################################################################ HOST_URL="https://defects4j.org/downloads" # Directories for project repositories and external libraries BASE="$(cd "$(dirname "$0")"; pwd)" DIR_REPOS="$BASE/project_repos" DIR_LIB_GEN="$BASE/framework/lib/test_generation/generation" DIR_LIB_RT="$BASE/framework/lib/test_generation/runtime" DIR_LIB_GRADLE="$BASE/framework/lib/build_systems/gradle" ################################################################################ main() { echo "Checking system configuration ... " # Check whether wget is available on OSX if [ "$(uname)" = "Darwin" ] ; then if ! wget --version > /dev/null 2>&1; then print_error_and_exit "Couldn't find wget to download dependencies. Please install wget and re-run this script." fi fi # Check whether curl is available if ! curl --version > /dev/null 2>&1; then print_error_and_exit "Couldn't find curl to download dependencies. Please install curl and re-run this script." fi # Check whether unzip is available if ! unzip -v > /dev/null 2>&1; then print_error_and_exit "Couldn't find unzip to extract dependencies. Please install unzip and re-run this script." fi # Create lib folders if necessary mkdir -p "$DIR_LIB_GEN" && mkdir -p "$DIR_LIB_RT" && mkdir -p "$DIR_LIB_GRADLE" ############################################################################ # # Download project repositories if necessary # echo "Setting up project repositories ... " cd "$DIR_REPOS" && ./get_repos.sh ############################################################################ # # Download Major # # Adapt Major's default wrapper scripts: # - set headless to true to support Chart on machines without X. # - do not mutate code unless an MML is specified (for historical reasons, # major v1 was sometimes called without specifying an MML to simply act as # javac; Major v2+'s default is to generate all mutants as opposed to none). # echo echo "Setting up Major ... " MAJOR_VERSION="1.3.2" MAJOR_URL="https://mutation-testing.org/downloads" MAJOR_ZIP="major-${MAJOR_VERSION}_jre7.zip" # Download & unzip Major into $BASE/major cd "$BASE" rm -rf major download_url_and_unzip "$MAJOR_URL/$MAJOR_ZIP" rm -f "$MAJOR_ZIP" # Normalize ant wrapper name: some packages ship .ant instead of ant if [ ! -f major/bin/ant ] && [ -f major/bin/.ant ]; then cp major/bin/.ant major/bin/ant fi # Set headless=true to support Chart on machines without X if [ -f major/bin/ant ]; then perl -pi -e '$_ .= qq( -Djava.awt.headless=true \\\n) if /CodeCacheSize/' major/bin/ant fi # If MML is empty, act like javac (avoid mutating unless explicitly requested) if [ -f major/bin/major ]; then perl -pi -e '$_ .= qq(\nif [ -z "\$MML" ]; then javac \$*; exit \$?; fi\n) if /^REFACTOR=/' major/bin/major perl -pi -e '$_ = qq(REFACTOR=\${REFACTOR:-"enable.decl.refactor enable.method.refactor"}\n) if /^REFACTOR=/' major/bin/major fi ############################################################################ # # Download EvoSuite # echo echo "Setting up EvoSuite ... " EVOSUITE_VERSION="1.0.6" EVOSUITE_URL="https://github.com/EvoSuite/evosuite/releases/download/v${EVOSUITE_VERSION}" EVOSUITE_JAR="evosuite-${EVOSUITE_VERSION}.jar" EVOSUITE_RT_JAR="evosuite-standalone-runtime-${EVOSUITE_VERSION}.jar" cd "$DIR_LIB_GEN" && download_url "$EVOSUITE_URL/$EVOSUITE_JAR" cd "$DIR_LIB_RT" && download_url "$EVOSUITE_URL/$EVOSUITE_RT_JAR" # Set symlinks for the supported version of EvoSuite (cd "$DIR_LIB_GEN" && ln -sf "$EVOSUITE_JAR" "evosuite-current.jar") (cd "$DIR_LIB_RT" && ln -sf "$EVOSUITE_RT_JAR" "evosuite-rt.jar") ############################################################################ # # Download Randoop # echo echo "Setting up Randoop ... " RANDOOP_VERSION="4.0.4" RANDOOP_URL="https://github.com/randoop/randoop/releases/download/v${RANDOOP_VERSION}" RANDOOP_ZIP="randoop-${RANDOOP_VERSION}.zip" RANDOOP_JAR="randoop-all-${RANDOOP_VERSION}.jar" REPLACECALL_JAR="replacecall-${RANDOOP_VERSION}.jar" COVEREDCLASS_JAR="covered-class-${RANDOOP_VERSION}.jar" (cd "$DIR_LIB_GEN" && download_url_and_unzip "$RANDOOP_URL/$RANDOOP_ZIP") # Set symlink for the supported version of Randoop (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$RANDOOP_JAR" "randoop-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$REPLACECALL_JAR" "replacecall-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/$COVEREDCLASS_JAR" "covered-class-current.jar") (cd "$DIR_LIB_GEN" && ln -sf "randoop-${RANDOOP_VERSION}/jacocoagent.jar" "jacocoagent.jar") ############################################################################ # # Download build system dependencies # echo echo "Setting up Gradle dependencies ... " cd "$DIR_LIB_GRADLE" GRADLE_DISTS_ZIP=defects4j-gradle-dists.zip GRADLE_DEPS_ZIP=defects4j-gradle-deps.zip old_dists_ts=0 old_deps_ts=0 if [ -e $GRADLE_DISTS_ZIP ]; then old_dists_ts=$(get_modification_timestamp $GRADLE_DISTS_ZIP) fi if [ -e $GRADLE_DEPS_ZIP ]; then old_deps_ts=$(get_modification_timestamp $GRADLE_DEPS_ZIP) fi # Only download archive if the server has a newer file download_url $HOST_URL/$GRADLE_DISTS_ZIP download_url $HOST_URL/$GRADLE_DEPS_ZIP new_dists_ts=$(get_modification_timestamp $GRADLE_DISTS_ZIP) new_deps_ts=$(get_modification_timestamp $GRADLE_DEPS_ZIP) # Update gradle distributions/dependencies if a newer archive was available [ "$old_dists_ts" != "$new_dists_ts" ] && mkdir "dists" && unzip -q -u $GRADLE_DISTS_ZIP -d "dists" [ "$old_deps_ts" != "$new_deps_ts" ] && unzip -q -u $GRADLE_DEPS_ZIP cd "$BASE" ############################################################################ # # Download utility programs # echo echo "Setting up utility programs ... " BUILD_ANALYZER_VERSION="0.0.1" BUILD_ANALYZER_JAR=build-analyzer-$BUILD_ANALYZER_VERSION.jar BUILD_ANALYZER_URL="https://github.com/jose/build-analyzer/releases/download/v$BUILD_ANALYZER_VERSION/$BUILD_ANALYZER_JAR" BUILD_ANALYZER_JAR_LOCAL="analyzer.jar" cd "$BASE/framework/lib" && download_url "$BUILD_ANALYZER_URL" rm -f "$BUILD_ANALYZER_JAR_LOCAL" ln -s "$BUILD_ANALYZER_JAR" "$BUILD_ANALYZER_JAR_LOCAL" echo echo "Defects4J successfully initialized." } ################################################################################ # # Utility functions # # Print an error message and terminate the script. # Takes one argument, a custom error message. # Prints the supplied error message and a script termination notice to stderr. # Terminates the script with exit code 1. print_error_and_exit() { echo -e "${1} \nTerminating initialization... " >&2 exit 1 } # MacOS does not install the timeout command by default. if [ "$(uname)" = "Darwin" ] ; then function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; } fi # Download the remote resource to a local file of the same name. # Takes a single argument, a URL. # Skips the download if the remote resource is newer. # Works around connections that hang. download_url() { if [ "$#" -ne 1 ]; then echo "Illegal number of arguments" fi URL=$1 echo "Downloading ${URL}" if [ "$(uname)" = "Darwin" ] ; then wget -nv -N "$URL" || print_error_and_exit "Could not download $URL" echo "Downloaded $URL" else BASENAME="$(basename "$URL")" if [ -f "$BASENAME" ]; then ZBASENAME="-z $BASENAME" else ZBASENAME="" fi (timeout 300 curl -f -sS -R -L $ZBASENAME -O "$URL" || (echo "retrying curl $URL" && rm -f "$BASENAME" && curl -f -sS -R -L -O "$URL")) && echo "Downloaded $URL" fi } # Download the remote resource and unzip it. # Takes a single argument, a URL. # Skips the download if the local file of the same name is newer. # Works around connections that hang and corrupted downloads. download_url_and_unzip() { if [ "$#" -ne 1 ]; then echo "Illegal number of arguments" fi URL=$1 BASENAME="$(basename "$URL")" download_url "$URL" if ! unzip -o "$BASENAME" > /dev/null ; then echo "retrying download and unzip" rm -rf "$BASENAME" download_url "$URL" unzip -o "$BASENAME" fi } # Get time of last data modification of a file get_modification_timestamp() { local USAGE="Usage: get_modification_timestamp <file>" if [ "$#" != 1 ]; then print_error_and_exit "$USAGE" fi local f="$1" # The BSD version of stat does not support --version or -c if stat --version &> /dev/null; then # GNU version cmd="stat -c %Y $f" else # BSD version cmd="stat -f %m $f" fi local ts; ts=$($cmd) echo "$ts" } main ``` ::: ### 3. 設定 Defects4J 環境變數 ``` sudo nano ~/.bashrc ``` 輸入以下環境變數。 ``` export PATH=$PATH:~/defects4j/framework/bin export DEFECTS4J_HOME=~/defects4j ``` 執行環境設定,並確認能夠使用defects4j指令。 ``` source ~/.bashrc defects4j ``` (若想要知道"defects4j"這個指令在哪裡就輸入"`whereis defects4j`",就能取得位置。) ### 4. 使用 Defects4J (以 Chart 為例) 輸入指令能夠查看 Chart 整體的資訊。 ``` defects4j info -p Chart ``` 輸入指令則是查看 Chart-1 的詳細資訊。 ``` defects4j info -p Chart -b 1 ``` 下載 Chart-1 (存放位置自訂)。 ``` defects4j checkout -p [Project名稱] -v [project的版本][b表示buggy version] -w [要存放的位置,最後的"chart_1_buggy"表示資料夾要存甚麼名稱,可以自訂] defects4j checkout -p Chart -v 1b -w ~/d4j_project/Chart/chart_1_buggy ``` 進到 Chart-1 的資料夾中,輸入指令可編譯或測試。 ``` defects4j compile defects4j test ``` ## 自動 compile 所有的 bug-id 可以建立一個 sh檔,自動把所有的資料下載下來。 ### 1. 建立一個想要存放 defects4j project 的資料夾 ( p.s. : 要建立各個專案資料夾,不然容易出錯。) ( p.s. : 變數看清楚,常常因為變數問題出錯。) > 我是在Home下建立一個 "d4j_project" 資料夾, > 在裡面再建立 "chart"、"closure"、"math"、"time"、"lang" 資料夾, > 可以直接打開 Document 手動添加。 ### 2. 建立一個 sh檔 > 名稱設定為"all_D4J"。 ``` touch all_D4J.sh ``` ### 3. 寫入 sh檔內容 :::spoiler all_D4J.sh ``` dir=~/d4j_project/ # Store the buggy projects. proj=Chart proj2=chart for bug_id in $(seq 1 26) do cd ~/defects4j/ defects4j checkout -p $proj -v ${bug_id}b -w ${dir}${proj2}/${proj2}_${bug_id}_buggy #cd to checkout folder cd ${dir}${proj2}/${proj2}_${bug_id}_buggy defects4j compile defects4j test done proj=Closure proj2=closure for bug_id in $(seq 1 133) do cd ~/defects4j/ defects4j checkout -p $proj -v ${bug_id}b -w ${dir}${proj2}/${proj2}_${bug_id}_buggy #cd to checkout folder cd ${dir}${proj2}/${proj2}_${bug_id}_buggy defects4j compile defects4j test done proj=Math proj2=math for bug_id in $(seq 1 106) do cd ~/defects4j/ defects4j checkout -p $proj -v ${bug_id}b -w ${dir}${proj2}/${proj2}_${bug_id}_buggy #cd to checkout folder cd ${dir}${proj2}/${proj2}_${bug_id}_buggy defects4j compile defects4j test done proj=Time proj2=time for bug_id in $(seq 1 27) do cd ~/defects4j/ defects4j checkout -p $proj -v ${bug_id}b -w ${dir}${proj2}/${proj2}_${bug_id}_buggy #cd to checkout folder cd ${dir}${proj2}/${proj2}_${bug_id}_buggy defects4j compile defects4j test done proj=Lang proj2=lang for bug_id in $(seq 1 65) do cd ~/defects4j/ defects4j checkout -p $proj -v ${bug_id}b -w ${dir}${proj2}/${proj2}_${bug_id}_buggy #cd to checkout folder cd ${dir}${proj2}/${proj2}_${bug_id}_buggy defects4j compile defects4j test done ``` ::: ### 4. 將 sh檔加入執行權限,並執行 ``` chmod +x all_D4J.sh ./all_D4J.sh ```