Path: blob/master/test/jdk/tools/lib/tests/Helper.java
41149 views
/*1* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package tests;2324import java.io.File;25import java.io.IOException;26import java.net.URI;27import java.nio.file.FileSystem;28import java.nio.file.FileSystems;29import java.nio.file.Files;30import java.nio.file.Path;31import java.nio.file.Paths;32import java.util.ArrayList;33import java.util.Arrays;34import java.util.Collections;35import java.util.HashMap;36import java.util.List;37import java.util.Map;38import java.util.stream.Collectors;3940import tests.JImageGenerator.JLinkTask;41import tests.JImageGenerator.JModTask;4243/**44* JLink tests helper.45*/46public class Helper {4748private final Path explodedmodssrc;49private final Path jmodssrc;50private final Path jarssrc;51private final Path explodedmodsclasses;52private final Path jmodsclasses;53private final Path jarsclasses;54private final Path jmods;55private final Path jars;56private final Path images;57private final Path explodedmods;58private final Path stdjmods;59private final Path extracted;60private final Path recreated;6162private final Map<String, List<String>> moduleClassDependencies = new HashMap<>();63private final Map<String, List<String>> moduleDependencies = new HashMap<>();64private final List<String> bootClasses;65private final FileSystem fs;6667public static Helper newHelper() throws IOException {68Path jdkHome = Paths.get(System.getProperty("test.jdk"));69if (!Files.exists(jdkHome.resolve("jmods"))) {70// Skip test if the jmods directory is missing (e.g. exploded image)71System.err.println("Test not run, NO jmods directory");72return null;73}74return new Helper(jdkHome);75}7677private Helper(Path jdkHome) throws IOException {78this.stdjmods = jdkHome.resolve("jmods").normalize();79if (!Files.exists(stdjmods)) {80throw new IOException("Standard jMods do not exist.");81}82this.fs = FileSystems.getFileSystem(URI.create("jrt:/"));8384Path javabase = fs.getPath("/modules/java.base");85this.bootClasses = Files.find(javabase, Integer.MAX_VALUE,86(file, attrs) -> file.toString().endsWith(".class"))87.map(Object::toString)88.map(s -> s.substring("/modules".length()))89.collect(Collectors.toList());9091if (bootClasses.isEmpty()) {92throw new AssertionError("No boot class to check against");93}9495this.jmods = Paths.get("jmods").toAbsolutePath();96Files.createDirectories(jmods);97this.jars = Paths.get("jars").toAbsolutePath();98Files.createDirectories(jars);99this.explodedmods = Paths.get("explodedmods").toAbsolutePath();100Files.createDirectories(explodedmods);101this.explodedmodssrc = explodedmods.resolve("src");102Files.createDirectories(explodedmodssrc);103this.jarssrc = jars.resolve("src");104Files.createDirectories(jarssrc);105this.jmodssrc = jmods.resolve("src");106Files.createDirectories(jmodssrc);107this.explodedmodsclasses = explodedmods.resolve("classes");108Files.createDirectories(explodedmodsclasses);109this.jmodsclasses = jmods.resolve("classes");110Files.createDirectories(jmodsclasses);111this.jarsclasses = jars.resolve("classes");112Files.createDirectories(jarsclasses);113this.images = Paths.get("images").toAbsolutePath();114Files.createDirectories(images);115this.extracted = Paths.get("extracted").toAbsolutePath();116Files.createDirectories(extracted);117this.recreated = Paths.get("recreated").toAbsolutePath();118Files.createDirectories(recreated);119}120121public void generateDefaultModules() throws IOException {122generateDefaultJModule("leaf1");123generateDefaultJModule("leaf2");124generateDefaultJModule("leaf3");125126generateDefaultJarModule("leaf4");127generateDefaultJarModule("leaf5");128129generateDefaultExplodedModule("leaf6");130generateDefaultExplodedModule("leaf7");131132generateDefaultJarModule("composite1", "leaf1", "leaf2", "leaf4", "leaf6");133generateDefaultJModule("composite2", "composite1", "leaf3", "leaf5", "leaf7",134"java.management");135}136137public String defaultModulePath() {138return defaultModulePath(true);139}140141public String defaultModulePath(boolean includeStdMods) {142return (includeStdMods? stdjmods.toAbsolutePath().toString() : "") + File.pathSeparator143+ jmods.toAbsolutePath().toString() + File.pathSeparator144+ jars.toAbsolutePath().toString() + File.pathSeparator145+ explodedmodsclasses.toAbsolutePath().toString();146}147148public Path generateModuleCompiledClasses(149Path src, Path classes, String moduleName, String... dependencies) throws IOException {150return generateModuleCompiledClasses(src, classes, moduleName, getDefaultClasses(moduleName), dependencies);151}152153public Path generateModuleCompiledClasses(154Path src, Path classes, String moduleName,155List<String> classNames, String... dependencies) throws IOException {156if (classNames == null) {157classNames = getDefaultClasses(moduleName);158}159putAppClasses(moduleName, classNames);160moduleDependencies.put(moduleName, Arrays.asList(dependencies));161String modulePath = defaultModulePath();162JImageGenerator.generateSourcesFromTemplate(src, moduleName, classNames.toArray(new String[classNames.size()]));163List<String> packages = classNames.stream()164.map(JImageGenerator::getPackageName)165.distinct()166.collect(Collectors.toList());167Path srcMod = src.resolve(moduleName);168JImageGenerator.generateModuleInfo(srcMod, packages, dependencies);169Path destination = classes.resolve(moduleName);170if (!JImageGenerator.compile(srcMod, destination, "--module-path", modulePath, "-g")) {171throw new AssertionError("Compilation failure");172}173return destination;174}175176public Result generateDefaultJModule(String moduleName, String... dependencies) throws IOException {177return generateDefaultJModule(moduleName, getDefaultClasses(moduleName), dependencies);178}179180public Result generateDefaultJModule(String moduleName, List<String> classNames,181String... dependencies) throws IOException {182generateModuleCompiledClasses(jmodssrc, jmodsclasses, moduleName, classNames, dependencies);183generateGarbage(jmodsclasses.resolve(moduleName));184185Path jmodFile = jmods.resolve(moduleName + ".jmod");186JModTask task = JImageGenerator.getJModTask()187.jmod(jmodFile)188.addJmods(stdjmods)189.addJmods(jmods.toAbsolutePath())190.addJars(jars.toAbsolutePath())191.addClassPath(jmodsclasses.resolve(moduleName));192if (!classNames.isEmpty()) {193task.mainClass(classNames.get(0));194}195return task.create();196}197198public Result generateDefaultJarModule(String moduleName, String... dependencies) throws IOException {199return generateDefaultJarModule(moduleName, getDefaultClasses(moduleName), dependencies);200}201202public Result generateDefaultJarModule(String moduleName, List<String> classNames,203String... dependencies) throws IOException {204generateModuleCompiledClasses(jarssrc, jarsclasses, moduleName, classNames, dependencies);205generateGarbage(jarsclasses.resolve(moduleName));206207Path jarFile = jars.resolve(moduleName + ".jar");208JImageGenerator.createJarFile(jarFile, jarsclasses.resolve(moduleName));209return new Result(0, "", jarFile);210}211212public Result generateDefaultExplodedModule(String moduleName, String... dependencies) throws IOException {213return generateDefaultExplodedModule(moduleName, getDefaultClasses(moduleName), dependencies);214}215216public Result generateDefaultExplodedModule(String moduleName, List<String> classNames,217String... dependencies) throws IOException {218generateModuleCompiledClasses(explodedmodssrc, explodedmodsclasses,219moduleName, classNames, dependencies);220221Path dir = explodedmods.resolve("classes").resolve(moduleName);222return new Result(0, "", dir);223}224225private void generateGarbage(Path compiled) throws IOException {226Path metaInf = compiled.resolve("META-INF").resolve("services");227Files.createDirectories(metaInf);228Path provider = metaInf.resolve("MyProvider");229Files.createFile(provider);230Files.createFile(compiled.resolve("toto.jcov"));231}232233public static Path createNewFile(Path root, String pathName, String extension) {234Path out = root.resolve(pathName + extension);235int i = 1;236while (Files.exists(out)) {237out = root.resolve(pathName + "-" + (++i) + extension);238}239return out;240}241242public Result generateDefaultImage(String module) {243return generateDefaultImage(new String[0], module);244}245246public Result generateDefaultImage(String[] options, String module) {247Path output = createNewFile(images, module, ".image");248JLinkTask jLinkTask = JImageGenerator.getJLinkTask()249.modulePath(defaultModulePath())250.output(output)251.addMods(module)252.limitMods(module);253for (String option : options) {254jLinkTask.option(option);255}256return jLinkTask.call();257}258259public Result postProcessImage(Path root, String[] options) {260JLinkTask jLinkTask = JImageGenerator.getJLinkTask()261.existing(root);262for (String option : options) {263jLinkTask.option(option);264}265return jLinkTask.callPostProcess();266}267268private List<String> getDefaultClasses(String module) {269return Arrays.asList(module + ".Main", module + ".com.foo.bar.X");270}271272private void putAppClasses(String module, List<String> classes) {273List<String> appClasses = toLocation(module, classes).stream().collect(Collectors.toList());274appClasses.add(toLocation(module, "module-info"));275moduleClassDependencies.put(module, appClasses);276}277278private static String toLocation(String module, String className) {279return "/" + module + "/" + className.replaceAll("\\.", "/") + ".class";280}281282public static List<String> toLocation(String module, List<String> classNames) {283return classNames.stream()284.map(clazz -> toLocation(module, clazz))285.collect(Collectors.toList());286}287288public void checkImage(Path imageDir, String module, String[] paths, String[] files) throws IOException {289checkImage(imageDir, module, paths, files, null);290}291292public void checkImage(Path imageDir, String module, String[] paths, String[] files, String[] expectedFiles) throws IOException {293List<String> unexpectedPaths = new ArrayList<>();294if (paths != null) {295Collections.addAll(unexpectedPaths, paths);296}297List<String> unexpectedFiles = new ArrayList<>();298if (files != null) {299Collections.addAll(unexpectedFiles, files);300}301302JImageValidator validator = new JImageValidator(module, gatherExpectedLocations(module),303imageDir.toFile(),304unexpectedPaths,305unexpectedFiles,306expectedFiles);307System.out.println("*** Validate Image " + module);308validator.validate();309long moduleExecutionTime = validator.getModuleLauncherExecutionTime();310if (moduleExecutionTime != 0) {311System.out.println("Module launcher execution time " + moduleExecutionTime);312}313System.out.println("Java launcher execution time "314+ validator.getJavaLauncherExecutionTime());315System.out.println("***");316}317318private List<String> gatherExpectedLocations(String module) throws IOException {319List<String> expectedLocations = new ArrayList<>();320expectedLocations.addAll(bootClasses);321List<String> modules = moduleDependencies.get(module);322for (String dep : modules) {323Path path = fs.getPath("/modules/" + dep);324if (Files.exists(path)) {325List<String> locations = Files.find(path, Integer.MAX_VALUE,326(p, attrs) -> Files.isRegularFile(p) && p.toString().endsWith(".class")327&& !p.toString().endsWith("module-info.class"))328.map(p -> p.toString().substring("/modules".length()))329.collect(Collectors.toList());330expectedLocations.addAll(locations);331}332}333334List<String> appClasses = moduleClassDependencies.get(module);335if (appClasses != null) {336expectedLocations.addAll(appClasses);337}338return expectedLocations;339}340341public static String getDebugSymbolsExtension() {342return ".diz";343}344345public Path createNewImageDir(String moduleName) {346return createNewFile(getImageDir(), moduleName, ".image");347}348349public Path createNewExtractedDir(String name) {350return createNewFile(getExtractedDir(), name, ".extracted");351}352353public Path createNewRecreatedDir(String name) {354return createNewFile(getRecreatedDir(), name, ".jimage");355}356357public Path createNewJmodFile(String moduleName) {358return createNewFile(getJmodDir(), moduleName, ".jmod");359}360361public Path createNewJarFile(String moduleName) {362return createNewFile(getJarDir(), moduleName, ".jar");363}364365public Path getJmodSrcDir() {366return jmodssrc;367}368369public Path getJarSrcDir() {370return jarssrc;371}372373public Path getJmodClassesDir() {374return jmodsclasses;375}376377public Path getJarClassesDir() {378return jarsclasses;379}380381public Path getJmodDir() {382return jmods;383}384385public Path getExplodedModsDir() {386return explodedmods;387}388389public Path getJarDir() {390return jars;391}392393public Path getImageDir() {394return images;395}396397public Path getStdJmodsDir() {398return stdjmods;399}400401public Path getExtractedDir() {402return extracted;403}404405public Path getRecreatedDir() {406return recreated;407}408}409410411