From 17d04f29306c602dccffdc261655014e9232cd43 Mon Sep 17 00:00:00 2001 From: Scott Babcock Date: Tue, 6 Apr 2021 20:34:25 -0700 Subject: [PATCH] Fix event sequencing issues --- .../automation/junit/AtomicTest.java | 2 +- .../automation/junit/CreateTest.java | 2 +- .../junit/EachTestNotifierInit.java | 2 +- .../nordstrom/automation/junit/Finished.java | 2 +- .../automation/junit/LifecycleHooks.java | 14 +- .../automation/junit/MethodBlock.java | 18 +- .../com/nordstrom/automation/junit/Run.java | 160 +++++++++++++++++- .../nordstrom/automation/junit/RunChild.java | 38 ++--- .../automation/junit/RunChildren.java | 147 ---------------- .../automation/junit/RunReflectiveCall.java | 8 +- .../junit/RunWithCompleteAssignment.java | 6 +- .../nordstrom/automation/junit/Schedule.java | 25 --- 12 files changed, 193 insertions(+), 231 deletions(-) delete mode 100644 src/main/java/com/nordstrom/automation/junit/RunChildren.java delete mode 100644 src/main/java/com/nordstrom/automation/junit/Schedule.java diff --git a/src/main/java/com/nordstrom/automation/junit/AtomicTest.java b/src/main/java/com/nordstrom/automation/junit/AtomicTest.java index 83523d8..544e2fa 100644 --- a/src/main/java/com/nordstrom/automation/junit/AtomicTest.java +++ b/src/main/java/com/nordstrom/automation/junit/AtomicTest.java @@ -35,7 +35,7 @@ public class AtomicTest { private static final Pattern PARAM = Pattern.compile("[(\\[]"); public AtomicTest(Description description) { - this.runner = RunChildren.getThreadRunner(); + this.runner = Run.getThreadRunner(); this.description = description; this.particles = getParticles(runner, description); this.identity = this.particles.get(0); diff --git a/src/main/java/com/nordstrom/automation/junit/CreateTest.java b/src/main/java/com/nordstrom/automation/junit/CreateTest.java index 0d3fbff..59150ad 100644 --- a/src/main/java/com/nordstrom/automation/junit/CreateTest.java +++ b/src/main/java/com/nordstrom/automation/junit/CreateTest.java @@ -66,7 +66,7 @@ public static Object intercept(@This final Object runner, @Argument(0) final Fra Object target = LifecycleHooks.callProxy(proxy); if (0 == depthGauge.decreaseDepth()) { - METHOD_DEPTH.remove(); + METHOD_DEPTH.get().remove(hashCode); LOGGER.debug("testObjectCreated: {}", target); TARGET_TO_METHOD.put(toMapKey(target), method); diff --git a/src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java b/src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java index 8dc3ddf..29d316b 100644 --- a/src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java +++ b/src/main/java/com/nordstrom/automation/junit/EachTestNotifierInit.java @@ -37,7 +37,7 @@ public static void interceptor(@Argument(0) final RunNotifier notifier, if (description.isTest()) { newAtomicTestFor(description); - Object runner = RunChildren.getThreadRunner(); + Object runner = Run.getThreadRunner(); FrameworkMethod method = null; List children = LifecycleHooks.invoke(runner, "getChildren"); for (Object child : children) { diff --git a/src/main/java/com/nordstrom/automation/junit/Finished.java b/src/main/java/com/nordstrom/automation/junit/Finished.java index 6488a68..c0c31d3 100644 --- a/src/main/java/com/nordstrom/automation/junit/Finished.java +++ b/src/main/java/com/nordstrom/automation/junit/Finished.java @@ -20,6 +20,6 @@ public class Finished { */ public static void intercept(@This final Object scheduler, @SuperCall final Callable proxy) throws Exception { LifecycleHooks.callProxy(proxy); - RunChildren.finished(); + RunChild.finished(); } } diff --git a/src/main/java/com/nordstrom/automation/junit/LifecycleHooks.java b/src/main/java/com/nordstrom/automation/junit/LifecycleHooks.java index b25d49b..35b4968 100644 --- a/src/main/java/com/nordstrom/automation/junit/LifecycleHooks.java +++ b/src/main/java/com/nordstrom/automation/junit/LifecycleHooks.java @@ -166,8 +166,6 @@ public static ClassFileTransformer installTransformer(Instrumentation instrument final TypeDescription fireTestFinished = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.FireTestFinished").resolve(); final TypeDescription runReflectiveCall = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.RunReflectiveCall").resolve(); final TypeDescription finished = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.Finished").resolve(); - final TypeDescription schedule = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.Schedule").resolve(); - final TypeDescription runChildren = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.RunChildren").resolve(); final TypeDescription runChild = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.RunChild").resolve(); final TypeDescription run = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.Run").resolve(); final TypeDescription describeChild = TypePool.Default.ofSystemLoader().describe("com.nordstrom.automation.junit.DescribeChild").resolve(); @@ -178,7 +176,6 @@ public static ClassFileTransformer installTransformer(Instrumentation instrument final TypeDescription runNotifier = TypePool.Default.ofSystemLoader().describe("org.junit.runner.notification.RunNotifier").resolve(); final TypeDescription description = TypePool.Default.ofSystemLoader().describe("org.junit.runner.Description").resolve(); - final SignatureToken runChildrenToken = new SignatureToken("runChildren", TypeDescription.VOID, Arrays.asList(runNotifier)); final SignatureToken runToken = new SignatureToken("run", TypeDescription.VOID, Arrays.asList(runNotifier)); final TypeDescription frameworkMethod = TypePool.Default.ofSystemLoader().describe("org.junit.runners.model.FrameworkMethod").resolve(); @@ -210,8 +207,7 @@ public Builder transform(Builder builder, TypeDescription type, @Override public Builder transform(Builder builder, TypeDescription type, ClassLoader classloader, JavaModule module) { - return builder.method(named("schedule")).intercept(MethodDelegation.to(schedule)) - .method(named("finished")).intercept(MethodDelegation.to(finished)) + return builder.method(named("finished")).intercept(MethodDelegation.to(finished)) .implement(Hooked.class); } }) @@ -221,7 +217,6 @@ public Builder transform(Builder builder, TypeDescription type, public Builder transform(Builder builder, TypeDescription type, ClassLoader classloader, JavaModule module) { return builder.method(named("runChild")).intercept(MethodDelegation.to(runChild)) - .method(hasSignature(runChildrenToken)).intercept(MethodDelegation.to(runChildren)) .method(hasSignature(runToken)).intercept(MethodDelegation.to(run)) .method(named("describeChild")).intercept(MethodDelegation.to(describeChild)) // NOTE: The 'methodBlock', 'createTest', and 'getTestRules' methods @@ -300,7 +295,7 @@ public static AtomicTest getAtomicTestOf(Object target) { * objects) */ public static Object getParentOf(Object child) { - return RunChildren.getParentOf(child); + return Run.getParentOf(child); } /** @@ -320,7 +315,7 @@ public static Object getNotifierOf(final Object runner) { * @return active {@code ParentRunner} object (may be ({@code null}) */ public static Object getThreadRunner() { - return RunChildren.getThreadRunner(); + return Run.getThreadRunner(); } /** @@ -354,8 +349,6 @@ public static Description describeChild(Object runner, Object child) { return invoke(runner, "describeChild", child); } - - /** * Get the {@link ReflectiveCallable} object for the specified description. * @@ -652,6 +645,5 @@ public T get(int index) { public int size() { return indexes.length; } - } } diff --git a/src/main/java/com/nordstrom/automation/junit/MethodBlock.java b/src/main/java/com/nordstrom/automation/junit/MethodBlock.java index 5fc9964..5e12513 100644 --- a/src/main/java/com/nordstrom/automation/junit/MethodBlock.java +++ b/src/main/java/com/nordstrom/automation/junit/MethodBlock.java @@ -20,20 +20,20 @@ * methodBlock} method. */ public class MethodBlock { - private static final ThreadLocal> METHOD_DEPTH; - private static final Function NEW_INSTANCE; + private static final ThreadLocal> METHOD_DEPTH; + private static final Function NEW_INSTANCE; private static final Map RUNNER_TO_STATEMENT = new ConcurrentHashMap<>(); static { - METHOD_DEPTH = new ThreadLocal>() { + METHOD_DEPTH = new ThreadLocal>() { @Override - protected ConcurrentMap initialValue() { + protected ConcurrentMap initialValue() { return new ConcurrentHashMap<>(); } }; - NEW_INSTANCE = new Function() { + NEW_INSTANCE = new Function() { @Override - public DepthGauge apply(Integer input) { + public DepthGauge apply(String input) { return new DepthGauge(); } }; @@ -56,14 +56,14 @@ public DepthGauge apply(Integer input) { public static Statement intercept(@This final Object runner, @SuperCall final Callable proxy, @Argument(0) final FrameworkMethod method) throws Exception { - DepthGauge depthGauge = LifecycleHooks.computeIfAbsent(METHOD_DEPTH.get(), runner.hashCode(), NEW_INSTANCE); + DepthGauge depthGauge = LifecycleHooks.computeIfAbsent(METHOD_DEPTH.get(), toMapKey(runner), NEW_INSTANCE); depthGauge.increaseDepth(); Statement statement = (Statement) LifecycleHooks.callProxy(proxy); // if at ground level if (0 == depthGauge.decreaseDepth()) { - METHOD_DEPTH.remove(); + METHOD_DEPTH.get().remove(toMapKey(runner)); try { // get parent of test runner Object parent = LifecycleHooks.getFieldValue(runner, "this$0"); @@ -78,7 +78,7 @@ public static Statement intercept(@This final Object runner, @SuperCall final Ca @Override public void evaluate() throws Throwable { // attach class runner to thread - RunChildren.pushThreadRunner(threadRunner); + Run.pushThreadRunner(threadRunner); } }; } diff --git a/src/main/java/com/nordstrom/automation/junit/Run.java b/src/main/java/com/nordstrom/automation/junit/Run.java index 4584dcc..41ff688 100644 --- a/src/main/java/com/nordstrom/automation/junit/Run.java +++ b/src/main/java/com/nordstrom/automation/junit/Run.java @@ -2,10 +2,25 @@ import static com.nordstrom.automation.junit.LifecycleHooks.toMapKey; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.EmptyStackException; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.junit.runner.Description; +import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Function; + import net.bytebuddy.implementation.bind.annotation.Argument; import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; @@ -14,7 +29,35 @@ * This class declares the interceptor for the {@link org.junit.runners.ParentRunner#run run} method. */ public class Run { + private static final ThreadLocal> RUNNER_STACK; + private static final ThreadLocal> METHOD_DEPTH; + private static final Function NEW_INSTANCE; + private static final Set START_NOTIFIED = new CopyOnWriteArraySet<>(); + private static final Map CHILD_TO_PARENT = new ConcurrentHashMap<>(); private static final Map RUNNER_TO_NOTIFIER = new ConcurrentHashMap<>(); + private static final Set NOTIFIERS = new CopyOnWriteArraySet<>(); + private static final Logger LOGGER = LoggerFactory.getLogger(Run.class); + + static { + RUNNER_STACK = new ThreadLocal>() { + @Override + protected Deque initialValue() { + return new ArrayDeque<>(); + } + }; + METHOD_DEPTH = new ThreadLocal>() { + @Override + protected ConcurrentMap initialValue() { + return new ConcurrentHashMap<>(); + } + }; + NEW_INSTANCE = new Function() { + @Override + public DepthGauge apply(String input) { + return new DepthGauge(); + } + }; + } /** * Interceptor for the {@link org.junit.runners.ParentRunner#run run} method. @@ -27,13 +70,24 @@ public class Run { public static void intercept(@This final Object runner, @SuperCall final Callable proxy, @Argument(0) final RunNotifier notifier) throws Exception { + DepthGauge depthGauge = LifecycleHooks.computeIfAbsent(METHOD_DEPTH.get(), toMapKey(runner), NEW_INSTANCE); + try { - RUNNER_TO_NOTIFIER.put(toMapKey(runner), notifier); - RunChildren.pushThreadRunner(runner); + if (0 == depthGauge.increaseDepth()) { + RUNNER_TO_NOTIFIER.put(toMapKey(runner), notifier); + pushThreadRunner(runner); + attachRunListeners(runner, notifier); + fireRunStarted(runner); + } + LifecycleHooks.callProxy(proxy); } finally { - RunChildren.popThreadRunner(); - RUNNER_TO_NOTIFIER.remove(toMapKey(runner)); + if (0 == depthGauge.decreaseDepth()) { + METHOD_DEPTH.get().remove(toMapKey(runner)); + fireRunFinished(runner); + popThreadRunner(); + RUNNER_TO_NOTIFIER.remove(toMapKey(runner)); + } } } @@ -46,4 +100,102 @@ public static void intercept(@This final Object runner, @SuperCall final Callabl static RunNotifier getNotifierOf(final Object runner) { return RUNNER_TO_NOTIFIER.get(toMapKey(runner)); } + + /** + * Get the parent runner that owns specified child runner or framework method. + * + * @param child {@code ParentRunner} or {@code FrameworkMethod} object + * @return {@code ParentRunner} object that owns the specified child ({@code null} for root objects) + */ + static Object getParentOf(final Object child) { + return CHILD_TO_PARENT.get(toMapKey(child)); + } + + /** + * Push the specified JUnit test runner onto the stack for the current thread. + * + * @param runner JUnit test runner + */ + static void pushThreadRunner(final Object runner) { + RUNNER_STACK.get().push(runner); + } + + /** + * Pop the top JUnit test runner from the stack for the current thread. + * + * @return {@code ParentRunner} object + * @throws EmptyStackException if called outside the scope of an active runner + */ + static Object popThreadRunner() { + return RUNNER_STACK.get().pop(); + } + + /** + * Get the runner that owns the active thread context. + * + * @return active {@code ParentRunner} object + */ + static Object getThreadRunner() { + return RUNNER_STACK.get().peek(); + } + + /** + * Fire the {@link RunnerWatcher#runStarted(Object)} event for the specified runner. + *

+ * NOTE: If {@code runStarted} for the specified runner has already been fired, do nothing. + * @param runner JUnit test runner + * @return {@code true} if the {@code runStarted} event was fired; otherwise {@code false} + */ + static boolean fireRunStarted(Object runner) { + if (START_NOTIFIED.add(toMapKey(runner))) { + for (Object child : (List) LifecycleHooks.invoke(runner, "getChildren")) { + CHILD_TO_PARENT.put(toMapKey(child), runner); + } + + LOGGER.debug("runStarted: {}", runner); + for (RunnerWatcher watcher : LifecycleHooks.getRunnerWatchers()) { + watcher.runStarted(runner); + } + return true; + } + return false; + } + + /** + * Fire the {@link RunnerWatcher#runFinished(Object)} event for the specified runner. + * + * @param runner JUnit test runner + */ + static void fireRunFinished(Object runner) { + LOGGER.debug("runFinished: {}", runner); + for (RunnerWatcher watcher : LifecycleHooks.getRunnerWatchers()) { + watcher.runFinished(runner); + } + + START_NOTIFIED.remove(toMapKey(runner)); + for (Object child : (List) LifecycleHooks.invoke(runner, "getChildren")) { + CHILD_TO_PARENT.remove(toMapKey(child)); + } + } + + /** + * Attach registered run listeners to the specified run notifier. + *

+ * NOTE: If the specified run notifier has already been seen, do nothing. + * + * @param runner JUnit test runner + * @param notifier JUnit {@link RunNotifier} object + * @throws Exception if {@code run-started} notification + */ + static void attachRunListeners(Object runner, final RunNotifier notifier) throws Exception { + if (NOTIFIERS.add(toMapKey(notifier))) { + Description description = LifecycleHooks.invoke(runner, "getDescription"); + for (RunListener listener : LifecycleHooks.getRunListeners()) { + // prevent potential duplicates + notifier.removeListener(listener); + notifier.addListener(listener); + listener.testRunStarted(description); + } + } + } } diff --git a/src/main/java/com/nordstrom/automation/junit/RunChild.java b/src/main/java/com/nordstrom/automation/junit/RunChild.java index f946942..4e5e9e6 100644 --- a/src/main/java/com/nordstrom/automation/junit/RunChild.java +++ b/src/main/java/com/nordstrom/automation/junit/RunChild.java @@ -2,13 +2,10 @@ import static com.nordstrom.automation.junit.LifecycleHooks.toMapKey; -import java.util.Set; +import java.util.Map; import java.util.concurrent.Callable; -import java.util.concurrent.CopyOnWriteArraySet; - +import java.util.concurrent.ConcurrentHashMap; import org.junit.Ignore; -import org.junit.runner.Description; -import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.FrameworkMethod; import net.bytebuddy.implementation.bind.annotation.Argument; @@ -21,7 +18,7 @@ */ public class RunChild { - private static final Set NOTIFIERS = new CopyOnWriteArraySet<>(); + private static final Map DID_NOTIFY = new ConcurrentHashMap<>(); /** * Interceptor for the {@link org.junit.runners.BlockJUnit4ClassRunner#runChild runChild} method. @@ -36,7 +33,11 @@ public static void intercept(@This final Object runner, @SuperCall final Callabl @Argument(0) final Object child, @Argument(1) final RunNotifier notifier) throws Exception { - attachRunListeners(runner, notifier); + String mapKey = toMapKey(runner); + if ( ! DID_NOTIFY.containsKey(mapKey)) { + DID_NOTIFY.put(mapKey, Run.fireRunStarted(runner)); + Run.attachRunListeners(runner, notifier); + } if (child instanceof FrameworkMethod) { FrameworkMethod method = (FrameworkMethod) child; @@ -54,23 +55,12 @@ public static void intercept(@This final Object runner, @SuperCall final Callabl } /** - * Attach registered run listeners to the specified run notifier. - *

- * NOTE: If the specified run notifier has already been seen, do nothing. - * - * @param runner JUnit test runner - * @param notifier JUnit {@link RunNotifier} object - * @throws Exception if {@code run-started} notification + * Fire the {@link RunnerWatcher#runFinished(Object)} event for the current runner. */ - static void attachRunListeners(Object runner, final RunNotifier notifier) throws Exception { - if (NOTIFIERS.add(toMapKey(notifier))) { - Description description = LifecycleHooks.invoke(runner, "getDescription"); - for (RunListener listener : LifecycleHooks.getRunListeners()) { - // prevent potential duplicates - notifier.removeListener(listener); - notifier.addListener(listener); - listener.testRunStarted(description); - } + static void finished() { + Object runner = Run.getThreadRunner(); + if (Boolean.TRUE == DID_NOTIFY.remove(toMapKey(runner))) { + Run.fireRunFinished(runner); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/nordstrom/automation/junit/RunChildren.java b/src/main/java/com/nordstrom/automation/junit/RunChildren.java deleted file mode 100644 index 9636410..0000000 --- a/src/main/java/com/nordstrom/automation/junit/RunChildren.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.nordstrom.automation.junit; - -import static com.nordstrom.automation.junit.LifecycleHooks.toMapKey; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.EmptyStackException; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import org.junit.runner.notification.RunNotifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import net.bytebuddy.implementation.bind.annotation.Argument; -import net.bytebuddy.implementation.bind.annotation.SuperCall; -import net.bytebuddy.implementation.bind.annotation.This; - -/** - * This class declares the interceptor for the {@link org.junit.runners.ParentRunner#runChildren runChildren} method. - */ -public class RunChildren { - - private static final ThreadLocal> RUNNER_STACK; - private static final Set START_NOTIFIED = new CopyOnWriteArraySet<>(); - private static final Map CHILD_TO_PARENT = new ConcurrentHashMap<>(); - private static final Logger LOGGER = LoggerFactory.getLogger(RunChildren.class); - - static { - RUNNER_STACK = new ThreadLocal>() { - @Override - protected Deque initialValue() { - return new ArrayDeque<>(); - } - }; - } - - /** - * Interceptor for the {@link org.junit.runners.ParentRunner#runChildren runChildren} method. - * - * @param runner underlying test runner - * @param proxy callable proxy for the intercepted method - * @param notifier run notifier through which events are published - * @throws Exception {@code anything} (exception thrown by the intercepted method) - */ - public static void intercept(@This final Object runner, @SuperCall final Callable proxy, - @Argument(0) final RunNotifier notifier) throws Exception { - - try { - pushThreadRunner(runner); - LifecycleHooks.callProxy(proxy); - } finally { - popThreadRunner(); - } - } - - /** - * Fire the {@link RunnerWatcher#runStarted(Object)} event for the current runner. - */ - static void started() { - fireRunStarted(getThreadRunner()); - } - - /** - * Fire the {@link RunnerWatcher#runStarted(Object)} event for the specified runner. - * - * @param runner JUnit test runner - */ - static void fireRunStarted(Object runner) { - if (START_NOTIFIED.add(toMapKey(runner))) { - for (Object child : (List) LifecycleHooks.invoke(runner, "getChildren")) { - CHILD_TO_PARENT.put(toMapKey(child), runner); - } - - LOGGER.debug("runStarted: {}", runner); - for (RunnerWatcher watcher : LifecycleHooks.getRunnerWatchers()) { - watcher.runStarted(runner); - } - } - } - - /** - * Fire the {@link RunnerWatcher#runFinished(Object)} event for the current runner. - */ - static void finished() { - fireRunFinished(getThreadRunner()); - } - - /** - * Fire the {@link RunnerWatcher#runFinished(Object)} event for the specified runner. - * - * @param runner JUnit test runner - */ - static void fireRunFinished(Object runner) { - LOGGER.debug("runFinished: {}", runner); - for (RunnerWatcher watcher : LifecycleHooks.getRunnerWatchers()) { - watcher.runFinished(runner); - } - - START_NOTIFIED.remove(toMapKey(runner)); - for (Object child : (List) LifecycleHooks.invoke(runner, "getChildren")) { - CHILD_TO_PARENT.remove(toMapKey(child)); - } - } - - /** - * Get the parent runner that owns specified child runner or framework method. - * - * @param child {@code ParentRunner} or {@code FrameworkMethod} object - * @return {@code ParentRunner} object that owns the specified child ({@code null} for root objects) - */ - static Object getParentOf(final Object child) { - return CHILD_TO_PARENT.get(toMapKey(child)); - } - - /** - * Push the specified JUnit test runner onto the stack for the current thread. - * - * @param runner JUnit test runner - */ - static void pushThreadRunner(final Object runner) { - RUNNER_STACK.get().push(runner); - } - - /** - * Pop the top JUnit test runner from the stack for the current thread. - * - * @return {@code ParentRunner} object - * @throws EmptyStackException if called outside the scope of an active runner - */ - static Object popThreadRunner() { - return RUNNER_STACK.get().pop(); - } - - /** - * Get the runner that owns the active thread context. - * - * @return active {@code ParentRunner} object - */ - static Object getThreadRunner() { - return RUNNER_STACK.get().peek(); - } -} diff --git a/src/main/java/com/nordstrom/automation/junit/RunReflectiveCall.java b/src/main/java/com/nordstrom/automation/junit/RunReflectiveCall.java index 3368db2..2fdc39d 100644 --- a/src/main/java/com/nordstrom/automation/junit/RunReflectiveCall.java +++ b/src/main/java/com/nordstrom/automation/junit/RunReflectiveCall.java @@ -68,9 +68,9 @@ public static Object intercept(@This final ReflectiveCallable callable, @SuperCa // handled below } - Object runner = RunChildren.getParentOf(child); + Object runner = Run.getParentOf(child); if (runner == null) { - runner = RunChildren.getThreadRunner(); + runner = Run.getThreadRunner(); } Object result = null; @@ -184,9 +184,9 @@ private static boolean fireBeforeInvocation(Object runner, Object child, Reflect @SuppressWarnings({"rawtypes", "unchecked"}) private static boolean fireAfterInvocation(Object runner, Object child, ReflectiveCallable callable, Throwable thrown) { if ((runner != null) && (child != null)) { - DepthGauge depthGauge = LifecycleHooks.computeIfAbsent(METHOD_DEPTH.get(), callable.hashCode(), NEW_INSTANCE); + DepthGauge depthGauge = METHOD_DEPTH.get().get(callable.hashCode()); if (0 == depthGauge.decreaseDepth()) { - METHOD_DEPTH.remove(); + METHOD_DEPTH.get().remove(callable.hashCode()); if (child instanceof FrameworkMethod) { Description description = LifecycleHooks.describeChild(runner, child); if (LOGGER.isDebugEnabled()) { diff --git a/src/main/java/com/nordstrom/automation/junit/RunWithCompleteAssignment.java b/src/main/java/com/nordstrom/automation/junit/RunWithCompleteAssignment.java index 73c794a..11b30b9 100644 --- a/src/main/java/com/nordstrom/automation/junit/RunWithCompleteAssignment.java +++ b/src/main/java/com/nordstrom/automation/junit/RunWithCompleteAssignment.java @@ -40,12 +40,12 @@ public static void intercept(@This final TheoryAnchor anchor, @SuperCall final C @Argument(0) final Assignments assignments) throws Exception { // grab the current thread runner - Object parentRunner = RunChildren.getThreadRunner(); + Object parentRunner = Run.getThreadRunner(); LifecycleHooks.callProxy(proxy); // NOTE: This pushes the BlockJUnit4ClassRunner Throwable thrown = null; - Object classRunner = RunChildren.getThreadRunner(); + Object classRunner = Run.getThreadRunner(); FrameworkMethod method = LifecycleHooks.getFieldValue(anchor, "testMethod"); RunNotifier notifier = Run.getNotifierOf(parentRunner); @@ -63,7 +63,7 @@ public static void intercept(@This final TheoryAnchor anchor, @SuperCall final C eachNotifier.addFailure(e); } finally { eachNotifier.fireTestFinished(); - RunChildren.popThreadRunner(); + Run.popThreadRunner(); } if (thrown != null) { diff --git a/src/main/java/com/nordstrom/automation/junit/Schedule.java b/src/main/java/com/nordstrom/automation/junit/Schedule.java deleted file mode 100644 index 3e8d3a7..0000000 --- a/src/main/java/com/nordstrom/automation/junit/Schedule.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.nordstrom.automation.junit; - -import java.util.concurrent.Callable; - -import net.bytebuddy.implementation.bind.annotation.SuperCall; -import net.bytebuddy.implementation.bind.annotation.This; - -/** - * This class declares the interceptor for the {@link org.junit.runners.model.RunnerScheduler#schedule schedule} - * method. - */ -public class Schedule { - - /** - * Interceptor for the {@link org.junit.runners.model.RunnerScheduler#schedule schedule} method. - * - * @param scheduler current {@link org.junit.runners.model.RunnerScheduler RunnerScheduler} - * @param proxy callable proxy for the intercepted method - * @throws Exception {@code anything} (exception thrown by the intercepted method) - */ - public static void intercept(@This final Object scheduler, @SuperCall final Callable proxy) throws Exception { - RunChildren.started(); - LifecycleHooks.callProxy(proxy); - } -}