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