1 /* 2 * Copyright (c) 2016, 2017, 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 import java.nio.file.Path; 25 import java.nio.file.Paths; 26 import java.util.LinkedHashMap; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Arrays; 30 import java.io.IOException; 31 import java.lang.module.ModuleDescriptor; 32 import java.util.ArrayList; 33 import jdk.test.lib.compiler.CompilerUtils; 34 import jdk.testlibrary.ProcessTools; 35 import jdk.testlibrary.OutputAnalyzer; 36 import org.testng.annotations.BeforeTest; 37 38 /** 39 * @test 40 * @bug 8151654 41 * @library /lib/testlibrary /test/lib 42 * @library /java/security/modules 43 * @build jdk.test.lib.compiler.CompilerUtils JarUtils 44 * @summary Test custom JAAS callback handler with all possible modular option. 45 * @run testng JaasModularDefaultHandlerTest 46 */ 47 public class JaasModularDefaultHandlerTest extends ModularTest { 48 49 private static final Path S_SRC = SRC.resolve("TestCallbackHandler.java"); 50 private static final String MODULAR = "M"; 51 private static final String S_PKG = "handler"; 52 private static final String S_JAR_NAME = S_PKG + JAR_EXTN; 53 private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN; 54 private static final String HANDLER = S_PKG + ".TestCallbackHandler"; 55 56 private static final Path C_SRC 57 = SRC.resolve("JaasClientWithDefaultHandler.java"); 58 private static final Path CL_SRC = SRC.resolve("TestLoginModule.java"); 59 private static final String C_PKG = "login"; 60 private static final String C_JAR_NAME = C_PKG + JAR_EXTN; 61 private static final String MCN_JAR_NAME 62 = MODULAR + C_PKG + "NoMUse" + JAR_EXTN; 63 private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN; 64 65 private static final Path BUILD_DIR = Paths.get(".").resolve("build"); 66 private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); 67 private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG); 68 private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG); 69 private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase"); 70 private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); 71 72 private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG); 73 private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME); 74 private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME); 75 76 private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG); 77 private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME); 78 private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME); 79 private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME); 80 81 private static final String MAIN = C_PKG + ".JaasClientWithDefaultHandler"; 82 private static final List<String> M_REQUIRED = Arrays.asList("java.base", 83 "jdk.security.auth"); 84 85 private static final String CLASS_NOT_FOUND_MSG 86 = "java.lang.ClassNotFoundException: handler.TestCallbackHandler"; 87 private static final String NO_FAILURE = null; 88 89 /** 90 * Generates Test specific input parameters. 91 */ 92 @Override 93 public Object[][] getTestInput() { 94 95 List<List<Object>> params = new ArrayList<>(); 96 String[] args = new String[]{HANDLER}; 97 // PARAMETER ORDERS - 98 // Client Module Type, Service Module Type, 99 // Service META Descriptor Required, 100 // Expected Failure message, Client arguments 101 params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, 102 false, NO_FAILURE, args)); 103 params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, 104 false, NO_FAILURE, args)); 105 params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, 106 false, NO_FAILURE, args)); 107 108 params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, 109 false, NO_FAILURE, args)); 110 params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, 111 false, NO_FAILURE, args)); 112 params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, 113 false, NO_FAILURE, args)); 114 115 params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, 116 false, NO_FAILURE, args)); 117 params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, 118 false, NO_FAILURE, args)); 119 params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, 120 false, NO_FAILURE, args)); 121 return params.stream().map(p -> p.toArray()).toArray(Object[][]::new); 122 } 123 124 /** 125 * Pre-compile and generate the artifacts required to run this test before 126 * running each test cases. 127 */ 128 @BeforeTest 129 public void buildArtifacts() { 130 131 boolean done = true; 132 try { 133 done = CompilerUtils.compile(S_SRC, S_BUILD_DIR); 134 // Generate modular/regular handler jars. 135 generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false); 136 generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false); 137 // Compile client source codes. 138 done &= CompilerUtils.compile(C_SRC, C_BLD_DIR); 139 done &= CompilerUtils.compile(CL_SRC, C_BLD_DIR); 140 // Generate modular client jar with explicit dependency 141 generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true); 142 // Generate modular client jar without any dependency 143 generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false); 144 // Generate regular client jar 145 generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false); 146 System.out.format("%nArtifacts generated successfully? %s", done); 147 if (!done) { 148 throw new RuntimeException("Artifact generation failed"); 149 } 150 } catch (IOException e) { 151 throw new RuntimeException(e); 152 } 153 } 154 155 /** 156 * Generate modular/regular jar based on module type for this test. 157 */ 158 private void generateJar(boolean isService, MODULE_TYPE moduleType, 159 Path jar, Path compilePath, boolean depends) throws IOException { 160 161 ModuleDescriptor mDescriptor = null; 162 if (isService) { 163 mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG, 164 S_PKG, null, null, null, M_REQUIRED, depends); 165 } else { 166 mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG, 167 C_PKG, null, null, S_PKG, M_REQUIRED, depends); 168 } 169 generateJar(mDescriptor, jar, compilePath); 170 } 171 172 /** 173 * Holds Logic for the test client. This method will get called with each 174 * test parameter. 175 */ 176 @Override 177 public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType, 178 Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath, 179 String... args) throws Exception { 180 181 OutputAnalyzer output = null; 182 try { 183 // For automated/explicit module types, copy the corresponding 184 // jars to module base folder, which will be considered as 185 // module base path during execution. 186 if (!(cModuleType == MODULE_TYPE.UNNAMED 187 && sModuletype == MODULE_TYPE.UNNAMED)) { 188 copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH); 189 copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH); 190 } 191 192 System.out.format("%nExecuting java client with required" 193 + " custom service in class/module path."); 194 String mName = getModuleName(cModuleType, cJarPath, C_PKG); 195 Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED 196 || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null; 197 String cPath = buildClassPath(cModuleType, cJarPath, sModuletype, 198 sJarPath); 199 Map<String, String> vmArgs = getVMArgs(sModuletype, cModuleType, 200 getModuleName(sModuletype, sJarPath, S_PKG)); 201 output = ProcessTools.executeTestJava( 202 getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs, 203 args)).outputTo(System.out).errorTo(System.out); 204 } finally { 205 // Clean module path to hold required jars for next run. 206 cleanModuleBasePath(M_BASE_PATH); 207 } 208 return output; 209 } 210 211 /** 212 * Decide the pre-generated client/service jar path for each test case 213 * based on client/service module type. 214 */ 215 @Override 216 public Path findJarPath(boolean depends, MODULE_TYPE moduleType, 217 boolean addMetaDesc, boolean dependsOnServiceModule) { 218 if (depends) { 219 if (moduleType == MODULE_TYPE.EXPLICIT) { 220 return MS_JAR; 221 } else { 222 return S_JAR; 223 } 224 } else { 225 // Choose corresponding client jar using dependent module 226 if (moduleType == MODULE_TYPE.EXPLICIT) { 227 if (dependsOnServiceModule) { 228 return MC_JAR; 229 } else { 230 return MCN_JAR; 231 } 232 } else { 233 return C_JAR; 234 } 235 } 236 } 237 238 /** 239 * VM argument required for the test. 240 */ 241 private Map<String, String> getVMArgs(MODULE_TYPE sModuletype, 242 MODULE_TYPE cModuleType, String addModName) throws IOException { 243 final Map<String, String> vmArgs = new LinkedHashMap<>(); 244 vmArgs.put("-Duser.language=", "en"); 245 vmArgs.put("-Duser.region=", "US"); 246 vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve( 247 "jaas.conf").toFile().getCanonicalPath()); 248 if (addModName != null 249 && !(cModuleType == MODULE_TYPE.EXPLICIT 250 && sModuletype == MODULE_TYPE.EXPLICIT)) { 251 vmArgs.put("--add-modules=", addModName); 252 } 253 return vmArgs; 254 } 255 256 }