1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.IOException; 25 import java.nio.file.Files; 26 import java.nio.file.Path; 27 28 import jdk.incubator.foreign.Addressable; 29 import jdk.incubator.foreign.MemoryAddress; 30 31 import org.testng.annotations.Test; 32 import static org.testng.Assert.assertEquals; 33 import static org.testng.Assert.assertFalse; 34 import static org.testng.Assert.assertNotNull; 35 import static org.testng.Assert.assertNull; 36 import static org.testng.Assert.assertTrue; 37 38 /* 39 * @test 40 * @modules jdk.incubator.jextract 41 * @library /test/lib 42 * @build JextractToolRunner 43 * @bug 8240181 44 * @run testng/othervm --enable-native-access=jdk.incubator.jextract -Duser.language=en --add-modules jdk.incubator.jextract JextractToolProviderTest 45 */ 46 public class JextractToolProviderTest extends JextractToolRunner { 47 @Test 48 public void testHelp() { 49 run().checkFailure(OPTION_ERROR); // no options 50 run("--help").checkSuccess(); 51 run("-h").checkSuccess(); 52 run("-?").checkSuccess(); 53 } 54 55 // error for non-existent header file 56 @Test 57 public void testNonExistentHeader() { 58 run(getInputFilePath("non_existent.h").toString()) 59 .checkFailure(INPUT_ERROR) 60 .checkContainsOutput("cannot read header file"); 61 } 62 63 // error for header including non_existent.h file 64 @Test 65 public void testNonExistentIncluder() { 66 run(getInputFilePath("non_existent_includer.h").toString()) 67 .checkFailure(CLANG_ERROR) 68 .checkContainsOutput("file not found"); 69 } 70 71 @Test 72 public void testDirectoryAsHeader() { 73 run(getInputFilePath("directory.h").toString()) 74 .checkFailure(INPUT_ERROR) 75 .checkContainsOutput("not a file"); 76 } 77 78 // error for header with parser errors 79 @Test 80 public void testHeaderWithDeclarationErrors() { 81 run(getInputFilePath("illegal_decls.h").toString()) 82 .checkFailure(CLANG_ERROR) 83 .checkContainsOutput("cannot combine with previous 'short' declaration specifier"); 84 } 85 86 // @bug 8267504: jextract should report unsupported language and exit rather 87 // than generating partial nonworking code 88 @Test 89 public void testUnsupportedLanguage() { 90 run("-C-xc++", getInputFilePath("unsupported_lang.h").toString()) 91 .checkFailure(RUNTIME_ERROR) 92 .checkContainsOutput("Unsupported language: C++"); 93 } 94 95 @Test 96 public void testOutputClass() { 97 Path helloOutput = getOutputFilePath("hellogen"); 98 Path helloH = getInputFilePath("hello.h"); 99 run("-d", helloOutput.toString(), helloH.toString()).checkSuccess(); 100 try(Loader loader = classLoader(helloOutput)) { 101 Class<?> cls = loader.loadClass("hello_h"); 102 // check a method for "void func(int)" 103 assertNotNull(findMethod(cls, "func", int.class)); 104 // check a method for "int printf(MemoryAddress, Object[])" 105 assertNotNull(findMethod(cls, "printf", Addressable.class, Object[].class)); 106 } finally { 107 deleteDir(helloOutput); 108 } 109 } 110 111 private void testTargetPackage(String targetPkgOption) { 112 Path helloOutput = getOutputFilePath("hellogen"); 113 Path helloH = getInputFilePath("hello.h"); 114 run(targetPkgOption, "com.acme", "-d", 115 helloOutput.toString(), helloH.toString()).checkSuccess(); 116 try(Loader loader = classLoader(helloOutput)) { 117 Class<?> cls = loader.loadClass("com.acme.hello_h"); 118 // check a method for "void func(int)" 119 assertNotNull(findMethod(cls, "func", int.class)); 120 // check a method for "int printf(MemoryAddress, Object[])" 121 assertNotNull(findMethod(cls, "printf", Addressable.class, Object[].class)); 122 } finally { 123 deleteDir(helloOutput); 124 } 125 } 126 127 @Test 128 public void testTargetPackageOption() { 129 testTargetPackage("-t"); 130 } 131 132 @Test 133 public void testTargetPackageLongOption() { 134 testTargetPackage("--target-package"); 135 } 136 137 @Test 138 public void testHeaderClassName() { 139 Path helloOutput = getOutputFilePath("hellogen"); 140 Path helloH = getInputFilePath("hello.h"); 141 run("--header-class-name", "MyHello", "-t", "com.acme", "-d", 142 helloOutput.toString(), helloH.toString()).checkSuccess(); 143 try(Loader loader = classLoader(helloOutput)) { 144 Class<?> cls = loader.loadClass("com.acme.MyHello"); 145 // check a method for "void func(int)" 146 assertNotNull(findMethod(cls, "func", int.class)); 147 // check a method for "int printf(MemoryAddress, Object[])" 148 assertNotNull(findMethod(cls, "printf", Addressable.class, Object[].class)); 149 } finally { 150 deleteDir(helloOutput); 151 } 152 } 153 }