Class Junit5TrialExecutor

java.lang.Object
edu.berkeley.cs.jqf.junit5.Junit5TrialExecutor
All Implemented Interfaces:
TrialExecutor

public final class Junit5TrialExecutor extends Object implements TrialExecutor
Runs trials reflectively under a JUnit 5 (Jupiter) lifecycle.

The fuzzing loop runs millions of trials, so it must not re-enter the Jupiter engine per trial. This executor instead replays the relevant lifecycle directly: @BeforeAll/@AfterAll run once around the whole campaign, and every trial gets a fresh test instance with its @BeforeEach/@AfterEach callbacks. The test method's return value is captured for differential fuzzing.

This is a pragmatic subset of Jupiter's lifecycle: it honours inheritance (superclass callbacks run first for "before", last for "after") but does not resolve parameters into lifecycle methods, nor support @Nested classes or PER_CLASS instances. The regression run path uses the real Jupiter engine instead, so this executor only drives the dedicated fuzzing campaign.

  • Constructor Details

    • Junit5TrialExecutor

      public Junit5TrialExecutor(Class<?> testClass, Method testMethod)
  • Method Details

    • runTrial

      public void runTrial(Object[] args) throws Throwable
      Description copied from interface: TrialExecutor
      Runs one trial with the given arguments.

      Throwables raised by the test body propagate unchanged so the engine can classify them (failure, unmet assumption, timeout). Implementations must not swallow them.

      Specified by:
      runTrial in interface TrialExecutor
      Parameters:
      args - the arguments for this trial
      Throws:
      Throwable - whatever the test body raises
    • getLastOutput

      public Object getLastOutput()
      Description copied from interface: TrialExecutor
      Returns the value returned by the most recent trial's test method.

      Differential fuzzing compares these return values across runs; ordinary test runners discard them. The default returns null for executors that do not capture the return value.

      Specified by:
      getLastOutput in interface TrialExecutor
      Returns:
      the most recent return value, or null
    • runAfterAll

      public void runAfterAll()
      Runs the @AfterAll callbacks once, after the campaign has finished.

      This is outside the TrialExecutor contract because the engine has no end-of-campaign hook; the campaign driver calls it explicitly. It is a no-op if no trial ever ran (so @BeforeAll never ran either).