blob: 887b5ece77f794316ca5ae2420d9d16aecd97fa1 [file] [log] [blame]
/*
* 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
* 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.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.io.File;
import java.io.OutputStream;
import java.lang.module.ModuleDescriptor;
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 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 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";
/**
* 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.
*/
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 {
// 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));
// 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));
// 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));
}
/**
* Execute with command arguments and process the result.
*/
private void execute(String args) throws Exception {
String[] safeArgs = Stream.concat(commonArgs.stream(),
Stream.of(args.split("\\s+"))).filter(s -> {
if (s.contains(" ")) {
throw new RuntimeException("No spaces in args");
}
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.");
}
}
/**
* Creates Unnamed/modular jar files for TestClient and TestClassLoader.
*/
private static void setUp() throws Exception {
if (ARTIFACT_DIR.toFile().exists()) {
System.out.println("Skipping setup: Artifacts already exists.");
return;
}
// 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());
}
/**
* Update Unnamed jars and include module descriptor files.
*/
private static void generateJar(Path sjar, Path djar,
ModuleDescriptor mDesc) throws Exception {
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("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();
}
}