66import com .carrotsearch .randomizedtesting .jupiter .Seed ;
77import com .carrotsearch .randomizedtesting .jupiter .SeedChain ;
88import com .carrotsearch .randomizedtesting .jupiter .SysProps ;
9+ import java .lang .reflect .Constructor ;
10+ import java .lang .reflect .Method ;
911import java .util .ArrayList ;
1012import java .util .Arrays ;
1113import java .util .List ;
1214import java .util .Objects ;
1315import java .util .Optional ;
1416import java .util .Random ;
1517import java .util .function .LongFunction ;
18+ import org .jspecify .annotations .Nullable ;
1619import org .junit .jupiter .api .extension .BeforeAllCallback ;
20+ import org .junit .jupiter .api .extension .DynamicTestInvocationContext ;
1721import org .junit .jupiter .api .extension .ExtensionContext ;
18- import org .junit .jupiter .api .extension .LifecycleMethodExecutionExceptionHandler ;
22+ import org .junit .jupiter .api .extension .InvocationInterceptor ;
1923import org .junit .jupiter .api .extension .ParameterContext ;
2024import org .junit .jupiter .api .extension .ParameterResolutionException ;
2125import org .junit .jupiter .api .extension .ParameterResolver ;
22- import org .junit .jupiter .api .extension .TestExecutionExceptionHandler ;
26+ import org .junit .jupiter .api .extension .ReflectiveInvocationContext ;
2327
2428public class RandomizedContextExtension
25- implements ParameterResolver ,
26- BeforeAllCallback ,
27- TestExecutionExceptionHandler ,
28- LifecycleMethodExecutionExceptionHandler {
29+ implements ParameterResolver , BeforeAllCallback , InvocationInterceptor {
2930 private static final ExtensionContext .Namespace EXTENSION_NAMESPACE =
3031 ExtensionContext .Namespace .create (RandomizedContextExtension .class );
3132
@@ -131,7 +132,7 @@ public Object resolveParameter(
131132 // internal handling of randomized contexts within junit contexts.
132133 //
133134
134- private RandomizedContextImpl getRandomizedContextFor (ExtensionContext extensionContext ) {
135+ private static RandomizedContextImpl getRandomizedContextFor (ExtensionContext extensionContext ) {
135136 var store =
136137 extensionContext .getStore (
137138 ExtensionContext .StoreScope .EXTENSION_CONTEXT , EXTENSION_NAMESPACE );
@@ -153,37 +154,97 @@ private RandomizedContextImpl getRandomizedContextFor(ExtensionContext extension
153154 // exception handling and seed stack frame injection
154155 //
155156
157+ private static <T > T wrapInvoke (Invocation <T > invocation , ExtensionContext context )
158+ throws Throwable {
159+ try {
160+ return invocation .proceed ();
161+ } catch (Throwable throwable ) {
162+ throw addSeedChainStackFrame (throwable , getRandomizedContextFor (context ).getSeedChain ());
163+ }
164+ }
165+
156166 @ Override
157- public void handleTestExecutionException (ExtensionContext context , Throwable throwable )
167+ public <T > T interceptTestClassConstructor (
168+ Invocation <T > invocation ,
169+ ReflectiveInvocationContext <Constructor <T >> invocationContext ,
170+ ExtensionContext extensionContext )
158171 throws Throwable {
159- throw addSeedChainStackFrame ( throwable , getRandomizedContextFor ( context ). getSeedChain () );
172+ return wrapInvoke ( invocation , extensionContext );
160173 }
161174
162175 @ Override
163- public void handleBeforeAllMethodExecutionException (ExtensionContext context , Throwable throwable )
176+ public void interceptBeforeAllMethod (
177+ Invocation <@ Nullable Void > invocation ,
178+ ReflectiveInvocationContext <Method > invocationContext ,
179+ ExtensionContext extensionContext )
164180 throws Throwable {
165- throw addSeedChainStackFrame ( throwable , getRandomizedContextFor ( context ). getSeedChain () );
181+ wrapInvoke ( invocation , extensionContext );
166182 }
167183
168184 @ Override
169- public void handleBeforeEachMethodExecutionException (
170- ExtensionContext context , Throwable throwable ) throws Throwable {
171- throw addSeedChainStackFrame (throwable , getRandomizedContextFor (context ).getSeedChain ());
185+ public void interceptBeforeEachMethod (
186+ Invocation <@ Nullable Void > invocation ,
187+ ReflectiveInvocationContext <Method > invocationContext ,
188+ ExtensionContext extensionContext )
189+ throws Throwable {
190+ wrapInvoke (invocation , extensionContext );
191+ }
192+
193+ @ Override
194+ public void interceptTestMethod (
195+ Invocation <@ Nullable Void > invocation ,
196+ ReflectiveInvocationContext <Method > invocationContext ,
197+ ExtensionContext extensionContext )
198+ throws Throwable {
199+ wrapInvoke (invocation , extensionContext );
200+ }
201+
202+ @ Override
203+ public <T > T interceptTestFactoryMethod (
204+ Invocation <T > invocation ,
205+ ReflectiveInvocationContext <Method > invocationContext ,
206+ ExtensionContext extensionContext )
207+ throws Throwable {
208+ return wrapInvoke (invocation , extensionContext );
209+ }
210+
211+ @ Override
212+ public void interceptTestTemplateMethod (
213+ Invocation <@ Nullable Void > invocation ,
214+ ReflectiveInvocationContext <Method > invocationContext ,
215+ ExtensionContext extensionContext )
216+ throws Throwable {
217+ wrapInvoke (invocation , extensionContext );
218+ }
219+
220+ @ Override
221+ public void interceptAfterEachMethod (
222+ Invocation <@ Nullable Void > invocation ,
223+ ReflectiveInvocationContext <Method > invocationContext ,
224+ ExtensionContext extensionContext )
225+ throws Throwable {
226+ wrapInvoke (invocation , extensionContext );
172227 }
173228
174229 @ Override
175- public void handleAfterEachMethodExecutionException (ExtensionContext context , Throwable throwable )
230+ public void interceptAfterAllMethod (
231+ Invocation <@ Nullable Void > invocation ,
232+ ReflectiveInvocationContext <Method > invocationContext ,
233+ ExtensionContext extensionContext )
176234 throws Throwable {
177- throw addSeedChainStackFrame ( throwable , getRandomizedContextFor ( context ). getSeedChain () );
235+ wrapInvoke ( invocation , extensionContext );
178236 }
179237
180238 @ Override
181- public void handleAfterAllMethodExecutionException (ExtensionContext context , Throwable throwable )
239+ public void interceptDynamicTest (
240+ Invocation <@ Nullable Void > invocation ,
241+ DynamicTestInvocationContext invocationContext ,
242+ ExtensionContext extensionContext )
182243 throws Throwable {
183- throw addSeedChainStackFrame ( throwable , getRandomizedContextFor ( context ). getSeedChain () );
244+ wrapInvoke ( invocation , extensionContext );
184245 }
185246
186- private Throwable addSeedChainStackFrame (Throwable throwable , SeedChain seedChain ) {
247+ private static Throwable addSeedChainStackFrame (Throwable throwable , SeedChain seedChain ) {
187248 List <StackTraceElement > stack = new ArrayList <>(Arrays .asList (throwable .getStackTrace ()));
188249 stack .addFirst (
189250 new StackTraceElement (Constants .AUGMENTED_SEED_CLASS , "seed" , seedChain .toString (), -1 ));
0 commit comments