1 /*
   2  * Copyright (c) 2019, Red Hat, Inc.
   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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 import java.util.Map;
  27 
  28 import jdk.tools.jlink.internal.ResourcePoolManager;
  29 import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin;
  30 import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin.NativePluginFactory;
  31 import jdk.tools.jlink.plugin.Plugin;
  32 import jdk.tools.jlink.plugin.ResourcePool;
  33 import jdk.tools.jlink.plugin.ResourcePoolBuilder;
  34 import jdk.tools.jlink.plugin.ResourcePoolEntry;
  35 import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
  36 
  37 /*
  38  * @test
  39  * @summary Test for combination of java debug attributes stripping and
  40  * native debug symbols stripping.
  41  * @author Severin Gehwolf
  42  * @modules jdk.jlink/jdk.tools.jlink.internal
  43  *          jdk.jlink/jdk.tools.jlink.internal.plugins
  44  *          jdk.jlink/jdk.tools.jlink.plugin
  45  * @run main/othervm DefaultStripDebugPluginTest
  46  */
  47 public class DefaultStripDebugPluginTest {
  48 
  49     public void testWithNativeStripPresent() {
  50         MockStripPlugin javaPlugin = new MockStripPlugin(false);
  51         MockStripPlugin nativePlugin = new MockStripPlugin(true);
  52         TestNativeStripPluginFactory nativeFactory =
  53                                  new TestNativeStripPluginFactory(nativePlugin);
  54         DefaultStripDebugPlugin plugin = new DefaultStripDebugPlugin(javaPlugin,
  55                                                                      nativeFactory);
  56         ResourcePoolManager inManager = new ResourcePoolManager();
  57         ResourcePool pool = plugin.transform(inManager.resourcePool(),
  58                                              inManager.resourcePoolBuilder());
  59         if (!pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent() ||
  60             !pool.findEntry(MockStripPlugin.NATIVE_PATH).isPresent()) {
  61             throw new AssertionError("Expected both native and java to get called");
  62         }
  63     }
  64 
  65     public void testNoNativeStripPluginPresent() {
  66         MockStripPlugin javaPlugin = new MockStripPlugin(false);
  67         TestNativeStripPluginFactory nativeFactory =
  68                                          new TestNativeStripPluginFactory(null);
  69         DefaultStripDebugPlugin plugin = new DefaultStripDebugPlugin(javaPlugin,
  70                                                                      nativeFactory);
  71         ResourcePoolManager inManager = new ResourcePoolManager();
  72         ResourcePool pool = plugin.transform(inManager.resourcePool(),
  73                                              inManager.resourcePoolBuilder());
  74         if (!pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent()) {
  75             throw new AssertionError("Expected java strip plugin to get called");
  76         }
  77     }
  78 
  79     public static void main(String[] args) {
  80         DefaultStripDebugPluginTest test = new DefaultStripDebugPluginTest();
  81         test.testNoNativeStripPluginPresent();
  82         test.testWithNativeStripPresent();
  83     }
  84 
  85     public static class MockStripPlugin implements Plugin {
  86 
  87         private static final String NATIVE_PATH = "/foo/lib/test.so.debug";
  88         private static final String JAVA_PATH = "/foo/TestClass.class";
  89         private static final String STRIP_NATIVE_NAME = "strip-native-debug-symbols";
  90         private static final String OMIT_ARG = "omit-debuginfo";
  91         private final boolean isNative;
  92 
  93         MockStripPlugin(boolean isNative) {
  94             this.isNative = isNative;
  95         }
  96 
  97         @Override
  98         public void configure(Map<String, String> config) {
  99             if (isNative) {
 100                 if (config.get(STRIP_NATIVE_NAME) == null ||
 101                     !config.get(STRIP_NATIVE_NAME).equals(OMIT_ARG)) {
 102                     throw new AssertionError("Test failed!, Expected native " +
 103                                              "plugin to be properly configured.");
 104                 } else {
 105                     System.out.println("DEBUG: native plugin properly configured with: " +
 106                                        STRIP_NATIVE_NAME + "=" + config.get(STRIP_NATIVE_NAME));
 107                 }
 108             }
 109         }
 110 
 111         @Override
 112         public ResourcePool transform(ResourcePool in,
 113                                       ResourcePoolBuilder out) {
 114             in.transformAndCopy((r) -> {return r; }, out); // identity
 115             String resPath = JAVA_PATH;
 116             ResourcePoolEntry.Type type = Type.CLASS_OR_RESOURCE;
 117             if (isNative) {
 118                 resPath = NATIVE_PATH;
 119                 type = Type.NATIVE_LIB;
 120             }
 121             ResourcePoolEntry entry = createMockEntry(resPath, type);
 122             out.add(entry);
 123             return out.build();
 124         }
 125 
 126         private ResourcePoolEntry createMockEntry(String path,
 127                                                   ResourcePoolEntry.Type type) {
 128             byte[] mockContent = new byte[] { 0, 1, 2, 3 };
 129             ResourcePoolEntry entry = ResourcePoolEntry.create(path,
 130                                                                type,
 131                                                                mockContent);
 132             return entry;
 133         }
 134 
 135     }
 136 
 137     public static class TestNativeStripPluginFactory implements NativePluginFactory {
 138 
 139         private final MockStripPlugin plugin;
 140 
 141         TestNativeStripPluginFactory(MockStripPlugin plugin) {
 142             this.plugin = plugin;
 143         }
 144 
 145         @Override
 146         public Plugin create() {
 147             return plugin;
 148         }
 149 
 150     }
 151 }