Repository: maven-surefire Updated Branches: refs/heads/master c343cc412 -> 58a4dad81
Revert "[SUREFIRE-1302] Surefire does not wait long enough for the forked VM and assumes it to be dead" This reverts commit c343cc412b986fd9da839696c709542d03679d68. Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/58a4dad8 Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/58a4dad8 Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/58a4dad8 Branch: refs/heads/master Commit: 58a4dad81b02dba8ccc0f3fe511e31bfaa914d43 Parents: c343cc4 Author: Tibor17 <[email protected]> Authored: Wed Jul 26 04:26:05 2017 +0200 Committer: Tibor17 <[email protected]> Committed: Wed Jul 26 04:26:05 2017 +0200 ---------------------------------------------------------------------- maven-failsafe-plugin/pom.xml | 17 + maven-surefire-common/pom.xml | 6 - .../surefire/report/FileReporterUtils.java | 11 +- maven-surefire-plugin/pom.xml | 17 + .../src/site/apt/examples/shutdown.apt.vm | 9 - maven-surefire-report-plugin/pom.xml | 4 + pom.xml | 17 +- surefire-api/pom.xml | 10 +- .../maven/surefire/booter/CommandReader.java | 4 +- surefire-booter/pom.xml | 25 +- .../maven/surefire/booter/ForkedBooter.java | 71 +--- .../maven/surefire/booter/PpidChecker.java | 382 ------------------- .../maven/surefire/booter/ProcessInfo.java | 77 ---- .../maven/surefire/booter/JUnit4SuiteTest.java | 3 +- .../maven/surefire/booter/PpidCheckerTest.java | 204 ---------- ...urefire1295AttributeJvmCrashesToTestsIT.java | 6 +- 16 files changed, 70 insertions(+), 793 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-failsafe-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/maven-failsafe-plugin/pom.xml b/maven-failsafe-plugin/pom.xml index ec48929..f42e682 100644 --- a/maven-failsafe-plugin/pom.xml +++ b/maven-failsafe-plugin/pom.xml @@ -45,10 +45,27 @@ <dependencies> <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>maven-surefire-common</artifactId> </dependency> <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-shared-utils</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-annotations</artifactId> + <scope>compile</scope> + </dependency> + <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${project.version}</version> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-surefire-common/pom.xml ---------------------------------------------------------------------- diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml index e911a4c..4064bc2 100644 --- a/maven-surefire-common/pom.xml +++ b/maven-surefire-common/pom.xml @@ -93,7 +93,6 @@ <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> - <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> @@ -193,7 +192,6 @@ <include>org.apache.maven.shared:maven-shared-utils</include> <include>org.apache.maven.shared:maven-common-artifact-filters</include> <include>commons-io:commons-io</include> - <include>org.apache.commons:commons-lang3</include> </includes> </artifactSet> <relocations> @@ -205,10 +203,6 @@ <pattern>org.apache.commons.io</pattern> <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.io</shadedPattern> </relocation> - <relocation> - <pattern>org.apache.commons.lang3</pattern> - <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang3</shadedPattern> - </relocation> </relocations> </configuration> </execution> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/FileReporterUtils.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/FileReporterUtils.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/FileReporterUtils.java index fd33d8e..36bc269 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/FileReporterUtils.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/FileReporterUtils.java @@ -19,8 +19,6 @@ package org.apache.maven.plugin.surefire.report; * under the License. */ -import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; - /** * Utils class for file-based reporters * @@ -47,6 +45,13 @@ public final class FileReporterUtils private static String getOSSpecificIllegalChars() { - return IS_OS_WINDOWS ? "\\/:*?\"<>|\0" : "/\0"; + if ( System.getProperty( "os.name" ).toLowerCase().startsWith( "win" ) ) + { + return "\\/:*?\"<>|\0"; + } + else + { + return "/\0"; + } } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-surefire-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/maven-surefire-plugin/pom.xml b/maven-surefire-plugin/pom.xml index 2a186e3..62ec4a7 100644 --- a/maven-surefire-plugin/pom.xml +++ b/maven-surefire-plugin/pom.xml @@ -45,9 +45,26 @@ <dependencies> <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>maven-surefire-common</artifactId> </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-toolchain</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-annotations</artifactId> + <scope>compile</scope> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm ---------------------------------------------------------------------- diff --git a/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm b/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm index 4c4a0a3..a546853 100644 --- a/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm +++ b/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm @@ -39,15 +39,6 @@ Shutdown of Forked JVM * Pinging forked JVM - << Since ${thisPlugin} Plugin 2.20.1 ping is platform dependent and fallbacks to old mechanism if platform is - not recognized or native commands fail in Java. >> - - Simply the mechanism checks the <<<PPID>>> still exists and it is not reused by OS in another application. - If parent (normally Maven) process has died, the forked JVM is killed. - - - << Since ${thisPlugin} Plugin 2.19 the old mechanism is significantly slower: >> - The master process sends NOOP command to a forked JVM every 10 seconds. Forked JVM is waiting for the command every 20 seconds. If the master process is killed (received SIGKILL signal) or shutdown http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/maven-surefire-report-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/maven-surefire-report-plugin/pom.xml b/maven-surefire-report-plugin/pom.xml index 93a2e80..a4fe7e2 100644 --- a/maven-surefire-report-plugin/pom.xml +++ b/maven-surefire-report-plugin/pom.xml @@ -48,6 +48,10 @@ <dependencies> <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-logger-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-project</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 397d5d9..962a5bf 100644 --- a/pom.xml +++ b/pom.xml @@ -91,9 +91,6 @@ <mavenVersion>2.2.1</mavenVersion> <!-- <shadedVersion>2.12.4</shadedVersion> commented out due to https://issues.apache.org/jira/browse/MRELEASE-799 --> <mavenPluginPluginVersion>3.3</mavenPluginPluginVersion> - <commonsLang3Version>3.5</commonsLang3Version> - <commonsIoVersion>2.5</commonsIoVersion> - <mavenSharedUtilsVersion>0.9</mavenSharedUtilsVersion> <maven.surefire.scm.devConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven-surefire.git</maven.surefire.scm.devConnection> <maven.site.path>surefire-archives/surefire-LATEST</maven.site.path> </properties> @@ -108,12 +105,12 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>${commonsLang3Version}</version> + <version>3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>${commonsIoVersion}</version> + <version>2.2</version> </dependency> <dependency> <groupId>org.apache.maven.surefire</groupId> @@ -218,13 +215,7 @@ <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-utils</artifactId> - <version>${mavenSharedUtilsVersion}</version> - <exclusions> - <exclusion> - <groupId>com.google.code.findbugs</groupId> - <artifactId>jsr305</artifactId> - </exclusion> - </exclusions> + <version>0.9</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> @@ -386,7 +377,7 @@ </plugin> <plugin> <artifactId>maven-shade-plugin</artifactId> - <version>3.0.0</version> + <version>1.5</version> </plugin> <plugin> <artifactId>maven-plugin-plugin</artifactId> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-api/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-api/pom.xml b/surefire-api/pom.xml index 96c5be3..7e407d2 100644 --- a/surefire-api/pom.xml +++ b/surefire-api/pom.xml @@ -40,11 +40,6 @@ <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-utils</artifactId> </dependency> - <dependency> - <groupId>com.google.code.findbugs</groupId> - <artifactId>jsr305</artifactId> - <scope>provided</scope> - </dependency> </dependencies> <build> @@ -79,6 +74,7 @@ <artifactSet> <includes> <include>org.apache.maven.shared:maven-shared-utils</include> + <include>commons-lang:commons-lang</include> </includes> </artifactSet> <relocations> @@ -86,6 +82,10 @@ <pattern>org.apache.maven.shared</pattern> <shadedPattern>org.apache.maven.surefire.shade.org.apache.maven.shared</shadedPattern> </relocation> + <relocation> + <pattern>org.apache.commons.lang</pattern> + <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang</shadedPattern> + </relocation> </relocations> </configuration> </execution> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java index c3d80ea..ed7d4fa 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java @@ -438,7 +438,7 @@ public final class CommandReader DumpErrorSingleton.getSingleton().dumpStreamException( e, msg ); exitByConfiguration(); - // does not go to finally for non-default config: Shutdown.EXIT or Shutdown.KILL + // does not go to finally } } catch ( IOException e ) @@ -493,7 +493,7 @@ public final class CommandReader { Runtime.getRuntime().halt( 1 ); } - // else is default: other than Shutdown.DEFAULT should not happen; otherwise you missed enum case + // else is default: should not happen; otherwise you missed enum case } } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-booter/pom.xml b/surefire-booter/pom.xml index 65802a3..b79cceb 100644 --- a/surefire-booter/pom.xml +++ b/surefire-booter/pom.xml @@ -36,14 +36,6 @@ <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-api</artifactId> </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - </dependency> - <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - </dependency> </dependencies> <build> @@ -58,7 +50,6 @@ </dependency> </dependencies> <configuration> - <argLine>-DPpidCheckerTest.args=shouldFindPid</argLine> <redirectTestOutputToFile>true</redirectTestOutputToFile> <includes> <include>**/JUnit4SuiteTest.java</include> @@ -78,23 +69,13 @@ <minimizeJar>true</minimizeJar> <artifactSet> <includes> - <include>org.apache.commons:commons-lang3</include> - <include>commons-io:commons-io</include> - <include>org.apache.maven.shared:maven-shared-utils</include> + <include>commons-lang:commons-lang</include> </includes> </artifactSet> <relocations> <relocation> - <pattern>org.apache.commons.lang3</pattern> - <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang3</shadedPattern> - </relocation> - <relocation> - <pattern>org.apache.commons.io</pattern> - <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.io</shadedPattern> - </relocation> - <relocation> - <pattern>org.apache.maven.shared.utils</pattern> - <shadedPattern>org.apache.maven.surefire.shade.org.apache.maven.shared.utils</shadedPattern> + <pattern>org.apache.commons.lang</pattern> + <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang</shadedPattern> </relocation> </relocations> </configuration> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java index 22c2c04..1e3863e 100644 --- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java +++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java @@ -37,9 +37,7 @@ import java.lang.reflect.InvocationTargetException; import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.Semaphore; @@ -91,15 +89,13 @@ public final class ForkedBooter */ public static void main( String... args ) { + final ExecutorService pingScheduler = isDebugging() ? null : listenToShutdownCommands(); final PrintStream originalOut = out; - ExecutorService pingScheduler = null; try { final String tmpDir = args[0]; final String dumpFileName = args[1]; final String surefirePropsFileName = args[2]; - PpidChecker.uniqueCommandLineToken = surefirePropsFileName; - pingScheduler = isDebugging() ? null : listenToShutdownCommands(); BooterDeserializer booterDeserializer = new BooterDeserializer( createSurefirePropertiesIfFileExists( tmpDir, surefirePropsFileName ) ); @@ -211,51 +207,12 @@ public final class ForkedBooter COMMAND_READER.addShutdownListener( createExitHandler() ); AtomicBoolean pingDone = new AtomicBoolean( true ); COMMAND_READER.addNoopListener( createPingHandler( pingDone ) ); + Runnable pingJob = createPingJob( pingDone ); ScheduledExecutorService pingScheduler = createPingScheduler(); - Future<PpidChecker> checker = pingScheduler.submit( createProcessCheckerJob() ); - pingScheduler.scheduleWithFixedDelay( processCheckerJob( checker ), 0L, 1L, SECONDS ); - pingScheduler.scheduleAtFixedRate( createPingJob( pingDone, checker ), 0L, PING_TIMEOUT_IN_SECONDS, SECONDS ); + pingScheduler.scheduleAtFixedRate( pingJob, 0, PING_TIMEOUT_IN_SECONDS, SECONDS ); return pingScheduler; } - private static Runnable processCheckerJob( final Future<PpidChecker> processChecker ) - { - return new Runnable() - { - @Override - public void run() - { - if ( processChecker.isDone() && !processChecker.isCancelled() ) - { - try - { - PpidChecker checker = processChecker.get(); - if ( checker.canUse() && !checker.isParentProcessAlive() && !processChecker.isCancelled() ) - { - kill(); - } - } - catch ( Exception e ) - { - // nothing to do - } - } - } - }; - } - - private static Callable<PpidChecker> createProcessCheckerJob() - { - return new Callable<PpidChecker>() - { - @Override - public PpidChecker call() throws Exception - { - return new PpidChecker(); - } - }; - } - private static CommandListener createPingHandler( final AtomicBoolean pingDone ) { return new CommandListener() @@ -289,17 +246,13 @@ public final class ForkedBooter }; } - private static Runnable createPingJob( final AtomicBoolean pingDone, final Future<PpidChecker> processChecker ) + private static Runnable createPingJob( final AtomicBoolean pingDone ) { return new Runnable() { @Override public void run() { - if ( canUseNewPingMechanism( processChecker ) ) - { - return; - } boolean hasPing = pingDone.getAndSet( false ); if ( !hasPing ) { @@ -309,18 +262,6 @@ public final class ForkedBooter }; } - private static boolean canUseNewPingMechanism( Future<PpidChecker> processChecker ) - { - try - { - return ( !processChecker.isDone() || processChecker.get().canUse() ) && !processChecker.isCancelled(); - } - catch ( Exception e ) - { - return false; - } - } - private static void encodeAndWriteToOutput( String string, PrintStream out ) { byte[] encodeBytes = encodeStringForForkCommunication( string ); @@ -416,8 +357,8 @@ public final class ForkedBooter { ThreadFactory threadFactory = newDaemonThreadFactory( "ping-" + PING_TIMEOUT_IN_SECONDS + "s" ); ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1, threadFactory ); - executor.setKeepAliveTime( 3L, SECONDS ); - executor.setMaximumPoolSize( 3 ); + executor.setMaximumPoolSize( 1 ); + executor.prestartCoreThread(); return executor; } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PpidChecker.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PpidChecker.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PpidChecker.java deleted file mode 100644 index 665f36d..0000000 --- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PpidChecker.java +++ /dev/null @@ -1,382 +0,0 @@ -package org.apache.maven.surefire.booter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.shared.utils.cli.CommandLineException; -import org.apache.maven.shared.utils.cli.Commandline; -import org.apache.maven.shared.utils.cli.StreamConsumer; - -import java.io.File; -import java.lang.management.ManagementFactory; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static java.lang.Character.isDigit; -import static java.lang.Long.parseLong; -import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.HOURS; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.regex.Pattern.compile; -import static org.apache.commons.lang3.SystemUtils.IS_OS_UNIX; -import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; -import static org.apache.maven.shared.utils.cli.CommandLineUtils.executeCommandLine; -import static org.apache.maven.surefire.booter.ProcessInfo.INVALID_PROCESS_INFO; - -/** - * Recognizes PPID. Determines lifetime of parent process. - * - * @author <a href="mailto:[email protected]">Tibor Digana (tibor17)</a> - * @since 2.20.1 - */ -final class PpidChecker -{ - private static final String WMIC_CL = "CommandLine"; - - private static final String WMIC_PID = "ProcessId"; - - private static final String WMIC_PPID = "ParentProcessId"; - - private static final String WMIC_CREATION_DATE = "CreationDate"; - - private static final String WINDOWS_CMD = - "wmic process where (ProcessId=%s) get " + WMIC_CREATION_DATE + "," + WMIC_PPID; - - private static final String[] WINDOWS_PID_CMD = - { "wmic", "process", "where", "(Name='java.exe')", "get", WMIC_PID, ",", WMIC_CL }; - - private static final String UNIX_CMD1 = "/usr/bin/ps -o etime= -p $PPID"; - - private static final String UNIX_CMD2 = "/bin/ps -o etime= -p $PPID"; - - /** - * etime is in the form of [[dd-]hh:]mm:ss - */ - static final Pattern UNIX_CMD_OUT_PATTERN = compile( "^(((\\d+)-)?(\\d{2}):)?(\\d{2}):(\\d{2})$" ); - - private static final Pattern NUMBER_PATTERN = compile( "^\\d+$" ); - - static volatile String uniqueCommandLineToken; - - private final ProcessInfo parentProcessInfo; - - PpidChecker() - { - ProcessInfo parentProcess = INVALID_PROCESS_INFO; - if ( IS_OS_WINDOWS ) - { - String pid = pid(); - if ( pid == null && uniqueCommandLineToken != null ) - { - pid = pidOnWindows(); - } - - if ( pid != null ) - { - ProcessInfo currentProcessInfo = windows( pid ); - String ppid = currentProcessInfo.getPPID(); - parentProcess = currentProcessInfo.isValid() ? windows( ppid ) : INVALID_PROCESS_INFO; - } - } - else if ( IS_OS_UNIX ) - { - parentProcess = unix(); - } - parentProcessInfo = parentProcess.isValid() ? parentProcess : INVALID_PROCESS_INFO; - } - - boolean canUse() - { - return parentProcessInfo.isValid(); - } - - @SuppressWarnings( "unchecked" ) - boolean isParentProcessAlive() - { - if ( !canUse() ) - { - throw new IllegalStateException(); - } - - if ( IS_OS_WINDOWS ) - { - ProcessInfo pp = windows( parentProcessInfo.getPID() ); - // let's compare creation time, should be same unless killed or PPID is reused by OS into another process - return pp.isValid() && pp.getTime().compareTo( parentProcessInfo.getTime() ) == 0; - } - else if ( IS_OS_UNIX ) - { - ProcessInfo pp = unix(); - // let's compare elapsed time, should be greater or equal if parent process is the same and still alive - return pp.isValid() && pp.getTime().compareTo( parentProcessInfo.getTime() ) >= 0; - } - - throw new IllegalStateException(); - } - - // https://www.freebsd.org/cgi/man.cgi?ps(1) - // etimes elapsed running time, in decimal integer seconds - - // http://manpages.ubuntu.com/manpages/xenial/man1/ps.1.html - // etimes elapsed time since the process was started, in seconds. - - // http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/test/java/lang/ProcessBuilder/Basic.java#L167 - static ProcessInfo unix() - { - Commandline cli = new Commandline(); - cli.getShell().setQuotedArgumentsEnabled( false ); - cli.createArg().setLine( new File( "/usr/bin/ps" ).canExecute() ? UNIX_CMD1 : UNIX_CMD2 ); - final AtomicReference<ProcessInfo> processInfo = new AtomicReference<ProcessInfo>( INVALID_PROCESS_INFO ); - try - { - final int exitCode = executeCommandLine( cli, new StreamConsumer() - { - @Override - public void consumeLine( String line ) - { - if ( processInfo.get().isValid() ) - { - return; - } - line = line.trim(); - if ( !line.isEmpty() ) - { - Matcher matcher = UNIX_CMD_OUT_PATTERN.matcher( line ); - if ( matcher.matches() ) - { - long pidUptime = fromDays( matcher ) - + fromHours( matcher ) - + fromMinutes( matcher ) - + fromSeconds( matcher ); - processInfo.set( ProcessInfo.unixProcessInfo( pidUptime ) ); - } - } - } - }, null - ); - return exitCode == 0 ? processInfo.get() : INVALID_PROCESS_INFO; - } - catch ( CommandLineException e ) - { - return INVALID_PROCESS_INFO; - } - } - - static String pid() - { - String processName = ManagementFactory.getRuntimeMXBean().getName(); - if ( processName != null && processName.contains( "@" ) ) - { - String pid = processName.substring( 0, processName.indexOf( '@' ) ).trim(); - if ( NUMBER_PATTERN.matcher( pid ).matches() ) - { - return pid; - } - } - return null; - } - - static String pidOnWindows() - { - final AtomicReference<String> pid = new AtomicReference<String>(); - Commandline cli = new Commandline(); - cli.getShell().setQuotedArgumentsEnabled( false ); - cli.addArguments( WINDOWS_PID_CMD ); - try - { - final int exitCode = executeCommandLine( cli, new StreamConsumer() - { - private boolean hasHeader; - private boolean isPidFirst; - - @Override - public void consumeLine( String line ) - { - line = line.trim(); - if ( line.isEmpty() ) - { - return; - } - - if ( hasHeader ) - { - if ( line.contains( uniqueCommandLineToken ) ) - { - String extractedPid = - isPidFirst ? extractNumberFromBegin( line ) : extractNumberFromEnd( line ); - pid.set( extractedPid ); - } - } - else - { - StringTokenizer args = new StringTokenizer( line ); - if ( args.countTokens() == 2 ) - { - String arg0 = args.nextToken(); - String arg1 = args.nextToken(); - isPidFirst = WMIC_PID.equals( arg0 ); - hasHeader = WMIC_PID.equals( arg0 ) || WMIC_CL.equals( arg0 ); - hasHeader &= WMIC_PID.equals( arg1 ) || WMIC_CL.equals( arg1 ); - } - } - } - }, null - ); - return exitCode == 0 ? pid.get() : null; - } - catch ( CommandLineException e ) - { - return null; - } - } - - static ProcessInfo windows( final String pid ) - { - Commandline cli = new Commandline(); - cli.getShell().setQuotedArgumentsEnabled( false ); - cli.createArg().setLine( String.format( Locale.ROOT, WINDOWS_CMD, pid ) ); - - final AtomicReference<ProcessInfo> processInfo = new AtomicReference<ProcessInfo>( INVALID_PROCESS_INFO ); - try - { - final int exitCode = executeCommandLine( cli, new StreamConsumer() - { - private boolean hasHeader; - private boolean isStartTimestampFirst; - - @Override - public void consumeLine( String line ) - { - if ( processInfo.get().isValid() ) - { - return; - } - - line = line.trim(); - - if ( line.isEmpty() ) - { - return; - } - - if ( hasHeader ) - { - StringTokenizer args = new StringTokenizer( line ); - if ( args.countTokens() == 2 ) - { - if ( isStartTimestampFirst ) - { - String startTimestamp = args.nextToken(); - String ppid = args.nextToken(); - processInfo.set( ProcessInfo.windowsProcessInfo( pid, startTimestamp, ppid ) ); - } - else - { - String ppid = args.nextToken(); - String startTimestamp = args.nextToken(); - processInfo.set( ProcessInfo.windowsProcessInfo( pid, startTimestamp, ppid ) ); - } - } - } - else - { - StringTokenizer args = new StringTokenizer( line ); - if ( args.countTokens() == 2 ) - { - String arg0 = args.nextToken(); - String arg1 = args.nextToken(); - isStartTimestampFirst = WMIC_CREATION_DATE.equals( arg0 ); - hasHeader = WMIC_CREATION_DATE.equals( arg0 ) || WMIC_PPID.equals( arg0 ); - hasHeader &= WMIC_CREATION_DATE.equals( arg1 ) || WMIC_PPID.equals( arg1 ); - } - } - } - }, null - ); - return exitCode == 0 ? processInfo.get() : INVALID_PROCESS_INFO; - } - catch ( CommandLineException e ) - { - return INVALID_PROCESS_INFO; - } - } - - static long fromDays( Matcher matcher ) - { - String s = matcher.group( 3 ); - return s == null ? 0L : DAYS.toSeconds( parseLong( s ) ); - } - - static long fromHours( Matcher matcher ) - { - String s = matcher.group( 4 ); - return s == null ? 0L : HOURS.toSeconds( parseLong( s ) ); - } - - static long fromMinutes( Matcher matcher ) - { - String s = matcher.group( 5 ); - return s == null ? 0L : MINUTES.toSeconds( parseLong( s ) ); - } - - static long fromSeconds( Matcher matcher ) - { - String s = matcher.group( 6 ); - return s == null ? 0L : parseLong( s ); - } - - static String extractNumberFromBegin( String line ) - { - StringBuilder number = new StringBuilder(); - for ( int i = 0, len = line.length(); i < len; i++ ) - { - char c = line.charAt( i ); - if ( isDigit( c ) ) - { - number.append( c ); - } - else - { - break; - } - } - return number.toString(); - } - - static String extractNumberFromEnd( String line ) - { - StringBuilder number = new StringBuilder(); - for ( int i = line.length() - 1; i >= 0; i-- ) - { - char c = line.charAt( i ); - if ( isDigit( c ) ) - { - number.insert( 0, c ); - } - else - { - break; - } - } - return number.toString(); - } -} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProcessInfo.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProcessInfo.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProcessInfo.java deleted file mode 100644 index a300658..0000000 --- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProcessInfo.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.apache.maven.surefire.booter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * PID, PPID, elapsed time (Unix) or start time (Windows). - * - * @author <a href="mailto:[email protected]">Tibor Digana (tibor17)</a> - * @since 2.20.1 - */ -final class ProcessInfo -{ - static final ProcessInfo INVALID_PROCESS_INFO = new ProcessInfo( null, null, null ); - - /** - * On Unix we do not get PID due to the command is interested only to etime of PPID: - * <br> - * <pre>/bin/ps -o etime= -p $PPID</pre> - */ - static ProcessInfo unixProcessInfo( long etime ) - { - return new ProcessInfo( "pid not needed on Unix", etime, null ); - } - - static ProcessInfo windowsProcessInfo( String pid, String startTimestamp, String ppid ) - { - return new ProcessInfo( pid, startTimestamp, ppid ); - } - - private final String pid; - private final Comparable time; - private final String ppid; - - private ProcessInfo( String pid, Comparable time, String ppid ) - { - this.pid = pid; - this.time = time; - this.ppid = ppid; - } - - boolean isValid() - { - return pid != null && time != null; - } - - String getPID() - { - return pid; - } - - Comparable getTime() - { - return time; - } - - String getPPID() - { - return ppid; - } -} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java index b08423f..2bdcf21 100644 --- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java +++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java @@ -34,8 +34,7 @@ import org.junit.runners.Suite; ClasspathTest.class, CommandReaderTest.class, PropertiesWrapperTest.class, - SurefireReflectorTest.class, - PpidCheckerTest.class + SurefireReflectorTest.class } ) @RunWith( Suite.class ) public class JUnit4SuiteTest http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PpidCheckerTest.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PpidCheckerTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PpidCheckerTest.java deleted file mode 100644 index 2d49f62..0000000 --- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PpidCheckerTest.java +++ /dev/null @@ -1,204 +0,0 @@ -package org.apache.maven.surefire.booter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.junit.Test; - -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; - -import static org.apache.commons.lang3.SystemUtils.IS_OS_UNIX; -import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; -import static org.fest.assertions.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Testing {@link PpidChecker} on a platform. - * - * @author <a href="mailto:[email protected]">Tibor Digana (tibor17)</a> - * @since 2.20.1 - */ -public class PpidCheckerTest -{ - @Test - public void shouldHavePid() - { - String pid = PpidChecker.pid(); - - assertThat( pid ) - .isNotNull(); - - assertThat( pid ) - .matches( "^\\d+$" ); - } - - @Test - public void shouldHavePpidAsWindows() - { - assumeTrue( IS_OS_WINDOWS ); - - ProcessInfo processInfo = PpidChecker.windows( PpidChecker.pid() ); - - assertThat( processInfo ) - .isNotNull(); - - assertThat( processInfo.getPID() ) - .isNotNull(); - - assertThat( processInfo.getPID() ) - .matches( "^\\d+$" ); - - assertThat( processInfo.getTime() ) - .isNotNull(); - - processInfo = PpidChecker.windows( processInfo.getPID() ); - - assertThat( processInfo.getPID() ) - .isNotNull(); - - assertThat( processInfo.getPID() ) - .matches( "^\\d+$" ); - - assertThat( processInfo.getTime() ) - .isNotNull(); - } - - @Test - public void shouldFindPid() - { - assumeTrue( IS_OS_WINDOWS ); - - PpidChecker.uniqueCommandLineToken = "PpidCheckerTest.args=shouldFindPid"; - String pid = PpidChecker.pidOnWindows(); - - assertThat( pid ) - .isNotNull(); - - assertThat( pid ) - .isEqualTo( PpidChecker.pid() ); - } - - @Test - public void shouldHavePpidAsUnix() - { - assumeTrue( IS_OS_UNIX ); - - ProcessInfo processInfo = PpidChecker.unix(); - - assertThat( processInfo ) - .isNotNull(); - - assertThat( processInfo.getPID() ) - .isNotNull(); - - assertThat( processInfo.getPID() ) - .isEqualTo( "pid not needed on Unix" ); - - assertThat( processInfo.getTime() ) - .isNotNull(); - } - - @Test - public void shouldFindAliveParentProcess() - throws InterruptedException - { - PpidChecker checker = new PpidChecker(); - - assertThat( checker.canUse() ) - .isTrue(); - - TimeUnit.MILLISECONDS.sleep( 100L ); - - assertThat( checker.isParentProcessAlive() ) - .isTrue(); - } - - @Test - public void shouldParseEtime() - { - Matcher m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "38" ); - assertThat( m.matches() ) - .isFalse(); - - m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "05:38" ); - assertThat( m.matches() ) - .isTrue(); - assertThat( PpidChecker.fromDays( m ) ).isEqualTo( 0L ); - assertThat( PpidChecker.fromHours( m ) ).isEqualTo( 0L ); - assertThat( PpidChecker.fromMinutes( m ) ).isEqualTo( 300L ); - assertThat( PpidChecker.fromSeconds( m ) ).isEqualTo( 38L ); - - m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "00:05:38" ); - assertThat( m.matches() ) - .isTrue(); - assertThat( PpidChecker.fromDays( m ) ).isEqualTo( 0L ); - assertThat( PpidChecker.fromHours( m ) ).isEqualTo( 0L ); - assertThat( PpidChecker.fromMinutes( m ) ).isEqualTo( 300L ); - assertThat( PpidChecker.fromSeconds( m ) ).isEqualTo( 38L ); - - m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "01:05:38" ); - assertThat( m.matches() ) - .isTrue(); - assertThat( PpidChecker.fromDays( m ) ).isEqualTo( 0L ); - assertThat( PpidChecker.fromHours( m ) ).isEqualTo( 3600L ); - assertThat( PpidChecker.fromMinutes( m ) ).isEqualTo( 300L ); - assertThat( PpidChecker.fromSeconds( m ) ).isEqualTo( 38L ); - - m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "02-01:05:38" ); - assertThat( m.matches() ) - .isTrue(); - assertThat( PpidChecker.fromDays( m ) ).isEqualTo( 2 * 24 * 3600L ); - assertThat( PpidChecker.fromHours( m ) ).isEqualTo( 3600L ); - assertThat( PpidChecker.fromMinutes( m ) ).isEqualTo( 300L ); - assertThat( PpidChecker.fromSeconds( m ) ).isEqualTo( 38L ); - } - - @Test - public void shouldExtractNumberFromBegin() - { - String num = PpidChecker.extractNumberFromBegin( "123 abc" ); - assertThat( num ) - .isEqualTo( "123" ); - } - - @Test - public void shouldNotExtractNumberFromBegin() - { - String num = PpidChecker.extractNumberFromBegin( " 123 abc" ); - assertThat( num ) - .isEmpty(); - } - - @Test - public void shouldExtractNumberFromEnd() - { - String num = PpidChecker.extractNumberFromEnd( "abc 123" ); - assertThat( num ) - .isEqualTo( "123" ); - } - - @Test - public void shouldNotExtractNumberFromEnd() - { - String num = PpidChecker.extractNumberFromEnd( "abs 123 " ); - assertThat( num ) - .isEmpty(); - } -} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/58a4dad8/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1295AttributeJvmCrashesToTestsIT.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1295AttributeJvmCrashesToTestsIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1295AttributeJvmCrashesToTestsIT.java index f051c1c..1fa88f6 100644 --- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1295AttributeJvmCrashesToTestsIT.java +++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1295AttributeJvmCrashesToTestsIT.java @@ -27,9 +27,8 @@ import org.junit.Before; import org.junit.Test; import java.util.Iterator; +import java.util.Locale; -import static org.apache.commons.lang.SystemUtils.IS_OS_LINUX; -import static org.apache.commons.lang.SystemUtils.IS_OS_MAC_OSX; import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -47,7 +46,8 @@ public class Surefire1295AttributeJvmCrashesToTestsIT @Before public void skipWindows() { - assumeTrue( IS_OS_LINUX || IS_OS_MAC_OSX ); + String os = System.getProperty( "os.name" ).toLowerCase( Locale.ROOT ); + assumeTrue( os.equals( "mac os x" ) || os.equals( "linux" ) /*|| os.contains( "windows" )*/ ); } @Test
