blob: 810a75178f26ad6a5a89be44425c764a366b5f24 [file] [log] [blame]
/**
* Copyright (c) 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.
*/
/*
* @test
* @summary Test --no-man-pages and --no-header-files
* @library /lib/testlibrary
* @modules jdk.compiler
* jdk.jlink
* @build CompilerUtils
* @run testng ExcludeJmodSectionPluginTest
*/
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class ExcludeJmodSectionPluginTest {
static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
.orElseThrow(() ->
new RuntimeException("jmod tool not found")
);
static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
.orElseThrow(() ->
new RuntimeException("jlink tool not found")
);
static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods");
static final Path SRC_DIR = Paths.get("src");
static final Path MODS_DIR = Paths.get("mods");
static final Path JMODS_DIR = Paths.get("jmods");
static final Path MAN_DIR = Paths.get("man");
static final Path INCLUDE_DIR = Paths.get("include");
static final Path IMAGES_DIR = Paths.get("images");
@BeforeTest
private void setup() throws Exception {
// build jmod files
JmodFileBuilder m1 = new JmodFileBuilder("m1");
m1.headerFile("m1a.h");
m1.headerFile("m1b.h");
m1.build();
JmodFileBuilder m2 = new JmodFileBuilder("m2");
m2.headerFile("m2.h");
m2.manPage("tool2.1");
m2.build();
JmodFileBuilder m3 = new JmodFileBuilder("m3");
m3.manPage("tool3.1");
m3.build();
}
private String imageDir(String dir) {
return IMAGES_DIR.resolve(dir).toString();
}
@DataProvider(name = "jlinkoptions")
public Object[][] jlinkoptions() {
// options and expected header files & man pages
return new Object[][] {
{ new String [] {
"test1",
"--exclude-files=/java.base/include/**,/java.base/man/**",
},
List.of("include/m1a.h",
"include/m1b.h",
"include/m2.h",
"man/tool2.1",
"man/tool3.1")
},
{ new String [] {
"test2",
"--no-man-pages",
"--no-header-files",
},
List.of()
},
{ new String[] {
"test3",
"--no-header-files",
"--exclude-files=/java.base/man/**"
},
List.of("man/tool2.1",
"man/tool3.1") },
{ new String [] {
"test4",
"--no-man-pages",
"--exclude-files=/java.base/include/**,/m2/include/**",
},
List.of("include/m1a.h",
"include/m1b.h")
},
{ new String [] {
"test5",
"--no-header-files",
"--exclude-files=/java.base/man/**,/m2/man/**"
},
List.of("man/tool3.1")
},
};
}
@Test(dataProvider = "jlinkoptions")
public void test(String[] opts, List<String> expectedFiles) throws Exception {
if (Files.notExists(MODULE_PATH)) {
// exploded image
return;
}
String dir = opts[0];
List<String> options = new ArrayList<>();
for (int i = 1; i < opts.length; i++) {
options.add(opts[i]);
}
String mpath = MODULE_PATH.toString() + File.pathSeparator +
JMODS_DIR.toString();
Stream.of("--module-path", mpath,
"--add-modules", "m1,m2,m3",
"--output", imageDir(dir))
.forEach(options::add);
Path image = createImage(dir, options, expectedFiles);
// check if any unexpected header file or man page
Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE)
.filter(p -> Files.isRegularFile(p))
.filter(p -> p.getParent().endsWith("include") ||
p.getParent().endsWith("man"))
.filter(p -> {
String fn = String.format("%s/%s",
p.getParent().getFileName().toString(),
p.getFileName().toString());
return !expectedFiles.contains(fn);
})
.collect(Collectors.toSet());
if (extraFiles.size() > 0) {
System.out.println("Unexpected files: " + extraFiles.toString());
assertTrue(extraFiles.isEmpty());
}
}
/**
* Test java.base's include header files
*/
@Test
public void testJavaBase() {
if (Files.notExists(MODULE_PATH)) {
// exploded image
return;
}
List<String> options = List.of("--module-path",
MODULE_PATH.toString(),
"--add-modules", "java.base",
"--output", imageDir("base"));
createImage("base", options,
List.of("include/jni.h", "include/jvmti.h"));
}
private Path createImage(String outputDir, List<String> options,
List<String> expectedFiles) {
System.out.println("jlink " + options.toString());
int rc = JLINK_TOOL.run(System.out, System.out,
options.toArray(new String[0]));
assertTrue(rc == 0);
Path d = IMAGES_DIR.resolve(outputDir);
for (String fn : expectedFiles) {
Path path = d.resolve(fn);
if (Files.notExists(path)) {
throw new RuntimeException(path + " not found");
}
}
return d;
}
private void deleteDirectory(Path dir) throws IOException {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
{
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException
{
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
* Builder to create JMOD file
*/
class JmodFileBuilder {
final String name;
final Set<String> manPages = new HashSet<>();
final Set<String> headerFiles = new HashSet<>();
JmodFileBuilder(String name) throws IOException {
this.name = name;
Path msrc = SRC_DIR.resolve(name);
if (Files.exists(msrc)) {
deleteDirectory(msrc);
}
}
JmodFileBuilder manPage(String filename) {
manPages.add(filename);
return this;
}
JmodFileBuilder headerFile(String filename) {
headerFiles.add(filename);
return this;
}
Path build() throws IOException {
compileModule();
// create man pages
Path mdir = MAN_DIR.resolve(name);
for (String filename : manPages) {
Files.createDirectories(mdir);
Files.createFile(mdir.resolve(filename));
}
// create header files
mdir = INCLUDE_DIR.resolve(name);
for (String filename : headerFiles) {
Files.createDirectories(mdir);
Files.createFile(mdir.resolve(filename));
}
return createJmodFile();
}
void compileModule() throws IOException {
Path msrc = SRC_DIR.resolve(name);
Files.createDirectories(msrc);
Path minfo = msrc.resolve("module-info.java");
try (BufferedWriter bw = Files.newBufferedWriter(minfo);
PrintWriter writer = new PrintWriter(bw)) {
writer.format("module %s { }%n", name);
}
assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
"--module-source-path",
SRC_DIR.toString()));
}
Path createJmodFile() throws IOException {
Path mclasses = MODS_DIR.resolve(name);
Files.createDirectories(JMODS_DIR);
Path outfile = JMODS_DIR.resolve(name + ".jmod");
List<String> args = new ArrayList<>();
args.add("create");
// add classes
args.add("--class-path");
args.add(mclasses.toString());
// man pages
if (manPages.size() > 0) {
args.add("--man-pages");
args.add(MAN_DIR.resolve(name).toString());
}
// header files
if (headerFiles.size() > 0) {
args.add("--header-files");
args.add(INCLUDE_DIR.resolve(name).toString());
}
args.add(outfile.toString());
if (Files.exists(outfile))
Files.delete(outfile);
System.out.println("jmod " +
args.stream().collect(Collectors.joining(" ")));
int rc = JMOD_TOOL.run(System.out, System.out,
args.toArray(new String[args.size()]));
if (rc != 0) {
throw new AssertionError("jmod failed: rc = " + rc);
}
return outfile;
}
}
}