From 68ee3acdead4d5075547f61187829cde3fa4ce15 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Mon, 14 May 2018 15:56:23 +0200 Subject: [PATCH 01/14] Don't add try/catch for expected exceptions --- .../assertGenerator/AssertGenerator.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java b/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java index 717abb7ba..b374c67aa 100644 --- a/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java +++ b/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java @@ -5,11 +5,13 @@ import fr.inria.diversify.utils.compilation.DSpotCompiler; import fr.inria.diversify.utils.compilation.TestCompiler; import fr.inria.diversify.utils.sosiefier.InputConfiguration; +import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -130,8 +132,22 @@ private List> innerAssertionAmplification(CtType testClass, List> failingTests = tests.stream() - .filter(ctMethod -> - failuresMethodName.contains(ctMethod.getSimpleName())) + .filter(ctMethod -> { + if (failuresMethodName.contains(ctMethod.getSimpleName())) { + Annotation annotation = ctMethod.getAnnotation(org.junit.Test.class); + if (annotation != null) { + Class expected_exception = ((Test) annotation).expected(); + if (expected_exception != org.junit.Test.None.class) { + final String nameRaisedException = testResult.getFailureOf(ctMethod.getSimpleName()).fullQualifiedNameOfException; + final String nameExpectedException = expected_exception.getName(); + // the raised exception should be unexpected + return nameExpectedException.equals(nameRaisedException); + } + } + } + return false; + } + ) .map(ctMethod -> this.tryCatchFailGenerator .surroundWithTryCatchFail(ctMethod, testResult.getFailureOf(ctMethod.getSimpleName())) From 02a26c35dfbe2e5b2784d2f2e00b8360893350cc Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Mon, 14 May 2018 15:57:13 +0200 Subject: [PATCH 02/14] test: don't add try/catch for expected exceptions --- .../dspot/assertGenerator/AssertGeneratorTest.java | 8 ++++++++ .../test/java/fr/inria/filter/passing/PassingTest.java | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/dspot/src/test/java/fr/inria/diversify/dspot/assertGenerator/AssertGeneratorTest.java b/dspot/src/test/java/fr/inria/diversify/dspot/assertGenerator/AssertGeneratorTest.java index e7902bae9..3a5ab4f7e 100644 --- a/dspot/src/test/java/fr/inria/diversify/dspot/assertGenerator/AssertGeneratorTest.java +++ b/dspot/src/test/java/fr/inria/diversify/dspot/assertGenerator/AssertGeneratorTest.java @@ -174,6 +174,14 @@ public void testMakeFailureTest() throws Exception { assertTrue(generatedAssertion.isEmpty()); } + @Test + public void testMakeExpectedFailureTest() throws Exception { + CtClass testClass = Utils.findClass("fr.inria.filter.passing.PassingTest"); + final CtMethod testAssertionError = Utils.findMethod("fr.inria.filter.passing.PassingTest", "testNPEExpected"); + final List> generatedAssertion = assertGenerator.assertionAmplification(testClass, Collections.singletonList(testAssertionError)); + assertTrue(generatedAssertion.isEmpty()); + } + private static final String expectedBody = "{" + AmplificationHelper.LINE_SEPARATOR + " fr.inria.sample.ClassWithBoolean cl = new fr.inria.sample.ClassWithBoolean();" + AmplificationHelper.LINE_SEPARATOR + " org.junit.Assert.assertTrue(((fr.inria.sample.ClassWithBoolean)cl).getBoolean());" + AmplificationHelper.LINE_SEPARATOR + diff --git a/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java b/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java index 1fcb6a498..25118d279 100644 --- a/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java +++ b/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java @@ -2,6 +2,7 @@ import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; /** @@ -20,4 +21,10 @@ public void testAssertion() throws Exception { public void failingTestCase() throws Exception { assertFalse(true); } + + @Test (expected = NullPointerException.class) + public void testNPEExpected() throws Exception { + String nullString = null; + assertEquals(-1, nullString.length()); + } } From 8548e2e72a51162c6996fcd8d928699b2a3b2c5b Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Mon, 14 May 2018 17:53:10 +0200 Subject: [PATCH 03/14] Revert "Don't add try/catch for expected exceptions" This reverts commit 68ee3acdead4d5075547f61187829cde3fa4ce15. --- .../assertGenerator/AssertGenerator.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java b/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java index b374c67aa..717abb7ba 100644 --- a/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java +++ b/dspot/src/main/java/fr/inria/diversify/dspot/assertGenerator/AssertGenerator.java @@ -5,13 +5,11 @@ import fr.inria.diversify.utils.compilation.DSpotCompiler; import fr.inria.diversify.utils.compilation.TestCompiler; import fr.inria.diversify.utils.sosiefier.InputConfiguration; -import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; -import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -132,22 +130,8 @@ private List> innerAssertionAmplification(CtType testClass, List> failingTests = tests.stream() - .filter(ctMethod -> { - if (failuresMethodName.contains(ctMethod.getSimpleName())) { - Annotation annotation = ctMethod.getAnnotation(org.junit.Test.class); - if (annotation != null) { - Class expected_exception = ((Test) annotation).expected(); - if (expected_exception != org.junit.Test.None.class) { - final String nameRaisedException = testResult.getFailureOf(ctMethod.getSimpleName()).fullQualifiedNameOfException; - final String nameExpectedException = expected_exception.getName(); - // the raised exception should be unexpected - return nameExpectedException.equals(nameRaisedException); - } - } - } - return false; - } - ) + .filter(ctMethod -> + failuresMethodName.contains(ctMethod.getSimpleName())) .map(ctMethod -> this.tryCatchFailGenerator .surroundWithTryCatchFail(ctMethod, testResult.getFailureOf(ctMethod.getSimpleName())) From 5806f2fdca2a858158ea4642db9af982c4027a00 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 09:57:27 +0200 Subject: [PATCH 04/14] fix number of passing tests --- dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java index eddb35d8d..6a68cb676 100644 --- a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java +++ b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java @@ -39,7 +39,7 @@ public void testExcludedClassesInPropertyFile() throws Exception { new JacocoCoverageSelector() ); // the test class fr.inria.filter.passing.PassingTest has 2 method, but only one is amplified - assertEquals(2, Utils.findClass("fr.inria.filter.passing.PassingTest").getMethods().size()); + assertEquals(3, Utils.findClass("fr.inria.filter.passing.PassingTest").getMethods().size()); // the test class fr.inria.filter.failing.FailingTest match the regex, but it is excluded in the properties final List ctTypes = dSpot.amplifyTest("fr.inria.filter.*"); assertEquals(1, ctTypes.size()); From e0ce422f83bcf9c506c1ba0da337fbda6eab9a66 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 09:58:53 +0200 Subject: [PATCH 05/14] Don't completely override existing test annotation --- .../diversify/utils/AmplificationHelper.java | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 61f162f72..01789f2ea 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -8,6 +8,7 @@ import fr.inria.stamp.minimization.Minimizer; import org.junit.After; import org.junit.Before; +import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spoon.reflect.code.CtComment; @@ -45,6 +46,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static java.lang.Math.toIntExact; + /** * Created by Benjamin DANGLOT * benjamin.danglot@inria.fr @@ -344,17 +347,17 @@ private static CtMethod cloneMethod(CtMethod method, String suffix) { */ private static CtMethod cloneTestMethod(CtMethod method, String suffix) { CtMethod cloned_method = cloneMethod(method, suffix); - CtAnnotation testAnnotation = cloned_method.getAnnotations().stream() - .filter(annotation -> annotation.toString().contains("Test")) - .findFirst().orElse(null); - if (testAnnotation != null) { - cloned_method.removeAnnotation(testAnnotation); - } final Factory factory = method.getFactory(); prepareTestMethod(cloned_method, factory); return cloned_method; } + /** + * Modifies the test annotation of a method by adding a timeout limit. + * + * @param cloned_method The test method to modify + * @param factory The factory to create the new updated test annotation + */ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { CtAnnotation testAnnotation; testAnnotation = factory.Core().createAnnotation(); @@ -367,10 +370,29 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { testAnnotation.setAnnotationType(ref); Map elementValue = new HashMap<>(); - elementValue.put("timeout", timeOutInMs); + LOGGER.info(cloned_method.getAnnotations().toString()); + java.lang.annotation.Annotation originalTestAnnotation = cloned_method.getAnnotation(org.junit.Test.class); + if (originalTestAnnotation != null) { + int originalTimeout = toIntExact(((Test) originalTestAnnotation).timeout()); + if (originalTimeout < timeOutInMs) + elementValue.put("timeout", timeOutInMs); + else + elementValue.put("timeout", originalTimeout); + Class originalExpected = ((Test) originalTestAnnotation).expected(); + LOGGER.info(originalExpected.toString()); + if (originalExpected != org.junit.Test.None.class) + elementValue.put("expected", originalExpected); + } else { + elementValue.put("timeout", timeOutInMs); + } testAnnotation.setElementValues(elementValue); + CtAnnotation ctAnnotation = cloned_method.getAnnotations().stream() + .filter(annotation -> annotation.toString().contains("Test")) + .findFirst().orElse(null); + cloned_method.removeAnnotation(ctAnnotation); cloned_method.addAnnotation(testAnnotation); + LOGGER.info(cloned_method.getAnnotations().toString()); cloned_method.addThrownType(factory.Type().createReference(Exception.class)); } From a5de852470ec7df5a00e9fa4faea40cb66ba29c1 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 10:17:53 +0200 Subject: [PATCH 06/14] fix number of valid test methods --- dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java index 6a68cb676..40c375f00 100644 --- a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java +++ b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java @@ -44,7 +44,7 @@ public void testExcludedClassesInPropertyFile() throws Exception { final List ctTypes = dSpot.amplifyTest("fr.inria.filter.*"); assertEquals(1, ctTypes.size()); // uses the mock to retrieve the number of method to be amplified - assertEquals(1, dSpot.numberOfMethod); + assertEquals(2, dSpot.numberOfMethod); } private class MockDSpot extends DSpot { From 3e5ffc09416116a5efb683013f2dbb96b57505d1 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 10:19:45 +0200 Subject: [PATCH 07/14] update test doc --- dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java index 40c375f00..00d96d4bf 100644 --- a/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java +++ b/dspot/src/test/java/fr/inria/diversify/dspot/DSpotTest.java @@ -38,7 +38,7 @@ public void testExcludedClassesInPropertyFile() throws Exception { Collections.singletonList(new TestMethodCallAdder()), new JacocoCoverageSelector() ); - // the test class fr.inria.filter.passing.PassingTest has 2 method, but only one is amplified + // the test class fr.inria.filter.passing.PassingTest has 3 methods, but only two are amplified assertEquals(3, Utils.findClass("fr.inria.filter.passing.PassingTest").getMethods().size()); // the test class fr.inria.filter.failing.FailingTest match the regex, but it is excluded in the properties final List ctTypes = dSpot.amplifyTest("fr.inria.filter.*"); From a16856920a2be68a7e0ea306eb152170c2995f62 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 10:37:32 +0200 Subject: [PATCH 08/14] remove debug logger calls --- .../java/fr/inria/diversify/utils/AmplificationHelper.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 01789f2ea..dd0d57cb8 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -370,7 +370,6 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { testAnnotation.setAnnotationType(ref); Map elementValue = new HashMap<>(); - LOGGER.info(cloned_method.getAnnotations().toString()); java.lang.annotation.Annotation originalTestAnnotation = cloned_method.getAnnotation(org.junit.Test.class); if (originalTestAnnotation != null) { int originalTimeout = toIntExact(((Test) originalTestAnnotation).timeout()); @@ -379,7 +378,6 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { else elementValue.put("timeout", originalTimeout); Class originalExpected = ((Test) originalTestAnnotation).expected(); - LOGGER.info(originalExpected.toString()); if (originalExpected != org.junit.Test.None.class) elementValue.put("expected", originalExpected); } else { @@ -392,7 +390,6 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { .findFirst().orElse(null); cloned_method.removeAnnotation(ctAnnotation); cloned_method.addAnnotation(testAnnotation); - LOGGER.info(cloned_method.getAnnotations().toString()); cloned_method.addThrownType(factory.Type().createReference(Exception.class)); } From 88b18469b309a035130fc430f2f9af7a5625111d Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 10:40:19 +0200 Subject: [PATCH 09/14] checkstyle mandatory braces --- .../fr/inria/diversify/utils/AmplificationHelper.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index dd0d57cb8..011e2a10c 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -373,13 +373,15 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { java.lang.annotation.Annotation originalTestAnnotation = cloned_method.getAnnotation(org.junit.Test.class); if (originalTestAnnotation != null) { int originalTimeout = toIntExact(((Test) originalTestAnnotation).timeout()); - if (originalTimeout < timeOutInMs) + if (originalTimeout < timeOutInMs) { elementValue.put("timeout", timeOutInMs); - else + } else { elementValue.put("timeout", originalTimeout); + } Class originalExpected = ((Test) originalTestAnnotation).expected(); - if (originalExpected != org.junit.Test.None.class) + if (originalExpected != org.junit.Test.None.class) { elementValue.put("expected", originalExpected); + } } else { elementValue.put("timeout", timeOutInMs); } From 08b137ab7d9a6e19223ec6af647910779bee9243 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 18:11:08 +0200 Subject: [PATCH 10/14] go through spoon to modify annotation --- .../diversify/utils/AmplificationHelper.java | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 011e2a10c..823e9be15 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -8,10 +8,10 @@ import fr.inria.stamp.minimization.Minimizer; import org.junit.After; import org.junit.Before; -import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtExpression; import spoon.reflect.code.CtInvocation; import spoon.reflect.code.CtSuperAccess; import spoon.reflect.declaration.CtAnnotation; @@ -46,6 +46,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static java.lang.Integer.parseInt; +import static java.lang.Long.parseLong; import static java.lang.Math.toIntExact; /** @@ -353,45 +355,47 @@ private static CtMethod cloneTestMethod(CtMethod method, String suffix) { } /** - * Modifies the test annotation of a method by adding a timeout limit. + * Prepares the test annotation of a method * * @param cloned_method The test method to modify - * @param factory The factory to create the new updated test annotation + * @param factory The factory to create a new test annotation if needed */ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { - CtAnnotation testAnnotation; - testAnnotation = factory.Core().createAnnotation(); - CtTypeReference ref = factory.Core().createTypeReference(); - ref.setSimpleName("Test"); - - CtPackageReference refPackage = factory.Core().createPackageReference(); - refPackage.setSimpleName("org.junit"); - ref.setPackage(refPackage); - testAnnotation.setAnnotationType(ref); - - Map elementValue = new HashMap<>(); - java.lang.annotation.Annotation originalTestAnnotation = cloned_method.getAnnotation(org.junit.Test.class); + CtAnnotation originalTestAnnotation = cloned_method.getAnnotations().stream() + .filter(annotation -> annotation.toString().contains("Test")) + .findFirst().orElse(null); if (originalTestAnnotation != null) { - int originalTimeout = toIntExact(((Test) originalTestAnnotation).timeout()); - if (originalTimeout < timeOutInMs) { - elementValue.put("timeout", timeOutInMs); + CtExpression originalTimeout = originalTestAnnotation.getValue("timeout"); + if (originalTimeout == null) { + originalTestAnnotation.addValue("timeout", timeOutInMs); } else { - elementValue.put("timeout", originalTimeout); - } - Class originalExpected = ((Test) originalTestAnnotation).expected(); - if (originalExpected != org.junit.Test.None.class) { - elementValue.put("expected", originalExpected); + int valueOriginalTimeout; + if (originalTimeout.toString().endsWith("L")) { + String stringTimeout = originalTimeout.toString(); + valueOriginalTimeout = toIntExact(parseLong(stringTimeout.substring(0, stringTimeout.length() - 1))); + } else { + valueOriginalTimeout = parseInt(originalTimeout.toString()); + } + if (valueOriginalTimeout < timeOutInMs) { + originalTestAnnotation.addValue("timeout", timeOutInMs); + } } } else { + CtAnnotation testAnnotation; + testAnnotation = factory.Core().createAnnotation(); + CtTypeReference ref = factory.Core().createTypeReference(); + ref.setSimpleName("Test"); + + CtPackageReference refPackage = factory.Core().createPackageReference(); + refPackage.setSimpleName("org.junit"); + ref.setPackage(refPackage); + testAnnotation.setAnnotationType(ref); + + Map elementValue = new HashMap<>(); elementValue.put("timeout", timeOutInMs); + testAnnotation.setElementValues(elementValue); + cloned_method.addAnnotation(testAnnotation); } - testAnnotation.setElementValues(elementValue); - - CtAnnotation ctAnnotation = cloned_method.getAnnotations().stream() - .filter(annotation -> annotation.toString().contains("Test")) - .findFirst().orElse(null); - cloned_method.removeAnnotation(ctAnnotation); - cloned_method.addAnnotation(testAnnotation); cloned_method.addThrownType(factory.Type().createReference(Exception.class)); } From 02185255eee5bc88cca5cc4d3ca08db48ab8cd3a Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Tue, 15 May 2018 19:33:27 +0200 Subject: [PATCH 11/14] modify directly the ctAnnotation --- .../diversify/utils/AmplificationHelper.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 823e9be15..8395be059 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -10,10 +10,7 @@ import org.junit.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import spoon.reflect.code.CtComment; -import spoon.reflect.code.CtExpression; -import spoon.reflect.code.CtInvocation; -import spoon.reflect.code.CtSuperAccess; +import spoon.reflect.code.*; import spoon.reflect.declaration.CtAnnotation; import spoon.reflect.declaration.CtImport; import spoon.reflect.declaration.CtMethod; @@ -27,6 +24,7 @@ import spoon.reflect.visitor.ImportScannerImpl; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.TypeFilter; +import spoon.support.reflect.code.CtLiteralImpl; import spoon.support.reflect.declaration.CtClassImpl; import java.io.File; @@ -361,13 +359,13 @@ private static CtMethod cloneTestMethod(CtMethod method, String suffix) { * @param factory The factory to create a new test annotation if needed */ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { - CtAnnotation originalTestAnnotation = cloned_method.getAnnotations().stream() + CtAnnotation testAnnotation = cloned_method.getAnnotations().stream() .filter(annotation -> annotation.toString().contains("Test")) .findFirst().orElse(null); - if (originalTestAnnotation != null) { - CtExpression originalTimeout = originalTestAnnotation.getValue("timeout"); + if (testAnnotation != null) { + CtExpression originalTimeout = testAnnotation.getValue("timeout"); if (originalTimeout == null) { - originalTestAnnotation.addValue("timeout", timeOutInMs); + testAnnotation.addValue("timeout", timeOutInMs); } else { int valueOriginalTimeout; if (originalTimeout.toString().endsWith("L")) { @@ -377,24 +375,26 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { valueOriginalTimeout = parseInt(originalTimeout.toString()); } if (valueOriginalTimeout < timeOutInMs) { - originalTestAnnotation.addValue("timeout", timeOutInMs); + CtLiteral newTimeout = new CtLiteralImpl(); + newTimeout.setValue(timeOutInMs); + originalTimeout.replace(newTimeout); } } } else { - CtAnnotation testAnnotation; - testAnnotation = factory.Core().createAnnotation(); + CtAnnotation newTestAnnotation; + newTestAnnotation = factory.Core().createAnnotation(); CtTypeReference ref = factory.Core().createTypeReference(); ref.setSimpleName("Test"); CtPackageReference refPackage = factory.Core().createPackageReference(); refPackage.setSimpleName("org.junit"); ref.setPackage(refPackage); - testAnnotation.setAnnotationType(ref); + newTestAnnotation.setAnnotationType(ref); Map elementValue = new HashMap<>(); elementValue.put("timeout", timeOutInMs); - testAnnotation.setElementValues(elementValue); - cloned_method.addAnnotation(testAnnotation); + newTestAnnotation.setElementValues(elementValue); + cloned_method.addAnnotation(newTestAnnotation); } cloned_method.addThrownType(factory.Type().createReference(Exception.class)); From 8b70cb020bfc547dba8c846286528fb6990a30ef Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Wed, 16 May 2018 10:27:34 +0200 Subject: [PATCH 12/14] test: test annotation modifications --- .../inria/diversify/dspot/AmplificationTest.java | 16 ++++++++++++++++ .../fr/inria/filter/passing/PassingTest.java | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dspot/src/test/java/fr/inria/diversify/dspot/AmplificationTest.java b/dspot/src/test/java/fr/inria/diversify/dspot/AmplificationTest.java index 01b704c26..d2208be0f 100644 --- a/dspot/src/test/java/fr/inria/diversify/dspot/AmplificationTest.java +++ b/dspot/src/test/java/fr/inria/diversify/dspot/AmplificationTest.java @@ -5,10 +5,13 @@ import fr.inria.Utils; import org.junit.Test; import spoon.reflect.declaration.CtClass; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.factory.Factory; import java.util.Arrays; import java.util.Collections; +import static fr.inria.diversify.utils.AmplificationHelper.prepareTestMethod; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -43,4 +46,17 @@ public void compileAndRunTest() throws Exception { assertEquals(4, testListener.getRunningTests().size()); assertEquals(4, testListener.getPassingTests().size()); } + + /** + * Tests that original test annotations are kept and modified correctly. + */ + @Test + public void prepareTestMethodTest() throws Exception { + CtMethod testMethodWithAnnotations = ((CtMethod) (Utils.findClass("fr.inria.filter.passing.PassingTest").getMethodsByName("testNPEExpected").get(0))); + final Factory factory = testMethodWithAnnotations.getFactory(); + prepareTestMethod(testMethodWithAnnotations, factory); + // expected was kept and timeout was increased + assertEquals("[@org.junit.Test(timeout = 10000, expected = java.lang.NullPointerException.class)]", + testMethodWithAnnotations.getAnnotations().toString()); + } } diff --git a/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java b/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java index 25118d279..6dde83c31 100644 --- a/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java +++ b/dspot/src/test/resources/sample/src/test/java/fr/inria/filter/passing/PassingTest.java @@ -22,7 +22,7 @@ public void failingTestCase() throws Exception { assertFalse(true); } - @Test (expected = NullPointerException.class) + @Test (expected = NullPointerException.class, timeout = 100) public void testNPEExpected() throws Exception { String nullString = null; assertEquals(-1, nullString.length()); From 8094e29288dbd7e0bcc26ebb756d2e38c0913b35 Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Wed, 16 May 2018 10:56:51 +0200 Subject: [PATCH 13/14] use factory --- .../main/java/fr/inria/diversify/utils/AmplificationHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 8395be059..9731547db 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -375,7 +375,7 @@ public static void prepareTestMethod(CtMethod cloned_method, Factory factory) { valueOriginalTimeout = parseInt(originalTimeout.toString()); } if (valueOriginalTimeout < timeOutInMs) { - CtLiteral newTimeout = new CtLiteralImpl(); + CtLiteral newTimeout = factory.createLiteral(timeOutInMs); newTimeout.setValue(timeOutInMs); originalTimeout.replace(newTimeout); } From 1476a42dd332a97362239fad9149204c00e42d5b Mon Sep 17 00:00:00 2001 From: Simon Bihel Date: Wed, 16 May 2018 11:08:47 +0200 Subject: [PATCH 14/14] checkstyle: unused import --- .../main/java/fr/inria/diversify/utils/AmplificationHelper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java index 9731547db..e22a7c168 100644 --- a/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java +++ b/dspot/src/main/java/fr/inria/diversify/utils/AmplificationHelper.java @@ -24,7 +24,6 @@ import spoon.reflect.visitor.ImportScannerImpl; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.TypeFilter; -import spoon.support.reflect.code.CtLiteralImpl; import spoon.support.reflect.declaration.CtClassImpl; import java.io.File;