jdk/test/tools/jlink/asmplugin/AsmPluginTestBase.java
changeset 36511 9d0388c6b336
child 38320 e24c7029e8ba
equal deleted inserted replaced
36510:043f1af70518 36511:9d0388c6b336
       
     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 import java.io.IOException;
       
    24 import java.net.URI;
       
    25 import java.nio.file.FileSystem;
       
    26 import java.nio.file.FileSystems;
       
    27 import java.nio.file.Files;
       
    28 import java.nio.file.Path;
       
    29 import java.nio.file.Paths;
       
    30 import java.util.ArrayList;
       
    31 import java.util.Collection;
       
    32 import java.util.Collections;
       
    33 import java.util.HashMap;
       
    34 import java.util.Iterator;
       
    35 import java.util.List;
       
    36 import java.util.Map;
       
    37 import java.util.Set;
       
    38 import java.util.function.Predicate;
       
    39 import java.util.stream.Collectors;
       
    40 import java.util.stream.Stream;
       
    41 import jdk.tools.jlink.internal.PoolImpl;
       
    42 import jdk.tools.jlink.internal.StringTable;
       
    43 
       
    44 import jdk.tools.jlink.internal.plugins.asm.AsmPlugin;
       
    45 import jdk.tools.jlink.internal.plugins.asm.AsmPools;
       
    46 import jdk.tools.jlink.plugin.Pool;
       
    47 import jdk.tools.jlink.plugin.Pool.ModuleData;
       
    48 
       
    49 public abstract class AsmPluginTestBase {
       
    50 
       
    51     protected static final String TEST_MODULE = "jlink.test";
       
    52     protected static final Map<String, List<String>> MODULES;
       
    53 
       
    54     private static final Predicate<ModuleData> isClass = r -> r.getPath().endsWith(".class");
       
    55     private final List<String> classes;
       
    56     private final List<String> resources;
       
    57     private final Pool pool;
       
    58 
       
    59     static {
       
    60         Map<String, List<String>> map = new HashMap<>();
       
    61         map.put("jdk.localedata", new ArrayList<>());
       
    62         map.put("java.base", new ArrayList<>());
       
    63         map.put(TEST_MODULE, new ArrayList<>());
       
    64         MODULES = Collections.unmodifiableMap(map);
       
    65     }
       
    66 
       
    67     public static boolean isImageBuild() {
       
    68         Path javaHome = Paths.get(System.getProperty("test.jdk"));
       
    69         Path jmods = javaHome.resolve("jmods");
       
    70         return Files.exists(jmods);
       
    71     }
       
    72 
       
    73     public AsmPluginTestBase() {
       
    74         try {
       
    75             List<String> classes = new ArrayList<>();
       
    76             List<String> resources = new ArrayList<>();
       
    77 
       
    78             pool = new PoolImpl();
       
    79 
       
    80             FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
       
    81             Path root = fs.getPath("/modules");
       
    82 
       
    83             List<byte[]> moduleInfos = new ArrayList<>();
       
    84             try (Stream<Path> stream = Files.walk(root)) {
       
    85                 for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext(); ) {
       
    86                     Path p = iterator.next();
       
    87                     if (Files.isRegularFile(p)) {
       
    88                         String module = p.toString().substring("/modules/".length());
       
    89                         module = module.substring(0, module.indexOf("/"));
       
    90                         if (MODULES.keySet().contains(module)) {
       
    91                             try {
       
    92                                 boolean isModuleInfo = p.endsWith("module-info.class");
       
    93                                 if (isModuleInfo) {
       
    94                                     moduleInfos.add(Files.readAllBytes(p));
       
    95                                 }
       
    96                                 byte[] content = Files.readAllBytes(p);
       
    97                                 if (p.toString().endsWith(".class") && !isModuleInfo) {
       
    98                                     classes.add(toClassName(p));
       
    99                                 } else if (!isModuleInfo) {
       
   100                                     MODULES.get(module).add(toResourceFile(p));
       
   101                                 }
       
   102                                 resources.add(toPath(p.toString()));
       
   103                                 ModuleData res = Pool.newResource(toPath(p.toString()), content);
       
   104                                 pool.add(res);
       
   105                             } catch (Exception ex) {
       
   106                                 throw new RuntimeException(ex);
       
   107                             }
       
   108                         }
       
   109                     }
       
   110                 }
       
   111             }
       
   112             // There is more than 10 classes in java.base...
       
   113             if (classes.size() < 10 || pool.getContent().size() < 10) {
       
   114                 throw new AssertionError("Not expected resource or class number");
       
   115             }
       
   116 
       
   117             //Add a fake resource file
       
   118             String content = "java.lang.Object";
       
   119             String path = "META-INF/services/com.foo.BarProvider";
       
   120             ModuleData resFile = Pool.newResource("/" + TEST_MODULE + "/" +
       
   121                     path, content.getBytes());
       
   122             pool.add(resFile);
       
   123             ModuleData fakeInfoFile = Pool.newResource("/" + TEST_MODULE
       
   124                     + "/module-info.class", moduleInfos.get(0));
       
   125             pool.add(fakeInfoFile);
       
   126             MODULES.get(TEST_MODULE).add(path);
       
   127             for(Map.Entry<String, List<String>> entry : MODULES.entrySet()) {
       
   128                 if (entry.getValue().isEmpty()) {
       
   129                     throw new AssertionError("No resource file for " + entry.getKey());
       
   130                 }
       
   131             }
       
   132             this.classes = Collections.unmodifiableList(classes);
       
   133             this.resources = Collections.unmodifiableList(resources);
       
   134         } catch (Exception e) {
       
   135             throw new ExceptionInInitializerError(e);
       
   136         }
       
   137     }
       
   138 
       
   139     public List<String> getClasses() {
       
   140         return classes;
       
   141     }
       
   142 
       
   143     public List<String> getResources() {
       
   144         return resources;
       
   145     }
       
   146 
       
   147     public Pool getPool() {
       
   148         return pool;
       
   149     }
       
   150 
       
   151     public abstract void test() throws Exception;
       
   152 
       
   153     public Collection<ModuleData> extractClasses(Pool pool) {
       
   154         return pool.getContent().stream()
       
   155                 .filter(isClass)
       
   156                 .collect(Collectors.toSet());
       
   157     }
       
   158 
       
   159     public Collection<ModuleData> extractResources(Pool pool) {
       
   160         return pool.getContent().stream()
       
   161                 .filter(isClass.negate())
       
   162                 .collect(Collectors.toSet());
       
   163     }
       
   164 
       
   165     public String getModule(String path) {
       
   166         int index = path.indexOf("/", 1);
       
   167         return path.substring(1, index);
       
   168     }
       
   169 
       
   170     public String removeModule(String path) {
       
   171         int index = path.indexOf("/", 1);
       
   172         return path.substring(index + 1);
       
   173     }
       
   174 
       
   175     private String toPath(String p) {
       
   176         return p.substring("/modules".length());
       
   177     }
       
   178 
       
   179     private String toClassName(Path p) {
       
   180         String path = p.toString();
       
   181         path = path.substring("/modules/".length());
       
   182         // remove module
       
   183         if (!path.endsWith("module-info.class")) {
       
   184             path = path.substring(path.indexOf("/") + 1);
       
   185         }
       
   186         path = path.substring(0, path.length() - ".class".length());
       
   187 
       
   188         return path;
       
   189     }
       
   190 
       
   191     private String toResourceFile(Path p) {
       
   192         String path = p.toString();
       
   193         path = path.substring("/modules/".length());
       
   194         // remove module
       
   195         path = path.substring(path.indexOf("/") + 1);
       
   196 
       
   197         return path;
       
   198     }
       
   199 
       
   200     public abstract class TestPlugin extends AsmPlugin {
       
   201 
       
   202         private AsmPools pools;
       
   203 
       
   204         public AsmPools getPools() {
       
   205             return pools;
       
   206         }
       
   207 
       
   208         public boolean isVisitCalled() {
       
   209             return pools != null;
       
   210         }
       
   211 
       
   212         public Pool visit(Pool inResources) throws IOException {
       
   213             try {
       
   214                 Pool outResources = new PoolImpl(inResources.getByteOrder(), new StringTable() {
       
   215                     @Override
       
   216                     public int addString(String str) {
       
   217                         return -1;
       
   218                     }
       
   219 
       
   220                     @Override
       
   221                     public String getString(int id) {
       
   222                         return null;
       
   223                     }
       
   224                 });
       
   225                 visit(inResources, outResources);
       
   226                 return outResources;
       
   227             } catch (Exception e) {
       
   228                 throw new IOException(e);
       
   229             }
       
   230         }
       
   231 
       
   232         @Override
       
   233         public void visit(AsmPools pools) {
       
   234             if (isVisitCalled()) {
       
   235                 throw new AssertionError("Visit was called twice");
       
   236             }
       
   237             this.pools = pools;
       
   238             visit();
       
   239         }
       
   240 
       
   241         public abstract void visit();
       
   242         public abstract void test(Pool inResources, Pool outResources) throws Exception;
       
   243 
       
   244         @Override
       
   245         public String getName() {
       
   246             return "test-plugin";
       
   247         }
       
   248     }
       
   249 }