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