Skip to content

Commit

Permalink
[SUREFIRE-1717] Enable Process Checkers
Browse files Browse the repository at this point in the history
  • Loading branch information
Tibor17 committed Nov 13, 2019
1 parent 0c0d902 commit 08ff28f
Show file tree
Hide file tree
Showing 24 changed files with 502 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,55 @@ public class IntegrationTestMojo
* their environment variable.
* <br>
* Example to exclude three environment variables:
* <br>
* <i>mvn test -Dfailsafe.excludedEnvironmentVariables=ACME1,ACME2,ACME3</i>
*
* @since 3.0.0-M4
*/
@Parameter( property = "failsafe.excludedEnvironmentVariables" )
private String[] excludedEnvironmentVariables;

/**
* Since 3.0.0-M4 the process checkers are disabled.
* You can enable them namely by setting {@code ping} and {@code native} or {@code all} in this parameter.
* <br>
* The checker is useful in situations when you kill the build on CI and you want the Surefire forked JVM to kill
* the tests asap and free all handlers on the file system been previously used by the JVM and by the tests.
*
* <br>
*
* The {@code ping} should be safely used together with ZGC or Shenandoah Garbage Collector.
* Due to the {@code ping} relies on timing of PING (triggered every 30 seconds), slow GC may pause
* the timers and pretend that the parent process of the fork JVM does not exist.
*
* <br>
*
* The {@code native} is very fast checker.
* It is useful mechanism on Unix based systems, Linux distributions and Alpine/BusyBox Linux.
* See the JIRA <a href="https://issues.apache.org/jira/browse/SUREFIRE-1631">SUREFIRE-1631</a> for Windows issues.
*
* <br>
*
* Another useful configuration parameter is {@code forkedProcessTimeoutInSeconds}.
* <br>
* See the Frequently Asked Questions page with more details:<br>
* <a href="http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm">
* http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm</a>
* <br>
* <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm">
* http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm</a>
*
* <br>
*
* Example of use:
* <br>
* <i>mvn test -Dsurefire.enableProcessChecker=all</i>
*
* @since 3.0.0-M4
*/
@Parameter( property = "failsafe.enableProcessChecker" )
private String enableProcessChecker;

@Override
protected int getRerunFailingTestsCount()
{
Expand Down Expand Up @@ -864,4 +906,10 @@ void setExcludedEnvironmentVariables( String[] excludedEnvironmentVariables )
{
this.excludedEnvironmentVariables = excludedEnvironmentVariables;
}

@Override
protected final String getEnableProcessChecker()
{
return enableProcessChecker;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.apache.maven.surefire.booter.KeyValueSource;
import org.apache.maven.surefire.booter.ModularClasspath;
import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
import org.apache.maven.surefire.booter.ProcessCheckerType;
import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.booter.ProviderParameterNames;
import org.apache.maven.surefire.booter.Shutdown;
Expand Down Expand Up @@ -836,6 +837,8 @@ protected abstract void handleSummary( RunResult summary, Exception firstForkExc

protected abstract void setUseModulePath( boolean useModulePath );

protected abstract String getEnableProcessChecker();

/**
* This plugin MOJO artifact.
*
Expand Down Expand Up @@ -1029,6 +1032,7 @@ boolean verifyParameters()
}
else
{
ensureEnableProcessChecker();
convertDeprecatedForkMode();
ensureWorkingDirectoryExists();
ensureParallelRunningCompatibility();
Expand Down Expand Up @@ -1814,7 +1818,7 @@ private StartupConfiguration newStartupConfigWithClasspath(
inProcClasspath, effectiveIsEnableAssertions(), isChildDelegation() );

return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration, isForking(),
false );
false, ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
}

private static Set<Artifact> retainInProcArtifactsUnique( Set<Artifact> providerArtifacts,
Expand Down Expand Up @@ -1924,7 +1928,7 @@ private StartupConfiguration newStartupConfigWithModularPath(
getConsoleLogger().debug( inProcClasspath.getCompactLogMessage( "in-process(compact) classpath:" ) );

return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration, isForking(),
false );
false, ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
}

private Artifact getCommonArtifact()
Expand Down Expand Up @@ -2316,6 +2320,16 @@ else if ( getClassLoaderConfiguration().isManifestOnlyJarRequestedAndUsable() )
}
}

private void ensureEnableProcessChecker() throws MojoFailureException
{
if ( !ProcessCheckerType.isValid( getEnableProcessChecker() ) )
{
throw new MojoFailureException( "Unexpected value '"
+ getEnableProcessChecker()
+ "' in the configuration parameter 'enableProcessChecker'." );
}
}

private void convertDeprecatedForkMode()
{
String effectiveForkMode = getEffectiveForkMode();
Expand Down Expand Up @@ -2547,6 +2561,7 @@ private String getConfigChecksum()
checksum.add( getRerunFailingTestsCount() );
checksum.add( getTempDir() );
checksum.add( useModulePath() );
checksum.add( getEnableProcessChecker() );
addPluginSpecificChecksumItems( checksum );
return checksum.getSha1();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.KeyValueSource;
import org.apache.maven.surefire.booter.ProcessCheckerType;
import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.cli.CommandLineOption;
Expand Down Expand Up @@ -53,6 +54,7 @@
import static org.apache.maven.surefire.booter.BooterConstants.ISTRIMSTACKTRACE;
import static org.apache.maven.surefire.booter.BooterConstants.MAIN_CLI_OPTIONS;
import static org.apache.maven.surefire.booter.BooterConstants.PLUGIN_PID;
import static org.apache.maven.surefire.booter.BooterConstants.PROCESS_CHECKER;
import static org.apache.maven.surefire.booter.BooterConstants.PROVIDER_CONFIGURATION;
import static org.apache.maven.surefire.booter.BooterConstants.REPORTSDIRECTORY;
import static org.apache.maven.surefire.booter.BooterConstants.REQUESTEDTEST;
Expand Down Expand Up @@ -98,22 +100,24 @@ class BooterSerializer
/**
* Does not modify sourceProperties
*/
File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterConfiguration,
StartupConfiguration providerConfiguration, Object testSet, boolean readTestsFromInStream,
File serialize( KeyValueSource sourceProperties, ProviderConfiguration providerConfiguration,
StartupConfiguration startupConfiguration, Object testSet, boolean readTestsFromInStream,
Long pid, int forkNumber )
throws IOException
{
SurefireProperties properties = new SurefireProperties( sourceProperties );

properties.setProperty( PLUGIN_PID, pid );

AbstractPathConfiguration cp = providerConfiguration.getClasspathConfiguration();
AbstractPathConfiguration cp = startupConfiguration.getClasspathConfiguration();
properties.setClasspath( CLASSPATH, cp.getTestClasspath() );
properties.setClasspath( SUREFIRE_CLASSPATH, cp.getProviderClasspath() );
properties.setProperty( ENABLE_ASSERTIONS, toString( cp.isEnableAssertions() ) );
properties.setProperty( CHILD_DELEGATION, toString( cp.isChildDelegation() ) );
ProcessCheckerType processChecker = startupConfiguration.getProcessChecker();
properties.setNullableProperty( PROCESS_CHECKER, processChecker == null ? null : processChecker.getType() );

TestArtifactInfo testNg = booterConfiguration.getTestArtifact();
TestArtifactInfo testNg = providerConfiguration.getTestArtifact();
if ( testNg != null )
{
properties.setProperty( TESTARTIFACT_VERSION, testNg.getVersion() );
Expand All @@ -123,7 +127,7 @@ File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterCon
properties.setProperty( FORKTESTSET_PREFER_TESTS_FROM_IN_STREAM, readTestsFromInStream );
properties.setNullableProperty( FORKTESTSET, getTypeEncoded( testSet ) );

TestRequest testSuiteDefinition = booterConfiguration.getTestSuiteDefinition();
TestRequest testSuiteDefinition = providerConfiguration.getTestSuiteDefinition();
if ( testSuiteDefinition != null )
{
properties.setProperty( SOURCE_DIRECTORY, testSuiteDefinition.getTestSourceDirectory() );
Expand All @@ -141,7 +145,7 @@ File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterCon
properties.setNullableProperty( RERUN_FAILING_TESTS_COUNT, toString( rerunFailingTestsCount ) );
}

DirectoryScannerParameters directoryScannerParameters = booterConfiguration.getDirScannerParams();
DirectoryScannerParameters directoryScannerParameters = providerConfiguration.getDirScannerParams();
if ( directoryScannerParameters != null )
{
properties.setProperty( FAILIFNOTESTS, toString( directoryScannerParameters.isFailIfNoTests() ) );
Expand All @@ -151,31 +155,31 @@ File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterCon
properties.setProperty( TEST_CLASSES_DIRECTORY, directoryScannerParameters.getTestClassesDirectory() );
}

final RunOrderParameters runOrderParameters = booterConfiguration.getRunOrderParameters();
final RunOrderParameters runOrderParameters = providerConfiguration.getRunOrderParameters();
if ( runOrderParameters != null )
{
properties.setProperty( RUN_ORDER, RunOrder.asString( runOrderParameters.getRunOrder() ) );
properties.setProperty( RUN_STATISTICS_FILE, runOrderParameters.getRunStatisticsFile() );
}

ReporterConfiguration reporterConfiguration = booterConfiguration.getReporterConfiguration();
ReporterConfiguration reporterConfiguration = providerConfiguration.getReporterConfiguration();
boolean rep = reporterConfiguration.isTrimStackTrace();
File reportsDirectory = replaceForkThreadsInPath( reporterConfiguration.getReportsDirectory(), forkNumber );
properties.setProperty( ISTRIMSTACKTRACE, rep );
properties.setProperty( REPORTSDIRECTORY, reportsDirectory );
ClassLoaderConfiguration classLoaderConfig = providerConfiguration.getClassLoaderConfiguration();
ClassLoaderConfiguration classLoaderConfig = startupConfiguration.getClassLoaderConfiguration();
properties.setProperty( USESYSTEMCLASSLOADER, toString( classLoaderConfig.isUseSystemClassLoader() ) );
properties.setProperty( USEMANIFESTONLYJAR, toString( classLoaderConfig.isUseManifestOnlyJar() ) );
properties.setProperty( FAILIFNOTESTS, toString( booterConfiguration.isFailIfNoTests() ) );
properties.setProperty( PROVIDER_CONFIGURATION, providerConfiguration.getProviderClassName() );
properties.setProperty( FAIL_FAST_COUNT, toString( booterConfiguration.getSkipAfterFailureCount() ) );
properties.setProperty( SHUTDOWN, booterConfiguration.getShutdown().name() );
List<CommandLineOption> mainCliOptions = booterConfiguration.getMainCliOptions();
properties.setProperty( FAILIFNOTESTS, toString( providerConfiguration.isFailIfNoTests() ) );
properties.setProperty( PROVIDER_CONFIGURATION, startupConfiguration.getProviderClassName() );
properties.setProperty( FAIL_FAST_COUNT, toString( providerConfiguration.getSkipAfterFailureCount() ) );
properties.setProperty( SHUTDOWN, providerConfiguration.getShutdown().name() );
List<CommandLineOption> mainCliOptions = providerConfiguration.getMainCliOptions();
if ( mainCliOptions != null )
{
properties.addList( mainCliOptions, MAIN_CLI_OPTIONS );
}
properties.setNullableProperty( SYSTEM_EXIT_TIMEOUT, toString( booterConfiguration.getSystemExitTimeout() ) );
properties.setNullableProperty( SYSTEM_EXIT_TIMEOUT, toString( providerConfiguration.getSystemExitTimeout() ) );

File surefireTmpDir = forkConfiguration.getTempDirectory();
boolean debug = forkConfiguration.isDebug();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,12 @@ protected void setUseModulePath( boolean useModulePath )

}

@Override
protected String getEnableProcessChecker()
{
return null;
}

@Override
protected Artifact getMojoArtifact()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.surefire.AbstractSurefireMojo.JUnitPlatformProviderInfo;
import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
Expand All @@ -43,7 +44,9 @@
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.suite.RunResult;
import org.codehaus.plexus.logging.Logger;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
Expand Down Expand Up @@ -99,6 +102,9 @@
@PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
public class AbstractSurefireMojoTest
{
@Rule
public final ExpectedException e = ExpectedException.none();

@Mock
private ArtifactHandler handler;

Expand Down Expand Up @@ -1689,6 +1695,29 @@ private static ArtifactResolutionResult createSurefireProviderResolutionResult(
return surefirePlatformResolutionResult;
}

@Test
public void shouldVerifyConfigParameters() throws Exception
{
Mojo mojo = new Mojo()
{
@Override
public File getTestClassesDirectory()
{
return new File( System.getProperty( "user.dir" ), "target/test-classes" );
}

@Override
protected String getEnableProcessChecker()
{
return "fake";
}
};

e.expect( MojoFailureException.class );
e.expectMessage( "Unexpected value 'fake' in the configuration parameter 'enableProcessChecker'." );
mojo.verifyParameters();
}

/**
*
*/
Expand Down Expand Up @@ -2085,6 +2114,12 @@ protected void setUseModulePath( boolean useModulePath )

}

@Override
protected String getEnableProcessChecker()
{
return null;
}

@Override
protected Artifact getMojoArtifact()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,12 @@ protected void setUseModulePath( boolean useModulePath )

}

@Override
protected String getEnableProcessChecker()
{
return null;
}

@Override
protected Artifact getMojoArtifact()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.maven.surefire.booter.BooterDeserializer;
import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.ClasspathConfiguration;
import org.apache.maven.surefire.booter.ProcessCheckerType;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.booter.Shutdown;
Expand Down Expand Up @@ -285,7 +286,7 @@ private StartupConfiguration getTestStartupConfiguration( ClassLoaderConfigurati
ClasspathConfiguration classpathConfiguration = new ClasspathConfiguration( true, true );

return new StartupConfiguration( "com.provider", classpathConfiguration, classLoaderConfiguration, false,
false );
false, ProcessCheckerType.ALL );
}

private File getTestSourceDirectory()
Expand Down
Loading

0 comments on commit 08ff28f

Please sign in to comment.