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