Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/test/tools/javah/compareTest/CompareTest.java
38813 views
/*1* Copyright (c) 2009, 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*/2223import java.io.DataInputStream;24import java.io.File;25import java.io.IOException;26import java.io.InputStream;27import java.io.PrintWriter;28import java.io.StringWriter;29import java.util.ArrayList;30import java.util.Arrays;31import java.util.Enumeration;32import java.util.List;33import java.util.Set;34import java.util.TreeSet;35import java.util.jar.JarEntry;36import java.util.jar.JarFile;3738import com.sun.tools.classfile.AccessFlags;39import com.sun.tools.classfile.ClassFile;40import com.sun.tools.classfile.ConstantPoolException;41import com.sun.tools.classfile.Method;42import java.io.BufferedReader;43import java.io.FileInputStream;44import java.io.InputStreamReader;45import java.util.LinkedHashSet;4647public class CompareTest {48String[][] testCases = {49{ },50{ "-jni" },51// { "-llni" },52};5354public static void main(String... args) throws Exception {55new CompareTest().run(args);56}5758public void run(String... args) throws Exception {59old_javah_cmd = new File(args[0]);60rt_jar = new File(args[1]);6162Set<String> testClasses;63if (args.length > 2) {64testClasses = new LinkedHashSet<String>(Arrays.asList(Arrays.copyOfRange(args, 2, args.length)));65} else66testClasses = getNativeClasses(new JarFile(rt_jar));6768for (String[] options: testCases) {69for (String name: testClasses) {70test(Arrays.asList(options), rt_jar, name);71}72}7374if (errors == 0)75System.out.println(count + " tests passed");76else77throw new Exception(errors + "/" + count + " tests failed");78}7980public void test(List<String> options, File bootclasspath, String className)81throws IOException, InterruptedException {82System.err.println("test: " + options + " " + className);83count++;8485testOptions = options;86testClassName = className;8788File oldOutDir = initDir(file(new File("old"), className));89int old_rc = old_javah(options, oldOutDir, bootclasspath, className);9091File newOutDir = initDir(file(new File("new"), className));92int new_rc = new_javah(options, newOutDir, bootclasspath, className);9394if (old_rc != new_rc)95error("return codes differ; old: " + old_rc + ", new: " + new_rc);9697compare(oldOutDir, newOutDir);98}99100int old_javah(List<String> options, File outDir, File bootclasspath, String className)101throws IOException, InterruptedException {102List<String> cmd = new ArrayList<String>();103cmd.add(old_javah_cmd.getPath());104cmd.addAll(options);105cmd.add("-d");106cmd.add(outDir.getPath());107cmd.add("-bootclasspath");108cmd.add(bootclasspath.getPath());109cmd.add(className);110System.err.println("old_javah: " + cmd);111ProcessBuilder pb = new ProcessBuilder(cmd);112pb.redirectErrorStream(true);113Process p = pb.start();114BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));115String line;116StringBuilder sb = new StringBuilder();117while ((line = in.readLine()) != null) {118sb.append(line);119sb.append("\n");120}121System.err.println("old javah out: " + sb.toString());122return p.waitFor();123}124125int new_javah(List<String> options, File outDir, File bootclasspath, String className) {126List<String> args = new ArrayList<String>();127args.addAll(options);128args.add("-d");129args.add(outDir.getPath());130args.add("-bootclasspath");131args.add(bootclasspath.getPath());132args.add(className);133StringWriter sw = new StringWriter();134PrintWriter pw = new PrintWriter(sw);135int rc = com.sun.tools.javah.Main.run(args.toArray(new String[args.size()]), pw);136pw.close();137System.err.println("new javah out: " + sw.toString());138return rc;139}140141Set<String> getNativeClasses(JarFile jar) throws IOException, ConstantPoolException {142System.err.println("getNativeClasses: " + jar.getName());143Set<String> results = new TreeSet<String>();144Enumeration<JarEntry> e = jar.entries();145while (e.hasMoreElements()) {146JarEntry je = e.nextElement();147if (isNativeClass(jar, je)) {148String name = je.getName();149results.add(name.substring(0, name.length() - 6).replace("/", "."));150}151}152return results;153}154155boolean isNativeClass(JarFile jar, JarEntry entry) throws IOException, ConstantPoolException {156String name = entry.getName();157if (name.startsWith("META-INF") || !name.endsWith(".class"))158return false;159//String className = name.substring(0, name.length() - 6).replace("/", ".");160//System.err.println("check " + className);161InputStream in = jar.getInputStream(entry);162ClassFile cf = ClassFile.read(in);163for (int i = 0; i < cf.methods.length; i++) {164Method m = cf.methods[i];165if (m.access_flags.is(AccessFlags.ACC_NATIVE)) {166// System.err.println(className);167return true;168}169}170return false;171}172173void compare(File f1, File f2) throws IOException {174if (f1.isFile() && f2.isFile())175compareFiles(f1, f2);176else if (f1.isDirectory() && f2.isDirectory())177compareDirectories(f1, f2);178else179error("files differ: "180+ f1 + " (" + getFileType(f1) + "), "181+ f2 + " (" + getFileType(f2) + ")");182}183184void compareDirectories(File d1, File d2) throws IOException {185Set<String> list = new TreeSet<String>();186list.addAll(Arrays.asList(d1.list()));187list.addAll(Arrays.asList(d2.list()));188for (String c: list)189compare(new File(d1, c), new File(d2, c));190}191192void compareFiles(File f1, File f2) throws IOException {193byte[] c1 = readFile(f1);194byte[] c2 = readFile(f2);195if (!Arrays.equals(c1, c2))196error("files differ: " + f1 + ", " + f2);197}198199byte[] readFile(File file) throws IOException {200int size = (int) file.length();201byte[] data = new byte[size];202DataInputStream in = new DataInputStream(new FileInputStream(file));203try {204in.readFully(data);205} finally {206in.close();207}208return data;209}210211String getFileType(File f) {212return f.isDirectory() ? "directory"213: f.isFile() ? "file"214: f.exists() ? "other"215: "not found";216}217218/**219* Set up an empty directory.220*/221public File initDir(File dir) {222if (dir.exists())223deleteAll(dir);224dir.mkdirs();225return dir;226}227228/**229* Delete a file or a directory (including all its contents).230*/231boolean deleteAll(File file) {232if (file.isDirectory()) {233for (File f: file.listFiles())234deleteAll(f);235}236return file.delete();237}238239File file(File dir, String... path) {240File f = dir;241for (String p: path)242f = new File(f, p);243return f;244}245246/**247* Report an error.248*/249void error(String msg, String... more) {250System.err.println("test: " + testOptions + " " + testClassName);251System.err.println("error: " + msg);252for (String s: more)253System.err.println(s);254errors++;255System.exit(1);256}257258File old_javah_cmd;259File rt_jar;260List<String> testOptions;261String testClassName;262int count;263int errors;264}265266267