11/*
2- * Copyright (c) 2016, 2021 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2016, 2023 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2727import java .io .FileInputStream ;
2828import java .io .IOException ;
2929import java .io .InputStream ;
30+ import java .io .File ;
31+ import java .nio .charset .Charset ;
3032import java .nio .file .Files ;
3133import java .nio .file .Path ;
3234import java .nio .file .Paths ;
3335import java .nio .file .StandardOpenOption ;
36+ import java .time .Instant ;
3437import java .util .ArrayList ;
3538import java .util .Collections ;
3639import java .util .HashMap ;
@@ -87,6 +90,7 @@ public void put(String key, Supplier<String> s) {
8790 */
8891 @ Override
8992 public Map <String , String > call () {
93+ log ("Entering call()" );
9094 SafeMap map = new SafeMap ();
9195 map .put ("vm.flavor" , this ::vmFlavor );
9296 map .put ("vm.compMode" , this ::vmCompMode );
@@ -125,6 +129,7 @@ public Map<String, String> call() {
125129 vmOptFinalFlags (map );
126130
127131 dump (map .map );
132+ log ("Leaving call()" );
128133 return map .map ;
129134 }
130135
@@ -432,6 +437,8 @@ protected String isCompiler2Enabled() {
432437 * @return true if docker is supported in a given environment
433438 */
434439 protected String dockerSupport () {
440+ log ("Entering dockerSupport()" );
441+
435442 boolean isSupported = false ;
436443 if (Platform .isLinux ()) {
437444 // currently docker testing is only supported for Linux,
@@ -450,6 +457,8 @@ protected String dockerSupport() {
450457 }
451458 }
452459
460+ log ("dockerSupport(): platform check: isSupported = " + isSupported );
461+
453462 if (isSupported ) {
454463 try {
455464 isSupported = checkDockerSupport ();
@@ -458,15 +467,59 @@ protected String dockerSupport() {
458467 }
459468 }
460469
470+ log ("dockerSupport(): returning isSupported = " + isSupported );
461471 return "" + isSupported ;
462472 }
463473
474+ // Configures process builder to redirect process stdout and stderr to a file.
475+ // Returns file names for stdout and stderr.
476+ private Map <String , String > redirectOutputToLogFile (String msg , ProcessBuilder pb , String fileNameBase ) {
477+ Map <String , String > result = new HashMap <>();
478+ String timeStamp = Instant .now ().toString ().replace (":" , "-" ).replace ("." , "-" );
479+
480+ String stdoutFileName = String .format ("./%s-stdout--%s.log" , fileNameBase , timeStamp );
481+ pb .redirectOutput (new File (stdoutFileName ));
482+ log (msg + ": child process stdout redirected to " + stdoutFileName );
483+ result .put ("stdout" , stdoutFileName );
484+
485+ String stderrFileName = String .format ("./%s-stderr--%s.log" , fileNameBase , timeStamp );
486+ pb .redirectError (new File (stderrFileName ));
487+ log (msg + ": child process stderr redirected to " + stderrFileName );
488+ result .put ("stderr" , stderrFileName );
489+
490+ return result ;
491+ }
492+
493+ private void printLogfileContent (Map <String , String > logFileNames ) {
494+ logFileNames .entrySet ().stream ()
495+ .forEach (entry ->
496+ {
497+ log ("------------- " + entry .getKey ());
498+ try {
499+ Files .lines (Path .of (entry .getValue ()))
500+ .forEach (line -> log (line ));
501+ } catch (IOException ie ) {
502+ log ("Exception while reading file: " + ie );
503+ }
504+ log ("-------------" );
505+ });
506+ }
507+
464508 private boolean checkDockerSupport () throws IOException , InterruptedException {
509+ log ("checkDockerSupport(): entering" );
465510 ProcessBuilder pb = new ProcessBuilder (Container .ENGINE_COMMAND , "ps" );
511+ Map <String , String > logFileNames = redirectOutputToLogFile ("checkDockerSupport(): <container> ps" ,
512+ pb , "container-ps" );
466513 Process p = pb .start ();
467514 p .waitFor (10 , TimeUnit .SECONDS );
515+ int exitValue = p .exitValue ();
516+
517+ log (String .format ("checkDockerSupport(): exitValue = %s, pid = %s" , exitValue , p .pid ()));
518+ if (exitValue != 0 ) {
519+ printLogfileContent (logFileNames );
520+ }
468521
469- return (p . exitValue () == 0 );
522+ return (exitValue == 0 );
470523 }
471524
472525 /**
@@ -581,6 +634,40 @@ protected static void dump(Map<String, String> map) {
581634 }
582635 }
583636
637+ /**
638+ * Log diagnostic message.
639+ *
640+ * @param msg
641+ */
642+ protected static void log (String msg ) {
643+ // Always log to a file.
644+ logToFile (msg );
645+
646+ // Also log to stderr; guarded by property to avoid excessive verbosity.
647+ // By jtreg design stderr produced here will be visible
648+ // in the output of a parent process. Note: stdout should not be used
649+ // for logging as jtreg parses that output directly and only echoes it
650+ // in the event of a failure.
651+ if (Boolean .getBoolean ("jtreg.log.vmprops" )) {
652+ System .err .println ("VMProps: " + msg );
653+ }
654+ }
655+
656+ /**
657+ * Log diagnostic message to a file.
658+ *
659+ * @param msg
660+ */
661+ protected static void logToFile (String msg ) {
662+ String fileName = "./vmprops.log" ;
663+ try {
664+ Files .writeString (Paths .get (fileName ), msg + "\n " , Charset .forName ("ISO-8859-1" ),
665+ StandardOpenOption .APPEND , StandardOpenOption .CREATE );
666+ } catch (IOException e ) {
667+ throw new RuntimeException ("Failed to log into '" + fileName + "'" , e );
668+ }
669+ }
670+
584671 /**
585672 * This method is for the testing purpose only.
586673 *
0 commit comments