赞
踩
Nopol是一个比较成熟的java程序自动修复工具,在此描述在jdk 1.7版本下运行的Nopol存在的一个bug(问题,缺陷)。
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 )
还记得我第一次运行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出现了问题,现具体描述如下。
Ubuntu系统
jdk 1.7
jdk 1.7版本下的Nopol
jdk 1.7版本下的cocospoon
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); } }
2)添加测试用例之后,重新编译nopol,而后测试这个测试用例,脚本指令如下:
mvn package -DskipTests #重新编译,打包
mvn test -Dtest=CocospoonLocalizer2Test #运行指定的测试用例
运行如上命令后,得到失败信息如下:
------------------------------------------------------- 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...
详见: https://github.com/SpoonLabs/nopol/issues/179
详见: https://github.com/SpoonLabs/nopol/pull/180
具体如下:
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 #运行指定的测试用例
会发现,这个java-runtime-exception没了。
1)还是jdk 1.7版本的Nopol,但是这次我下载了cocospoon的兼容1.7版本:
git clone -b compat-java7 https://github.com/SpoonLabs/CoCoSpoon.git
然而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.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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。