From d21ec8186b40caa5ca9939d414bfc6b0663c7701 Mon Sep 17 00:00:00 2001 From: Yoshiki Higo Date: Sun, 8 Jul 2018 13:08:28 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=E5=BF=85=E8=A6=81=E6=95=B0=E3=81=AE?= =?UTF-8?q?=E3=83=90=E3=82=B0=E4=BF=AE=E6=AD=A3=E3=83=97=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E3=83=A9=E3=83=A0=E3=81=8C=E7=94=9F=E6=88=90=E3=81=97=E3=81=9F?= =?UTF-8?q?=E5=A0=B4=E5=90=88=EF=BC=8C=E5=88=B6=E9=99=90=E6=99=82=E9=96=93?= =?UTF-8?q?=E3=81=AB=E9=81=94=E6=88=90=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88?= =?UTF-8?q?=EF=BC=8C=E6=9C=80=E5=A4=A7=E4=B8=96=E4=BB=A3=E6=95=B0=E3=81=AB?= =?UTF-8?q?=E5=88=B0=E9=81=94=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AB?= =?UTF-8?q?GA=E3=81=8C=E7=B5=82=E4=BA=86=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/kusumotolab/kgenprog/CUILauncher.java | 8 +-- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 59 ++++++++++++++++--- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/CUILauncher.java b/src/main/java/jp/kusumotolab/kgenprog/CUILauncher.java index 1ddc8e941..f6c8bab12 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/CUILauncher.java +++ b/src/main/java/jp/kusumotolab/kgenprog/CUILauncher.java @@ -4,6 +4,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; +import org.kohsuke.args4j.spi.StringArrayOptionHandler; import jp.kusumotolab.kgenprog.fl.FaultLocalization; import jp.kusumotolab.kgenprog.fl.Ochiai; import jp.kusumotolab.kgenprog.ga.Crossover; @@ -23,10 +27,6 @@ import jp.kusumotolab.kgenprog.project.factory.JUnitLibraryResolver.JUnitVersion; import jp.kusumotolab.kgenprog.project.factory.TargetProject; import jp.kusumotolab.kgenprog.project.factory.TargetProjectFactory; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.Option; -import org.kohsuke.args4j.spi.StringArrayOptionHandler; public class CUILauncher { diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index ebb20be62..9942064a9 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -4,6 +4,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import jp.kusumotolab.kgenprog.fl.FaultLocalization; import jp.kusumotolab.kgenprog.fl.Suspiciouseness; import jp.kusumotolab.kgenprog.ga.Base; @@ -29,6 +30,12 @@ public class KGenProgMain { private SourceCodeValidation sourceCodeValidation; private VariantSelection variantSelection; private TestProcessBuilder testProcessBuilder; + private final List completedVariants; + + // 以下,一時的なフィールド #146 で解決すべき + private final long timeout; + private final int maxGeneration; + private final int requiredSolutions; // TODO #146 // workingdirのパスを一時的にMainに記述 @@ -38,6 +45,15 @@ public class KGenProgMain { public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization, Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration, SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection) { + + this(targetProject, faultLocalization, mutation, crossover, sourceCodeGeneration, + sourceCodeValidation, variantSelection, 600, 10, 1); + } + + public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization, + Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration, + SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection, + final long timeout, final int maxGeneration, final int requiredSolutions) { this.targetProject = targetProject; this.faultLocalization = faultLocalization; this.mutation = mutation; @@ -46,6 +62,11 @@ public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocaliza this.sourceCodeValidation = sourceCodeValidation; this.variantSelection = variantSelection; this.testProcessBuilder = new TestProcessBuilder(targetProject, WORKING_DIR); + this.completedVariants = new ArrayList<>(); + + this.timeout = timeout; + this.maxGeneration = maxGeneration; + this.requiredSolutions = requiredSolutions; } public void run() { @@ -53,10 +74,16 @@ public void run() { final Variant initialVariant = targetProject.getInitialVariant(); selectedVariants.add(initialVariant); mutation.setCandidates(initialVariant.getGeneratedSourceCode().getFiles()); + + final long startTime = System.nanoTime(); + int generation = 0; while (true) { - if (isTimedOut() || reachedMaxGeneration() || isSuccess(selectedVariants)) { + + // 制限時間に達したか,最大世代数に到達した場合には GA を抜ける + if (isTimedOut(startTime) || reachedMaxGeneration(generation++)) { break; } + List genes = new ArrayList<>(); for (Variant variant : selectedVariants) { List suspiciousenesses = @@ -79,24 +106,40 @@ public void run() { variants.add(variant); } + // この世代で生成された Variants のうち,Fitnessが 1.0 なものを complatedVariants に追加 + final List newComplatedVariants = + variants.stream().filter(v -> 0 == Double.compare(v.getFitness().getValue(), 1.0d)) + .collect(Collectors.toList()); + completedVariants.addAll(newComplatedVariants); + + // しきい値以上の complatedVariants が生成された場合は,GAを抜ける + if (areEnoughComplatedVariants()) { + break; + } + + // Fitness が 1.0 な Variants は除いた上で,次世代を生成するための Variants を選択 + variants.removeAll(newComplatedVariants); selectedVariants = variantSelection.exec(variants); } } // hitori - private boolean reachedMaxGeneration() { - // TODO Auto-generated method stub - return false; + private boolean reachedMaxGeneration(final int generation) { + return this.maxGeneration <= generation; } // hitori - private boolean isTimedOut() { - // TODO Auto-generated method stub - return false; + private boolean isTimedOut(final long startTime) { + final long elapsedTime = System.nanoTime() - startTime; + return elapsedTime > this.timeout * 1000 * 1000; } - // hitori + @Deprecated private boolean isSuccess(List variants) { return false; } + + private boolean areEnoughComplatedVariants() { + return this.requiredSolutions <= completedVariants.size(); + } } From 22fc8229bc35cff340abd8abc07d69d7185cd59f Mon Sep 17 00:00:00 2001 From: YoshikiHigo Date: Wed, 11 Jul 2018 16:16:07 +0900 Subject: [PATCH 2/5] avoid returning null --- .../jp/kusumotolab/kgenprog/ga/SiglePointCrossover.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/ga/SiglePointCrossover.java b/src/main/java/jp/kusumotolab/kgenprog/ga/SiglePointCrossover.java index 486010075..55098f9f2 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/ga/SiglePointCrossover.java +++ b/src/main/java/jp/kusumotolab/kgenprog/ga/SiglePointCrossover.java @@ -1,13 +1,13 @@ package jp.kusumotolab.kgenprog.ga; +import java.util.Collections; import java.util.List; public class SiglePointCrossover implements Crossover { @Override - public List exec(List variants) { - // TODO Auto-generated method stub - return null; + public List exec(final List variants) { + return Collections.emptyList(); } } From 81b46f711a9087f7994ed8d57d37ec99d56691c1 Mon Sep 17 00:00:00 2001 From: YoshikiHigo Date: Wed, 11 Jul 2018 16:16:33 +0900 Subject: [PATCH 3/5] add KGenProgMainTest --- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 9942064a9..6ad045123 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -1,10 +1,13 @@ package jp.kusumotolab.kgenprog; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import org.apache.commons.io.FileUtils; import jp.kusumotolab.kgenprog.fl.FaultLocalization; import jp.kusumotolab.kgenprog.fl.Suspiciouseness; import jp.kusumotolab.kgenprog.ga.Base; @@ -40,20 +43,30 @@ public class KGenProgMain { // TODO #146 // workingdirのパスを一時的にMainに記述 // 別クラスが管理すべき情報? - private final Path WORKING_DIR = Paths.get(System.getProperty("java.io.tmpdir"), "kgenprog-work"); + public final Path workingDir; public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization, Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration, SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection) { - + this(targetProject, faultLocalization, mutation, crossover, sourceCodeGeneration, - sourceCodeValidation, variantSelection, 600, 10, 1); + sourceCodeValidation, variantSelection, 60, 10, 1); } public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocalization, Mutation mutation, Crossover crossover, SourceCodeGeneration sourceCodeGeneration, SourceCodeValidation sourceCodeValidation, VariantSelection variantSelection, final long timeout, final int maxGeneration, final int requiredSolutions) { + + this.workingDir = Paths.get(System.getProperty("java.io.tmpdir"), "kgenprog-work"); + try { + if (Files.exists(this.workingDir)) { + FileUtils.deleteDirectory(this.workingDir.toFile()); + } + } catch (final IOException e) { + e.printStackTrace(); + } + this.targetProject = targetProject; this.faultLocalization = faultLocalization; this.mutation = mutation; @@ -61,12 +74,14 @@ public KGenProgMain(TargetProject targetProject, FaultLocalization faultLocaliza this.sourceCodeGeneration = sourceCodeGeneration; this.sourceCodeValidation = sourceCodeValidation; this.variantSelection = variantSelection; - this.testProcessBuilder = new TestProcessBuilder(targetProject, WORKING_DIR); + this.testProcessBuilder = new TestProcessBuilder(targetProject, this.workingDir); this.completedVariants = new ArrayList<>(); this.timeout = timeout; this.maxGeneration = maxGeneration; this.requiredSolutions = requiredSolutions; + + } public void run() { @@ -131,7 +146,7 @@ private boolean reachedMaxGeneration(final int generation) { // hitori private boolean isTimedOut(final long startTime) { final long elapsedTime = System.nanoTime() - startTime; - return elapsedTime > this.timeout * 1000 * 1000; + return elapsedTime > this.timeout * 1000 * 1000 * 1000; } @Deprecated @@ -142,4 +157,8 @@ private boolean isSuccess(List variants) { private boolean areEnoughComplatedVariants() { return this.requiredSolutions <= completedVariants.size(); } + + public List getComplatedVariants() { + return this.completedVariants; + } } From 334e2babe124ce3b1c4fb8a438b81752d0073f9a Mon Sep 17 00:00:00 2001 From: YoshikiHigo Date: Wed, 11 Jul 2018 16:16:53 +0900 Subject: [PATCH 4/5] small changes --- .../kgenprog/KGenProgMainTest.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java diff --git a/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java b/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java new file mode 100644 index 000000000..5f6c63208 --- /dev/null +++ b/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java @@ -0,0 +1,112 @@ +package jp.kusumotolab.kgenprog; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import jp.kusumotolab.kgenprog.fl.FaultLocalization; +import jp.kusumotolab.kgenprog.fl.Ochiai; +import jp.kusumotolab.kgenprog.ga.Crossover; +import jp.kusumotolab.kgenprog.ga.DefaultCodeValidation; +import jp.kusumotolab.kgenprog.ga.DefaultSourceCodeGeneration; +import jp.kusumotolab.kgenprog.ga.DefaultVariantSelection; +import jp.kusumotolab.kgenprog.ga.Mutation; +import jp.kusumotolab.kgenprog.ga.RandomMutation; +import jp.kusumotolab.kgenprog.ga.SiglePointCrossover; +import jp.kusumotolab.kgenprog.ga.SourceCodeGeneration; +import jp.kusumotolab.kgenprog.ga.SourceCodeValidation; +import jp.kusumotolab.kgenprog.ga.VariantSelection; +import jp.kusumotolab.kgenprog.project.DiffOutput; +import jp.kusumotolab.kgenprog.project.ResultOutput; +import jp.kusumotolab.kgenprog.project.SourceFile; +import jp.kusumotolab.kgenprog.project.TargetSourceFile; +import jp.kusumotolab.kgenprog.project.TestSourceFile; +import jp.kusumotolab.kgenprog.project.factory.JUnitLibraryResolver.JUnitVersion; +import jp.kusumotolab.kgenprog.project.factory.TargetProject; +import jp.kusumotolab.kgenprog.project.factory.TargetProjectFactory; + +public class KGenProgMainTest { + + @Test + public void testExample04() { + + final Path rootPath = Paths.get("example/example04/"); + final List targetSourceFiles = new ArrayList<>(); + targetSourceFiles.add(new TargetSourceFile( + Paths.get("example/example04/src/jp/kusumotolab/BuggyCalculator.java"))); + final List testSourceFiles = new ArrayList<>(); + testSourceFiles.add(new TestSourceFile( + Paths.get("example/example04/src/jp/kusumotolab/BuggyCalculatorTest.java"))); + + final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles, + testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4); + + final FaultLocalization faultLocalization = new Ochiai(); + final Mutation mutation = new RandomMutation(); + final Crossover crossover = new SiglePointCrossover(); + final SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration(); + final SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation(); + final VariantSelection variantSelection = new DefaultVariantSelection(); + + final KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, + crossover, sourceCodeGeneration, sourceCodeValidation, variantSelection); + kGenProgMain.run(); + + final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir); + ro.outputResult(project, kGenProgMain.getComplatedVariants()); + } + + @Test + public void testExample05() { + + final Path rootPath = Paths.get("example/example05/"); + final List targetSourceFiles = new ArrayList<>(); + targetSourceFiles.add(new TargetSourceFile( + Paths.get("example/example05/src/jp/kusumotolab/BuggyCalculator.java"))); + final List testSourceFiles = new ArrayList<>(); + testSourceFiles.add(new TestSourceFile( + Paths.get("example/example05/src/jp/kusumotolab/BuggyCalculatorTest.java"))); + + final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles, + testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4); + + FaultLocalization faultLocalization = new Ochiai(); + Mutation mutation = new RandomMutation(); + Crossover crossover = new SiglePointCrossover(); + SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration(); + SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation(); + VariantSelection variantSelection = new DefaultVariantSelection(); + + KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover, + sourceCodeGeneration, sourceCodeValidation, variantSelection); + kGenProgMain.run(); + } + + @Test + public void testExample06() { + + final Path rootPath = Paths.get("example/example06/"); + final List targetSourceFiles = new ArrayList<>(); + targetSourceFiles.add(new TargetSourceFile( + Paths.get("example/example06/src/jp/kusumotolab/BuggyCalculator.java"))); + final List testSourceFiles = new ArrayList<>(); + testSourceFiles.add(new TestSourceFile( + Paths.get("example/example06/src/jp/kusumotolab/BuggyCalculatorTest.java"))); + + final TargetProject project = TargetProjectFactory.create(rootPath, targetSourceFiles, + testSourceFiles, Collections.emptyList(), JUnitVersion.JUNIT4); + + FaultLocalization faultLocalization = new Ochiai(); + Mutation mutation = new RandomMutation(); + Crossover crossover = new SiglePointCrossover(); + SourceCodeGeneration sourceCodeGeneration = new DefaultSourceCodeGeneration(); + SourceCodeValidation sourceCodeValidation = new DefaultCodeValidation(); + VariantSelection variantSelection = new DefaultVariantSelection(); + + KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover, + sourceCodeGeneration, sourceCodeValidation, variantSelection); + kGenProgMain.run(); + } +} From d92fd16c17c8142354d7df07478015ac400eb4df Mon Sep 17 00:00:00 2001 From: shinsuke-mat Date: Wed, 11 Jul 2018 19:00:06 +0900 Subject: [PATCH 5/5] =?UTF-8?q?a=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kgenprog/project/jdt/JDTOperation.java | 18 +++++++++--------- .../kusumotolab/kgenprog/KGenProgMainTest.java | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTOperation.java b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTOperation.java index c1a12f00a..a5430b901 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTOperation.java +++ b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTOperation.java @@ -2,27 +2,27 @@ import java.util.List; import java.util.stream.Collectors; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.text.edits.MalformedTreeException; import jp.kusumotolab.kgenprog.project.GeneratedAST; import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; import jp.kusumotolab.kgenprog.project.GenerationFailedSourceCode; import jp.kusumotolab.kgenprog.project.Location; import jp.kusumotolab.kgenprog.project.Operation; -import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.text.edits.MalformedTreeException; public interface JDTOperation extends Operation { @Override default public GeneratedSourceCode apply(final GeneratedSourceCode generatedSourceCode, final Location location) { - + try { final List newASTs = generatedSourceCode.getFiles().stream() - .map(ast -> applyEachAST(ast, location)).collect(Collectors.toList()); + .map(ast -> applyEachAST(ast, location)).collect(Collectors.toList()); return new GeneratedSourceCode(newASTs); - }catch (Exception e) { - e.printStackTrace(); + } catch (Exception e) { + // e.printStackTrace(); return GenerationFailedSourceCode.GENERATION_FAILED; } } @@ -49,4 +49,4 @@ default public GeneratedAST applyEachAST(final GeneratedAST ast, final Location public void applyToASTRewrite(final GeneratedJDTAST ast, final JDTLocation location, final ASTRewrite astRewrite); -} \ No newline at end of file +} diff --git a/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java b/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java index 5f6c63208..a56747447 100644 --- a/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java +++ b/src/test/java/jp/kusumotolab/kgenprog/KGenProgMainTest.java @@ -82,6 +82,9 @@ public void testExample05() { KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover, sourceCodeGeneration, sourceCodeValidation, variantSelection); kGenProgMain.run(); + + final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir); + ro.outputResult(project, kGenProgMain.getComplatedVariants()); } @Test @@ -108,5 +111,8 @@ public void testExample06() { KGenProgMain kGenProgMain = new KGenProgMain(project, faultLocalization, mutation, crossover, sourceCodeGeneration, sourceCodeValidation, variantSelection); kGenProgMain.run(); + + final ResultOutput ro = new DiffOutput(kGenProgMain.workingDir); + ro.outputResult(project, kGenProgMain.getComplatedVariants()); } }