当前位置:   article > 正文

自动修复工具:探究在jdk1.7下运行的Nopol存在的一个bug_nopoll bug

nopoll bug

前言

Nopol是一个比较成熟的java程序自动修复工具,在此描述在jdk 1.7版本下运行的Nopol存在的一个bug(问题,缺陷)。

1 Nopol介绍

Nopol对应文章:

Xuan J , Martinez M , Demarco F , et al. Nopol: Automatic Repair of Conditional Statement Bugs in Java Programs[J]. IEEE Transactions on Software Engineering, 2017, 43(1):34-55.

顶刊级别的文章,可以说非常厉害了。

当然,对应文章还有:(更早的Nopol雏形)

“Automatic Repair of Buggy If Conditions and Missing Preconditions with SMT” (Favio DeMarco, Jifeng Xuan, Daniel Le Berre, Martin Monperrus), In Proceedings of the 6th International Workshop on Constraints in Software Testing, Verification, and Analysis (CSTVA 2014) (Bibtex)

DynaMoth: Dynamic Code Synthesis for Automatic Program Repair (Thomas Durieux, Martin Monperrus), In Proceedings of the 11th International Workshop in Automation of Software Test, 2016, describes the dynamic synthesis part of Nopol (Bibtex)

Automatic Repair of Infinite Loops (Sebastian Lamelas-Marcote and Martin Monperrus), Technical report hal-01144026, University of Lille, 2015, describes the Infinitel part. (Bibtex)

Nopol的github网址:https://github.com/SpoonLabs/nopol

截止当前时间2019年2月13日10:15:29,Nopol总共有806个commits,可以说更新非常之频繁了。(参考: https://github.com/SpoonLabs/nopol/commits/master

2 Nopol运行的环境

还记得我第一次运行Nopol的时候,大概是2017年5月份左右,那时候Nopol还是在jdk 1.7版本下运行。

但是后来,不知道什么时候改成了jdk 1.8版本。

但是呢,我做实验一般还是用jdk1.7版本的Nopol,因为现在的学术研究在java自动修复上主要使用的benchmark是defects4j 1.1.0版本,这个版本是不支持jdk 1.8版本的,只支持1.7版本。

所以为了和defects4j中的缺陷程序想适应,我使用的一直是jdk 1.7版本下的Nopol。


注意:Nopol在缺陷定位上,其实是集合了多个定位工具的,(具体请参考: https://github.com/SpoonLabs/nopol/tree/master/nopol/src/main/java/fr/inria/lille/localization ),如:GZoltar,Cocospoon等等。
且,之前我使用nopol做实验的时候,一直是用的GZoltar缺陷定位工具,后来,我把缺陷定位工具换成cocospoon之后,Nopol出现了问题,现具体描述如下。

3 jdk 1.7下的Nopol版本存在的缺陷

3.1 产生bug的环境

Ubuntu系统
jdk 1.7
jdk 1.7版本下的Nopol
jdk 1.7版本下的cocospoon

3.2 产生bug的操作

1)在nopol源代码的测试文件夹:nopol\src\test\java\fr\inria\lille\localization 下面添加一个测试文件:CocospoonLocalizer2Test.java

里面内容如下:

package fr.inria.lille.localization;

import fr.inria.lille.localization.metric.Ochiai;
import fr.inria.lille.repair.common.config.NopolContext;
import fr.inria.lille.repair.nopol.SourceLocation;
import org.junit.Assert;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;

import java.util.*; //added by deheng
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.util.Properties;

import static gov.nasa.jpf.util.test.TestJPF.assertEquals;
import static gov.nasa.jpf.util.test.TestJPF.assertTrue;

/**
 * Modified by deheng on Feb 1, 2019.
 * This test aims to expose the java.lang.RuntimeException when running test cases in Math_58, a real bug from defects4j. But this test file (CocospoonLocalizerTest.java) is created based on the version of Nopol of March 2017.
 * Use `mvn clean package -DskipTests` to build nopol and use `mvn test -Dtest=CocospoonLocalizerTest` to run this test.
 */
public class CocospoonLocalizer2Test {

    @Test
    public void testOchiaiCoCoSpoonLocalizer() throws Exception {
	String command = "mkdir ../Math_58 && cd ../Math_58 &&  defects4j checkout -p Math -v 58b -w . && cd ../nopol";
	Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", command});
	p.waitFor();
	if (p.exitValue() != 0) {
		System.out.println("defects4j download Math_58 failed.");
	}
	Process p2 = Runtime.getRuntime().exec(new String[]{"sh", "-c", "cd ../Math_58 && defects4j test && cd ../nopol"});
        p2.waitFor();
        if (p2.exitValue() != 0) {
                System.out.println("defects4j test Math_58 failed.");
        }
        File[] sources = new File[]{new File("../Math_58/src/main/java")}; // This is the source file of Math_58 
	String tests="org.apache.commons.math.distribution.HypergeometricDistributionTest"; // This test is the targeted test that can expose the problem of cocospoon.
        URL[] classpath = new URL[]{
                new File("../Math_58/target/classes/").toURI().toURL(),
                new File("../Math_58/target/test-classes/").toURI().toURL()
        }; // This corresponds to the paths of java classes files.
	String[] testClasses = tests.split(", ");
        CocoSpoonBasedSpectrumBasedFaultLocalizer localizer = new CocoSpoonBasedSpectrumBasedFaultLocalizer(new NopolContext(sources, classpath, testClasses), new Ochiai());
        Map<SourceLocation, List<TestResult>> executedSourceLocationPerTest = localizer.getTestListPerStatement();

        SourceLocation sourceLocation1 = new SourceLocation("org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer", 741);

	//System.out.println("dale stmt 0:"+executedSourceLocationPerTest.size()+"   "+new ArrayList<>(executedSourceLocationPerTest.keySet()).get(0) +new ArrayList<>(executedSourceLocationPerTest.keySet()).get(0).getSuspiciousValue()  );
        assertTrue(executedSourceLocationPerTest.keySet().contains(sourceLocation1));

        //List<SourceLocation> sortedStatements = new ArrayList<>(executedSourceLocationPerTest.keySet());

        //assertEquals(1, sortedStatements.get(0).getSuspiciousValue(), 10E-3);
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

2)添加测试用例之后,重新编译nopol,而后测试这个测试用例,脚本指令如下:

mvn package -DskipTests  #重新编译,打包
mvn test -Dtest=CocospoonLocalizer2Test #运行指定的测试用例
  • 1
  • 2

3.3 失败信息

运行如上命令后,得到失败信息如下:
在这里插入图片描述

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running fr.inria.lille.localization.CocospoonLocalizer2Test
defects4j download Math_58 failed.
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 124.819 sec <<< FAILURE!
testOchiaiCoCoSpoonLocalizer(fr.inria.lille.localization.CocospoonLocalizer2Test)  Time elapsed: 124.229 sec  <<< ERROR!
java.lang.RuntimeException: java.util.concurrent.TimeoutException
	at java.util.concurrent.FutureTask.get(FutureTask.java:201)
	at xxl.java.junit.TestSuiteExecution.executionResult(TestSuiteExecution.java:99)
	at xxl.java.junit.TestSuiteExecution.runTest(TestSuiteExecution.java:39)
	at fr.inria.lille.localization.CocoSpoonBasedSpectrumBasedFaultLocalizer.runTests(CocoSpoonBasedSpectrumBasedFaultLocalizer.java:50)
	at fr.inria.lille.localization.DumbFaultLocalizerImpl.<init>(DumbFaultLocalizerImpl.java:30)
	at fr.inria.lille.localization.CocoSpoonBasedSpectrumBasedFaultLocalizer.<init>(CocoSpoonBasedSpectrumBasedFaultLocalizer.java:33)
	at fr.inria.lille.localization.CocospoonLocalizer2Test.testOchiaiCoCoSpoonLocalizer(CocospoonLocalizer2Test.java:50)


Results :

Tests in error: 
  CocospoonLocalizer2Test.testOchiaiCoCoSpoonLocalizer:50 » Runtime java.util.co...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4 进行的一些尝试

4.1 在github上提问

详见: https://github.com/SpoonLabs/nopol/issues/179
在这里插入图片描述

4.2 提出pull request

详见: https://github.com/SpoonLabs/nopol/pull/180

具体如下:
在这里插入图片描述

4.3 成功尝试

1)下载jdk 1.8版本的Nopol,即:git clone https://github.com/DehengYang/nopol.git
2)并且,配置cocospoon jdk 1.8版本。(这一步非常重要)
3)如3.2-2):

mvn package -DskipTests  #重新编译,打包
mvn test -Dtest=CocospoonLocalizer2Test #运行指定的测试用例
  • 1
  • 2

会发现,这个java-runtime-exception没了。

4.4 失败尝试

1)还是jdk 1.7版本的Nopol,但是这次我下载了cocospoon的兼容1.7版本:

git clone -b compat-java7 https://github.com/SpoonLabs/CoCoSpoon.git
  • 1

然而mvn clean install出现问题,有测试用例无法通过,无奈之下运行:
mvn install -DskipTests
成功打包。

然后运行Nopol下我写的测试用例,还是出错:
在这里插入图片描述

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running fr.inria.lille.localization.CocospoonLocalizer2Test
defects4j download Math_58 failed.
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 93.992 sec <<< FAILURE!
testOchiaiCoCoSpoonLocalizer(fr.inria.lille.localization.CocospoonLocalizer2Test)  Time elapsed: 93.398 sec  <<< ERROR!
java.lang.NoSuchMethodError: spoon.reflect.code.CtBlock.addStatement(ILspoon/reflect/code/CtStatement;)Lspoon/reflect/code/CtStatementList;
	at fil.iagl.opl.cocospoon.insert.impl.SynchronizedInsert.apply(SynchronizedInsert.java:18)
	at fil.iagl.opl.cocospoon.processors.WatcherProcessor.instrumentLine(WatcherProcessor.java:80)
	at fil.iagl.opl.cocospoon.processors.WatcherProcessor.findMatcherAndApply(WatcherProcessor.java:63)
	at fil.iagl.opl.cocospoon.processors.WatcherProcessor.process(WatcherProcessor.java:55)
	at fil.iagl.opl.cocospoon.processors.WatcherProcessor.process(WatcherProcessor.java:16)
	at spoon.support.visitor.ProcessingVisitor.scan(ProcessingVisitor.java:92)
	at spoon.support.RuntimeProcessingManager.process(RuntimeProcessingManager.java:145)
	at spoon.support.RuntimeProcessingManager.process(RuntimeProcessingManager.java:133)
	at fr.inria.lille.commons.spoon.SpoonedFile.processModelledClasses(SpoonedFile.java:152)
	at fr.inria.lille.commons.spoon.SpoonedFile.process(SpoonedFile.java:143)
	at fr.inria.lille.commons.spoon.SpoonedFile.processedAndDumpedToClassLoader(SpoonedFile.java:134)
	at fr.inria.lille.commons.spoon.SpoonedFile.processedAndDumpedToClassLoader(SpoonedFile.java:130)
	at fr.inria.lille.localization.CocoSpoonBasedSpectrumBasedFaultLocalizer.runTests(CocoSpoonBasedSpectrumBasedFaultLocalizer.java:40)
	at fr.inria.lille.localization.DumbFaultLocalizerImpl.<init>(DumbFaultLocalizerImpl.java:30)
	at fr.inria.lille.localization.CocoSpoonBasedSpectrumBasedFaultLocalizer.<init>(CocoSpoonBasedSpectrumBasedFaultLocalizer.java:33)
	at fr.inria.lille.localization.CocospoonLocalizer2Test.testOchiaiCoCoSpoonLocalizer(CocospoonLocalizer2Test.java:50)


Results :

Tests in error: 
  CocospoonLocalizer2Test.testOchiaiCoCoSpoonLocalizer:50 ? NoSuchMethod spoon.r...

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

5 Nopol的CoCoSpoon缺陷定位失败的原因

在如上一番尝试之后,我发现,原来是1.7版本的CoCospoon存在问题。更新到1.8版本之后,就可以正常的进行缺陷定位了。

是不是这样也推动了Nopol向jdk1.8版本迈进呢?

但是现在defects4j还没有跟上。

所以,只能先这样了。

感想

致谢Nopol开发者,实在是非常耐心,非常给力。
无奈的是自己还很多知识不懂。还要继续努力。

小结

又是一个上午的研究,时间真的过得太快,由不得人

参考文献

[1] git修改文件后,怎么提交到远程仓库 https://blog.csdn.net/nly19900820/article/details/73613654
[2] 使用git克隆指定分支的代码 https://www.cnblogs.com/nylcy/p/6569284.html
[3] Java 执行系统命令 https://www.cnblogs.com/bencakes/p/6139477.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/241777
推荐阅读
相关标签
  

闽ICP备14008679号