You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/11/12 13:40:08 UTC

[maven-surefire] branch SUREFIRE-1631 updated (b072e24 -> 3d573e9)

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a change to branch SUREFIRE-1631
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.


 discard b072e24  build fix checkstyle
 discard 96376d4  build fix
 discard 5355373  fix
 discard 105707a  fix
 discard 43c8e51  skipped the its
 discard 7c253e3  [SUREFIRE-1631] Forked VM terminated without properly saying goodbye with AciveMQ
     new 3d573e9  [SUREFIRE-1631] Forked VM terminated without properly saying goodbye with AciveMQ

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (b072e24)
            \
             N -- N -- N   refs/heads/SUREFIRE-1631 (3d573e9)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Jenkinsfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[maven-surefire] 01/01: [SUREFIRE-1631] Forked VM terminated without properly saying goodbye with AciveMQ

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch SUREFIRE-1631
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 3d573e9a413ade372cf5cfb051fbad91ec467717
Author: tibordigana <ti...@apache.org>
AuthorDate: Tue Nov 12 04:32:32 2019 +0100

    [SUREFIRE-1631] Forked VM terminated without properly saying goodbye with AciveMQ
---
 .../apache/maven/surefire/booter/PpidChecker.java  | 77 +++++++++++++++-------
 .../maven/surefire/booter/PpidCheckerTest.java     | 17 +++++
 2 files changed, 72 insertions(+), 22 deletions(-)

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
index 3b5a007..c56a7ef 100644
--- 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
@@ -55,7 +55,7 @@ import static org.apache.maven.surefire.util.internal.StringUtils.NL;
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @since 2.20.1
  */
-final class PpidChecker
+class PpidChecker
 {
     private static final int MINUTES_TO_MILLIS = 60 * 1000;
     // 25 chars https://superuser.com/questions/937380/get-creation-time-of-file-in-milliseconds/937401#937401
@@ -68,6 +68,8 @@ final class PpidChecker
     private static final String RELATIVE_PATH_TO_WMIC = "System32\\Wbem";
     private static final String SYSTEM_PATH_TO_WMIC =
             "%" + WINDOWS_SYSTEM_ROOT_ENV + "%\\" + RELATIVE_PATH_TO_WMIC + "\\";
+    private static final String PS_ETIME_HEADER = "ELAPSED";
+    private static final String PS_PID_HEADER = "PID";
 
     private final Queue<Process> destroyableCommands = new ConcurrentLinkedQueue<>();
 
@@ -83,6 +85,7 @@ final class PpidChecker
 
     private volatile ProcessInfo parentProcessInfo;
     private volatile boolean stopped;
+    private volatile boolean isFirstCheckFailed;
 
     PpidChecker( @Nonnull String ppid )
     {
@@ -91,7 +94,7 @@ final class PpidChecker
 
     boolean canUse()
     {
-        if ( isStopped() )
+        if ( isStopped() || isFirstCheckFailed )
         {
             return false;
         }
@@ -121,8 +124,12 @@ final class PpidChecker
             checkProcessInfo();
 
             // let's compare creation time, should be same unless killed or PID is reused by OS into another process
-            return !parentProcessInfo.isInvalid()
+            boolean isAlive = !parentProcessInfo.isInvalid()
                     && ( previousInfo == null || parentProcessInfo.isTimeEqualTo( previousInfo ) );
+
+            fireOnFirstCommandFailure( previousInfo, isAlive );
+
+            return isAlive;
         }
         else if ( IS_OS_UNIX )
         {
@@ -130,13 +137,29 @@ final class PpidChecker
             checkProcessInfo();
 
             // let's compare elapsed time, should be greater or equal if parent process is the same and still alive
-            return !parentProcessInfo.isInvalid()
+            boolean isAlive = !parentProcessInfo.isInvalid()
                     && ( previousInfo == null || !parentProcessInfo.isTimeBefore( previousInfo ) );
+
+            fireOnFirstCommandFailure( previousInfo, isAlive );
+
+            return isAlive;
         }
         parentProcessInfo = ERR_PROCESS_INFO;
         throw new IllegalStateException( "unknown platform or you did not call canUse() before isProcessAlive()" );
     }
 
+    private void fireOnFirstCommandFailure( ProcessInfo previousInfo, boolean isAlive )
+    {
+        if ( !isFirstCheckFailed )
+        {
+            isFirstCheckFailed = previousInfo == null && !isAlive;
+            if ( isFirstCheckFailed )
+            {
+                throw new IllegalStateException( "irrelevant to call isProcessAlive(), first check failed" );
+            }
+        }
+    }
+
     private void checkProcessInfo()
     {
         if ( isStopped() )
@@ -168,20 +191,27 @@ final class PpidChecker
             {
                 if ( previousOutputLine.isInvalid() )
                 {
-                    Matcher matcher = UNIX_CMD_OUT_PATTERN.matcher( line );
-                    if ( matcher.matches() && ppid.equals( fromPID( matcher ) ) )
+                    if ( hasHeader )
                     {
-                        long pidUptime = fromDays( matcher )
-                                                 + fromHours( matcher )
-                                                 + fromMinutes( matcher )
-                                                 + fromSeconds( matcher );
-                        return unixProcessInfo( ppid, pidUptime );
+                        Matcher matcher = UNIX_CMD_OUT_PATTERN.matcher( line );
+                        if ( matcher.matches() && ppid.equals( fromPID( matcher ) ) )
+                        {
+                            long pidUptime = fromDays( matcher )
+                                                     + fromHours( matcher )
+                                                     + fromMinutes( matcher )
+                                                     + fromSeconds( matcher );
+                            return unixProcessInfo( ppid, pidUptime );
+                        }
+                        matcher = BUSYBOX_CMD_OUT_PATTERN.matcher( line );
+                        if ( matcher.matches() && ppid.equals( fromBusyboxPID( matcher ) ) )
+                        {
+                            long pidUptime = fromBusyboxHours( matcher ) + fromBusyboxMinutes( matcher );
+                            return unixProcessInfo( ppid, pidUptime );
+                        }
                     }
-                    matcher = BUSYBOX_CMD_OUT_PATTERN.matcher( line );
-                    if ( matcher.matches() && ppid.equals( fromBusyboxPID( matcher ) ) )
+                    else
                     {
-                        long pidUptime = fromBusyboxHours( matcher ) + fromBusyboxMinutes( matcher );
-                        return unixProcessInfo( ppid, pidUptime );
+                        hasHeader = line.contains( PS_ETIME_HEADER ) && line.contains( PS_PID_HEADER );
                     }
                 }
                 return previousOutputLine;
@@ -195,8 +225,6 @@ final class PpidChecker
     {
         ProcessInfoConsumer reader = new ProcessInfoConsumer( "US-ASCII" )
         {
-            private boolean hasHeader;
-
             @Override
             @Nonnull
             ProcessInfo consumeLine( String line, ProcessInfo previousProcessInfo ) throws Exception
@@ -372,6 +400,8 @@ final class PpidChecker
     {
         private final String charset;
 
+        boolean hasHeader;
+
         ProcessInfoConsumer( String charset )
         {
             this.charset = charset;
@@ -409,15 +439,18 @@ final class PpidChecker
                     DumpErrorSingleton.getSingleton()
                             .dumpText( out.toString() );
                 }
-                return isStopped() ? ERR_PROCESS_INFO : exitCode == 0 ? processInfo : INVALID_PROCESS_INFO;
+                return isStopped() ? ERR_PROCESS_INFO : ( exitCode == 0 ? processInfo : INVALID_PROCESS_INFO );
             }
             catch ( Exception e )
             {
-                DumpErrorSingleton.getSingleton()
-                        .dumpText( out.toString() );
+                if ( !( e instanceof InterruptedException ) && !( e.getCause() instanceof InterruptedException ) )
+                {
+                    DumpErrorSingleton.getSingleton()
+                            .dumpText( out.toString() );
 
-                DumpErrorSingleton.getSingleton()
-                        .dumpException( e );
+                    DumpErrorSingleton.getSingleton()
+                            .dumpException( e );
+                }
 
                 return ERR_PROCESS_INFO;
             }
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
index 915f2bc..52317e3 100644
--- 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
@@ -171,6 +171,8 @@ public class PpidCheckerTest
     {
         PpidChecker checker = new PpidChecker( "1000000" );
 
+        setInternalState( checker, "parentProcessInfo", ProcessInfo.unixProcessInfo( "", 0L ) );
+
         assertThat( checker.canUse() )
                 .isTrue();
 
@@ -179,6 +181,21 @@ public class PpidCheckerTest
     }
 
     @Test
+    public void shouldFailFirstCheck()
+    {
+        PpidChecker checker = new PpidChecker( "1000000" );
+
+        assertThat( checker.canUse() )
+                .isTrue();
+
+        exceptions.expect( IllegalStateException.class );
+        exceptions.expectMessage( "irrelevant to call isProcessAlive(), first check failed" );
+
+        checker.isProcessAlive();
+
+    }
+
+    @Test
     public void shouldParseEtime()
     {
         Matcher m = PpidChecker.UNIX_CMD_OUT_PATTERN.matcher( "38 1234567890" );