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 2017/06/10 08:17:57 UTC

maven-surefire git commit: [SUREFIRE-1302] Surefire does not wait long enough for the forked VM and assumes it to be dead

Repository: maven-surefire
Updated Branches:
  refs/heads/SUREFIRE-1302_2 [created] 8b6c3e0b0


[SUREFIRE-1302] Surefire does not wait long enough for the forked VM and assumes it to be dead


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/8b6c3e0b
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/8b6c3e0b
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/8b6c3e0b

Branch: refs/heads/SUREFIRE-1302_2
Commit: 8b6c3e0b0fe671686b2bdd64181c564811b62a91
Parents: dd518d2
Author: Tibor17 <ti...@apache.org>
Authored: Sat Jun 10 10:17:39 2017 +0200
Committer: Tibor17 <ti...@apache.org>
Committed: Sat Jun 10 10:17:39 2017 +0200

----------------------------------------------------------------------
 .../maven/surefire/booter/PpidChecker.java      | 178 +++++++++++++++++++
 1 file changed, 178 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/8b6c3e0b/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
new file mode 100644
index 0000000..ac291e1
--- /dev/null
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PpidChecker.java
@@ -0,0 +1,178 @@
+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 java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Recognizes PPID.
+ *
+ * @since 2.20.1
+ */
+final class PpidChecker
+{
+    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=%d) get " + WMIC_CREATION_DATE + ", " + WMIC_PPID;
+
+    private static final String UNIX_CMD = "ps -o etime -p %s";
+
+    private static final Pattern UNIX_CMD_OUT_PATTERN =
+            Pattern.compile( "^((([\\d]+)-)?([\\d]{2}))?[:]?([\\d]{2}):([\\d]{2})$" );
+
+    private static long fromDays( Matcher matcher ) {
+        String s = matcher.group( 3 );
+        return s == null ? 0L : 24L * 60L * 60L * Byte.parseByte( s );
+    }
+
+    private static long fromHours( Matcher matcher ) {
+        String s = matcher.group( 4 );
+        return s == null ? 0L : 60L * 60L * Byte.parseByte( s );
+    }
+
+    private static long fromMinutes( Matcher matcher ) {
+        String s = matcher.group( 5 );
+        return s == null ? 0L : 60L * Byte.parseByte( s );
+    }
+
+    private static long fromSeconds( Matcher matcher ) {
+        String s = matcher.group( 6 );
+        return s == null ? 0L : Byte.parseByte( s );
+    }
+
+    // http://manpages.ubuntu.com/manpages/precise/en/man1/ps.1.html
+    // https://www.freebsd.org/cgi/man.cgi?query=ps&manpath=SuSE+Linux/i386+11.3
+
+    // http://manpages.ubuntu.com/manpages/xenial/man1/ps.1.html
+    // etime       ELAPSED   elapsed time since the process was started, in
+    //             the form [[DD-]hh:]mm:ss.
+
+    static void unix() throws IOException, InterruptedException
+    {
+        String ppid = System.getProperty( "surefire.ppid" );
+        String[] cmd = { "/bin/sh", "-c", String.format( Locale.ROOT, UNIX_CMD, ppid ) };
+        ProcessBuilder probuilder = new ProcessBuilder( cmd );
+        Process p = probuilder.start();
+        BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+        for ( String line = reader.readLine(); line != null; line = reader.readLine() )
+        {
+            System.out.println(line);
+            line = line.trim();
+            if ( !line.isEmpty() )
+            {
+                Matcher matcher = UNIX_CMD_OUT_PATTERN.matcher( line );
+                if (matcher.matches()) {
+                    long pidUptime = (long) Math.floor( ManagementFactory.getRuntimeMXBean().getUptime() / 1000d );
+                    long ppidUptime = fromDays( matcher )
+                                              + fromHours( matcher )
+                                              + fromMinutes( matcher )
+                                              + fromSeconds( matcher );
+                    System.out.printf( "%d %d\n", pidUptime, ppidUptime);
+                    break;
+                }
+            }
+        }
+        reader.close();
+        p.waitFor();
+        p.destroy();
+    }
+
+    static void windows() throws IOException, InterruptedException
+    {
+        final long pid;
+        String processName = ManagementFactory.getRuntimeMXBean().getName();
+        if ( processName != null && processName.contains( "@" ) )
+        {
+            try
+            {
+                pid = Long.parseLong( processName.substring( 0, processName.indexOf( '@' ) ) );
+            }
+            catch ( NumberFormatException e )
+            {
+                return;
+            }
+        }
+        else
+        {
+            return;
+        }
+
+        String[] cmd = { "CMD", "/A/C", String.format( Locale.ROOT, WINDOWS_CMD, pid ) };
+        ProcessBuilder probuilder = new ProcessBuilder( cmd );
+        Process p = probuilder.start();
+        BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
+        boolean hasHeader = false;
+        boolean isStartTimestampFirst = false;
+        String startTimestamp = null;
+        long ppid = 0;
+        for ( String line = reader.readLine(); line != null; line = reader.readLine() )
+        {
+            line = line.trim();
+
+            if ( line.isEmpty() )
+            {
+                continue;
+            }
+
+            if ( hasHeader )
+            {
+                StringTokenizer args = new StringTokenizer( line );
+                if ( args.countTokens() == 2 )
+                {
+                    if ( isStartTimestampFirst )
+                    {
+                        startTimestamp = args.nextToken();
+                        ppid = Long.parseLong( args.nextToken() );
+                    }
+                    else
+                    {
+                        startTimestamp = args.nextToken();
+                        ppid = Long.parseLong( args.nextToken() );
+                    }
+                }
+            }
+            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 = isStartTimestampFirst || WMIC_PPID.equals( arg0 );
+                    hasHeader &= WMIC_CREATION_DATE.equals( arg1 ) || WMIC_PPID.equals( arg1 );
+                }
+            }
+        }
+        reader.close();
+        p.waitFor();
+        p.destroy();
+    }
+}