OpenJDK / jdk / hs
changeset 46898:4d2a6afafb76
8183310: java/security/modules/ModularTest.java should clean up better
Summary: This require cleaning up Test files.
Reviewed-by: weijun
author | ssahoo |
---|---|
date | Wed, 23 Aug 2017 09:13:32 -0700 |
parents | 3aa0378f0490 |
children | ea81af6257b3 |
files | jdk/test/java/security/Provider/SecurityProviderModularTest.java jdk/test/java/security/Provider/TestClient.java jdk/test/java/security/Provider/TestProvider.java jdk/test/java/security/Provider/TestSecurityProvider.java jdk/test/java/security/Provider/TestSecurityProviderClient.java jdk/test/java/security/modules/ModularTest.java jdk/test/javax/security/auth/login/modules/JaasClient.java jdk/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java jdk/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java jdk/test/javax/security/auth/login/modules/TEST.properties jdk/test/javax/security/auth/login/modules/TestLoginModule.java |
diffstat | 12 files changed, 827 insertions(+), 1112 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/test/java/security/Provider/SecurityProviderModularTest.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/java/security/Provider/SecurityProviderModularTest.java Wed Aug 23 09:13:32 2017 -0700 @@ -24,318 +24,362 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.nio.file.StandardCopyOption; +import java.security.Security; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Arrays; +import java.util.stream.Stream; +import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.lang.module.ModuleDescriptor; -import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.OutputAnalyzer; -import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; +import java.lang.module.ModuleDescriptor.Builder; +import jdk.internal.module.ModuleInfoWriter; +import jdk.test.lib.process.ProcessTools; -/** - * @test - * @bug 8130360 - * @library /lib/testlibrary - * @library /java/security/modules - * @library /test/lib - * @modules java.base/jdk.internal.module - * @build jdk.test.lib.compiler.CompilerUtils JarUtils - * @summary Test custom security provider module with all possible modular - * condition. The test includes different combination of security - * client/provider modules interaction with or without service - * description. - * @run testng SecurityProviderModularTest - */ -public class SecurityProviderModularTest extends ModularTest { - - private static final Path S_SRC = SRC.resolve("TestSecurityProvider.java"); - private static final String S_PKG = "provider"; - private static final String S_JAR_NAME = S_PKG + JAR_EXTN; - private static final String S_WITH_DESCR_JAR_NAME = S_PKG + DESCRIPTOR - + JAR_EXTN; - private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN; - private static final String MS_WITH_DESCR_JAR_NAME = MODULAR + S_PKG - + DESCRIPTOR + JAR_EXTN; - - private static final Path C_SRC = SRC.resolve( - "TestSecurityProviderClient.java"); - private static final String C_PKG = "client"; - private static final String C_JAR_NAME = C_PKG + JAR_EXTN; - private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN; - private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN; - private static final Path BUILD_DIR = Paths.get(".").resolve("build"); - private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); - private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG); - private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve( - S_PKG + DESCRIPTOR); - private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG); - private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase"); - private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); - - private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG); - private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME); - private static final Path S_WITH_DESCRIPTOR_JAR = S_ARTIFACTS_DIR.resolve( - S_WITH_DESCR_JAR_NAME); - private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve( - MS_JAR_NAME); - private static final Path MS_WITH_DESCR_JAR = S_ARTIFACTS_DIR.resolve( - MS_WITH_DESCR_JAR_NAME); +/* + * @test + * @bug 8130360 8183310 + * @summary Test security provider in different combination of modular option + * defined with(out) service description. + * @library /lib/testlibrary /test/lib + * @modules java.base/jdk.internal.module + * @build JarUtils TestProvider TestClient + * @run main SecurityProviderModularTest CL true + * @run main SecurityProviderModularTest CL false + * @run main SecurityProviderModularTest SL true + * @run main SecurityProviderModularTest SL false + * @run main SecurityProviderModularTest SPN true + * @run main SecurityProviderModularTest SPN false + * @run main SecurityProviderModularTest SPT true + * @run main SecurityProviderModularTest SPT false + */ +public class SecurityProviderModularTest { - private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG); - private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME); - private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME); - private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME); - - private static final String MAIN = C_PKG + ".TestSecurityProviderClient"; - private static final String S_INTERFACE = "java.security.Provider"; - private static final String S_IMPL = S_PKG + ".TestSecurityProvider"; - private static final List<String> M_REQUIRED = Arrays.asList("java.base"); - private static final Path META_DESCR_PATH = Paths.get("META-INF") - .resolve("services").resolve(S_INTERFACE); - private static final Path S_META_DESCR_FPATH = S_WITH_META_DESCR_BUILD_DIR - .resolve(META_DESCR_PATH); - - private static final boolean WITH_S_DESCR = true; - private static final boolean WITHOUT_S_DESCR = false; - private static final String PROVIDER_NOT_FOUND_MSG = "Unable to find Test" - + " Security Provider"; - private static final String CAN_NOT_ACCESS_MSG = "cannot access class"; - private static final String NO_FAILURE = null; - private static final String SERVICE_LOADER = "SERVICE_LOADER"; - private static final String CLASS_LOADER = "CLASS_LOADER"; - private static final String SECURITY_PROP = "SECURITY_PROP"; - private static final List<String> MECHANISMS = Arrays.asList(SERVICE_LOADER, - CLASS_LOADER, SECURITY_PROP); - private static final Path SECURE_PROP_EXTN = Paths.get("./java.secure.ext"); + private static final Path TEST_CLASSES + = Paths.get(System.getProperty("test.classes")); + private static final Path ARTIFACT_DIR = Paths.get("jars"); + private static final Path SEC_FILE = Paths.get("java.extn.security"); + private static final String PS = File.pathSeparator; + private static final String P_TYPE = "p.TestProvider"; + private static final String C_TYPE = "c.TestClient"; /** - * Generates Test specific input parameters. + * Here is the naming convention followed. + * Test runtime arguments, + * CL - Provider class loaded through ClassLoader + * SL - Provider class to be discovered by ServiceLoader + * SPN - Provider name defined through "java.extn.security" file which + * referred through system property "java.security.properties". + * SPT - Provider type defined through "java.extn.security" file which + * referred through system property "java.security.properties". + * + * For each jar file name, + * p.jar - Unnamed provider jar. + * pd.jar - Unnamed provider jar with META-INF provider descriptor. + * mp.jar - Modular provider jar. + * mpd.jar - Modular provider jar with META-INF provider descriptor. + * msp.jar - Modular provider jar provides service through module-info.java + * mspd.jar - Modular provider jar with META-INF provider descriptor and + * provides service through module-info.java. + * c.jar - Unnamed client jar. + * mc.jar - Modular client jar. + * mcs.jar - Modular client jar uses service through module-info.java. + * amc.jar - Modular client used for automatic provider jar. + * amcs.jar - Modular client used for automatic provider jar uses service + * through module-info.java. */ - @Override - public Object[][] getTestInput() { + private static final Path P_JAR = artifact("p.jar"); + private static final Path PD_JAR = artifact("pd.jar"); + private static final Path MP_JAR = artifact("mp.jar"); + private static final Path MPD_JAR = artifact("mpd.jar"); + private static final Path MSP_JAR = artifact("msp.jar"); + private static final Path MSPD_JAR = artifact("mspd.jar"); + private static final Path C_JAR = artifact("c.jar"); + private static final Path MC_JAR = artifact("mc.jar"); + private static final Path MCS_JAR = artifact("mcs.jar"); + private static final Path AMC_JAR = artifact("amc.jar"); + private static final Path AMCS_JAR = artifact("amcs.jar"); + private static final Map<String, String> MSG_MAP = new HashMap<>(); - List<List<Object>> params = new ArrayList<>(); - MECHANISMS.stream().forEach((mechanism) -> { - boolean useCLoader = CLASS_LOADER.equals(mechanism); - boolean useSLoader = SERVICE_LOADER.equals(mechanism); - String[] args = new String[]{mechanism}; - // PARAMETER ORDERS - - // Client Module Type, Service Module Type, - // If Service META Descriptor Required, - // Expected Failure message, mechanism used to find the provider - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, - WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG - : NO_FAILURE), args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG - : PROVIDER_NOT_FOUND_MSG), args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG - : NO_FAILURE), args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG - : ((useSLoader) ? PROVIDER_NOT_FOUND_MSG - : NO_FAILURE)), args)); + static { + /* + * This mapping help process finding expected message based + * on the key passed as argument while executing java command. + */ + MSG_MAP.put("NoAccess", "cannot access class p.TestProvider"); + MSG_MAP.put("Success", "Client: found provider TestProvider"); + MSG_MAP.put("NoProvider", "Provider TestProvider not found"); + } + + private final String addUNArg; + private final String addNMArg; + private final String cArg; + private final String unnP; + private final String modP; + private final String unnC; + private final String modC; + private final String autoMC; + private final String expModRes; + private final String expAModRes; + // Common set of VM arguments used in all test cases + private final List<String> commonArgs; + + public SecurityProviderModularTest(String use, boolean metaDesc) { + + List<String> argList = new LinkedList<>(); + argList.add("-Duser.language=en"); + argList.add("-Duser.region=US"); + final boolean useSL = "SL".equals(use) || "SPN".equals(use); + final boolean useCL = "CL".equals(use); + final boolean useSPT = "SPT".equals(use); + final boolean useSP = use.startsWith("SP"); + /* Use Security property file when the provider expected to + * loaded through Security property file. */ + if (useSP) { + /* Create a java.security file to specify the new provider. + * java.security file extension can be provided using + * "-Djava.security.properties" VM argument at runtime.*/ + createJavaSecurityFileExtn("SPN".equals(use)); + argList.add("-Djava.security.properties=" + toAbsPath(SEC_FILE)); + } + commonArgs = Collections.unmodifiableList(argList); + cArg = (useCL) ? P_TYPE : "TestProvider"; + addUNArg = (useSL) ? "" : ("--add-modules=" + + ((metaDesc) ? "pd" : "p")); + addNMArg = (useSL) ? "" : "--add-modules=mp"; - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, - (useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, ((useSLoader) ? PROVIDER_NOT_FOUND_MSG - : NO_FAILURE), args)); + // Based on Testcase, select unnamed/modular jar files to use. + unnP = toAbsPath((metaDesc) ? PD_JAR : P_JAR); + modP = toAbsPath(useSL ? (metaDesc ? MSPD_JAR : MSP_JAR) + : (metaDesc ? MPD_JAR : MP_JAR)); + unnC = toAbsPath(C_JAR); + modC = toAbsPath(useSL ? MCS_JAR : MC_JAR); + autoMC = toAbsPath(useSL ? AMCS_JAR : AMC_JAR); + + expModRes = "Success"; + expAModRes = (useSPT | useCL) ? "Success" + : (metaDesc) ? "Success" : "NoProvider"; + String loadByMsg = useSP ? "SecurityPropertyFile" + : ((useCL) ? "ClassLoader" : "ServiceLoader"); + System.out.printf("%n*** Providers loaded through %s and includes" + + " META Descriptor: %s ***%n%n", loadByMsg, metaDesc); + } + + /* + * Test cases are based on the following logic, + * for (ProviderLoadedThrough : {"ServiceLoader", "ClassLoader", + * "SecurityPropertyFile"}) { + * for (definedWith : {"METAINFService", "WithoutMETAINFService"}) { + * for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * for (providerType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * Create and run java command for each possible case + * } + * } + * } + * } + */ + public static void main(String[] args) throws Exception { + + // Generates unnamed and modular jars. + setUp(); + boolean metaDesc = Boolean.valueOf(args[1]); + SecurityProviderModularTest test + = new SecurityProviderModularTest(args[0], metaDesc); + test.process(args[0]); + } + + private void process(String use) throws Exception { - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, - (useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, ((useSLoader) ? PROVIDER_NOT_FOUND_MSG - : NO_FAILURE), args)); - }); - return params.stream().map(p -> p.toArray()).toArray(Object[][]::new); + // Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED + System.out.printf("Case: Modular Client and Modular Provider"); + execute(String.format("--module-path %s%s%s -m mc/%s %s %s", + modC, PS, modP, C_TYPE, use, cArg), expModRes); + System.out.printf("Case: Modular Client and automatic Provider"); + execute(String.format("--module-path %s%s%s %s -m mc/%s %s %s", autoMC, + PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes); + System.out.printf("Case: Modular Client and unnamed Provider"); + execute(String.format("--module-path %s -cp %s -m mc/%s %s %s", autoMC, + unnP, C_TYPE, use, cArg), expAModRes); + + // Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED + System.out.printf("Case: Automatic Client and modular Provider"); + execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC, + PS, modP, addNMArg, C_TYPE, use, cArg), expModRes); + System.out.printf("Case: Automatic Client and automatic Provider"); + execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC, + PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes); + System.out.printf("Case: Automatic Client and unnamed Provider"); + execute(String.format("--module-path %s -cp %s -m c/%s %s %s", unnC, + unnP, C_TYPE, use, cArg), expAModRes); + + // Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED + System.out.printf("Case: Unnamed Client and modular Provider"); + execute(String.format("-cp %s --module-path %s %s %s %s %s", unnC, + modP, addNMArg, C_TYPE, use, cArg), expModRes); + System.out.printf("Case: Unnamed Client and automatic Provider"); + execute(String.format("-cp %s --module-path %s %s %s %s %s", unnC, + unnP, addUNArg, C_TYPE, use, cArg), expAModRes); + System.out.printf("Case: Unnamed Client and unnamed Provider"); + execute(String.format("-cp %s%s%s %s %s %s", unnC, PS, unnP, C_TYPE, + use, cArg), expAModRes); + + // Case: unnamed jars in --module-path and modular jars in -cp. + System.out.printf( + "Case: Unnamed Client and Unnamed Provider in modulepath"); + execute(String.format("--module-path %s%s%s %s -m c/%s %s %s", unnC, + PS, unnP, addUNArg, C_TYPE, use, cArg), expAModRes); + System.out.printf( + "Case: Modular Client and Modular Provider in classpath"); + execute(String.format("-cp %s%s%s %s %s %s", modC, PS, modP, C_TYPE, + use, cArg), expAModRes); } /** - * Pre-compile and generate the artifacts required to run this test before - * running each test cases. + * Execute with command arguments and process the result. */ - @BeforeTest - public void buildArtifacts() { - - boolean done = true; - try { + private void execute(String args, String msgKey) throws Exception { - done &= CompilerUtils.compile(S_SRC, S_BUILD_DIR); - done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR); - done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL); - // Generate modular/regular jars with(out) META-INF - // service descriptor - generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR, - S_WITH_META_DESCR_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR, - S_WITH_META_DESCR_BUILD_DIR, false); - // Compile client source codes. - done &= CompilerUtils.compile(C_SRC, C_BLD_DIR, "-cp", - S_JAR.toFile().getCanonicalPath()); - // Generate modular client jar with explicit dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true); - // Generate modular client jar without any dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false); - // Generate regular client jar - generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false); - System.out.format("%nArtifacts generated successfully? %s", done); - if (!done) { - throw new RuntimeException("Artifacts generation failed"); + String[] safeArgs = Stream.concat(commonArgs.stream(), + Stream.of(args.split("\\s+"))).filter(s -> { + if (s.contains(" ")) { + throw new RuntimeException("No spaces in args"); } - } catch (IOException e) { - throw new RuntimeException(e); + return !s.isEmpty(); + }).toArray(String[]::new); + String out = ProcessTools.executeTestJvm(safeArgs).getOutput(); + // Handle response. + if ((msgKey != null && out.contains(MSG_MAP.get(msgKey)))) { + System.out.printf("PASS: Expected Result: %s.%n", + MSG_MAP.get(msgKey)); + } else if (out.contains("Exception") || out.contains("Error")) { + System.out.printf("OUTPUT: %s", out); + throw new RuntimeException("FAIL: Unknown Exception occured. " + + "Expected: " + MSG_MAP.get(msgKey)); + } else { + System.out.printf("OUTPUT: %s", out); + throw new RuntimeException("FAIL: Unknown Test case found"); } } /** - * Generate modular/regular jar based on module type for this test. + * Creates Unnamed/modular jar files for TestClient and TestClassLoader. */ - private void generateJar(boolean isService, MODULE_TYPE moduleType, - Path jar, Path compilePath, boolean depends) throws IOException { + private static void setUp() throws Exception { - ModuleDescriptor mDescriptor = null; - if (isService) { - mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG, - S_PKG, S_INTERFACE, S_IMPL, null, M_REQUIRED, depends); - } else { - mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG, - C_PKG, S_INTERFACE, null, S_PKG, M_REQUIRED, depends); + if (ARTIFACT_DIR.toFile().exists()) { + System.out.println("Skipping setup: Artifacts already exists."); + return; } - generateJar(mDescriptor, jar, compilePath); - } + // Generate unnamed provider jar file. + JarUtils.createJarFile(P_JAR, TEST_CLASSES, "p/TestProvider.class"); + // Generate unnamed client jar file. + JarUtils.createJarFile(C_JAR, TEST_CLASSES, "c/TestClient.class"); + // Generate unnamed provider jar files with META-INF descriptor. + generateJar(P_JAR, PD_JAR, null, true); - /** - * Holds Logic for the test. This method will get called with each test - * parameter. - */ - @Override - public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType, - Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath, - String... args) throws Exception { + Builder mBuilder = ModuleDescriptor.newModule("mp").exports("p"); + // Modular provider defined as META-INF service. + generateJar(P_JAR, MPD_JAR, mBuilder.build(), true); + // Modular jar exports package to let the provider type accessible. + generateJar(P_JAR, MP_JAR, mBuilder.build(), false); - OutputAnalyzer output = null; - try { - // For automated/explicit module types, copy the corresponding - // jars to module base folder, which will be considered as - // module base path during execution. - if (!(cModuleType == MODULE_TYPE.UNNAMED - && sModuletype == MODULE_TYPE.UNNAMED)) { - copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH); - copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH); - } + mBuilder = ModuleDescriptor.newModule("mp") + .provides("java.security.Provider", Arrays.asList(P_TYPE)); + // Modular provider Service in module-info does not need to export + // its package. + generateJar(P_JAR, MSP_JAR, mBuilder.build(), false); + // Modular provider Service in module-info also have META-INF descriptor + generateJar(P_JAR, MSPD_JAR, mBuilder.build(), true); - System.out.format("%nExecuting java client with required" - + " custom security provider in class/module path."); - String mName = getModuleName(cModuleType, cJarPath, C_PKG); - Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED - || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null; - String cPath = buildClassPath(cModuleType, cJarPath, sModuletype, - sJarPath); + mBuilder = ModuleDescriptor.newModule("mc").exports("c"); + // Generate modular client jar file to use automatic provider jar. + generateJar(C_JAR, AMC_JAR, mBuilder.build(), false); + // Generate modular client jar file to use modular provider jar. + generateJar(C_JAR, MC_JAR, mBuilder.requires("mp").build(), false); - Map<String, String> vmArgs = getVMArgs(sModuletype, - getModuleName(sModuletype, sJarPath, S_PKG), args); - output = ProcessTools.executeTestJava( - getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs, - args)).outputTo(System.out).errorTo(System.out); - } finally { - // Clean module path to hold required jars for next run. - cleanModuleBasePath(M_BASE_PATH); - } - return output; + mBuilder = ModuleDescriptor.newModule("mc").exports("c") + .uses("java.security.Provider"); + // Generate modular client jar file to use automatic provider service. + generateJar(C_JAR, AMCS_JAR, mBuilder.build(), false); + // Generate modular client jar file using modular provider service. + generateJar(C_JAR, MCS_JAR, mBuilder.requires("mp").build(), false); } /** - * Decide the pre-generated client/service jar path for each test case - * based on client/service module type. + * Update Unnamed jars and include descriptor files. */ - @Override - public Path findJarPath(boolean isService, MODULE_TYPE moduleType, - boolean addMetaDesc, boolean dependsOnServiceModule) { - if (isService) { - if (moduleType == MODULE_TYPE.EXPLICIT) { - if (addMetaDesc) { - return MS_WITH_DESCR_JAR; - } else { - return MS_JAR; - } - } else { - if (addMetaDesc) { - return S_WITH_DESCRIPTOR_JAR; - } else { - return S_JAR; - } + private static void generateJar(Path sjar, Path djar, + ModuleDescriptor mDesc, boolean metaDesc) throws Exception { + + Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING); + Path dir = Files.createTempDirectory("tmp"); + if (metaDesc) { + write(dir.resolve(Paths.get("META-INF", "services", + "java.security.Provider")), P_TYPE); + } + if (mDesc != null) { + Path mi = dir.resolve("module-info.class"); + try (OutputStream out = Files.newOutputStream(mi)) { + ModuleInfoWriter.write(mDesc, out); } - } else { - // Choose corresponding client jar to use dependent module - if (moduleType == MODULE_TYPE.EXPLICIT) { - if (dependsOnServiceModule) { - return MC_JAR; - } else { - return MCN_JAR; - } - } else { - return C_JAR; - } + System.out.format("Added 'module-info.class' in '%s'%n", djar); } + JarUtils.updateJarFile(djar, dir); + } + + /** + * Look for file path in generated jars. + */ + private static Path artifact(String file) { + return ARTIFACT_DIR.resolve(file); + } + + /** + * Convert to absolute file path. + */ + private static String toAbsPath(Path path) { + return path.toFile().getAbsolutePath(); } /** - * VM argument required for the test. + * Create the parent directories if missing to ensure the path exist. */ - private Map<String, String> getVMArgs(MODULE_TYPE sModuletype, - String addModName, String... args) throws IOException { - final Map<String, String> vmArgs = new LinkedHashMap<>(); - vmArgs.put("-Duser.language=", "en"); - vmArgs.put("-Duser.region=", "US"); - if (addModName != null && sModuletype == MODULE_TYPE.AUTO) { - vmArgs.put("--add-modules=", addModName); + private static Path ensurePath(Path at) throws IOException { + Path parent = at.getParent(); + if (parent != null && !parent.toFile().exists()) { + ensurePath(parent); } - // If mechanism selected to find the provider through - // Security.getProvider() then use providerName/ProviderClassName based - // on modular/regular provider jar in security configuration file. - if (args != null && args.length > 0 && SECURITY_PROP.equals(args[0])) { - if (sModuletype == MODULE_TYPE.UNNAMED) { - Files.write(SECURE_PROP_EXTN, ("security.provider.10=" + S_IMPL) - .getBytes()); - } else { - Files.write(SECURE_PROP_EXTN, "security.provider.10=TEST" - .getBytes()); - } - vmArgs.put("-Djava.security.properties=", SECURE_PROP_EXTN.toFile() - .getCanonicalPath()); - } - return vmArgs; + return Files.createDirectories(parent); + } + + /** + * Generates service descriptor inside META-INF folder. + */ + private static void write(Path at, String content) throws IOException { + ensurePath(at); + Files.write(at, content.getBytes("UTF-8")); } + /** + * Create new provider entry through java.security file extension. + * New provider entry will be the last entry inside the JRE. + */ + private static void createJavaSecurityFileExtn(boolean useName) { + int insertAt = Security.getProviders().length + 1; + String provider = (useName ? "TestProvider" : P_TYPE); + try { + Files.write(SEC_FILE, String.format("security.provider.%s=%s", + insertAt, provider).getBytes("UTF-8")); + } catch (IOException e) { + throw new RuntimeException(e); + } + System.out.printf("Security property file created at: %s with value:" + + " %s%n", SEC_FILE, provider); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Provider/TestClient.java Wed Aug 23 09:13:32 2017 -0700 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package c; + +import java.security.Provider; +import java.security.Security; +import java.util.Iterator; +import java.util.ServiceLoader; + +/** + * A Test client using different mechanism to search the custom security + * provider. It uses ClassLoader, ServiceLoader and default mechanism to find + * a provider registered through "java.security" extension file. + */ +public class TestClient { + + public static void main(String[] args) throws Exception { + + Provider p = null; + if (args != null && args.length > 1) { + switch (args[0]) { + case "CL": + p = (Provider) Class.forName(args[1]).newInstance(); + if (Security.addProvider(p) == -1) { + throw new RuntimeException("Failed to add provider"); + } + break; + case "SL": + ServiceLoader<Provider> services + = ServiceLoader.load(java.security.Provider.class); + Iterator<Provider> iterator = services.iterator(); + while (iterator.hasNext()) { + Provider spr = iterator.next(); + if (spr.getName().equals(args[1])) { + p = spr; + if (Security.addProvider(p) == -1) { + throw new RuntimeException( + "Failed to add provider"); + } + break; + } + } + break; + case "SPN": + case "SPT": + p = Security.getProvider(args[1]); + break; + default: + throw new RuntimeException("Invalid argument."); + } + } + if (p == null) { + throw new RuntimeException("Provider TestProvider not found"); + } + System.out.printf("Client: found provider %s", p.getName()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Provider/TestProvider.java Wed Aug 23 09:13:32 2017 -0700 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 2016, 2017 Oracle and/or its affiliates. All rights + * reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package p; + +import java.security.Provider; + +/** + * Custom Security provider for modular test. + */ +public final class TestProvider extends Provider { + + public TestProvider() { + super("TestProvider", "1.0", "Test Security provider"); + System.out.println(String.format("TEST Security provider loaded" + + " successfully : %s", this.toString())); + } + + @Override + public String toString() { + return "TestProvider [getName()=" + getName() + + ", getVersion()=" + getVersionStr() + ", getInfo()=" + + getInfo() + ", toString()=" + super.toString() + "]"; + } +}
--- a/jdk/test/java/security/Provider/TestSecurityProvider.java Tue Aug 22 16:20:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package provider; - -import java.security.Provider; - -/** - * Custom Security provider for modular test. - */ -public final class TestSecurityProvider extends Provider { - - public TestSecurityProvider() { - super("TEST", "1.0", "Test Security provider"); - System.out.println(String.format("TEST Security provider loaded" - + " successfully : %s", this.toString())); - } - - @Override - public String toString() { - return "TestSecurityProvider [getName()=" + getName() - + ", getVersion()=" + getVersionStr() + ", getInfo()=" - + getInfo() + ", toString()=" + super.toString() + "]"; - } - -}
--- a/jdk/test/java/security/Provider/TestSecurityProviderClient.java Tue Aug 22 16:20:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package client; - -import java.security.Provider; -import java.security.Security; -import java.util.Iterator; -import java.util.ServiceLoader; - -/** - * Modular test for client using different mechanism to find the custom security - * provider. It uses ServiceLoader and ClassLoader to find the TEST provider - * available in classPath/modulePath. It also tries to find, if the provider is - * configured through "java.security" file. - */ -public class TestSecurityProviderClient { - - private static final String CUSTOM_PROVIDER_NAME = "TEST"; - private static final String EXCEPTION_MESSAGE - = "Unable to find Test Security Provider"; - private static final String SERVICE_LOADER = "SERVICE_LOADER"; - private static final String CLASS_LOADER = "CLASS_LOADER"; - - public static void main(String[] args) { - Provider provider = null; - //Try to find the TEST provider loaded by ServiceLoader. - if (args != null && args.length > 0 - && SERVICE_LOADER.equals(args[0])) { - System.out.println( - "Using service loader to find Security provider."); - ServiceLoader<Provider> services - = ServiceLoader.load(java.security.Provider.class); - Iterator<Provider> iterator = services.iterator(); - while (iterator.hasNext()) { - Provider p = iterator.next(); - if (p.getName().equals(CUSTOM_PROVIDER_NAME)) { - provider = p; - break; - } - } - } else if (args != null && args.length > 0 - && CLASS_LOADER.equals(args[0])) { - System.out.println("Using class loader to find Security provider."); - //Find the TEST provider loaded by ClassLoader. - provider = new provider.TestSecurityProvider(); - } else { - //Find the TEST provider configured through Security.getProvider(). - System.out.println("Finding Security provider through" - + " Security.getProvider()."); - provider = Security.getProvider(CUSTOM_PROVIDER_NAME); - } - - if (provider != null) { - System.out.format("%nTest Security provider named '%s' loaded " - + "successfully", CUSTOM_PROVIDER_NAME); - } else { - throw new RuntimeException(EXCEPTION_MESSAGE); - } - } -}
--- a/jdk/test/java/security/modules/ModularTest.java Tue Aug 22 16:20:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.IOException; -import java.io.OutputStream; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; -import java.util.Arrays; -import java.util.stream.Collectors; -import java.lang.module.ModuleDescriptor; -import jdk.testlibrary.OutputAnalyzer; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import jdk.internal.module.ModuleInfoWriter; -import static java.lang.module.ModuleDescriptor.Builder; - -/** - * Base class need to be extended by modular test for security. - */ -public abstract class ModularTest { - - /** - * Enum represents all supported module types supported in JDK9. i.e. - * EXPLICIT - Modules have module descriptor(module-info.java) - * defining the module. - * AUTO - Are regular jar files but provided in MODULE_PATH instead - * of CLASS_PATH. - * UNNAMED - Are regular jar but provided through CLASS_PATH. - */ - public enum MODULE_TYPE { - - EXPLICIT, AUTO, UNNAMED; - } - - public static final String SPACE = " "; - public static final Path SRC = Paths.get(System.getProperty("test.src")); - public static final String DESCRIPTOR = "MetaService"; - public static final String MODULAR = "Modular"; - public static final String AUTO = "AutoServiceType"; - public static final String JAR_EXTN = ".jar"; - - /** - * Setup test data for the test. - */ - @DataProvider(name = "TestParams") - public Object[][] setUpTestData() { - return getTestInput(); - } - - /** - * Test method for TestNG. - */ - @Test(dataProvider = "TestParams") - public void runTest(MODULE_TYPE cModuleType, MODULE_TYPE sModuletype, - boolean addMetaDesc, String failureMsgExpected, String[] args) - throws Exception { - - String testName = new StringJoiner("_").add(cModuleType.toString()) - .add(sModuletype.toString()).add( - (addMetaDesc) ? "WITH_SERVICE" : "NO_SERVICE") - .toString(); - - System.out.format("%nStarting Test case: '%s'", testName); - Path cJarPath = findJarPath(false, cModuleType, false, - (sModuletype == MODULE_TYPE.EXPLICIT)); - Path sJarPath = findJarPath(true, sModuletype, addMetaDesc, false); - System.out.format("%nClient jar path : %s ", cJarPath); - System.out.format("%nService jar path : %s ", sJarPath); - OutputAnalyzer output = executeTestClient(cModuleType, cJarPath, - sModuletype, sJarPath, args); - - if (output.getExitValue() != 0) { - if (failureMsgExpected != null - && output.getOutput().contains(failureMsgExpected)) { - System.out.println("PASS: Test is expected to fail here."); - } else { - System.out.format("%nUnexpected failure occured with exit code" - + " '%s'.", output.getExitValue()); - throw new RuntimeException("Unexpected failure occured."); - } - } - } - - /** - * Abstract method need to be implemented by each Test type to provide - * test parameters. - */ - public abstract Object[][] getTestInput(); - - /** - * Execute the test client to access required service. - */ - public abstract OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType, - Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath, - String... args) throws Exception; - - /** - * Find the Jar for service/client based on module type and if service - * descriptor required. - */ - public abstract Path findJarPath(boolean service, MODULE_TYPE moduleType, - boolean addMetaDesc, boolean dependsOnServiceModule); - - /** - * Constructs a Java Command line string based on modular structure followed - * by modular client and service. - */ - public String[] getJavaCommand(Path modulePath, String classPath, - String clientModuleName, String mainClass, - Map<String, String> vmArgs, String... options) throws IOException { - - final StringJoiner command = new StringJoiner(SPACE, SPACE, SPACE); - vmArgs.forEach((key, value) -> command.add(key + value)); - if (modulePath != null) { - command.add("--module-path").add(modulePath.toFile().getCanonicalPath()); - } - if (classPath != null && classPath.length() > 0) { - command.add("-cp").add(classPath); - } - if (clientModuleName != null && clientModuleName.length() > 0) { - command.add("-m").add(clientModuleName + "/" + mainClass); - } else { - command.add(mainClass); - } - command.add(Arrays.stream(options).collect(Collectors.joining(SPACE))); - return command.toString().trim().split("[\\s]+"); - } - - /** - * Generate ModuleDescriptor object for explicit/auto based client/Service - * modules type. - */ - public ModuleDescriptor generateModuleDescriptor(boolean isService, - MODULE_TYPE moduleType, String moduleName, String pkg, - String serviceInterface, String serviceImpl, - String serviceModuleName, List<String> requiredModules, - boolean depends) { - - final Builder builder; - if (moduleType == MODULE_TYPE.EXPLICIT) { - System.out.format(" %nGenerating ModuleDescriptor object"); - builder = ModuleDescriptor.newModule(moduleName).exports(pkg); - if (isService && serviceInterface != null && serviceImpl != null) { - builder.provides(serviceInterface, List.of(serviceImpl)); - } else { - if (serviceInterface != null) { - builder.uses(serviceInterface); - } - if (depends) { - builder.requires(serviceModuleName); - } - } - } else { - System.out.format(" %nModuleDescriptor object not required."); - return null; - } - requiredModules.stream().forEach(reqMod -> builder.requires(reqMod)); - return builder.build(); - } - - /** - * Generates service descriptor inside META-INF folder. - */ - public boolean createMetaInfServiceDescriptor( - Path serviceDescriptorFile, String serviceImpl) { - boolean created = true; - System.out.format("%nCreating META-INF service descriptor for '%s' " - + "at path '%s'", serviceImpl, serviceDescriptorFile); - try { - Path parent = serviceDescriptorFile.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - Files.write(serviceDescriptorFile, serviceImpl.getBytes("UTF-8")); - System.out.println( - "META-INF service descriptor generated successfully"); - } catch (IOException e) { - e.printStackTrace(System.out); - created = false; - } - return created; - } - - /** - * Generate modular/regular jar file. - */ - public void generateJar(ModuleDescriptor mDescriptor, Path jar, - Path compilePath) throws IOException { - System.out.format("%nCreating jar file '%s'", jar); - JarUtils.createJarFile(jar, compilePath); - if (mDescriptor != null) { - Path dir = Files.createTempDirectory("tmp"); - Path mi = dir.resolve("module-info.class"); - try (OutputStream out = Files.newOutputStream(mi)) { - ModuleInfoWriter.write(mDescriptor, out); - } - System.out.format("%nAdding 'module-info.class' to jar '%s'", jar); - JarUtils.updateJarFile(jar, dir); - } - } - - /** - * Copy pre-generated jar files to the module base path. - */ - public void copyJarsToModuleBase(MODULE_TYPE moduleType, Path jar, - Path mBasePath) throws IOException { - if (mBasePath != null) { - Files.createDirectories(mBasePath); - } - if (moduleType != MODULE_TYPE.UNNAMED) { - Path artifactName = mBasePath.resolve(jar.getFileName()); - System.out.format("%nCopy jar path: '%s' to module base path: %s", - jar, artifactName); - Files.copy(jar, artifactName); - } - } - - /** - * Construct class path string. - */ - public String buildClassPath(MODULE_TYPE cModuleType, - Path cJarPath, MODULE_TYPE sModuletype, - Path sJarPath) throws IOException { - StringJoiner classPath = new StringJoiner(File.pathSeparator); - classPath.add((cModuleType == MODULE_TYPE.UNNAMED) - ? cJarPath.toFile().getCanonicalPath() : ""); - classPath.add((sModuletype == MODULE_TYPE.UNNAMED) - ? sJarPath.toFile().getCanonicalPath() : ""); - return classPath.toString(); - } - - /** - * Construct executable module name for java. It is fixed for explicit - * module type while it is same as jar file name for automated module type. - */ - public String getModuleName(MODULE_TYPE moduleType, - Path jarPath, String mName) { - String jarName = jarPath.toFile().getName(); - return (moduleType == MODULE_TYPE.EXPLICIT) ? mName - : ((moduleType == MODULE_TYPE.AUTO) ? jarName.substring(0, - jarName.indexOf(JAR_EXTN)) : null); - } - - /** - * Delete all the files inside the base module path. - */ - public void cleanModuleBasePath(Path mBasePath) { - Arrays.asList(mBasePath.toFile().listFiles()).forEach(f -> { - System.out.println("delete: " + f); - f.delete(); - }); - } - -}
--- a/jdk/test/javax/security/auth/login/modules/JaasClient.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/javax/security/auth/login/modules/JaasClient.java Wed Aug 23 09:13:32 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginContext; -import com.sun.security.auth.UnixPrincipal; +import com.sun.security.auth.UserPrincipal; /** * JAAS client which will try to authenticate a user through a custom JAAS LOGIN @@ -71,13 +71,13 @@ return; } for (Principal p : loginContext.getSubject().getPrincipals()) { - if (p instanceof UnixPrincipal + if (p instanceof UserPrincipal && USER_NAME.equals(p.getName())) { //Proper principal was found, return. return; } } - throw new RuntimeException("Test failed. UnixPrincipal " + throw new RuntimeException("Test failed. UserPrincipal " + USER_NAME + " expected."); }
--- a/jdk/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java Wed Aug 23 09:13:32 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ import java.security.Principal; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import com.sun.security.auth.UnixPrincipal; +import com.sun.security.auth.UserPrincipal; public class JaasClientWithDefaultHandler { @@ -61,13 +61,13 @@ return; } for (Principal p : loginContext.getSubject().getPrincipals()) { - if (p instanceof UnixPrincipal + if (p instanceof UserPrincipal && USER_NAME.equals(p.getName())) { //Proper principal was found, return. return; } } - throw new RuntimeException("Test failed. UnixPrincipal " + throw new RuntimeException("Test failed. UserPrincipal " + USER_NAME + " expected."); }
--- a/jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java Wed Aug 23 09:13:32 2017 -0700 @@ -21,280 +21,252 @@ * questions. */ +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.LinkedHashMap; +import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Arrays; -import java.io.IOException; +import java.io.File; +import java.io.OutputStream; import java.lang.module.ModuleDescriptor; -import java.util.ArrayList; -import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.OutputAnalyzer; -import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; +import java.lang.module.ModuleDescriptor.Builder; +import jdk.internal.module.ModuleInfoWriter; +import java.util.stream.Stream; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; -/** - * @test - * @bug 8078813 - * @library /lib/testlibrary /test/lib - * @library /java/security/modules - * @build jdk.test.lib.compiler.CompilerUtils JarUtils - * @summary Test custom JAAS module with all possible modular option. The test - * includes different combination of JAAS client/login modules - * interaction with or without service description. - * @run testng JaasModularClientTest - */ -public class JaasModularClientTest extends ModularTest { - - private static final Path S_SRC = SRC.resolve("TestLoginModule.java"); - private static final String S_PKG = "login"; - private static final String S_JAR_NAME = S_PKG + JAR_EXTN; - private static final String S_DESCR_JAR_NAME = S_PKG + DESCRIPTOR - + JAR_EXTN; - private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN; - private static final String MS_DESCR_JAR_NAME = MODULAR + S_PKG + DESCRIPTOR - + JAR_EXTN; - private static final Path C_SRC = SRC.resolve("JaasClient.java"); - private static final String C_PKG = "client"; - private static final String C_JAR_NAME = C_PKG + JAR_EXTN; - private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN; - private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN; - - private static final Path BUILD_DIR = Paths.get(".").resolve("build"); - private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); - private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG); - private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve( - S_PKG + DESCRIPTOR); - private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG); - private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase"); - private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); +/* + * @test + * @bug 8078813 8183310 + * @summary Test custom JAAS login module with all possible modular option. + * @library /lib/testlibrary /test/lib + * @modules java.base/jdk.internal.module + * @build JarUtils + * @build TestLoginModule JaasClient + * @run main JaasModularClientTest false + * @run main JaasModularClientTest true + */ +public class JaasModularClientTest { - private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG); - private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME); - private static final Path S_WITH_DESCRIPTOR_JAR = S_ARTIFACTS_DIR.resolve( - S_DESCR_JAR_NAME); - private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME); - private static final Path MS_WITH_DESCR_JAR = S_ARTIFACTS_DIR.resolve( - MS_DESCR_JAR_NAME); - - private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG); - private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME); - private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME); - private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME); - - private static final String MAIN = C_PKG + ".JaasClient"; - private static final String S_INTERFACE - = "javax.security.auth.spi.LoginModule"; - private static final String S_IMPL = S_PKG + ".TestLoginModule"; - private static final List<String> M_REQUIRED = Arrays.asList("java.base", - "jdk.security.auth"); - private static final Path META_DESCR_PATH = Paths.get("META-INF") - .resolve("services").resolve(S_INTERFACE); - private static final Path S_META_DESCR_FPATH = S_WITH_META_DESCR_BUILD_DIR - .resolve(META_DESCR_PATH); - - private static final boolean WITH_S_DESCR = true; - private static final boolean WITHOUT_S_DESCR = false; - private static final String NO_FAILURE = null; + private static final Path SRC = Paths.get(System.getProperty("test.src")); + private static final Path TEST_CLASSES + = Paths.get(System.getProperty("test.classes")); + private static final Path ARTIFACT_DIR = Paths.get("jars"); + private static final String PS = File.pathSeparator; + private static final String L_TYPE = "login.TestLoginModule"; + private static final String C_TYPE = "client.JaasClient"; /** - * Generates Test specific input parameters. + * Here is the naming convention followed. + * l.jar - Unnamed login module jar. + * ml.jar - Modular login module jar. + * msl.jar - Modular login module jar provides login module service + * through module-info + * c.jar - Unnamed client jar. + * mc.jar - Modular client jar. + * mcs.jar - Modular client jar uses login module service through + * module-info. + * amc.jar - Modular client used for automatic login module jar. + * amcs.jar - Modular client used for automatic login module jar and uses + * login module service through module-info. */ - @Override - public Object[][] getTestInput() { + private static final Path L_JAR = artifact("l.jar"); + private static final Path ML_JAR = artifact("ml.jar"); + private static final Path MSL_JAR = artifact("msl.jar"); + private static final Path C_JAR = artifact("c.jar"); + private static final Path MC_JAR = artifact("mc.jar"); + private static final Path MCS_JAR = artifact("mcs.jar"); + private static final Path AMC_JAR = artifact("amc.jar"); + private static final Path AMCS_JAR = artifact("amcs.jar"); - List<List<Object>> params = new ArrayList<>(); - String[] args = new String[]{}; - // PARAMETER ORDERS - - // Client Module Type, Service Module Type, - // If Service META descriptor Required, - // Expected Failure message, Client arguments - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, NO_FAILURE, args)); + private final String unnL; + private final String modL; + private final String unnC; + private final String modC; + private final String autoMC; + // Common set of VM arguments used in all test cases + private final List<String> commonArgs; + + public JaasModularClientTest(boolean service) { + + System.out.printf("%n*** Login Module defined as service in " + + "module-info: %s ***%n%n", service); + List<String> argList = new LinkedList<>(); + argList.add("-Djava.security.auth.login.config=" + + toAbsPath(SRC.resolve("jaas.conf"))); + commonArgs = Collections.unmodifiableList(argList); + + // Based on Testcase, select unnamed/modular jar files to use. + unnL = toAbsPath(L_JAR); + modL = toAbsPath(service ? MSL_JAR : ML_JAR); + unnC = toAbsPath(C_JAR); + modC = toAbsPath(service ? MCS_JAR : MC_JAR); + autoMC = toAbsPath(service ? AMCS_JAR : AMC_JAR); + } - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, NO_FAILURE, args)); + /* + * Test cases are based on the following logic, + * for (definedAs : {"Service in module-info", "Class Type"}) { + * for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * for (loginModuleType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * Create and run java command for each possible case + * } + * } + * } + */ + public static void main(String[] args) throws Exception { + + // Generates unnamed and modular jars. + setUp(); + boolean service = Boolean.valueOf(args[0]); + JaasModularClientTest test = new JaasModularClientTest(service); + test.process(); + } + + private void process() throws Exception { - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, - WITHOUT_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, - WITH_S_DESCR, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, - WITHOUT_S_DESCR, NO_FAILURE, args)); - return params.stream().map(p -> p.toArray()).toArray(Object[][]::new); + // Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED + System.out.println("Case: Modular Client and Modular Login module."); + execute(String.format("--module-path %s%s%s -m mc/%s", + modC, PS, modL, C_TYPE)); + System.out.println("Case: Modular Client and automatic Login module."); + execute(String.format("--module-path %s%s%s --add-modules=l -m mc/%s", + autoMC, PS, unnL, C_TYPE)); + System.out.println("Case: Modular Client and unnamed Login module."); + execute(String.format("--module-path %s -cp %s -m mc/%s", autoMC, + unnL, C_TYPE)); + + // Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED + System.out.println("Case: Automatic Client and modular Login module."); + execute(String.format("--module-path %s%s%s --add-modules=ml -m c/%s", + unnC, PS, modL, C_TYPE)); + System.out.println("Case: Automatic Client and automatic Login module"); + execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s", + unnC, PS, unnL, C_TYPE)); + System.out.println("Case: Automatic Client and unnamed Login module."); + execute(String.format("--module-path %s -cp %s -m c/%s", unnC, + unnL, C_TYPE)); + + // Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED + System.out.println("Case: Unnamed Client and modular Login module."); + execute(String.format("-cp %s --module-path %s --add-modules=ml %s", + unnC, modL, C_TYPE)); + System.out.println("Case: Unnamed Client and automatic Login module."); + execute(String.format("-cp %s --module-path %s --add-modules=l %s", + unnC, unnL, C_TYPE)); + System.out.println("Case: Unnamed Client and unnamed Login module."); + execute(String.format("-cp %s%s%s %s", unnC, PS, unnL, C_TYPE)); + + // Case: unnamed jars in --module-path and modular jars in -cp. + System.out.println( + "Case: Unnamed Client and Login module from modulepath."); + execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s", + unnC, PS, unnL, C_TYPE)); + System.out.println( + "Case: Modular Client and Login module in classpath."); + execute(String.format("-cp %s%s%s %s", modC, PS, modL, C_TYPE)); } /** - * Pre-compile and generate the artifacts required to run this test before - * running each test cases. + * Execute with command arguments and process the result. */ - @BeforeTest - public void buildArtifacts() { + private void execute(String args) throws Exception { - boolean done = true; - try { - done = CompilerUtils.compile(S_SRC, S_BUILD_DIR); - done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR); - done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL); - // Generate modular/regular jars with(out) META-INF - // service descriptor - generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR, - S_WITH_META_DESCR_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR, - S_WITH_META_DESCR_BUILD_DIR, false); - // Compile client source codes. - done &= CompilerUtils.compile(C_SRC, C_BLD_DIR); - // Generate modular client jar with explicit dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true); - // Generate modular client jar without any dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false); - // Generate regular client jar - generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false); - System.out.format("%nArtifacts generated successfully? %s", done); - if (!done) { - throw new RuntimeException("Artifact generation failed"); + String[] safeArgs = Stream.concat(commonArgs.stream(), + Stream.of(args.split("\\s+"))).filter(s -> { + if (s.contains(" ")) { + throw new RuntimeException("No spaces in args"); } - } catch (IOException e) { - throw new RuntimeException(e); + return !s.isEmpty(); + }).toArray(String[]::new); + OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + // Handle response. + if (out.getExitValue() != 0) { + System.out.printf("OUTPUT: %s", out.getOutput()); + throw new RuntimeException("FAIL: Unknown failure occured."); + } else { + System.out.println("Passed."); } } /** - * Generate modular/regular jar based on module type for this test. + * Creates Unnamed/modular jar files for TestClient and TestClassLoader. */ - private void generateJar(boolean isService, MODULE_TYPE moduleType, - Path jar, Path compilePath, boolean depends) throws IOException { + private static void setUp() throws Exception { + + if (ARTIFACT_DIR.toFile().exists()) { + System.out.println("Skipping setup: Artifacts already exists."); + return; + } + // Generate unnamed login module jar file. + JarUtils.createJarFile(L_JAR, TEST_CLASSES, + "login/TestLoginModule.class"); + // Generate unnamed client jar. + JarUtils.createJarFile(C_JAR, TEST_CLASSES, "client/JaasClient.class", + "client/JaasClient$MyCallbackHandler.class"); + + Builder mBuilder = ModuleDescriptor.newModule("ml") + .requires("jdk.security.auth"); + // Modular jar exports package to let the login module type accessible. + generateJar(L_JAR, ML_JAR, mBuilder.exports("login").build()); - ModuleDescriptor mDescriptor = null; - if (isService) { - mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG, - S_PKG, S_INTERFACE, S_IMPL, null, M_REQUIRED, depends); - } else { - mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG, - C_PKG, S_INTERFACE, null, S_PKG, M_REQUIRED, depends); - } - generateJar(mDescriptor, jar, compilePath); + mBuilder = ModuleDescriptor.newModule("ml") + .requires("jdk.security.auth") + .provides("javax.security.auth.spi.LoginModule", + Arrays.asList(L_TYPE)); + // Modular login module as Service in module-info does not need to + // export service package. + generateJar(L_JAR, MSL_JAR, mBuilder.build()); + + mBuilder = ModuleDescriptor.newModule("mc").exports("client") + .requires("jdk.security.auth"); + // Generate modular client jar to use automatic login module jar. + generateJar(C_JAR, AMC_JAR, mBuilder.build()); + // Generate modular client jar to use modular login module jar. + generateJar(C_JAR, MC_JAR, mBuilder.requires("ml").build()); + + mBuilder = ModuleDescriptor.newModule("mc").exports("client") + .requires("jdk.security.auth") + .uses("javax.security.auth.spi.LoginModule"); + // Generate modular client jar to use automatic login module service. + generateJar(C_JAR, AMCS_JAR, mBuilder.build()); + // Generate modular client jar using modular login module service. + generateJar(C_JAR, MCS_JAR, mBuilder.requires("ml").build()); } /** - * Holds Logic for the test client. This method will get called with each - * test parameter. + * Update Unnamed jars and include module descriptor files. */ - @Override - public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType, - Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath, - String... args) throws Exception { + private static void generateJar(Path sjar, Path djar, + ModuleDescriptor mDesc) throws Exception { - OutputAnalyzer output = null; - try { - // For automated/explicit module types, copy the corresponding - // jars to module base folder, which will be considered as - // module base path during execution. - if (!(cModuleType == MODULE_TYPE.UNNAMED - && sModuletype == MODULE_TYPE.UNNAMED)) { - copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH); - copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH); + Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING); + Path dir = Files.createTempDirectory("tmp"); + if (mDesc != null) { + Path mi = dir.resolve("module-info.class"); + try (OutputStream out = Files.newOutputStream(mi)) { + ModuleInfoWriter.write(mDesc, out); } - - System.out.format("%nExecuting java client with required" - + " custom service in class/module path."); - String mName = getModuleName(cModuleType, cJarPath, C_PKG); - Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED - || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null; - String cPath = buildClassPath(cModuleType, cJarPath, sModuletype, - sJarPath); - Map<String, String> vmArgs = getVMArgs(sModuletype, - getModuleName(sModuletype, sJarPath, S_PKG)); - output = ProcessTools.executeTestJava( - getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs, - args)).outputTo(System.out).errorTo(System.out); - } finally { - // Clean module path to hold required jars for next run. - cleanModuleBasePath(M_BASE_PATH); + System.out.format("Added 'module-info.class' in '%s'%n", djar); } - return output; + JarUtils.updateJarFile(djar, dir); } /** - * Decide the pre-generated client/service jar path for each test case - * based on client/service module type. + * Look for file path in generated jars. */ - @Override - public Path findJarPath(boolean isService, MODULE_TYPE moduleType, - boolean addMetaDesc, boolean dependsOnServiceModule) { - if (isService) { - if (moduleType == MODULE_TYPE.EXPLICIT) { - if (addMetaDesc) { - return MS_WITH_DESCR_JAR; - } else { - return MS_JAR; - } - } else { - if (addMetaDesc) { - return S_WITH_DESCRIPTOR_JAR; - } else { - return S_JAR; - } - } - } else { - // Choose corresponding client jar using dependent module - if (moduleType == MODULE_TYPE.EXPLICIT) { - if (dependsOnServiceModule) { - return MC_JAR; - } else { - return MCN_JAR; - } - } else { - return C_JAR; - } - } + private static Path artifact(String file) { + return ARTIFACT_DIR.resolve(file); } /** - * VM argument required for the test. + * Convert to absolute file path. */ - private Map<String, String> getVMArgs(MODULE_TYPE sModuletype, - String addModName) throws IOException { - final Map<String, String> vmArgs = new LinkedHashMap<>(); - vmArgs.put("-Duser.language=", "en"); - vmArgs.put("-Duser.region=", "US"); - vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve( - "jaas.conf").toFile().getCanonicalPath()); - if (addModName != null && sModuletype == MODULE_TYPE.AUTO) { - vmArgs.put("--add-modules ", addModName); - } - return vmArgs; + private static String toAbsPath(Path path) { + return path.toFile().getAbsolutePath(); } - }
--- a/jdk/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java Wed Aug 23 09:13:32 2017 -0700 @@ -21,236 +21,219 @@ * questions. */ +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.LinkedHashMap; +import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.Arrays; -import java.io.IOException; +import java.io.File; +import java.io.OutputStream; import java.lang.module.ModuleDescriptor; -import java.util.ArrayList; -import jdk.test.lib.compiler.CompilerUtils; -import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.OutputAnalyzer; -import org.testng.annotations.BeforeTest; - -/** - * @test - * @bug 8151654 - * @library /lib/testlibrary /test/lib - * @library /java/security/modules - * @build jdk.test.lib.compiler.CompilerUtils JarUtils - * @summary Test custom JAAS callback handler with all possible modular option. - * @run testng JaasModularDefaultHandlerTest - */ -public class JaasModularDefaultHandlerTest extends ModularTest { - - private static final Path S_SRC = SRC.resolve("TestCallbackHandler.java"); - private static final String MODULAR = "M"; - private static final String S_PKG = "handler"; - private static final String S_JAR_NAME = S_PKG + JAR_EXTN; - private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN; - private static final String HANDLER = S_PKG + ".TestCallbackHandler"; +import java.lang.module.ModuleDescriptor.Builder; +import jdk.internal.module.ModuleInfoWriter; +import java.util.stream.Stream; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; - private static final Path C_SRC - = SRC.resolve("JaasClientWithDefaultHandler.java"); - private static final Path CL_SRC = SRC.resolve("TestLoginModule.java"); - private static final String C_PKG = "login"; - private static final String C_JAR_NAME = C_PKG + JAR_EXTN; - private static final String MCN_JAR_NAME - = MODULAR + C_PKG + "NoMUse" + JAR_EXTN; - private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN; - - private static final Path BUILD_DIR = Paths.get(".").resolve("build"); - private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin"); - private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG); - private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG); - private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase"); - private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts"); +/* + * @test + * @bug 8151654 8183310 + * @summary Test default callback handler with all possible modular option. + * @library /lib/testlibrary /test/lib + * @modules java.base/jdk.internal.module + * @build JarUtils + * @build TestCallbackHandler TestLoginModule JaasClientWithDefaultHandler + * @run main JaasModularDefaultHandlerTest + */ +public class JaasModularDefaultHandlerTest { - private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG); - private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME); - private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME); - - private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG); - private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME); - private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME); - private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME); - - private static final String MAIN = C_PKG + ".JaasClientWithDefaultHandler"; - private static final List<String> M_REQUIRED = Arrays.asList("java.base", - "jdk.security.auth"); - - private static final String CLASS_NOT_FOUND_MSG - = "java.lang.ClassNotFoundException: handler.TestCallbackHandler"; - private static final String NO_FAILURE = null; + private static final Path SRC = Paths.get(System.getProperty("test.src")); + private static final Path TEST_CLASSES + = Paths.get(System.getProperty("test.classes")); + private static final Path ARTIFACT_DIR = Paths.get("jars"); + private static final String PS = File.pathSeparator; + private static final String H_TYPE = "handler.TestCallbackHandler"; + private static final String C_TYPE = "login.JaasClientWithDefaultHandler"; /** - * Generates Test specific input parameters. + * Here is the naming convention followed for each jar. + * h.jar - Unnamed handler jar. + * mh.jar - Modular handler jar. + * c.jar - Unnamed client jar. + * mc.jar - Modular client jar. + * amc.jar - Modular client used for automatic handler jar. */ - @Override - public Object[][] getTestInput() { + private static final Path H_JAR = artifact("h.jar"); + private static final Path MH_JAR = artifact("mh.jar"); + private static final Path C_JAR = artifact("c.jar"); + private static final Path MC_JAR = artifact("mc.jar"); + private static final Path AMC_JAR = artifact("amc.jar"); + + private final String unnH; + private final String modH; + private final String unnC; + private final String modC; + private final String autoMC; + // Common set of VM arguments used in all test cases + private final List<String> commonArgs; + + public JaasModularDefaultHandlerTest() { + + List<String> argList = new LinkedList<>(); + argList.add("-Djava.security.auth.login.config=" + + toAbsPath(SRC.resolve("jaas.conf"))); + commonArgs = Collections.unmodifiableList(argList); + + // Based on Testcase, select unnamed/modular jar files to use. + unnH = toAbsPath(H_JAR); + modH = toAbsPath(MH_JAR); + unnC = toAbsPath(C_JAR); + modC = toAbsPath(MC_JAR); + autoMC = toAbsPath(AMC_JAR); + } + + /* + * Test cases are based on the following logic, + * for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * for (handlerType : {"NAMED", "AUTOMATIC", "UNNAMED"}) { + * Create and run java command for each possible case + * } + * } + */ + public static void main(String[] args) throws Exception { - List<List<Object>> params = new ArrayList<>(); - String[] args = new String[]{HANDLER}; - // PARAMETER ORDERS - - // Client Module Type, Service Module Type, - // Service META Descriptor Required, - // Expected Failure message, Client arguments - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED, - false, NO_FAILURE, args)); + // Generates unnamed and modular jars. + setUp(); + JaasModularDefaultHandlerTest jt = new JaasModularDefaultHandlerTest(); + jt.process(); + } + + private void process() throws Exception { + + // Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED + System.out.println("Case: Modular Client and Modular Handler"); + execute(String.format("--module-path %s%s%s -m mc/%s %s", + modC, PS, modH, C_TYPE, H_TYPE)); + System.out.println("Case: Modular Client and automatic Handler"); + execute(String.format("--module-path %s%s%s --add-modules=h -m mc/%s %s", + autoMC, PS, unnH, C_TYPE, H_TYPE)); + System.out.println("Case: Modular Client and unnamed Handler"); + execute(String.format("--module-path %s -cp %s -m mc/%s %s", autoMC, + unnH, C_TYPE, H_TYPE)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED, - false, NO_FAILURE, args)); + // Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED + System.out.println("Case: Automatic Client and modular Handler"); + execute(String.format("--module-path %s%s%s --add-modules=mh -m c/%s %s", + unnC, PS, modH, C_TYPE, H_TYPE)); + System.out.println("Case: Automatic Client and automatic Handler"); + execute(String.format("--module-path %s%s%s --add-modules=h -m c/%s %s", + unnC, PS, unnH, C_TYPE, H_TYPE)); + System.out.println("Case: Automatic Client and unnamed Handler"); + execute(String.format("--module-path %s -cp %s -m c/%s %s", unnC, + unnH, C_TYPE, H_TYPE)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO, - false, NO_FAILURE, args)); - params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED, - false, NO_FAILURE, args)); - return params.stream().map(p -> p.toArray()).toArray(Object[][]::new); + // Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED + System.out.println("Case: Unnamed Client and modular Handler"); + execute(String.format("-cp %s --module-path %s --add-modules=mh %s %s", + unnC, modH, C_TYPE, H_TYPE)); + System.out.println("Case: Unnamed Client and automatic Handler"); + execute(String.format("-cp %s --module-path %s --add-modules=h %s %s", + unnC, unnH, C_TYPE, H_TYPE)); + System.out.println("Case: Unnamed Client and unnamed Handler"); + execute(String.format("-cp %s%s%s %s %s", unnC, PS, unnH, C_TYPE, + H_TYPE)); + + // Case: unnamed jars in --module-path and modular jars in -cp. + System.out.println("Case: Unnamed Client and Handler in modulepath"); + execute(String.format("--module-path %s%s%s --add-modules=h -m c/%s %s", + unnC, PS, unnH, C_TYPE, H_TYPE)); + System.out.println("Case: Modular Client and Provider in classpath"); + execute(String.format("-cp %s%s%s %s %s", + modC, PS, modH, C_TYPE, H_TYPE)); } /** - * Pre-compile and generate the artifacts required to run this test before - * running each test cases. + * Execute with command arguments and process the result. */ - @BeforeTest - public void buildArtifacts() { + private void execute(String args) throws Exception { - boolean done = true; - try { - done = CompilerUtils.compile(S_SRC, S_BUILD_DIR); - // Generate modular/regular handler jars. - generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false); - generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false); - // Compile client source codes. - done &= CompilerUtils.compile(C_SRC, C_BLD_DIR); - done &= CompilerUtils.compile(CL_SRC, C_BLD_DIR); - // Generate modular client jar with explicit dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true); - // Generate modular client jar without any dependency - generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false); - // Generate regular client jar - generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false); - System.out.format("%nArtifacts generated successfully? %s", done); - if (!done) { - throw new RuntimeException("Artifact generation failed"); + String[] safeArgs = Stream.concat(commonArgs.stream(), + Stream.of(args.split("\\s+"))).filter(s -> { + if (s.contains(" ")) { + throw new RuntimeException("No spaces in args"); } - } catch (IOException e) { - throw new RuntimeException(e); + return !s.isEmpty(); + }).toArray(String[]::new); + OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs); + // Handle response. + if (out.getExitValue() != 0) { + System.out.printf("OUTPUT: %s", out.getOutput()); + throw new RuntimeException("FAIL: Unknown failure occured."); + } else { + System.out.println("Passed."); } } /** - * Generate modular/regular jar based on module type for this test. + * Creates Unnamed/modular jar files for TestClient and TestClassLoader. */ - private void generateJar(boolean isService, MODULE_TYPE moduleType, - Path jar, Path compilePath, boolean depends) throws IOException { + private static void setUp() throws Exception { - ModuleDescriptor mDescriptor = null; - if (isService) { - mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG, - S_PKG, null, null, null, M_REQUIRED, depends); - } else { - mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG, - C_PKG, null, null, S_PKG, M_REQUIRED, depends); + if (ARTIFACT_DIR.toFile().exists()) { + System.out.println("Skipping setup: Artifacts already exists."); + return; } - generateJar(mDescriptor, jar, compilePath); + // Generate unnamed handler jar file. + JarUtils.createJarFile(H_JAR, TEST_CLASSES, + "handler/TestCallbackHandler.class"); + // Generate unnamed client jar file. + JarUtils.createJarFile(C_JAR, TEST_CLASSES, + "login/TestLoginModule.class", + "login/JaasClientWithDefaultHandler.class"); + + Builder mBuilder = ModuleDescriptor.newModule("mh"); + // Modular jar exports package to let the handler type accessible. + generateJar(H_JAR, MH_JAR, mBuilder.exports("handler").build()); + + mBuilder = ModuleDescriptor.newModule("mc").exports("login") + .requires("jdk.security.auth"); + // Generate modular client jar file to use automatic handler jar. + generateJar(C_JAR, AMC_JAR, mBuilder.build()); + // Generate modular client jar file to use modular handler jar. + generateJar(C_JAR, MC_JAR, mBuilder.requires("mh").build()); } /** - * Holds Logic for the test client. This method will get called with each - * test parameter. + * Update Unnamed jars and include module descriptor files. */ - @Override - public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType, - Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath, - String... args) throws Exception { + private static void generateJar(Path sjar, Path djar, + ModuleDescriptor mDesc) throws Exception { - OutputAnalyzer output = null; - try { - // For automated/explicit module types, copy the corresponding - // jars to module base folder, which will be considered as - // module base path during execution. - if (!(cModuleType == MODULE_TYPE.UNNAMED - && sModuletype == MODULE_TYPE.UNNAMED)) { - copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH); - copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH); + Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING); + Path dir = Files.createTempDirectory("tmp"); + if (mDesc != null) { + Path mi = dir.resolve("module-info.class"); + try (OutputStream out = Files.newOutputStream(mi)) { + ModuleInfoWriter.write(mDesc, out); } - - System.out.format("%nExecuting java client with required" - + " custom service in class/module path."); - String mName = getModuleName(cModuleType, cJarPath, C_PKG); - Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED - || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null; - String cPath = buildClassPath(cModuleType, cJarPath, sModuletype, - sJarPath); - Map<String, String> vmArgs = getVMArgs(sModuletype, cModuleType, - getModuleName(sModuletype, sJarPath, S_PKG)); - output = ProcessTools.executeTestJava( - getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs, - args)).outputTo(System.out).errorTo(System.out); - } finally { - // Clean module path to hold required jars for next run. - cleanModuleBasePath(M_BASE_PATH); + System.out.format("Added 'module-info.class' in '%s'%n", djar); } - return output; + JarUtils.updateJarFile(djar, dir); } /** - * Decide the pre-generated client/service jar path for each test case - * based on client/service module type. + * Look for file path in generated jars. */ - @Override - public Path findJarPath(boolean depends, MODULE_TYPE moduleType, - boolean addMetaDesc, boolean dependsOnServiceModule) { - if (depends) { - if (moduleType == MODULE_TYPE.EXPLICIT) { - return MS_JAR; - } else { - return S_JAR; - } - } else { - // Choose corresponding client jar using dependent module - if (moduleType == MODULE_TYPE.EXPLICIT) { - if (dependsOnServiceModule) { - return MC_JAR; - } else { - return MCN_JAR; - } - } else { - return C_JAR; - } - } + private static Path artifact(String file) { + return ARTIFACT_DIR.resolve(file); } /** - * VM argument required for the test. + * Convert to absolute file path. */ - private Map<String, String> getVMArgs(MODULE_TYPE sModuletype, - MODULE_TYPE cModuleType, String addModName) throws IOException { - final Map<String, String> vmArgs = new LinkedHashMap<>(); - vmArgs.put("-Duser.language=", "en"); - vmArgs.put("-Duser.region=", "US"); - vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve( - "jaas.conf").toFile().getCanonicalPath()); - if (addModName != null - && !(cModuleType == MODULE_TYPE.EXPLICIT - && sModuletype == MODULE_TYPE.EXPLICIT)) { - vmArgs.put("--add-modules=", addModName); - } - return vmArgs; + private static String toAbsPath(Path path) { + return path.toFile().getAbsolutePath(); } - }
--- a/jdk/test/javax/security/auth/login/modules/TEST.properties Tue Aug 22 16:20:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -modules java.base/jdk.internal.module
--- a/jdk/test/javax/security/auth/login/modules/TestLoginModule.java Tue Aug 22 16:20:29 2017 +0200 +++ b/jdk/test/javax/security/auth/login/modules/TestLoginModule.java Wed Aug 23 09:13:32 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import com.sun.security.auth.UnixPrincipal; +import com.sun.security.auth.UserPrincipal; /** * Custom JAAS login module which will be loaded through Java LoginContext when @@ -44,7 +44,7 @@ private static final String PASSWORD = "testPassword"; private Subject subject; private CallbackHandler callbackHandler; - private UnixPrincipal userPrincipal; + private UserPrincipal userPrincipal; private String username; private String password; private boolean succeeded = false; @@ -99,7 +99,7 @@ if (succeeded == false) { return false; } - userPrincipal = new UnixPrincipal(username); + userPrincipal = new UserPrincipal(username); if (!subject.getPrincipals().contains(userPrincipal)) { subject.getPrincipals().add(userPrincipal); }