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 * @test 26 * @summary Test order of plugins 27 * @author Jean-Francois Denise 28 * @library ../../lib 29 * @modules java.base/jdk.internal.jimage 30 * jdk.jdeps/com.sun.tools.classfile 31 * jdk.jlink/jdk.tools.jlink 32 * jdk.jlink/jdk.tools.jlink.internal 33 * jdk.jlink/jdk.tools.jmod 34 * jdk.jlink/jdk.tools.jimage 35 * jdk.compiler 36 * @build tests.* 37 * @run main/othervm PluginOrderTest 38 */ 39 import java.io.IOException; 40 import java.nio.ByteBuffer; 41 import java.nio.ByteOrder; 42 import java.util.ArrayList; 43 import java.util.Arrays; 44 import java.util.Collections; 45 import java.util.List; 46 import java.util.Map; 47 48 import jdk.tools.jlink.internal.ImagePluginConfiguration; 49 import jdk.tools.jlink.internal.ImagePluginProviderRepository; 50 import jdk.tools.jlink.internal.ImagePluginStack; 51 import jdk.tools.jlink.internal.ResourcePoolImpl; 52 import jdk.tools.jlink.plugins.CmdResourcePluginProvider; 53 import jdk.tools.jlink.plugins.Jlink.PluginsConfiguration; 54 import jdk.tools.jlink.plugins.Jlink.StackedPluginConfiguration; 55 import jdk.tools.jlink.plugins.PluginProvider; 56 import jdk.tools.jlink.plugins.ResourcePlugin; 57 import jdk.tools.jlink.plugins.ResourcePool; 58 import jdk.tools.jlink.plugins.ResourcePool.Visitor; 59 import jdk.tools.jlink.plugins.StringTable; 60 61 import tests.Helper; 62 import tests.Result; 63 64 public class PluginOrderTest { 65 66 public static void main(String[] args) throws Exception { 67 new PluginOrderTest().test(); 68 } 69 70 public void test() throws Exception { 71 List<String> order = new ArrayList<>(); 72 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin1_F", 73 PluginProvider.FILTER, order)); 74 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin2_F", 75 PluginProvider.FILTER, order)); 76 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin3_F", 77 PluginProvider.FILTER, order)); 78 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin4_F", 79 PluginProvider.FILTER, order)); 80 81 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin1_T", 82 PluginProvider.TRANSFORMER, order)); 83 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin2_T", 84 PluginProvider.TRANSFORMER, order)); 85 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin3_T", 86 PluginProvider.TRANSFORMER, order)); 87 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin4_T", 88 PluginProvider.TRANSFORMER, order)); 89 90 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin1_S", 91 PluginProvider.SORTER, order)); 92 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin2_S", 93 PluginProvider.SORTER, order)); 94 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin3_S", 95 PluginProvider.SORTER, order)); 96 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin4_S", 97 PluginProvider.SORTER, order)); 98 99 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin1_C", 100 PluginProvider.COMPRESSOR, order)); 101 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin2_C", 102 PluginProvider.COMPRESSOR, order)); 103 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin3_C", 104 PluginProvider.COMPRESSOR, order)); 105 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin4_C", 106 PluginProvider.COMPRESSOR, order)); 107 108 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin1_A", 109 null, order)); 110 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin2_A", 111 null, order)); 112 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin3_A", 113 null, order)); 114 ImagePluginProviderRepository.registerPluginProvider(new PProvider("plugin4_A", 115 null, order)); 116 117 test1(order); 118 119 test2(order); 120 121 test3(order); 122 123 test4(order); 124 125 test5(order); 126 127 test6(order); 128 129 test7(order); 130 131 testAbs(order); 132 133 test8(order); 134 135 test9(order); 136 } 137 138 private void check(PluginsConfiguration config, List<String> expected, List<String> order) 139 throws Exception { 140 order.clear(); 141 ImagePluginStack plugins = ImagePluginConfiguration.parseConfiguration(config); 142 ResourcePoolImpl pool = new ResourcePoolImpl(ByteOrder.nativeOrder()); 143 pool.addResource(new ResourcePool.Resource("/mod/com/foo/bar/A.somthing", 144 ByteBuffer.allocate(0))); 145 plugins.visitResources(pool, new StringTable() { 146 147 @Override 148 public int addString(String str) { 149 return -1; 150 } 151 152 @Override 153 public String getString(int id) { 154 throw new UnsupportedOperationException("Not supported yet."); 155 } 156 }); 157 if (!order.equals(expected)) { 158 throw new Exception("plugins not called in right order. Expected " 159 + expected + " actual " + order); 160 } 161 System.err.println("Gathered plugins: " + order); 162 } 163 164 private PluginsConfiguration createConfig(String... nameIndexAbs) { 165 List<StackedPluginConfiguration> lst = new ArrayList<>(); 166 for (String s : nameIndexAbs) { 167 String name = s.substring(0, s.indexOf(":")); 168 int sep = s.indexOf("/"); 169 int index = Integer.valueOf(s.substring(s.indexOf(":") + 1, sep)); 170 boolean absolute = Boolean.valueOf(s.substring(sep + 1)); 171 lst.add(new StackedPluginConfiguration(name, index, 172 absolute, Collections.emptyMap())); 173 } 174 return new PluginsConfiguration(lst, Collections.emptyList(), null); 175 } 176 177 private void test1(List<String> order) throws Exception { 178 179 Helper helper = Helper.newHelper(); 180 if (helper == null) { 181 System.err.println("test1 not run"); 182 return; 183 } 184 helper.generateDefaultModules(); 185 186 { 187 order.clear(); 188 String[] userOptions = {"--plugin1_C", "--plugin2_C", "--plugin1_S", "--plugin2_S", "--plugin1_T", "--plugin2_T", "--plugin1_F", "--plugin2_F"}; 189 String moduleName = "order1"; 190 helper.generateDefaultJModule(moduleName, "composite2"); 191 Result res = helper.generateDefaultImage(userOptions, moduleName); 192 res.assertSuccess(); 193 if (!order.equals(Arrays.asList("plugin1_F", "plugin2_F", "plugin1_T", "plugin2_T", "plugin1_S", "plugin2_S", "plugin1_C", "plugin2_C"))) { 194 throw new Exception("plugins not called in right order. " + order); 195 } 196 } 197 198 { 199 order.clear(); 200 String[] userOptions = {"--plugin1_F:2", "--plugin2_F:1"}; 201 String moduleName = "order2"; 202 helper.generateDefaultJModule(moduleName, "composite2"); 203 Result res = helper.generateDefaultImage(userOptions, moduleName); 204 res.assertSuccess(); 205 if (!order.equals(Arrays.asList("plugin2_F", "plugin1_F"))) { 206 throw new Exception("plugins not called in right order. " + order); 207 } 208 } 209 210 { 211 order.clear(); 212 String[] userOptions = {"--plugin1_C:LAST", "--plugin2_C:FIRST"}; 213 String moduleName = "order3"; 214 helper.generateDefaultJModule(moduleName, "composite2"); 215 Result res = helper.generateDefaultImage(userOptions, moduleName); 216 res.assertSuccess(); 217 if (!order.equals(Arrays.asList("plugin2_C", "plugin1_C"))) { 218 throw new Exception("plugins not called in right order. " + order); 219 } 220 } 221 } 222 223 private void test2(List<String> order) throws Exception { 224 check(createConfig("plugin1_F:0/false", "plugin1_T:0/false", "plugin1_S:0/false", 225 "plugin1_C:0/false", "plugin1_A:900000/true"), 226 Arrays.asList("plugin1_F", "plugin1_T", "plugin1_S", "plugin1_C", "plugin1_A"), order); 227 } 228 229 private void test3(List<String> order) throws Exception { 230 check(createConfig("plugin1_F:250/false", "plugin1_T:100/false", "plugin1_S:50/false", 231 "plugin1_C:10/false", "plugin1_A:0/true"), 232 Arrays.asList("plugin1_A", "plugin1_F", "plugin1_T", "plugin1_S", "plugin1_C"), order); 233 } 234 235 private void test4(List<String> order) throws Exception { 236 check(createConfig("plugin2_F:0/false", "plugin3_F:1/false", "plugin4_F:2/false", 237 "plugin1_F:3/false"), 238 Arrays.asList("plugin2_F", "plugin3_F", "plugin4_F", "plugin1_F"), order); 239 } 240 241 private void test5(List<String> order) throws Exception { 242 check(createConfig("plugin2_T:0/false", "plugin3_T:1/false", "plugin4_T:2/false", 243 "plugin1_T:3/false"), 244 Arrays.asList("plugin2_T", "plugin3_T", "plugin4_T", "plugin1_T"), order); 245 } 246 247 private void test6(List<String> order) throws Exception { 248 check(createConfig("plugin2_S:0/false", "plugin3_S:1/false", "plugin4_S:2/false", 249 "plugin1_S:3/false"), 250 Arrays.asList("plugin2_S", "plugin3_S", "plugin4_S", "plugin1_S"), order); 251 } 252 253 private void test7(List<String> order) throws Exception { 254 check(createConfig("plugin2_C:0/false", "plugin3_C:1/false", "plugin4_C:2/false", 255 "plugin1_C:3/false"), 256 Arrays.asList("plugin2_C", "plugin3_C", "plugin4_C", "plugin1_C"), order); 257 } 258 259 private void testAbs(List<String> order) throws Exception { 260 check(createConfig("plugin2_A:0/true", "plugin3_A:1/true", "plugin4_A:2/true", 261 "plugin1_A:3/true"), 262 Arrays.asList("plugin2_A", "plugin3_A", "plugin4_A", "plugin1_A"), order); 263 } 264 265 private void test8(List<String> order) throws Exception { 266 check(createConfig("plugin1_F:" + ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.FILTER))[0] + "/true", 267 "plugin1_T:" + ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.TRANSFORMER))[0] + "/true", 268 "plugin1_S:" + ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.SORTER))[0] + "/true", 269 "plugin1_C:" + ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.COMPRESSOR))[0] + "/true"), 270 Arrays.asList("plugin1_F", "plugin1_T", "plugin1_S", "plugin1_C"), order); 271 } 272 273 private void test9(List<String> order) throws Exception { 274 List<String> expected = new ArrayList<>(); 275 expected.add("plugin1_F"); 276 expected.add("plugin2_F"); 277 expected.add("plugin1_T"); 278 expected.add("plugin2_T"); 279 expected.add("plugin1_S"); 280 expected.add("plugin2_S"); 281 expected.add("plugin1_C"); 282 expected.add("plugin2_C"); 283 284 check(createConfig("plugin1_F:0/false", "plugin1_T:0/false", "plugin1_S:0/false", 285 "plugin1_C:0/false", "plugin2_F:" + (ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.FILTER))[0] + 1) + "/true", 286 "plugin2_T:" + (ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.TRANSFORMER))[0] + 1) + "/true", 287 "plugin2_S:" + (ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.SORTER))[0] + 1) + "/true", 288 "plugin2_C:" + (ImagePluginConfiguration.getRange(new CategoryProvider(PluginProvider.COMPRESSOR))[0] + 1) + "/true"), expected, order); 289 } 290 291 public static class PProvider extends CmdResourcePluginProvider { 292 293 private final List<String> order; 294 private final String category; 295 private final String name; 296 PProvider(String name, String category, List<String> order) { 297 super(name, ""); 298 this.name = name; 299 this.order = order; 300 this.category = category; 301 } 302 303 @Override 304 public ResourcePlugin[] newPlugins(String[] argument, Map<String, String> options) throws IOException { 305 return new ResourcePlugin[]{new PluginTrap(getName(), order) 306 }; 307 } 308 309 @Override 310 public String getCategory() { 311 return category; 312 } 313 314 @Override 315 public String getToolOption() { 316 return name; 317 } 318 319 @Override 320 public String getToolArgument() { 321 return null; 322 } 323 324 @Override 325 public Map<String, String> getAdditionalOptions() { 326 return null; 327 } 328 } 329 330 public static class PluginTrap implements ResourcePlugin { 331 332 private final String name; 333 private final List<String> order; 334 335 private PluginTrap(String name, List<String> order) { 336 this.name = name; 337 this.order = order; 338 } 339 340 @Override 341 public void visit(ResourcePool resources, ResourcePool output, StringTable strings) 342 throws Exception { 343 order.add(name); 344 resources.visit((resource, order, str) -> { 345 return resource; 346 }, output, strings); 347 } 348 349 @Override 350 public String getName() { 351 return name; 352 } 353 } 354 355 public static class CategoryProvider extends CmdResourcePluginProvider { 356 357 private final String category; 358 359 CategoryProvider(String category) { 360 super("CategoryProvider", ""); 361 this.category = category; 362 } 363 364 @Override 365 public ResourcePlugin[] newPlugins(String[] argument, 366 Map<String, String> options) throws IOException { 367 throw new IOException("Shouldn't be called"); 368 } 369 370 @Override 371 public String getCategory() { 372 return category; 373 } 374 375 @Override 376 public String getToolArgument() { 377 throw new UnsupportedOperationException("Shouldn't be called"); 378 } 379 380 @Override 381 public String getToolOption() { 382 throw new UnsupportedOperationException("Shouldn't be called"); 383 } 384 385 @Override 386 public Map<String, String> getAdditionalOptions() { 387 throw new UnsupportedOperationException("Shouldn't be called"); 388 } 389 } 390 }