Gzoltar 工具【2021.6.11】

1. 下载

官网Github

2. 安装

可以在 Releases 页面直接下载 1.7.2 稳定版本的 Jar 包,或者源码自行打包:

git clone https://github.com/GZoltar/gzoltar
cd gzoltar
mvn package

3. 命令行使用

3.1 官方示例

com.gzoltar.cli.examples 中执行:

./run.sh
  --instrumentation <online|offline>
  [--help]

3.2 D4J示例(分步)

查看官方示例中的 run.sh,结构如下:

  • Envs & Args:
    检查 GZOLTAR_CLI_JARGZOLTAR_AGENT_RT_JAR,准备运行时依赖 JUNIT_JARHAMCREST_JAR
  • Main:
    四个步骤:编译 Compile;收集测试以供运行 listTestMethods;收集覆盖信息 runTestMethods;创建错误报告 faultLocalizationReport

以 D4J 的 Lang-1b 为对象,对其修改:

  • 首先,检查依赖部分的 jar 包路径是否正确。
  • 编译部分交给 defects4j compile 命令完成(⭐)。
    也可以自己编译(如下,但不推荐❌):
 # 将 .java 文件输入到 txt 然后 javac 编译
 find /home/ubuntu/lang_1_buggy/src/main/java -name *.java >> src.txt
 find /home/ubuntu/lang_1_buggy/src/test/java -name *.java >> test.txt
 SRC_DIR=/home/ubuntu/d4j-gzoltar/target/classes
 TEST_DIR=/home/ubuntu/d4j-gzoltar/target/tests
 # 使用 ISO 编码是因为其中该项目存在 UTF-8 不可映射的字符
 javac @src.txt -encoding ISO-8859-1 -d ${SRC_DIR}
 # 补充缺少的依赖包
 javac -cp ${JUNIT_JAR}:${HAMCREST_JAR}:${COMMONS_IO}:${EASY_MOCK}:${SRC_DIR} @test.txt -encoding ISO-8859-1 -d ${TEST_DIR}
  • 列出测试:

这段是官方的参考:

java -cp <project_classpath:gzoltarcli.jar> com.gzoltar.cli.Main listTestMethods \
  <list of folders that contain test classes> \
  --outputFile <path> \
  --includes <test classes/cases to consider, e.g., org.TestFoo#* to include all test cases of test class TestFoo>

对于本例 ,includes 来自 /home/ubuntu/defects4j-2.0.0/framework/projects/<pid>/relevant_tests/<bid>,借助命令获取:

cat "/home/ubuntu/defects4j-2.0.0/framework/projects/<pid>/relevant_tests/<bid>" | sed 's/$/#*/' | sed ':a;N;$!ba;s/\n/:/g' 
java -cp ${JUNIT_JAR}:${HAMCREST_JAR}:${GZOLTAR_CLI_JAR}:${SRC_DIR}:${TEST_DIR} \
  com.gzoltar.cli.Main listTestMethods \
  /home/ubuntu/d4j-gzoltar/target \
  --outputFile /home/ubuntu/d4j-gzoltar/tmp/tests.txt \
  --includes ${RELEVANT_TESTS}
  • 收集覆盖信息:通过 JavaAgent 完成。
参数含义备注
destfilejava 序列化文件gzoltar.ser
buildlocation构建位置源码类路径
includes包括加载的类
excludes排除不排除 “”
inclnolocationclasses(未知)false
output输出格式“file”

这里需要注意 includes 的格式( 错误将无法输出.ser文件 ),cli.example 中的示例为:

org.gzoltar.examples.CharacterCounter:org.gzoltar.examples.CharacterCounter\$*

本例中 includes 来自 /home/ubuntu/defects4j-2.0.0/framework/projects/Lang/loaded_classes/1.src,而 src 中的格式如下:

org.apache.commons.lang3.math.NumberUtils
org.apache.commons.lang3.StringUtils

借助如下命令修改格式:

LOADED_CLASSES_FILE="/home/ubuntu/defects4j-2.0.0/framework/projects/<pid>/loaded_classes/<bid>.src"
NORMAL_CLASSES=$(cat "$LOADED_CLASSES_FILE" | sed 's/$/:/' | sed ':a;N;$!ba;s/\n//g')
INNER_CLASSES=$(cat "$LOADED_CLASSES_FILE" | sed 's/$/$*:/' | sed ':a;N;$!ba;s/\n//g')
LOADED_CLASSES="$NORMAL_CLASSES$INNER_CLASSES"

执行:

java -javaagent:${GZOLTAR_AGENT_JAR}=destfile=<GZOLTAR.ser>,buildlocation=${SRC_DIR},includes=${LOADED_CLASSES},excludes="",inclnolocationclasses=false,output="file" \
  -cp ${JUNIT_JAR}:${HAMCREST_JAR}:${GZOLTAR_CLI_JAR}:${SRC_DIR}:${TEST_DIR} \
  com.gzoltar.cli.Main runTestMethods \
  --testMethods <tests.txt> \ # 上一步生成的文件
  --collectCoverage 
  • 创建错误报告:
java -cp ${SRC_DIR}:${TEST_DIR}:${JUNIT_JAR}:${HAMCREST_JAR}:${GZOLTAR_CLI_JAR} \
  com.gzoltar.cli.Main faultLocalizationReport \
    --buildLocation ${SRC_DIR} \
    --granularity "line" \
    --inclPublicMethods \
    --inclStaticConstructors \
    --inclDeprecatedMethods \
    --dataFile <GZOLTAR.ser> \
    --outputDirectory "/home/ubuntu/d4j-gzoltar" \
    --family "sfl" \
    --formula "ochiai" \
    --metric "entropy" \
    --formatter "txt" 

成功生成所需文件!!!
在这里插入图片描述
这里对 faultLocalizationReport 仔细分析下:

参数说明
buildLocationJava class 文件
dataFile.ser 文件
excludes不报告的 classes,可用? * :
family错误定位技术族,默认 SBFL/SFL
formatter格式,默认txt,使用 : 分隔
formula公式,默认 Ochiai,使用 : 分隔
granularity粒度,默认:line,还有 method 和 class
help帮助,默认 false
inclDeprecatedMethods是否报告已被注释弃用的方法,默认true
inclPublicMethods是否报告每个 class 的 public methods,默认 true
inclStaticConstructors是否报告每个 class 的 public static constructors,默认 false
includes报告的 classes,可用? * :
metric排名指标,默认 ambiguity,使用 : 分隔
outputDirectory输出目录
quietsuppress all output on stdout

3.3 脚本化

作者在 Issues-30 给出了可参考框架,项目 Fault-localization-data 也提供了脚本。这里给出一个单项目的脚本(许多细节未处理),稍加修改就可以满足整体脚本化需求。

SCRIPT_DIR=$(pwd)

PID=$1
BID=$2
PROJECT_DIR=/home/ubuntu/${PID}_${BID}_buggy

# Checkout defects4j project
defects4j checkout -p ${PID} -v ${BID}b -w ${PROJECT_DIR}
cd ${PROJECT_DIR}
defects4j compile
SRC_DIR=${PROJECT_DIR}/$(defects4j export -p dir.bin.classes)
TEST_DIR=${PROJECT_DIR}/$(defects4j export -p dir.bin.tests)
LIB_DIR=$(defects4j export -p cp.test)

RELEVANT_TESTS_FILE=${D4J_HOME}/framework/projects/${PID}/relevant_tests/${BID}
RELEVANT_TESTS=$(cat ${RELEVANT_TESTS_FILE} | sed 's/$/#*/' | sed ':a;N;$!ba;s/\n/:/g')

# List test methods
java -cp ${LIB_DIR}:${GZOLTAR_CLI_JAR} \
  com.gzoltar.cli.Main listTestMethods \
  ${TEST_DIR} \
  --outputFile ${PROJECT_DIR}/listTestMethods.txt \
  --includes ${RELEVANT_TESTS}

SER_FILE=${PROJECT_DIR}/gzoltar.ser
LOADED_CLASSES_FILE=${D4J_HOME}/framework/projects/${PID}/loaded_classes/${BID}.src
NORMAL_CLASSES=$(cat ${LOADED_CLASSES_FILE} | sed 's/$/:/' | sed ':a;N;$!ba;s/\n//g')
INNER_CLASSES=$(cat ${LOADED_CLASSES_FILE} | sed 's/$/$*:/' | sed ':a;N;$!ba;s/\n//g')
LOADED_CLASSES=${NORMAL_CLASSES}${INNER_CLASSES}

# Generate .ser file
java -javaagent:${GZOLTAR_AGENT_JAR}=destfile=${SER_FILE},buildlocation=${SRC_DIR},includes=${LOADED_CLASSES},excludes="",inclnolocationclasses=false,output="file" \
  -cp ${GZOLTAR_CLI_JAR}:${LIB_DIR} \
  com.gzoltar.cli.Main runTestMethods \
  --testMethods ${PROJECT_DIR}/listTestMethods.txt \
  --collectCoverage 

# Generate report
java -cp ${GZOLTAR_CLI_JAR}:${LIB_DIR} \
  com.gzoltar.cli.Main faultLocalizationReport \
    --buildLocation ${SRC_DIR} \
    --granularity line \
    --inclPublicMethods \
    --inclStaticConstructors \
    --inclDeprecatedMethods \
    --dataFile ${SER_FILE} \
    --outputDirectory ${PROJECT_DIR} \
    --family sfl \
    --formula ochiai \
    --metric entropy \
    --formatter txt

# Simple file processing
MATRIX_FILE=${PROJECT_DIR}/sfl/txt/matrix.txt
SPECTRA_FILE=${PROJECT_DIR}/sfl/txt/spectra.csv
TESTS_FILE=${PROJECT_DIR}/sfl/txt/tests.csv

ARCHIVE_DIR=/home/ubuntu/exec_info/${PID}/${BID}
mkdir -p ${ARCHIVE_DIR}

mv ${MATRIX_FILE} ${ARCHIVE_DIR}/matrix
tail -n +2 ${SPECTRA_FILE} > ${ARCHIVE_DIR}/spectra
tail -n +2 ${TESTS_FILE} > ${ARCHIVE_DIR}/tests

# Copied code
# Remove inner class(es) names (as there is not a .java file for each one)
sed -i -E 's/(\$\w+)\$.*#/\1#/g' ${ARCHIVE_DIR}/spectra
# Remove method name of each row in the spectra file
sed -i 's/#.*:/#/g' ${ARCHIVE_DIR}/spectra
# Replace class name symbol
sed -i 's/\$/./g' ${ARCHIVE_DIR}/spectra 

# Verification trigger/failed tests
cat ${D4J_HOME}/framework/projects/${PID}/trigger_tests/${BID} | sed -n 's/--- //p' | sort > ${PROJECT_DIR}/d4j_tests_tmp
grep -w "FAIL" ${ARCHIVE_DIR}/tests | awk -F ',' '{print $1}' | sed -n 's/#/::/p' | sort >  ${PROJECT_DIR}/gzoltar_tests_tmp
DIFF_INFO=$(diff ${PROJECT_DIR}/d4j_tests_tmp  ${PROJECT_DIR}/gzoltar_tests_tmp)
if [[ -n ${DIFF_INFO} ]]; then
	echo -e "${PID}-${BID}:\n${DIFF_INFO}" >> /home/ubuntu/exec_info/${PID}/log
fi

# Delete redundant files
rm -rf ${PROJECT_DIR}

其中 D4J_HOME| GZOLTAR_CLI_JAR | GZOLTAR_AGENT_JAR 的配置不在脚本中。

执行示例:./util.sh Lang 3

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值