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 );
@@ -123,6 +127,7 @@ public Map<String, String> call() {
123127 vmOptFinalFlags (map );
124128
125129 dump (map .map );
130+ log ("Leaving call()" );
126131 return map .map ;
127132 }
128133
@@ -452,6 +457,8 @@ protected String isCompiler2Enabled() {
452457 * @return true if docker is supported in a given environment
453458 */
454459 protected String dockerSupport () {
460+ log ("Entering dockerSupport()" );
461+
455462 boolean isSupported = true ;
456463 if (Platform .isLinux ()) {
457464 // currently docker testing is only supported for Linux,
@@ -470,6 +477,8 @@ protected String dockerSupport() {
470477 }
471478 }
472479
480+ log ("dockerSupport(): platform check: isSupported = " + isSupported );
481+
473482 if (isSupported ) {
474483 try {
475484 isSupported = checkDockerSupport ();
@@ -478,15 +487,59 @@ protected String dockerSupport() {
478487 }
479488 }
480489
490+ log ("dockerSupport(): returning isSupported = " + isSupported );
481491 return "" + isSupported ;
482492 }
483493
494+ // Configures process builder to redirect process stdout and stderr to a file.
495+ // Returns file names for stdout and stderr.
496+ private Map <String , String > redirectOutputToLogFile (String msg , ProcessBuilder pb , String fileNameBase ) {
497+ Map <String , String > result = new HashMap <>();
498+ String timeStamp = Instant .now ().toString ().replace (":" , "-" ).replace ("." , "-" );
499+
500+ String stdoutFileName = String .format ("./%s-stdout--%s.log" , fileNameBase , timeStamp );
501+ pb .redirectOutput (new File (stdoutFileName ));
502+ log (msg + ": child process stdout redirected to " + stdoutFileName );
503+ result .put ("stdout" , stdoutFileName );
504+
505+ String stderrFileName = String .format ("./%s-stderr--%s.log" , fileNameBase , timeStamp );
506+ pb .redirectError (new File (stderrFileName ));
507+ log (msg + ": child process stderr redirected to " + stderrFileName );
508+ result .put ("stderr" , stderrFileName );
509+
510+ return result ;
511+ }
512+
513+ private void printLogfileContent (Map <String , String > logFileNames ) {
514+ logFileNames .entrySet ().stream ()
515+ .forEach (entry ->
516+ {
517+ log ("------------- " + entry .getKey ());
518+ try {
519+ Files .lines (Path .of (entry .getValue ()))
520+ .forEach (line -> log (line ));
521+ } catch (IOException ie ) {
522+ log ("Exception while reading file: " + ie );
523+ }
524+ log ("-------------" );
525+ });
526+ }
527+
484528 private boolean checkDockerSupport () throws IOException , InterruptedException {
529+ log ("checkDockerSupport(): entering" );
485530 ProcessBuilder pb = new ProcessBuilder (Container .ENGINE_COMMAND , "ps" );
531+ Map <String , String > logFileNames = redirectOutputToLogFile ("checkDockerSupport(): <container> ps" ,
532+ pb , "container-ps" );
486533 Process p = pb .start ();
487534 p .waitFor (10 , TimeUnit .SECONDS );
535+ int exitValue = p .exitValue ();
536+
537+ log (String .format ("checkDockerSupport(): exitValue = %s, pid = %s" , exitValue , p .pid ()));
538+ if (exitValue != 0 ) {
539+ printLogfileContent (logFileNames );
540+ }
488541
489- return (p . exitValue () == 0 );
542+ return (exitValue == 0 );
490543 }
491544
492545 /**
@@ -596,6 +649,40 @@ protected static void dump(Map<String, String> map) {
596649 }
597650 }
598651
652+ /**
653+ * Log diagnostic message.
654+ *
655+ * @param msg
656+ */
657+ protected static void log (String msg ) {
658+ // Always log to a file.
659+ logToFile (msg );
660+
661+ // Also log to stderr; guarded by property to avoid excessive verbosity.
662+ // By jtreg design stderr produced here will be visible
663+ // in the output of a parent process. Note: stdout should not be used
664+ // for logging as jtreg parses that output directly and only echoes it
665+ // in the event of a failure.
666+ if (Boolean .getBoolean ("jtreg.log.vmprops" )) {
667+ System .err .println ("VMProps: " + msg );
668+ }
669+ }
670+
671+ /**
672+ * Log diagnostic message to a file.
673+ *
674+ * @param msg
675+ */
676+ protected static void logToFile (String msg ) {
677+ String fileName = "./vmprops.log" ;
678+ try {
679+ Files .writeString (Paths .get (fileName ), msg + "\n " , Charset .forName ("ISO-8859-1" ),
680+ StandardOpenOption .APPEND , StandardOpenOption .CREATE );
681+ } catch (IOException e ) {
682+ throw new RuntimeException ("Failed to log into '" + fileName + "'" , e );
683+ }
684+ }
685+
599686 /**
600687 * This method is for the testing purpose only.
601688 *
0 commit comments