From a0afcd67fa64432e089df89fc7b50676ee64e915 Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" Date: Thu, 18 Aug 2016 09:52:43 +0200 Subject: Assert execution order in validation tests with type cycles (#443) The method execution order in type cycles depends on the JVM implementation. This validation ensure our test setup produce the required scenarios. --- .../core/test/validation/BadCycleClassTest.java | 5 +++++ .../core/test/validation/ValidationTestBase.java | 23 ++++++++++++++++------ .../test/validation/targets/BadCycleClass.java | 6 +++--- .../jacoco/core/test/validation/targets/Stubs.java | 23 ++++++++++++++++++++++ 4 files changed, 48 insertions(+), 9 deletions(-) (limited to 'org.jacoco.core.test/src/org/jacoco/core') diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/BadCycleClassTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/BadCycleClassTest.java index cbf3c35b..4c02d68a 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/BadCycleClassTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/BadCycleClassTest.java @@ -29,6 +29,11 @@ public class BadCycleClassTest extends ValidationTestBase { assertLine("childinit", ICounter.FULLY_COVERED); assertLine("childsomeMethod", ICounter.FULLY_COVERED); assertLine("childclinit", ICounter.FULLY_COVERED); + + // The cycle causes a constructor and instance method to be called + // before the static initializer of a class: + assertLogEvents("childinit", "childsomeMethod", "childclinit", + "childinit"); } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index 67c4634d..d6dc6a11 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -15,6 +15,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Arrays; import org.jacoco.core.analysis.Analyzer; import org.jacoco.core.analysis.CoverageBuilder; @@ -26,6 +28,7 @@ import org.jacoco.core.data.ExecutionDataStore; import org.jacoco.core.internal.analysis.CounterImpl; import org.jacoco.core.test.InstrumentingLoader; import org.jacoco.core.test.TargetLoader; +import org.jacoco.core.test.validation.targets.Stubs; import org.junit.Before; /** @@ -37,19 +40,21 @@ public abstract class ValidationTestBase { private static final String[] STATUS_NAME = new String[4]; { - STATUS_NAME[ICounter.EMPTY] = "NO_CODE"; + STATUS_NAME[ICounter.EMPTY] = "EMPTY"; STATUS_NAME[ICounter.NOT_COVERED] = "NOT_COVERED"; STATUS_NAME[ICounter.FULLY_COVERED] = "FULLY_COVERED"; STATUS_NAME[ICounter.PARTLY_COVERED] = "PARTLY_COVERED"; } - protected final String srcFolder; + private final String srcFolder; - protected final Class target; + private final Class target; - protected ISourceFileCoverage sourceCoverage; + private ISourceFileCoverage sourceCoverage; - protected Source source; + private Source source; + + private InstrumentingLoader loader; protected ValidationTestBase(final String srcFolder, final Class target) { this.srcFolder = srcFolder; @@ -68,7 +73,7 @@ public abstract class ValidationTestBase { } private ExecutionDataStore execute() throws Exception { - InstrumentingLoader loader = new InstrumentingLoader(target); + loader = new InstrumentingLoader(target); run(loader.loadClass(target.getName())); return loader.collect(); } @@ -128,4 +133,10 @@ public abstract class ValidationTestBase { assertLine(tag, missedBranches, coveredBranches); } + protected void assertLogEvents(String... events) throws Exception { + final Method getter = Class.forName(Stubs.class.getName(), false, + loader).getMethod("getLogEvents"); + assertEquals("Log events", Arrays.asList(events), getter.invoke(null)); + } + } diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/BadCycleClass.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/BadCycleClass.java index c524a211..cf492714 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/BadCycleClass.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/BadCycleClass.java @@ -24,15 +24,15 @@ public class BadCycleClass { public static class Child extends Base { static { - Stubs.nop("child clinit"); // $line-childclinit$ + Stubs.logEvent("childclinit"); // $line-childclinit$ } public Child() { - Stubs.nop("child init"); // $line-childinit$ + Stubs.logEvent("childinit"); // $line-childinit$ } void someMethod() { - Stubs.nop("child someMethod"); // $line-childsomeMethod$ + Stubs.logEvent("childsomeMethod"); // $line-childsomeMethod$ } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java index eae387b7..c4cb5d48 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java @@ -11,6 +11,9 @@ *******************************************************************************/ package org.jacoco.core.test.validation.targets; +import java.util.ArrayList; +import java.util.List; + /** * Collection of stub methods that are called from the coverage targets. * */ @@ -117,4 +120,24 @@ public class Stubs { public static void noexec(Runnable task) { } + /** + * List of logged events. Using a static member here works as this class is + * loaded in a new class loader for every test case. + */ + private static List events = new ArrayList(); + + /** + * Records a event with the given id for later verification. + */ + public static void logEvent(String id) { + events.add(id); + } + + /** + * Returns a list of all recorded events in the sequence of recording. + */ + public static List getLogEvents() { + return events; + } + } -- cgit v1.2.3