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 2022/02/03 16:01:51 UTC
[maven-surefire] 01/01: [SUREFIRE-1999] PPID checker should redirect the error stream of the checker command to a dump file
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch InterruptedIOException
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit 3af614dc02630d1bba9ee86aec717535ac6ac359
Author: Tibor Digaňa <ti...@apache.org>
AuthorDate: Thu Feb 3 06:20:07 2022 +0100
[SUREFIRE-1999] PPID checker should redirect the error stream of the checker command to a dump file
---
.../apache/maven/surefire/booter/PpidChecker.java | 27 ++++++++-
.../maven/surefire/booter/PpidCheckerTest.java | 67 ++++++++++++++++++++++
2 files changed, 92 insertions(+), 2 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 a5287c7..3eb703d 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
@@ -25,6 +25,7 @@ import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Queue;
import java.util.Scanner;
@@ -36,6 +37,9 @@ import java.util.regex.Pattern;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.String.join;
+import static java.nio.file.Files.createTempFile;
+import static java.nio.file.Files.delete;
+import static java.nio.file.Files.readAllBytes;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MINUTES;
@@ -394,14 +398,16 @@ final class PpidChecker
ProcessInfo execute( String... command )
{
ProcessBuilder processBuilder = new ProcessBuilder( command );
- processBuilder.redirectErrorStream( true );
Process process = null;
ProcessInfo processInfo = INVALID_PROCESS_INFO;
StringBuilder out = new StringBuilder( 64 );
out.append( join( " ", command ) )
.append( NL );
+ Path stdErr = null;
try
{
+ stdErr = createTempFile( "surefire", null );
+ processBuilder.redirectError( stdErr.toFile() );
if ( IS_OS_HP_UX ) // force to run shell commands in UNIX Standard mode on HP-UX
{
processBuilder.environment().put( "UNIX95", "1" );
@@ -447,11 +453,28 @@ final class PpidChecker
if ( process != null )
{
destroyableCommands.remove( process );
- process.destroy();
closeQuietly( process.getInputStream() );
closeQuietly( process.getErrorStream() );
closeQuietly( process.getOutputStream() );
}
+
+ if ( stdErr != null )
+ {
+ try
+ {
+ String error = new String( readAllBytes( stdErr ) ).trim();
+ if ( !error.isEmpty() )
+ {
+ DumpErrorSingleton.getSingleton()
+ .dumpText( error );
+ }
+ delete( stdErr );
+ }
+ catch ( IOException e )
+ {
+ // cannot do anything about it, the dump file writes would fail as well
+ }
+ }
}
}
}
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 5f7a744..5455146 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
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.api.booter.DumpErrorSingleton;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -27,7 +29,9 @@ import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.regex.Matcher;
+import static java.nio.file.Files.readAllBytes;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.maven.surefire.shared.io.FileUtils.getTempDirectory;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_UNIX;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
import static org.apache.maven.surefire.booter.ProcessInfo.unixProcessInfo;
@@ -54,6 +58,15 @@ public class PpidCheckerTest
@Rule
public final ExpectedException exceptions = ExpectedException.none();
+ @Before
+ public void deinit()
+ {
+ DumpErrorSingleton dumper = DumpErrorSingleton.getSingleton();
+ setInternalState( dumper, "dumpFile", (Object) null );
+ setInternalState( dumper, "dumpStreamFile", (Object) null );
+ setInternalState( dumper, "binaryDumpStreamFile", (Object) null );
+ }
+
@Test
public void canExecuteUnixPs()
{
@@ -150,6 +163,60 @@ public class PpidCheckerTest
}
@Test
+ public void shouldBeStoppedCheckerWithError() throws Exception
+ {
+ String expectedPid = ManagementFactory.getRuntimeMXBean().getName().split( "@" )[0].trim();
+ DumpErrorSingleton.getSingleton().init( getTempDirectory(), "dump" );
+
+ PpidChecker checker = new PpidChecker( expectedPid );
+ checker.stop();
+
+ ProcessInfo processInfo = IS_OS_UNIX ? checker.unix() : checker.windows();
+ assertThat( processInfo.isError() ).isTrue();
+
+ File dump = DumpErrorSingleton.getSingleton().dumpText( null );
+
+ dump.deleteOnExit();
+
+ String error = new String( readAllBytes( dump.toPath() ) );
+
+ assertThat( error )
+ .contains( "<<exit>> <<0>>" )
+ .contains( "<<stopped>> <<true>>" );
+ }
+
+ @Test
+ public void shouldBeEmptyDump() throws Exception
+ {
+ String expectedPid = ManagementFactory.getRuntimeMXBean().getName().split( "@" )[0].trim();
+ DumpErrorSingleton.getSingleton().init( getTempDirectory(), "dump" );
+
+ PpidChecker checker = new PpidChecker( expectedPid );
+ Thread.currentThread().interrupt();
+
+ ProcessInfo processInfo = IS_OS_UNIX ? checker.unix() : checker.windows();
+ assertThat( processInfo.isError() ).isTrue();
+
+ // a hack to obtain the file
+ File dump = DumpErrorSingleton.getSingleton().dumpText( null );
+
+ dump.deleteOnExit();
+
+ String error = new String( readAllBytes( dump.toPath() ) ).trim();
+
+ String[] lines = error.split( "\r\n|\r|\n" );
+
+ assertThat( lines.length )
+ .isEqualTo( 2 );
+
+ assertThat( lines[0] )
+ .startsWith( "# Created at " );
+
+ assertThat( lines[1] )
+ .isEqualTo( "null" );
+ }
+
+ @Test
public void shouldNotFindSuchPID()
{
PpidChecker checker = new PpidChecker( "1000000" );