< prev index next >

test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java

Print this page


   1 /*
   2  * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.test.lib.containers.docker;
  25 
  26 import java.io.File;
  27 import java.io.IOException;
  28 import java.nio.file.Files;
  29 import java.nio.file.FileVisitResult;
  30 import java.nio.file.Path;
  31 import java.nio.file.Paths;
  32 import java.nio.file.SimpleFileVisitor;
  33 import java.nio.file.StandardCopyOption;
  34 import java.nio.file.attribute.BasicFileAttributes;
  35 import java.util.ArrayList;
  36 import java.util.Collections;
  37 import java.util.List;
  38 import jdk.test.lib.Platform;
  39 import jdk.test.lib.Utils;
  40 import jdk.test.lib.process.OutputAnalyzer;
  41 import jdk.test.lib.process.ProcessTools;
  42 
  43 
  44 public class DockerTestUtils {
  45     private static final String FS = File.separator;
  46     private static boolean isDockerEngineAvailable = false;
  47     private static boolean wasDockerEngineChecked = false;
  48 
  49     // Diagnostics: set to true to enable more diagnostic info
  50     private static final boolean DEBUG = false;
  51 
  52     /**
  53      * Optimized check of whether the docker engine is available in a given
  54      * environment. Checks only once, then remembers the result in a singleton.
  55      *
  56      * @return true if docker engine is available
  57      * @throws Exception
  58      */


 109     /**
 110      * Build a docker image that contains JDK under test.
 111      * The jdk will be placed under the "/jdk/" folder inside the docker file system.
 112      *
 113      * @param imageName     name of the image to be created, including version tag
 114      * @param dockerfile    name of the dockerfile residing in the test source;
 115      *                      we check for a platform specific dockerfile as well
 116      *                      and use this one in case it exists
 117      * @param buildDirName  name of the docker build/staging directory, which will
 118      *                      be created in the jtreg's scratch folder
 119      * @throws Exception
 120      */
 121     public static void
 122         buildJdkDockerImage(String imageName, String dockerfile, String buildDirName)
 123             throws Exception {
 124 
 125         Path buildDir = Paths.get(".", buildDirName);
 126         if (Files.exists(buildDir)) {
 127             throw new RuntimeException("The docker build directory already exists: " + buildDir);
 128         }
 129         // check for the existance of a platform specific docker file as well
 130         String platformSpecificDockerfile = dockerfile + "-" + Platform.getOsArch();
 131         if (Files.exists(Paths.get(Utils.TEST_SRC, platformSpecificDockerfile))) {
 132           dockerfile = platformSpecificDockerfile;
 133         }
 134 
 135         Path jdkSrcDir = Paths.get(Utils.TEST_JDK);
 136         Path jdkDstDir = buildDir.resolve("jdk");
 137 
 138         Files.createDirectories(jdkDstDir);
 139 
 140         // Copy JDK-under-test tree to the docker build directory.
 141         // This step is required for building a docker image.
 142         Files.walkFileTree(jdkSrcDir, new CopyFileVisitor(jdkSrcDir, jdkDstDir));
 143         buildDockerImage(imageName, Paths.get(Utils.TEST_SRC, dockerfile), buildDir);
 144     }
 145 
 146 
 147     /**
 148      * Build a docker image based on given docker file and docker build directory.
 149      *
 150      * @param imageName  name of the image to be created, including version tag
 151      * @param dockerfile  path to the Dockerfile to be used for building the docker
 152      *        image. The specified dockerfile will be copied to the docker build
 153      *        directory as 'Dockerfile'
 154      * @param buildDir  build directory; it should already contain all the content
 155      *        needed to build the docker image.
 156      * @throws Exception
 157      */
 158     public static void
 159         buildDockerImage(String imageName, Path dockerfile, Path buildDir) throws Exception {
 160 
 161         // Copy docker file to the build dir
 162         Files.copy(dockerfile, buildDir.resolve("Dockerfile"));

 163 
 164         // Build the docker
 165         execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
 166             .shouldHaveExitValue(0)
 167             .shouldContain("Successfully built");
 168     }
 169 
 170 
 171     /**
 172      * Run Java inside the docker image with specified parameters and options.
 173      *
 174      * @param DockerRunOptions optins for running docker
 175      *
 176      * @return output of the run command
 177      * @throws Exception
 178      */
 179     public static OutputAnalyzer dockerRunJava(DockerRunOptions opts) throws Exception {
 180         ArrayList<String> cmd = new ArrayList<>();
 181 
 182         cmd.add("docker");


 230     /**
 231      * Execute a specified command in a process, report diagnostic info.
 232      *
 233      * @param command to be executed
 234      * @return The output from the process
 235      * @throws Exception
 236      */
 237     public static OutputAnalyzer execute(String... command) throws Exception {
 238 
 239         ProcessBuilder pb = new ProcessBuilder(command);
 240         System.out.println("[COMMAND]\n" + Utils.getCommandLine(pb));
 241 
 242         long started = System.currentTimeMillis();
 243         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 244 
 245         System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]");
 246         System.out.println("[STDERR]\n" + output.getStderr());
 247         System.out.println("[STDOUT]\n" + output.getStdout());
 248 
 249         return output;












 250     }
 251 
 252 
 253     private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
 254         private final Path src;
 255         private final Path dst;
 256 
 257         public CopyFileVisitor(Path src, Path dst) {
 258             this.src = src;
 259             this.dst = dst;
 260         }
 261 
 262 
 263         @Override
 264         public FileVisitResult preVisitDirectory(Path file,
 265                 BasicFileAttributes attrs) throws IOException {
 266             Path dstDir = dst.resolve(src.relativize(file));
 267             if (!dstDir.toFile().exists()) {
 268                 Files.createDirectories(dstDir);
 269             }
   1 /*
   2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.test.lib.containers.docker;
  25 
  26 import java.io.File;
  27 import java.io.IOException;
  28 import java.nio.file.Files;
  29 import java.nio.file.FileVisitResult;
  30 import java.nio.file.Path;
  31 import java.nio.file.Paths;
  32 import java.nio.file.SimpleFileVisitor;
  33 import java.nio.file.StandardCopyOption;
  34 import java.nio.file.attribute.BasicFileAttributes;
  35 import java.util.ArrayList;
  36 import java.util.Collections;
  37 import java.util.List;

  38 import jdk.test.lib.Utils;
  39 import jdk.test.lib.process.OutputAnalyzer;
  40 import jdk.test.lib.process.ProcessTools;
  41 
  42 
  43 public class DockerTestUtils {
  44     private static final String FS = File.separator;
  45     private static boolean isDockerEngineAvailable = false;
  46     private static boolean wasDockerEngineChecked = false;
  47 
  48     // Diagnostics: set to true to enable more diagnostic info
  49     private static final boolean DEBUG = false;
  50 
  51     /**
  52      * Optimized check of whether the docker engine is available in a given
  53      * environment. Checks only once, then remembers the result in a singleton.
  54      *
  55      * @return true if docker engine is available
  56      * @throws Exception
  57      */


 108     /**
 109      * Build a docker image that contains JDK under test.
 110      * The jdk will be placed under the "/jdk/" folder inside the docker file system.
 111      *
 112      * @param imageName     name of the image to be created, including version tag
 113      * @param dockerfile    name of the dockerfile residing in the test source;
 114      *                      we check for a platform specific dockerfile as well
 115      *                      and use this one in case it exists
 116      * @param buildDirName  name of the docker build/staging directory, which will
 117      *                      be created in the jtreg's scratch folder
 118      * @throws Exception
 119      */
 120     public static void
 121         buildJdkDockerImage(String imageName, String dockerfile, String buildDirName)
 122             throws Exception {
 123 
 124         Path buildDir = Paths.get(".", buildDirName);
 125         if (Files.exists(buildDir)) {
 126             throw new RuntimeException("The docker build directory already exists: " + buildDir);
 127         }





 128 
 129         Path jdkSrcDir = Paths.get(Utils.TEST_JDK);
 130         Path jdkDstDir = buildDir.resolve("jdk");
 131 
 132         Files.createDirectories(jdkDstDir);
 133 
 134         // Copy JDK-under-test tree to the docker build directory.
 135         // This step is required for building a docker image.
 136         Files.walkFileTree(jdkSrcDir, new CopyFileVisitor(jdkSrcDir, jdkDstDir));
 137         buildDockerImage(imageName, Paths.get(Utils.TEST_SRC, dockerfile), buildDir);
 138     }
 139 
 140 
 141     /**
 142      * Build a docker image based on given docker file and docker build directory.
 143      *
 144      * @param imageName  name of the image to be created, including version tag
 145      * @param dockerfile  path to the Dockerfile to be used for building the docker
 146      *        image. The specified dockerfile will be copied to the docker build
 147      *        directory as 'Dockerfile'
 148      * @param buildDir  build directory; it should already contain all the content
 149      *        needed to build the docker image.
 150      * @throws Exception
 151      */
 152     public static void
 153         buildDockerImage(String imageName, Path dockerfile, Path buildDir) throws Exception {
 154 
 155         generateDockerFile(buildDir.resolve("Dockerfile"),
 156                            DockerfileConfig.getBaseImageName(),
 157                            DockerfileConfig.getBaseImageVersion());
 158 
 159         // Build the docker
 160         execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
 161             .shouldHaveExitValue(0)
 162             .shouldContain("Successfully built");
 163     }
 164 
 165 
 166     /**
 167      * Run Java inside the docker image with specified parameters and options.
 168      *
 169      * @param DockerRunOptions optins for running docker
 170      *
 171      * @return output of the run command
 172      * @throws Exception
 173      */
 174     public static OutputAnalyzer dockerRunJava(DockerRunOptions opts) throws Exception {
 175         ArrayList<String> cmd = new ArrayList<>();
 176 
 177         cmd.add("docker");


 225     /**
 226      * Execute a specified command in a process, report diagnostic info.
 227      *
 228      * @param command to be executed
 229      * @return The output from the process
 230      * @throws Exception
 231      */
 232     public static OutputAnalyzer execute(String... command) throws Exception {
 233 
 234         ProcessBuilder pb = new ProcessBuilder(command);
 235         System.out.println("[COMMAND]\n" + Utils.getCommandLine(pb));
 236 
 237         long started = System.currentTimeMillis();
 238         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 239 
 240         System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]");
 241         System.out.println("[STDERR]\n" + output.getStderr());
 242         System.out.println("[STDOUT]\n" + output.getStdout());
 243 
 244         return output;
 245     }
 246 
 247 
 248     private static void generateDockerFile(Path dockerfile, String baseImage,
 249                                            String baseImageVersion) throws Exception {
 250         String template =
 251             "FROM %s:%s\n" +
 252             "COPY /jdk /jdk\n" +
 253             "ENV JAVA_HOME=/jdk\n" +
 254             "CMD [\"/bin/bash\"]\n";
 255         String dockerFileStr = String.format(template, baseImage, baseImageVersion);
 256         Files.writeString(dockerfile, dockerFileStr);
 257     }
 258 
 259 
 260     private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
 261         private final Path src;
 262         private final Path dst;
 263 
 264         public CopyFileVisitor(Path src, Path dst) {
 265             this.src = src;
 266             this.dst = dst;
 267         }
 268 
 269 
 270         @Override
 271         public FileVisitResult preVisitDirectory(Path file,
 272                 BasicFileAttributes attrs) throws IOException {
 273             Path dstDir = dst.resolve(src.relativize(file));
 274             if (!dstDir.toFile().exists()) {
 275                 Files.createDirectories(dstDir);
 276             }
< prev index next >