Path: blob/master/test/jdk/tools/jar/multiRelease/RuntimeTest.java
41152 views
/*1* Copyright (c) 2016, 2017, 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*/2223/*24* @test25* @summary Test Multi-Release jar usage in runtime26* @library /test/lib27* @modules jdk.compiler28* @build jdk.test.lib.compiler.CompilerUtils29* jdk.test.lib.Utils30* jdk.test.lib.Asserts31* jdk.test.lib.JDKToolFinder32* jdk.test.lib.JDKToolLauncher33* jdk.test.lib.Platform34* jdk.test.lib.process.*35* @run testng RuntimeTest36*/3738import static org.testng.Assert.*;3940import java.io.BufferedReader;41import java.io.File;42import java.io.IOException;43import java.io.InputStream;44import java.io.InputStreamReader;45import java.io.UncheckedIOException;46import java.lang.reflect.InvocationTargetException;47import java.lang.reflect.Method;48import java.net.URL;49import java.net.URLClassLoader;50import java.nio.file.Files;51import java.nio.file.Path;52import java.nio.file.Paths;53import java.nio.file.StandardCopyOption;54import java.util.ArrayList;55import java.util.Arrays;56import java.util.HashMap;57import java.util.List;58import java.util.Map;59import java.util.stream.Collectors;60import java.util.stream.Stream;6162import org.testng.annotations.BeforeClass;63import org.testng.annotations.DataProvider;64import org.testng.annotations.Test;6566import jdk.test.lib.JDKToolFinder;67import jdk.test.lib.JDKToolLauncher;68import jdk.test.lib.compiler.CompilerUtils;69import jdk.test.lib.process.OutputAnalyzer;70import jdk.test.lib.process.ProcessTools;7172public class RuntimeTest {73public static final int SUCCESS = 0;74private static final String src = System.getProperty("test.src", ".");75private static final String usr = System.getProperty("user.dir", ".");7677private static final Path srcFileRoot = Paths.get(src, "data", "runtimetest");78private static final Path genFileRoot = Paths.get(usr, "data", "runtimetest");7980private static final int OLD_RELEASE = 8;81private static final int CURRENT_RELEASE = Runtime.version().major();82private static final int FUTURE_RELEASE = CURRENT_RELEASE + 1;83private static final String MRJAR_BOTH_RELEASES = "MV_BOTH.jar";84private static final String MRJAR_CURRENT_RELEASE = "MV_ONLY_" + CURRENT_RELEASE + ".jar";85private static final String NON_MRJAR_OLD_RELEASE = "NON_MV.jar";8687private static final int[] versions = { OLD_RELEASE, CURRENT_RELEASE, FUTURE_RELEASE };8889@DataProvider(name = "jarFiles")90Object[][] jarFiles() {91return new Object[][]{92{ MRJAR_BOTH_RELEASES, CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE },93{ MRJAR_CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE },94{ NON_MRJAR_OLD_RELEASE, OLD_RELEASE, OLD_RELEASE, OLD_RELEASE }95};96}9798@BeforeClass99protected void setUpTest() throws Throwable {100createJarSourceFiles();101compile();102Path classes = Paths.get("classes");103jar("cfm", MRJAR_BOTH_RELEASES, "manifest.txt",104"-C", classes.resolve("v" + OLD_RELEASE).toString(), ".",105"--release", "" + CURRENT_RELEASE, "-C", classes.resolve("v" + CURRENT_RELEASE).toString(), ".",106"--release", "" + FUTURE_RELEASE, "-C", classes.resolve("v" + FUTURE_RELEASE).toString(), ".")107.shouldHaveExitValue(0);108109jar("cfm", MRJAR_CURRENT_RELEASE, "manifest.txt",110"-C", classes.resolve("v" + OLD_RELEASE).toString(), ".",111"--release", "" + CURRENT_RELEASE, "-C", classes.resolve("v" + CURRENT_RELEASE).toString(), ".")112.shouldHaveExitValue(0);113jar("cfm", NON_MRJAR_OLD_RELEASE, "manifest.txt",114"-C", classes.resolve("v" + OLD_RELEASE).toString(), ".")115.shouldHaveExitValue(0);116}117118@Test(dataProvider = "jarFiles")119public void testClasspath(String jar, int mainVer, int helperVer,120int resVer) throws Throwable {121String[] command = { "-cp", jar, "testpackage.Main" };122System.out.println("Command arguments:" + Arrays.asList(command));123System.out.println();124java(command).shouldHaveExitValue(SUCCESS)125.shouldContain("Main version: " + mainVer)126.shouldContain("Helpers version: " + helperVer)127.shouldContain("Resource version: " + resVer);128}129130@Test(dataProvider = "jarFiles")131void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer)132throws Throwable {133String[] apps = { "UseByImport", "UseByReflection" };134for (String app : apps) {135String[] command = {"-cp",136jar + File.pathSeparatorChar + "classes/test/", app };137System.out.println("Command arguments:" + Arrays.asList(command));138System.out.println();139java(command).shouldHaveExitValue(SUCCESS)140.shouldContain("Main version: " + mainVer)141.shouldContain("Helpers version: " + helperVer)142.shouldContain("Resource version: " + resVer);143}144}145146@Test(dataProvider = "jarFiles")147void testJavaJar(String jar, int mainVer, int helperVer, int resVer)148throws Throwable {149String[] command = { "-jar", jar };150System.out.println("Command arguments:" + Arrays.asList(command));151System.out.println();152java(command).shouldHaveExitValue(SUCCESS)153.shouldContain("Main version: " + mainVer)154.shouldContain("Helpers version: " + helperVer)155.shouldContain("Resource version: " + resVer);156}157158@Test(dataProvider = "jarFiles")159void testURLClassLoader(String jarName, int mainVer, int helperVer,160int resVer) throws ClassNotFoundException, NoSuchMethodException,161IllegalAccessException, IllegalArgumentException,162InvocationTargetException, IOException {163Path pathToJAR = Paths.get(jarName).toAbsolutePath();164URL jarURL1 = new URL("jar:file:" + pathToJAR + "!/");165URL jarURL2 = new URL("file:///" + pathToJAR);166testURLClassLoaderURL(jarURL1, mainVer, helperVer, resVer);167testURLClassLoaderURL(jarURL2, mainVer, helperVer, resVer);168}169170private static void testURLClassLoaderURL(URL jarURL,171int mainVersionExpected, int helperVersionExpected,172int resourceVersionExpected) throws ClassNotFoundException,173NoSuchMethodException, IllegalAccessException,174IllegalArgumentException, InvocationTargetException, IOException {175System.out.println(176"Testing URLClassLoader MV JAR support for URL: " + jarURL);177URL[] urls = { jarURL };178int mainVersionActual;179int helperVersionActual;180int resourceVersionActual;181try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {182Class c = cl.loadClass("testpackage.Main");183Method getMainVersion = c.getMethod("getMainVersion");184mainVersionActual = (int) getMainVersion.invoke(null);185Method getHelperVersion = c.getMethod("getHelperVersion");186helperVersionActual = (int) getHelperVersion.invoke(null);187try (InputStream ris = cl.getResourceAsStream("versionResource");188BufferedReader br = new BufferedReader(189new InputStreamReader(ris))) {190resourceVersionActual = Integer.parseInt(br.readLine());191}192}193194assertEquals(mainVersionActual, mainVersionExpected,195"Test failed: Expected Main class version: "196+ mainVersionExpected + " Actual version: "197+ mainVersionActual);198assertEquals(helperVersionActual, helperVersionExpected,199"Test failed: Expected Helper class version: "200+ helperVersionExpected + " Actual version: "201+ helperVersionActual);202assertEquals(resourceVersionActual, resourceVersionExpected,203"Test failed: Expected resource version: "204+ resourceVersionExpected + " Actual version: "205+ resourceVersionActual);206}207208private static OutputAnalyzer jar(String... args) throws Throwable {209JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");210Stream.of(args).forEach(launcher::addToolArg);211return ProcessTools.executeCommand(launcher.getCommand());212}213214private static String platformPath(String p) {215return p.replace("/", File.separator);216}217218private static void createJarSourceFiles() throws IOException {219for (int ver : versions) {220Files.find(srcFileRoot, 3, (file, attrs) -> (file.toString().endsWith(".template")))221.map(srcFileRoot::relativize)222.map(Path::toString)223.map(p -> p.replace(".template", ""))224.forEach(f -> {225try {226Path template = srcFileRoot.resolve(f + ".template");227Path out = genFileRoot.resolve(platformPath("v" + ver + "/" + f));228Files.createDirectories(out.getParent());229List<String> lines = Files.lines(template)230.map(s -> s.replaceAll("\\$version", String.valueOf(ver)))231.collect(Collectors.toList());232Files.write(out, lines);233} catch (IOException x) {234throw new UncheckedIOException(x);235}236});237}238}239240private void compile() throws Throwable {241for (int ver : versions) {242Path classes = Paths.get(usr, "classes", "v" + ver);243Files.createDirectories(classes);244Path source = genFileRoot.resolve("v" + ver);245assertTrue(CompilerUtils.compile(source, classes));246Files.copy(source.resolve("versionResource"),247classes.resolve("versionResource"),248StandardCopyOption.REPLACE_EXISTING);249}250251Path classes = Paths.get(usr, "classes", "test");252Files.createDirectory(classes);253Path source = srcFileRoot.resolve("test");254assertTrue(255CompilerUtils.compile(source, classes, "-cp", "classes/v" + OLD_RELEASE));256Files.copy(srcFileRoot.resolve("manifest.txt"),257Paths.get(usr, "manifest.txt"),258StandardCopyOption.REPLACE_EXISTING);259}260261OutputAnalyzer java(String... args) throws Throwable {262String java = JDKToolFinder.getJDKTool("java");263264List<String> commands = new ArrayList<>();265commands.add(java);266Stream.of(args).forEach(x -> commands.add(x));267return ProcessTools.executeCommand(new ProcessBuilder(commands));268}269}270271272