1 /**
   2  * Copyright (c) 2015, 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 /*
  25  * @test
  26  * @summary Test the recording and checking of dependency hashes
  27  * @author Andrei Eremeev
  28  * @library /jdk/jigsaw/lib /lib/testlibrary
  29  * @modules java.base/jdk.internal.module
  30  *          jdk.jlink/jdk.tools.jlink
  31  *          jdk.jlink/jdk.tools.jmod
  32  *          jdk.compiler
  33  * @ignore
  34  * @build jdk.testlibrary.ProcessTools jdk.testlibrary.OutputAnalyzer CompilerUtils
  35  * @run main HashesTest
  36  */
  37 
  38 import java.io.File;
  39 import java.io.IOException;
  40 import java.io.PrintWriter;
  41 import java.nio.file.FileVisitResult;
  42 import java.nio.file.Files;
  43 import java.nio.file.Path;
  44 import java.nio.file.Paths;
  45 import java.nio.file.SimpleFileVisitor;
  46 import java.nio.file.attribute.BasicFileAttributes;
  47 import java.util.ArrayList;
  48 import java.util.Collections;
  49 import java.util.List;
  50 import java.util.stream.Collectors;
  51 
  52 import jdk.testlibrary.OutputAnalyzer;
  53 import jdk.testlibrary.ProcessTools;
  54 
  55 public class HashesTest {
  56 
  57     private final Path jdkHome = Paths.get(System.getProperty("test.jdk"));
  58     private final Path stdJmods = jdkHome.resolve("..").resolve("jmods");
  59     private final Path testSrc = Paths.get(System.getProperty("test.src"));
  60     private final Path modSrc = testSrc.resolve("src");
  61     private final Path newModSrc = testSrc.resolve("newsrc");
  62     private final Path classes = Paths.get("classes");
  63     private final Path jmods = Paths.get("jmods");
  64 
  65     public static void main(String[] args) throws Exception {
  66         new HashesTest().run();
  67     }
  68 
  69     private void run() throws Exception {
  70         if (!Files.exists(stdJmods)) {
  71             return;
  72         }
  73         Files.createDirectories(jmods);
  74         Path m1Classes = classes.resolve("m1");
  75         Path m2Classes = classes.resolve("m2");
  76         Path m3Classes = classes.resolve("not_matched");
  77         // build the second module
  78         compileClasses(modSrc, m2Classes);
  79         runJmod(m2Classes.toString(), m2Classes.getFileName().toString());
  80 
  81         // build the third module
  82         compileClasses(modSrc, m3Classes);
  83         runJmod(m3Classes.toString(), m3Classes.getFileName().toString());
  84 
  85         compileClasses(modSrc, m1Classes, "-mp", jmods.toString());
  86         runJmod(m1Classes.toString(), m1Classes.getFileName().toString(),
  87                 "--modulepath", jmods.toString(), "--hash-dependencies", "m2");
  88         runJava(0, "-mp", jmods.toString(), "-m", "m1/org.m1.Main");
  89 
  90         deleteDirectory(m3Classes);
  91         Files.delete(jmods.resolve("not_matched.jmod"));
  92 
  93         // build the new third module
  94         compileClasses(newModSrc, m3Classes);
  95         runJmod(m3Classes.toString(), m3Classes.getFileName().toString());
  96         runJava(0, "-mp", jmods.toString(), "-m", "m1/org.m1.Main");
  97 
  98         deleteDirectory(m2Classes);
  99         Files.delete(jmods.resolve("m2.jmod"));
 100 
 101         compileClasses(newModSrc, m2Classes);
 102         runJmod(m2Classes.toString(), m2Classes.getFileName().toString());
 103 
 104         runJava(1, "-mp", jmods.toString(), "-m", "m1/org.m1.Main");
 105 
 106         if (jdk.tools.jlink.Main.run(new String[]{
 107                 "--modulepath", stdJmods.toString() + File.pathSeparator + jmods.toString(),
 108                 "--addmods", "m1", "--output", "myimage"}, new PrintWriter(System.out)) == 0) {
 109             throw new AssertionError("Expected failure. rc = 0");
 110         }
 111     }
 112 
 113     private void deleteDirectory(Path dir) throws IOException {
 114         Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
 115             @Override
 116             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
 117                 Files.delete(file);
 118                 return FileVisitResult.CONTINUE;
 119             }
 120 
 121             @Override
 122             public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
 123                 Files.delete(dir);
 124                 return FileVisitResult.CONTINUE;
 125             }
 126         });
 127     }
 128 
 129     private void runJava(int expectedExitCode, String... args) throws Exception {
 130         OutputAnalyzer analyzer = ProcessTools.executeTestJava(args);
 131         if (analyzer.getExitValue() != expectedExitCode) {
 132             throw new AssertionError("Expected exit code: " + expectedExitCode +
 133                     ", got: " + analyzer.getExitValue());
 134         }
 135     }
 136 
 137     private void compileClasses(Path src, Path output, String... options) throws IOException {
 138         List<String> args = new ArrayList<>();
 139         Collections.addAll(args, options);
 140         Collections.addAll(args, "-d", output.toString());
 141         args.add(src.toString());
 142         System.out.println("javac options: " + args.stream().collect(Collectors.joining(" ")));
 143         if (!CompilerUtils.compile(src.resolve(output.getFileName()), output, options)) {
 144             throw new AssertionError("Compilation failure. See log.");
 145         }
 146     }
 147 
 148     private void runJmod(String cp, String modName, String... options) {
 149         List<String> args = new ArrayList<>();
 150         args.add("create");
 151         Collections.addAll(args, options);
 152         Collections.addAll(args, "--class-path", cp,
 153                 jmods + File.separator + modName + ".jmod");
 154         int rc = jdk.tools.jmod.Main.run(args.toArray(new String[args.size()]), System.out);
 155         System.out.println("jmod options: " + args.stream().collect(Collectors.joining(" ")));
 156         if (rc != 0) {
 157             throw new AssertionError("Jmod failed: rc = " + rc);
 158         }
 159     }
 160 }