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 * Asm plugin testing. 26 * @test 27 * @summary Test plugins 28 * @author Andrei Eremeev 29 * @modules jdk.jlink/jdk.tools.jlink.internal 30 * jdk.jlink/jdk.tools.jlink.internal.plugins.asm 31 * @run main PackageMappingTest 32 */ 33 import java.io.IOException; 34 import java.nio.ByteBuffer; 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.HashMap; 38 import java.util.HashSet; 39 import java.util.List; 40 import java.util.Map; 41 import java.util.Objects; 42 import java.util.Set; 43 import java.util.function.Function; 44 import java.util.stream.Collectors; 45 46 import jdk.tools.jlink.internal.plugins.asm.AsmGlobalPool; 47 import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; 48 import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile; 49 import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableResourcePool; 50 import jdk.tools.jlink.plugin.PluginException; 51 import jdk.tools.jlink.plugin.ModuleEntry; 52 import jdk.tools.jlink.plugin.ModulePool; 53 54 public class PackageMappingTest extends AsmPluginTestBase { 55 56 private final List<String> newFiles = Arrays.asList( 57 "/java.base/a1/bbb/c", 58 "/" + TEST_MODULE + "/a2/bbb/d" 59 ); 60 61 public static void main(String[] args) throws Exception { 62 if (!isImageBuild()) { 63 System.err.println("Test not run. Not image build."); 64 return; 65 } 66 new PackageMappingTest().test(); 67 } 68 69 public void test() throws Exception { 70 TestPlugin[] plugins = new TestPlugin[]{ 71 new PackageMappingPlugin(newFiles, false), 72 new PackageMappingPlugin(newFiles, true) 73 }; 74 for (TestPlugin p : plugins) { 75 ModulePool pool = p.visit(getPool()); 76 p.test(getPool(), pool); 77 } 78 } 79 80 public class PackageMappingPlugin extends TestPlugin { 81 82 private final Map<String, List<ResourceFile>> newFiles; 83 private final boolean testGlobal; 84 85 private String getModuleName(String res) { 86 return res.substring(1, res.indexOf("/", 1)); 87 } 88 89 private PackageMappingPlugin(List<String> files, boolean testGlobal) { 90 this.newFiles = new HashMap<>(); 91 this.testGlobal = testGlobal; 92 for (String file : files) { 93 String moduleName = getModuleName(file); 94 String path = file.substring(1 + moduleName.length() + 1); 95 newFiles.computeIfAbsent(moduleName, $ -> new ArrayList<>()).add( 96 new ResourceFile(path, new byte[0])); 97 } 98 } 99 100 @Override 101 public void visit() { 102 testMapToUnknownModule(); 103 testMapPackageTwice(); 104 testPackageMapping(); 105 } 106 107 @Override 108 public void test(ModulePool inResources, ModulePool outResources) { 109 Set<String> in = getPools().getGlobalPool().getResourceFiles().stream() 110 .map(ModuleEntry::getPath) 111 .collect(Collectors.toSet()); 112 Set<String> out = extractResources(outResources).stream() 113 .map(ModuleEntry::getPath) 114 .collect(Collectors.toSet()); 115 in.addAll(PackageMappingTest.this.newFiles); 116 if (!Objects.equals(in, out)) { 117 throw new AssertionError("Expected: " + in + ", got: " + outResources); 118 } 119 } 120 121 private void testPackageMapping() { 122 AsmGlobalPool globalPool = getPools().getGlobalPool(); 123 try { 124 Map<String, Set<String>> mappedPackages = new HashMap<>(); 125 Function<String, Set<String>> produceSet = $ -> new HashSet<>(); 126 for (Map.Entry<String, List<ResourceFile>> entry : newFiles.entrySet()) { 127 String moduleName = entry.getKey(); 128 Set<String> module = mappedPackages.computeIfAbsent(moduleName, produceSet); 129 AsmModulePool modulePool = getPools().getModulePool(moduleName); 130 for (ResourceFile r : entry.getValue()) { 131 String name = r.getPath(); 132 String packageName = name.substring(0, name.lastIndexOf('/')); 133 if (module.add(packageName)) { 134 globalPool.addPackageModuleMapping(packageName, moduleName); 135 } 136 WritableResourcePool transformedResourceFiles = testGlobal 137 ? globalPool.getTransformedResourceFiles() 138 : modulePool.getTransformedResourceFiles(); 139 transformedResourceFiles.addResourceFile(r); 140 } 141 try { 142 modulePool.getTransformedResourceFiles().addResourceFile( 143 new ResourceFile("a3/bbb", new byte[0])); 144 throw new AssertionError("Exception expected"); 145 } catch (Exception ex) { 146 // expected 147 } 148 } 149 try { 150 globalPool.getTransformedResourceFiles().addResourceFile( 151 new ResourceFile("a3/bbb", new byte[0])); 152 throw new AssertionError("Exception expected"); 153 } catch (Exception ex) { 154 // expected 155 } 156 } catch (Exception e) { 157 throw new RuntimeException(e); 158 } 159 } 160 161 private void testMapPackageTwice() { 162 try { 163 AsmGlobalPool globalPool = getPools().getGlobalPool(); 164 globalPool.addPackageModuleMapping("a/p1", TEST_MODULE); 165 globalPool.addPackageModuleMapping("a/p1", TEST_MODULE); 166 throw new AssertionError("Exception expected after mapping a package twice to the same module"); 167 } catch (Exception e) { 168 if (e instanceof PluginException) { 169 // expected 170 String message = e.getMessage(); 171 if (!(TEST_MODULE + " module already contains package a.p1").equals(message)) { 172 throw new AssertionError(e); 173 } 174 } else { 175 throw new AssertionError(e); 176 } 177 } 178 } 179 180 private void testMapToUnknownModule() { 181 AsmModulePool unknownModule = getPools().getModulePool("UNKNOWN"); 182 if (unknownModule != null) { 183 throw new AssertionError("getModulePool returned not null value: " + unknownModule.getModuleName()); 184 } 185 try { 186 AsmGlobalPool globalPool = getPools().getGlobalPool(); 187 globalPool.addPackageModuleMapping("a/b", "UNKNOWN"); 188 throw new AssertionError("Exception expected after mapping a package to unknown module"); 189 } catch (Exception e) { 190 String message = e.getMessage(); 191 if (message == null || !message.startsWith("Unknown module UNKNOWN")) { 192 throw new AssertionError(e); 193 } 194 } 195 } 196 } 197 }