Path: blob/master/test/jdk/tools/lib/tests/JImageValidator.java
41149 views
/*1* Copyright (c) 2015, 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.ByteArrayInputStream;25import java.io.File;26import java.io.FileInputStream;27import java.io.IOException;28import java.io.InputStream;29import java.nio.file.Files;30import java.nio.file.Path;31import java.util.ArrayList;32import java.util.List;33import java.util.Properties;3435import com.sun.tools.classfile.ClassFile;36import com.sun.tools.classfile.ConstantPoolException;37import jdk.internal.jimage.BasicImageReader;38import jdk.internal.jimage.ImageLocation;3940/**41*42* JDK Modular image validator43*/44public class JImageValidator {4546private static final String[] dirs = {"bin", "lib"};4748private final File rootDir;49private final List<String> expectedLocations;50private final String module;51private long moduleExecutionTime;52private long javaExecutionTime;53private final List<String> unexpectedPaths;54private final List<String> unexpectedFiles;55private final String[] expectedFiles;5657public JImageValidator(String module, List<String> expectedLocations,58File rootDir,59List<String> unexpectedPaths,60List<String> unexpectedFiles) throws Exception {61this(module, expectedLocations, rootDir, unexpectedPaths, unexpectedFiles, null);62}6364public JImageValidator(String module, List<String> expectedLocations,65File rootDir,66List<String> unexpectedPaths,67List<String> unexpectedFiles,68String[] expectedFiles) throws IOException {69if (!rootDir.exists()) {70throw new IOException("Image root dir not found " +71rootDir.getAbsolutePath());72}73this.expectedLocations = expectedLocations;74this.rootDir = rootDir;75this.module = module;76this.unexpectedPaths = unexpectedPaths;77this.unexpectedFiles = unexpectedFiles;78this.expectedFiles = expectedFiles == null ? new String[0] : expectedFiles;79}8081public void validate() throws IOException {82for (String d : dirs) {83File dir = new File(rootDir, d);84if (!dir.isDirectory()) {85throw new IOException("Invalid directory " + d);86}87}8889//check jimage file90Path path = rootDir.toPath().resolve("lib").resolve("modules");91if (!Files.isRegularFile(path)) {92throw new IOException(path + " No jimage file generated");93}9495// Check binary file96File launcher = new File(rootDir, "bin" + File.separator + module);97if (launcher.exists()) {98ProcessBuilder builder = new ProcessBuilder("sh", launcher.getAbsolutePath());99long t = System.currentTimeMillis();100Process process = builder.inheritIO().start();101int ret = waitFor(process);102moduleExecutionTime += System.currentTimeMillis() - t;103if (ret != 0) {104throw new IOException("Image " + module + " execution failed, check logs.");105}106}107108for (String f : expectedFiles) {109File dd = new File(rootDir, f);110if (!dd.exists()) {111throw new IOException("Expected File " + f + " not found");112}113}114115//Walk and check that unexpected files are not there116try (java.util.stream.Stream<Path> stream = Files.walk(rootDir.toPath())) {117stream.forEach((p) -> {118for (String u : unexpectedFiles) {119if (p.toString().equals(u)) {120throw new RuntimeException("Seen unexpected path " + p);121}122}123});124}125126File javaLauncher = new File(rootDir, "bin" + File.separator +127(isWindows() ? "java.exe" : "java"));128if (javaLauncher.exists()) {129ProcessBuilder builder = new ProcessBuilder(javaLauncher.getAbsolutePath(),130"-version");131long t = System.currentTimeMillis();132Process process = builder.start();133int ret = waitFor(process);134javaExecutionTime += System.currentTimeMillis() - t;135if (ret != 0) {136throw new RuntimeException("java launcher execution failed, check logs.");137}138} else {139throw new IOException("java launcher not found.");140}141142// Check release file143File release = new File(rootDir, "release");144if (!release.exists()) {145throw new IOException("Release file not generated");146} else {147Properties props = new Properties();148try (FileInputStream fs = new FileInputStream(release)) {149props.load(fs);150String s = props.getProperty("MODULES");151if (s == null) {152throw new IOException("No MODULES property in release");153}154if (!s.contains(module)) {155throw new IOException("Module not found in release file " + s);156}157}158}159160}161162private int waitFor(Process process) {163try {164return process.waitFor();165} catch (InterruptedException e) {166throw new RuntimeException(e);167}168}169170private static boolean isWindows() {171return System.getProperty("os.name").startsWith("Windows");172}173174public static void validate(Path jimage, List<String> expectedLocations,175List<String> unexpectedPaths) throws IOException {176BasicImageReader reader = BasicImageReader.open(jimage);177// Validate expected locations178List<String> seenLocations = new ArrayList<>();179for (String loc : expectedLocations) {180ImageLocation il = reader.findLocation(loc);181if (il == null) {182throw new IOException("Location " + loc + " not present in " + jimage);183}184}185seenLocations.addAll(expectedLocations);186187for (String s : reader.getEntryNames()) {188if (s.endsWith(".class") && !s.endsWith("module-info.class")) {189ImageLocation il = reader.findLocation(s);190try {191byte[] r = reader.getResource(il);192if(r == null) {193System.out.println("IL, compressed " +194il.getCompressedSize() + " uncompressed " +195il.getUncompressedSize());196throw new IOException("NULL RESOURCE " + s);197}198readClass(r);199} catch (IOException ex) {200System.err.println(s + " ERROR " + ex);201throw ex;202}203}204if (seenLocations.contains(s)) {205seenLocations.remove(s);206}207for(String p : unexpectedPaths) {208if (s.equals(p)) {209throw new IOException("Seen unexpected path " + s);210}211}212}213if (!seenLocations.isEmpty()) {214throw new IOException("ImageReader did not return " + seenLocations);215}216}217218public long getJavaLauncherExecutionTime() {219return javaExecutionTime;220}221222public long getModuleLauncherExecutionTime() {223return moduleExecutionTime;224}225226public static void readClass(byte[] clazz) throws IOException {227try (InputStream stream = new ByteArrayInputStream(clazz)) {228ClassFile.read(stream);229} catch (ConstantPoolException e) {230throw new IOException(e);231}232}233}234235236