< prev index next >

test/jdk/com/sun/tools/jextract/JextractToolProviderTest.java

Print this page




   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 org.testng.annotations.Test;
  25 

  26 import java.lang.reflect.Method;
  27 import java.foreign.annotations.NativeHeader;
  28 import java.foreign.annotations.NativeLocation;
  29 import java.foreign.memory.Pointer;
  30 import java.nio.file.Files;
  31 import java.nio.file.Path;
  32 import java.util.Arrays;
  33 import java.util.List;

  34 
  35 import static org.testng.Assert.assertEquals;
  36 import static org.testng.Assert.assertFalse;
  37 import static org.testng.Assert.assertNotNull;
  38 import static org.testng.Assert.assertNull;
  39 import static org.testng.Assert.assertTrue;
  40 
  41 /*
  42  * @test
  43  * @modules jdk.jextract
  44  * @build JextractToolProviderTest
  45  * @run testng/othervm -Duser.language=en JextractToolProviderTest
  46  */
  47 public class JextractToolProviderTest extends JextractToolRunner {
  48     @Test
  49     public void testHelp() {
  50         checkFailure(null); // no options
  51         checkSuccess(null, "--help");
  52         checkSuccess(null, "-h");
  53         checkSuccess(null, "-?");
  54     }
  55 
  56     // error for non-existent header file
  57     @Test
  58     public void testNonExistentHeader() {
  59         checkFailure("Cannot open header file", "--dry-run",
  60             getInputFilePath("non_existent.h").toString());

  61     }
  62 
  63     @Test
  64     public void testDryRun() {
  65         // only dry-run, don't produce any output
  66         Path simpleJar = getOutputFilePath("simple.jar");
  67         deleteFile(simpleJar);
  68         checkSuccess(null, "--dry-run", getInputFilePath("simple.h").toString());
  69         try {
  70             assertFalse(Files.isRegularFile(simpleJar));
  71         } finally {
  72             deleteFile(simpleJar);
  73         }
  74     }
  75 
  76     @Test
  77     public void testOutputFileOption() {
  78         // simple output file check
  79         Path simpleJar = getOutputFilePath("simple.jar");
  80         deleteFile(simpleJar);
  81         checkSuccess(null, "-o", simpleJar.toString(),
  82             getInputFilePath("simple.h").toString());
  83         try {
  84             assertTrue(Files.isRegularFile(simpleJar));
  85         } finally {
  86             deleteFile(simpleJar);
  87         }
  88     }
  89 
  90     @Test
  91     public void testOutputClass() {
  92         Path helloJar = getOutputFilePath("hello.jar");
  93         deleteFile(helloJar);
  94         Path helloH = getInputFilePath("hello.h");
  95         checkSuccess(null, "-o", helloJar.toString(), helloH.toString());
  96         try {
  97             Class<?> cls = loadClass("hello", helloJar);
  98             // check NativeHeader annotation
  99             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 100             assertNotNull(header);
 101             assertEquals(header.path(), helloH.toString());
 102             assertFalse(header.declarations().isEmpty());
 103 
 104             // check a method for "void func()"
 105             assertNotNull(findMethod(cls, "func", Object[].class));
 106         } finally {
 107             deleteFile(helloJar);
 108         }
 109     }
 110 
 111     private void testTargetPackage(String targetPkgOption) {
 112         Path helloJar = getOutputFilePath("hello.jar");
 113         deleteFile(helloJar);
 114         Path helloH = getInputFilePath("hello.h");
 115         checkSuccess(null, targetPkgOption, "com.acme", "-o", helloJar.toString(), helloH.toString());
 116         try {
 117             Class<?> cls = loadClass("com.acme.hello", helloJar);
 118             // check NativeHeader annotation
 119             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 120             assertNotNull(header);
 121             assertEquals(header.path(), helloH.toString());
 122 
 123             // check a method for "void func()"
 124             assertNotNull(findMethod(cls, "func", Object[].class));
 125         } finally {
 126             deleteFile(helloJar);
 127         }
 128     }
 129 
 130     @Test
 131     public void testTargetPackageOption() {
 132         testTargetPackage("-t");
 133     }
 134 
 135     @Test
 136     public void testTargetPackageLongOption() {
 137         testTargetPackage("--target-package");
 138     }
 139 
 140     private void testPackageMapping(String pkgMapOption) {
 141         Path worldJar = getOutputFilePath("world.jar");
 142         deleteFile(worldJar);
 143         Path mytypesJar = getOutputFilePath("mytypes.jar");
 144         deleteFile(mytypesJar);
 145 
 146         Path worldH = getInputFilePath("world.h");
 147         Path include = getInputFilePath("include");
 148         // generate jar for mytypes.h
 149         checkSuccess(null, "-t", "com.acme", "-o", mytypesJar.toString(),
 150             include.resolve("mytypes.h").toString());
 151         // world.h include mytypes.h, use appropriate package for stuff from mytypes.h
 152         checkSuccess(null, "-I", include.toString(), pkgMapOption, include.toString() + "=com.acme",
 153             "-o", worldJar.toString(), worldH.toString());
 154         try {
 155             Class<?> cls = loadClass("world", worldJar, mytypesJar);
 156             Method m = findFirstMethod(cls, "distance");
 157             Class<?>[] params = m.getParameterTypes();
 158             assertEquals(params[0].getName(), "com.acme.mytypes$Point");
 159         } finally {
 160             deleteFile(worldJar);
 161             deleteFile(mytypesJar);
 162         }
 163     }
 164 
 165     @Test
 166     public void testPackageDirMappingOption() {
 167         testPackageMapping("-m");
 168     }
 169 
 170     @Test
 171     public void testPackageDirMappingLongOption() {
 172         testPackageMapping("--package-map");
 173     }
 174 
 175     @Test
 176     public void test_no_input_files() {
 177         String err = "No input files";
 178         checkFailure(err, "-L", "foo");

 179     }
 180 
 181     @Test
 182     public void test_option_L_without_l() {
 183         Path helloJar = getOutputFilePath("hello.jar");
 184         deleteFile(helloJar);
 185         Path helloH = getInputFilePath("hello.h");
 186         Path linkDir = getInputFilePath("libs");
 187         String warning = "WARNING: -L option specified without any -l option";
 188         checkSuccess(warning, "-L", linkDir.toString(), "-o", helloJar.toString(), helloH.toString());


 189     }
 190 
 191     @Test
 192     public void test_option_rpath_without_l() {
 193         Path helloJar = getOutputFilePath("hello.jar");
 194         deleteFile(helloJar);
 195         Path helloH = getInputFilePath("hello.h");
 196         Path rpathDir = getInputFilePath("libs");
 197         String warning = "WARNING: -rpath option specified without any -l option";
 198         try {
 199             checkSuccess(warning, "-rpath", rpathDir.toString(), "-o", helloJar.toString(), helloH.toString());


 200         } finally {
 201             deleteFile(helloJar);
 202         }
 203     }
 204 
 205     @Test
 206     public void test_option_conflicting_rpaths() {
 207         Path helloJar = getOutputFilePath("hello.jar");
 208         deleteFile(helloJar);
 209         Path helloH = getInputFilePath("hello.h");
 210         Path rpathDir = getInputFilePath("libs");
 211         String warning = "WARNING: -infer-rpath used in conjunction with explicit -rpath paths";
 212         try {
 213             checkSuccess(warning, "-rpath", rpathDir.toString(),
 214                     "-infer-rpath",
 215                     "-o", helloJar.toString(), helloH.toString());


 216         } finally {
 217             deleteFile(helloJar);
 218         }
 219     }
 220 
 221     @Test
 222     public void test_option_rpath_no_libs() {
 223         Path helloJar = getOutputFilePath("hello.jar");
 224         deleteFile(helloJar);
 225         Path helloH = getInputFilePath("hello.h");
 226         String warning = "WARNING: -infer-rpath option specified without any -L option";
 227         try {
 228             checkSuccess(warning,
 229                     "-infer-rpath",
 230                     "-o", helloJar.toString(), helloH.toString());

 231         } finally {
 232             deleteFile(helloJar);
 233         }
 234     }
 235 
 236     @Test
 237     public void test_option_l_no_crash_missing_lib() {
 238         Path helloJar = getOutputFilePath("hello.jar");
 239         deleteFile(helloJar);
 240         Path helloH = getInputFilePath("hello.h");
 241         String warning = "WARNING: Some library names could not be resolved";
 242         try {
 243             checkSuccess(warning,
 244                     "-L", "nonExistent",
 245                     "-l", "nonExistent",
 246                     "-o", helloJar.toString(), helloH.toString());


 247         } finally {
 248             deleteFile(helloJar);
 249         }
 250     }
 251 
 252     @Test
 253     public void test_option_l() {
 254         Path helloJar = getOutputFilePath("hello.jar");
 255         deleteFile(helloJar);
 256         Path helloH = getInputFilePath("hello.h");
 257         checkSuccess(null, "-l", "hello", "-o", helloJar.toString(), helloH.toString());
 258         try {
 259             Class<?> cls = loadClass("hello", helloJar);
 260             // check that NativeHeader annotation captures -l value
 261             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 262             assertNotNull(header);
 263             assertEquals(header.libraries().length, 1);
 264             assertEquals(header.libraries()[0], "hello");
 265             // no library paths (rpath) set
 266             assertEquals(header.libraryPaths().length, 0);
 267         } finally {
 268             deleteFile(helloJar);
 269         }
 270     }
 271 
 272     @Test
 273     public void test_option_l_and_rpath() {
 274         Path helloJar = getOutputFilePath("hello.jar");
 275         deleteFile(helloJar);
 276     Path helloH = getInputFilePath("hello.h");
 277         Path rpathDir = getInputFilePath("libs");
 278         checkSuccess(null, "-l", "hello", "-rpath", rpathDir.toString(),
 279              "-o", helloJar.toString(), helloH.toString());
 280         try {
 281             Class<?> cls = loadClass("hello", helloJar);
 282             // check that NativeHeader annotation captures -l and -rpath values
 283             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 284             assertNotNull(header);
 285             assertEquals(header.libraries().length, 1);
 286             assertEquals(header.libraries()[0], "hello");
 287             assertEquals(header.libraryPaths().length, 1);
 288             assertEquals(header.libraryPaths()[0], rpathDir.toString());
 289         } finally {
 290             deleteFile(helloJar);
 291         }
 292     }
 293 
 294     @Test
 295     public void testUnionDeclaration() {
 296         Path uniondeclJar = getOutputFilePath("uniondecl.jar");
 297         deleteFile(uniondeclJar);
 298         Path uniondeclH = getInputFilePath("uniondecl.h");
 299         try {
 300             checkSuccess(null, "-o", uniondeclJar.toString(), uniondeclH.toString());
 301             Class<?> unionCls = loadClass("uniondecl", uniondeclJar);
 302             assertNotNull(unionCls);
 303             boolean found = Arrays.stream(unionCls.getClasses()).
 304                 map(Class::getSimpleName).
 305                 filter(n -> n.equals("IntOrFloat")).
 306                 findFirst().isPresent();
 307             assertTrue(found, "uniondecl.IntOrFloat not found");
 308         } finally {
 309             deleteFile(uniondeclJar);
 310         }
 311     }
 312 
 313     private void testEnumConstGetters(Class<?> enumCls, List<String> names) {
 314         for (String name : names) {
 315             if (findEnumConstGet(enumCls, name) == null) {
 316                 throw new RuntimeException(enumCls.getName() + " misses " + name);
 317             }
 318         }
 319     }
 320 
 321     @Test
 322     public void testAnonymousEnum() {
 323         Path anonenumJar = getOutputFilePath("anonenum.jar");
 324         deleteFile(anonenumJar);
 325         Path anonenumH = getInputFilePath("anonenum.h");
 326         try {
 327             checkSuccess(null, "-o", anonenumJar.toString(), anonenumH.toString());
 328             Class<?> anonenumCls = loadClass("anonenum", anonenumJar);
 329             assertNotNull(anonenumCls);
 330             testEnumConstGetters(anonenumCls, List.of("RED", "GREEN", "BLUE"));
 331             testEnumConstGetters(anonenumCls, List.of(
 332                     "Java", "C", "CPP", "Python", "Ruby"));
 333             testEnumConstGetters(anonenumCls, List.of(
 334                     "XS", "S", "M", "L", "XL", "XXL"));
 335             testEnumConstGetters(anonenumCls, List.of(
 336                     "ONE", "TWO"));
 337 
 338             Class<?> enumClz[] = anonenumCls.getClasses();
 339             assert(enumClz.length >= 4);
 340 
 341             Class<?> enumCls = findClass(enumClz, "codetype_t");
 342             assertNotNull(enumCls);
 343 
 344             enumCls = findClass(enumClz, "SIZE");
 345             assertNotNull(enumCls);
 346 
 347             enumCls = findClass(enumClz, "temp");
 348             assertNotNull(enumCls);
 349 
 350             enumCls = findClass(enumClz, "temp_t");
 351             assertNotNull(enumCls);
 352         } finally {
 353             deleteFile(anonenumJar);
 354         }
 355     }
 356 
 357     @Test
 358     public void testExcludeSymbols() {
 359         Path helloJar = getOutputFilePath("hello.jar");
 360         deleteFile(helloJar);
 361         Path helloH = getInputFilePath("hello.h");
 362         checkSuccess(null, "-o", helloJar.toString(), helloH.toString());
 363         try {
 364             Class<?> cls = loadClass("hello", helloJar);
 365             // check a method for "void func()"
 366             assertNotNull(findMethod(cls, "func", Object[].class));
 367             assertNotNull(findMethod(cls, "func2", Object[].class));
 368             assertNotNull(findMethod(cls, "func3", Object[].class));
 369             // check a method for "void junk()"
 370             assertNotNull(findMethod(cls, "junk", Object[].class));
 371             assertNotNull(findMethod(cls, "junk2", Object[].class));
 372             assertNotNull(findMethod(cls, "junk3", Object[].class));
 373         } finally {
 374             deleteFile(helloJar);
 375         }
 376 
 377         // try with --exclude-symbols" this time.
 378         checkSuccess(null, "--exclude-symbols", "junk.*", "-o", helloJar.toString(), helloH.toString());

 379         try {
 380             Class<?> cls = loadClass("hello", helloJar);
 381             // check a method for "void func()"
 382             assertNotNull(findMethod(cls, "func", Object[].class));
 383             assertNotNull(findMethod(cls, "func2", Object[].class));
 384             assertNotNull(findMethod(cls, "func3", Object[].class));
 385             // check a method for "void junk()"
 386             assertNull(findMethod(cls, "junk", Object[].class));
 387             assertNull(findMethod(cls, "junk2", Object[].class));
 388             assertNull(findMethod(cls, "junk3", Object[].class));
 389         } finally {
 390             deleteFile(helloJar);
 391         }
 392     }
 393 
 394     @Test
 395     public void testIncludeSymbols() {
 396         Path helloJar = getOutputFilePath("hello.jar");
 397         deleteFile(helloJar);
 398         Path helloH = getInputFilePath("hello.h");
 399         checkSuccess(null, "-o", helloJar.toString(), helloH.toString());
 400         try {
 401             Class<?> cls = loadClass("hello", helloJar);
 402             // check a method for "void func()"
 403             assertNotNull(findMethod(cls, "func", Object[].class));
 404             assertNotNull(findMethod(cls, "func2", Object[].class));
 405             assertNotNull(findMethod(cls, "func3", Object[].class));
 406             // check a method for "void junk()"
 407             assertNotNull(findMethod(cls, "junk", Object[].class));
 408             assertNotNull(findMethod(cls, "junk2", Object[].class));
 409             assertNotNull(findMethod(cls, "junk3", Object[].class));
 410         } finally {
 411             deleteFile(helloJar);
 412         }
 413 
 414         // try with --include-symbols" this time.
 415         checkSuccess(null, "--include-symbols", "junk.*", "-o", helloJar.toString(), helloH.toString());
 416         try {
 417             Class<?> cls = loadClass("hello", helloJar);
 418             // check a method for "void junk()"
 419             assertNotNull(findMethod(cls, "junk", Object[].class));
 420             assertNotNull(findMethod(cls, "junk2", Object[].class));
 421             assertNotNull(findMethod(cls, "junk3", Object[].class));
 422             // check a method for "void func()"
 423             assertNull(findMethod(cls, "func", Object[].class));
 424             assertNull(findMethod(cls, "func2", Object[].class));
 425             assertNull(findMethod(cls, "func3", Object[].class));
 426         } finally {
 427             deleteFile(helloJar);
 428         }
 429     }
 430 
 431     @Test
 432     public void testNoLocations() {
 433         Path simpleJar = getOutputFilePath("simple.jar");
 434         deleteFile(simpleJar);
 435         Path simpleH = getInputFilePath("simple.h");
 436         checkSuccess(null, "--no-locations", "-o", simpleJar.toString(), simpleH.toString());
 437         try {
 438             Class<?> simpleCls = loadClass("simple", simpleJar);
 439             Method func = findFirstMethod(simpleCls, "func");
 440             assertFalse(func.isAnnotationPresent(NativeLocation.class));
 441             Class<?> anonymousCls = loadClass("simple$anonymous", simpleJar);
 442             assertFalse(simpleCls.isAnnotationPresent(NativeLocation.class));
 443         } finally {
 444             deleteFile(simpleJar);
 445         }
 446     }
 447 
 448     @Test
 449     public void testIncludeExcludeSymbols() {
 450         Path helloJar = getOutputFilePath("hello.jar");
 451         deleteFile(helloJar);
 452         Path helloH = getInputFilePath("hello.h");
 453         checkSuccess(null, "-o", helloJar.toString(), helloH.toString());
 454         try {
 455             Class<?> cls = loadClass("hello", helloJar);
 456             // check a method for "void func()"
 457             assertNotNull(findMethod(cls, "func", Object[].class));
 458             assertNotNull(findMethod(cls, "func2", Object[].class));
 459             assertNotNull(findMethod(cls, "func3", Object[].class));
 460             // check a method for "void junk()"
 461             assertNotNull(findMethod(cls, "junk", Object[].class));
 462             assertNotNull(findMethod(cls, "junk2", Object[].class));
 463             assertNotNull(findMethod(cls, "junk3", Object[].class));
 464         } finally {
 465             deleteFile(helloJar);
 466         }
 467 
 468         // try with --include-symbols" this time.
 469         checkSuccess(null, "--include-symbols", "junk.*", "--exclude-symbols", "junk3",
 470              "-o", helloJar.toString(), helloH.toString());
 471         try {
 472             Class<?> cls = loadClass("hello", helloJar);
 473             // check a method for "void junk()"
 474             assertNotNull(findMethod(cls, "junk", Object[].class));
 475             assertNotNull(findMethod(cls, "junk2", Object[].class));
 476             // check a method for "void func()" - not included
 477             assertNull(findMethod(cls, "func", Object[].class));
 478             assertNull(findMethod(cls, "func2", Object[].class));
 479             assertNull(findMethod(cls, "func3", Object[].class));
 480             // excluded among the included set!
 481             assertNull(findMethod(cls, "junk3", Object[].class));
 482         } finally {
 483             deleteFile(helloJar);
 484         }
 485     }
 486 
 487     @Test
 488     public void testNestedStructsUnions() {
 489         Path nestedJar = getOutputFilePath("nested.jar");
 490         deleteFile(nestedJar);
 491         Path nestedH = getInputFilePath("nested.h");
 492         try {
 493             checkSuccess(null, "-o", nestedJar.toString(), nestedH.toString());
 494             Class<?> headerCls = loadClass("nested", nestedJar);
 495             assertNotNull(headerCls);
 496 
 497             Class<?> fooCls = loadClass("nested$Foo", nestedJar);
 498             assertNotNull(fooCls);
 499             // struct Foo has no getters for "x", "y" etc.
 500             assertNull(findStructFieldGet(fooCls, "x"));
 501             assertNull(findStructFieldGet(fooCls, "y"));
 502             // struct Foo has getters for bar and color
 503             assertNotNull(findStructFieldGet(fooCls, "bar"));
 504             assertNotNull(findStructFieldGet(fooCls, "color"));
 505             // make sure nested types are handled without nested namespace!
 506             assertNotNull(loadClass("nested$Bar", nestedJar));
 507             assertNotNull(loadClass("nested$Color", nestedJar));
 508 
 509             Class<?> uCls = loadClass("nested$U", nestedJar);
 510             assertNotNull(uCls);
 511             // union U has no getters for "x", "y" etc.
 512             assertNull(findStructFieldGet(uCls, "x"));
 513             assertNull(findStructFieldGet(uCls, "y"));


 560             assertNotNull(findStructFieldGet(myUnionCls, "k"));
 561             // "A", "B", "C" are enum constants -should not be in MyUnion
 562             assertNull(findStructFieldGet(myUnionCls, "A"));
 563             assertNull(findStructFieldGet(myUnionCls, "B"));
 564             assertNull(findStructFieldGet(myUnionCls, "C"));
 565             // anonymous enum constants are hoisted to containing scope
 566             assertNotNull(findEnumConstGet(headerCls, "A"));
 567             assertNotNull(findEnumConstGet(headerCls, "B"));
 568             assertNotNull(findEnumConstGet(headerCls, "C"));
 569         } finally {
 570             deleteFile(nestedJar);
 571         }
 572     }
 573 
 574     @Test
 575     public void testAnonymousStructTypeGlobalVar() {
 576         Path elaboratedTypeJar = getOutputFilePath("elaboratedtype.jar");
 577         deleteFile(elaboratedTypeJar);
 578         Path elaboratedTypeH = getInputFilePath("elaboratedtype.h");
 579         try {
 580             checkSuccess(null, "-o", elaboratedTypeJar.toString(), elaboratedTypeH.toString());
 581             Class<?> headerCls = loadClass("elaboratedtype", elaboratedTypeJar);
 582             assertNotNull(findGlobalVariableGet(headerCls, "point"));
 583             assertNotNull(findGlobalVariableGet(headerCls, "long_or_int"));
 584             assertNotNull(findMethod(headerCls, "func", Pointer.class));
 585         } finally {
 586             deleteFile(elaboratedTypeJar);
 587         }
 588     }
 589 
 590     private void testBuiltinInclude(String name) {
 591         Path fileJar = getOutputFilePath(name + "inc.jar");
 592         deleteFile(fileJar);
 593         Path fileH = getInputFilePath(name + "inc.h");
 594         checkSuccess(null, "-o", fileJar.toString(), fileH.toString());
 595         deleteFile(fileJar);
 596     }
 597 
 598     @Test
 599     public void testBuiltinHeader() {
 600         testBuiltinInclude("stdarg");
 601         testBuiltinInclude("stdbool");
 602     }
 603 
 604     @Test
 605     public void testGlobalFuncPointerCallback() {
 606         Path globalFuncPointerJar = getOutputFilePath("globalFuncPointer.jar");
 607         deleteFile(globalFuncPointerJar);
 608         Path globalFuncPointerH = getInputFilePath("globalFuncPointer.h");
 609         checkSuccess(null, "-o", globalFuncPointerJar.toString(), globalFuncPointerH.toString());
 610         Class<?> callbackCls = loadClass("globalFuncPointer$FI1", globalFuncPointerJar);
 611         Method callback = findFirstMethod(callbackCls, "fn");
 612         assertNotNull(callback);
 613         assertTrue(callback.isVarArgs());
 614         deleteFile(globalFuncPointerJar);
 615     }
 616 
 617     @Test
 618     public void testFuncPtrTypedef() {
 619         Path funcPtrTypedefJar = getOutputFilePath("funcPtrTypedef.jar");
 620         deleteFile(funcPtrTypedefJar);
 621         Path funcPtrTypedefH = getInputFilePath("funcPtrTypedef.h");
 622         checkSuccess(null, "-o", funcPtrTypedefJar.toString(), funcPtrTypedefH.toString());
 623         // force parsing of class, method
 624         Class<?> headerCls = loadClass("funcPtrTypedef", funcPtrTypedefJar);
 625         Method getter = findFirstMethod(headerCls, "my_function$get");
 626         assertNotNull(getter);
 627         assertNotNull(getter.getGenericParameterTypes());
 628         deleteFile(funcPtrTypedefJar);
 629     }
 630 
 631     @Test
 632     public void testDuplicatedecls() {
 633         Path duplicatedeclsJar = getOutputFilePath("duplicatedecls.jar");
 634         deleteFile(duplicatedeclsJar);
 635         Path duplicatedeclsH = getInputFilePath("duplicatedecls.h");
 636         checkSuccess(null, "-o", duplicatedeclsJar.toString(), duplicatedeclsH.toString());
 637         // load the class to make sure no duplicate methods generated in it
 638         Class<?> headerCls = loadClass("duplicatedecls", duplicatedeclsJar);
 639         assertNotNull(headerCls);
 640         deleteFile(duplicatedeclsJar);
 641     }
 642 }


   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 org.testng.annotations.Test;
  25 
  26 import java.lang.reflect.Field;
  27 import java.lang.reflect.Method;
  28 import java.foreign.annotations.NativeHeader;
  29 import java.foreign.annotations.NativeLocation;
  30 import java.foreign.memory.Pointer;
  31 import java.nio.file.Files;
  32 import java.nio.file.Path;
  33 import java.util.Arrays;
  34 import java.util.List;
  35 import java.util.stream.Stream;
  36 
  37 import static org.testng.Assert.assertEquals;
  38 import static org.testng.Assert.assertFalse;
  39 import static org.testng.Assert.assertNotNull;
  40 import static org.testng.Assert.assertNull;
  41 import static org.testng.Assert.assertTrue;
  42 
  43 /*
  44  * @test
  45  * @modules jdk.jextract
  46  * @build JextractToolProviderTest
  47  * @run testng/othervm -Duser.language=en JextractToolProviderTest
  48  */
  49 public class JextractToolProviderTest extends JextractToolRunner {
  50     @Test
  51     public void testHelp() {
  52         run().checkFailure(); // no options
  53         run("--help").checkSuccess();
  54         run("-h").checkSuccess();
  55         run("-?").checkSuccess();
  56     }
  57 
  58     // error for non-existent header file
  59     @Test
  60     public void testNonExistentHeader() {
  61         run("--dry-run", getInputFilePath("non_existent.h").toString())
  62             .checkFailure()
  63             .checkContainsOutput("Cannot open header file");
  64     }
  65 
  66     @Test
  67     public void testDryRun() {
  68         // only dry-run, don't produce any output
  69         Path simpleJar = getOutputFilePath("simple.jar");
  70         deleteFile(simpleJar);
  71         run("--dry-run", getInputFilePath("simple.h").toString()).checkSuccess();
  72         try {
  73             assertFalse(Files.isRegularFile(simpleJar));
  74         } finally {
  75             deleteFile(simpleJar);
  76         }
  77     }
  78 
  79     @Test
  80     public void testOutputFileOption() {
  81         // simple output file check
  82         Path simpleJar = getOutputFilePath("simple.jar");
  83         deleteFile(simpleJar);
  84         run("-o", simpleJar.toString(),
  85             getInputFilePath("simple.h").toString()).checkSuccess();
  86         try {
  87             assertTrue(Files.isRegularFile(simpleJar));
  88         } finally {
  89             deleteFile(simpleJar);
  90         }
  91     }
  92 
  93     @Test
  94     public void testOutputClass() {
  95         Path helloJar = getOutputFilePath("hello.jar");
  96         deleteFile(helloJar);
  97         Path helloH = getInputFilePath("hello.h");
  98         run("-o", helloJar.toString(), helloH.toString()).checkSuccess();
  99         try {
 100             Class<?> cls = loadClass("hello", helloJar);
 101             // check NativeHeader annotation
 102             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 103             assertNotNull(header);
 104             assertEquals(header.path(), helloH.toString());
 105             assertFalse(header.declarations().isEmpty());
 106 
 107             // check a method for "void func()"
 108             assertNotNull(findMethod(cls, "func", Object[].class));
 109         } finally {
 110             deleteFile(helloJar);
 111         }
 112     }
 113 
 114     private void testTargetPackage(String targetPkgOption) {
 115         Path helloJar = getOutputFilePath("hello.jar");
 116         deleteFile(helloJar);
 117         Path helloH = getInputFilePath("hello.h");
 118         run(targetPkgOption, "com.acme", "-o", helloJar.toString(), helloH.toString()).checkSuccess();
 119         try {
 120             Class<?> cls = loadClass("com.acme.hello", helloJar);
 121             // check NativeHeader annotation
 122             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 123             assertNotNull(header);
 124             assertEquals(header.path(), helloH.toString());
 125 
 126             // check a method for "void func()"
 127             assertNotNull(findMethod(cls, "func", Object[].class));
 128         } finally {
 129             deleteFile(helloJar);
 130         }
 131     }
 132 
 133     @Test
 134     public void testTargetPackageOption() {
 135         testTargetPackage("-t");
 136     }
 137 
 138     @Test
 139     public void testTargetPackageLongOption() {
 140         testTargetPackage("--target-package");
 141     }
 142 
 143     private void testPackageMapping(String pkgMapOption) {
 144         Path worldJar = getOutputFilePath("world.jar");
 145         deleteFile(worldJar);



 146         Path worldH = getInputFilePath("world.h");
 147         Path include = getInputFilePath("include");



 148         // world.h include mytypes.h, use appropriate package for stuff from mytypes.h
 149         run("-I", include.toString(), pkgMapOption, include.toString() + "=com.acme",
 150             "-o", worldJar.toString(), worldH.toString()).checkSuccess();
 151         try {
 152             Class<?> cls = loadClass("world", worldJar);
 153             Method m = findFirstMethod(cls, "distance");
 154             Class<?>[] params = m.getParameterTypes();
 155             assertEquals(params[0].getName(), "com.acme.mytypes$Point");
 156         } finally {
 157             deleteFile(worldJar);

 158         }
 159     }
 160 
 161     @Test
 162     public void testPackageDirMappingOption() {
 163         testPackageMapping("-m");
 164     }
 165 
 166     @Test
 167     public void testPackageDirMappingLongOption() {
 168         testPackageMapping("--package-map");
 169     }
 170 
 171     @Test
 172     public void test_no_input_files() {
 173         run("-L", "foo")
 174                 .checkContainsOutput("No input files")
 175                 .checkFailure();
 176     }
 177 
 178     @Test
 179     public void test_option_L_without_l() {
 180         Path helloJar = getOutputFilePath("hello.jar");
 181         deleteFile(helloJar);
 182         Path helloH = getInputFilePath("hello.h");
 183         Path linkDir = getInputFilePath("libs");
 184         String warning = "WARNING: -L option specified without any -l option";
 185         run("-L", linkDir.toString(), "-o", helloJar.toString(), helloH.toString())
 186                 .checkContainsOutput(warning)
 187                 .checkSuccess();
 188     }
 189 
 190     @Test
 191     public void test_option_rpath_without_l() {
 192         Path helloJar = getOutputFilePath("hello.jar");
 193         deleteFile(helloJar);
 194         Path helloH = getInputFilePath("hello.h");
 195         Path rpathDir = getInputFilePath("libs");
 196         String warning = "WARNING: -rpath option specified without any -l option";
 197         try {
 198             run("-rpath", rpathDir.toString(), "-o", helloJar.toString(), helloH.toString())
 199                     .checkContainsOutput(warning)
 200                     .checkSuccess();
 201         } finally {
 202             deleteFile(helloJar);
 203         }
 204     }
 205 
 206     @Test
 207     public void test_option_conflicting_rpaths() {
 208         Path helloJar = getOutputFilePath("hello.jar");
 209         deleteFile(helloJar);
 210         Path helloH = getInputFilePath("hello.h");
 211         Path rpathDir = getInputFilePath("libs");
 212         String warning = "WARNING: -infer-rpath used in conjunction with explicit -rpath paths";
 213         try {
 214             run("-rpath", rpathDir.toString(),
 215                     "-infer-rpath",
 216                     "-o", helloJar.toString(), helloH.toString())
 217                     .checkContainsOutput(warning)
 218                     .checkSuccess();
 219         } finally {
 220             deleteFile(helloJar);
 221         }
 222     }
 223 
 224     @Test
 225     public void test_option_rpath_no_libs() {
 226         Path helloJar = getOutputFilePath("hello.jar");
 227         deleteFile(helloJar);
 228         Path helloH = getInputFilePath("hello.h");
 229         String warning = "WARNING: -infer-rpath option specified without any -L option";
 230         try {
 231             run("-infer-rpath",
 232                     "-o", helloJar.toString(), helloH.toString())
 233                 .checkContainsOutput(warning)
 234                 .checkSuccess();
 235         } finally {
 236             deleteFile(helloJar);
 237         }
 238     }
 239 
 240     @Test
 241     public void test_option_l_no_crash_missing_lib() {
 242         Path helloJar = getOutputFilePath("hello.jar");
 243         deleteFile(helloJar);
 244         Path helloH = getInputFilePath("hello.h");
 245         String warning = "WARNING: Some library names could not be resolved";
 246         try {
 247             run("-L", "nonExistent",

 248                     "-l", "nonExistent",
 249                     "-o", helloJar.toString(), helloH.toString())
 250                     .checkContainsOutput(warning)
 251                     .checkSuccess();
 252         } finally {
 253             deleteFile(helloJar);
 254         }
 255     }
 256 
 257     @Test
 258     public void test_option_l() {
 259         Path helloJar = getOutputFilePath("hello.jar");
 260         deleteFile(helloJar);
 261         Path helloH = getInputFilePath("hello.h");
 262         run("-l", "hello", "-o", helloJar.toString(), helloH.toString()).checkSuccess();
 263         try {
 264             Class<?> cls = loadClass("hello", helloJar);
 265             // check that NativeHeader annotation captures -l value
 266             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 267             assertNotNull(header);
 268             assertEquals(header.libraries().length, 1);
 269             assertEquals(header.libraries()[0], "hello");
 270             // no library paths (rpath) set
 271             assertEquals(header.libraryPaths().length, 0);
 272         } finally {
 273             deleteFile(helloJar);
 274         }
 275     }
 276 
 277     @Test
 278     public void test_option_l_and_rpath() {
 279         Path helloJar = getOutputFilePath("hello.jar");
 280         deleteFile(helloJar);
 281     Path helloH = getInputFilePath("hello.h");
 282         Path rpathDir = getInputFilePath("libs");
 283         run("-l", "hello", "-rpath", rpathDir.toString(),
 284              "-o", helloJar.toString(), helloH.toString()).checkSuccess();
 285         try {
 286             Class<?> cls = loadClass("hello", helloJar);
 287             // check that NativeHeader annotation captures -l and -rpath values
 288             NativeHeader header = cls.getAnnotation(NativeHeader.class);
 289             assertNotNull(header);
 290             assertEquals(header.libraries().length, 1);
 291             assertEquals(header.libraries()[0], "hello");
 292             assertEquals(header.libraryPaths().length, 1);
 293             assertEquals(header.libraryPaths()[0], rpathDir.toString());
 294         } finally {
 295             deleteFile(helloJar);
 296         }
 297     }
 298 
 299     @Test
 300     public void testUnionDeclaration() {
 301         Path uniondeclJar = getOutputFilePath("uniondecl.jar");
 302         deleteFile(uniondeclJar);
 303         Path uniondeclH = getInputFilePath("uniondecl.h");
 304         try {
 305             run("-o", uniondeclJar.toString(), uniondeclH.toString()).checkSuccess();
 306             Class<?> unionCls = loadClass("uniondecl", uniondeclJar);
 307             assertNotNull(unionCls);
 308             boolean found = Arrays.stream(unionCls.getClasses()).
 309                 map(Class::getSimpleName).
 310                 filter(n -> n.equals("IntOrFloat")).
 311                 findFirst().isPresent();
 312             assertTrue(found, "uniondecl.IntOrFloat not found");
 313         } finally {
 314             deleteFile(uniondeclJar);
 315         }
 316     }
 317 
 318     private void testEnumConstGetters(Class<?> enumCls, List<String> names) {
 319         for (String name : names) {
 320             if (findEnumConstGet(enumCls, name) == null) {
 321                 throw new RuntimeException(enumCls.getName() + " misses " + name);
 322             }
 323         }
 324     }
 325 
 326     @Test
 327     public void testAnonymousEnum() {
 328         Path anonenumJar = getOutputFilePath("anonenum.jar");
 329         deleteFile(anonenumJar);
 330         Path anonenumH = getInputFilePath("anonenum.h");
 331         try {
 332             run("-o", anonenumJar.toString(), anonenumH.toString()).checkSuccess();
 333             Class<?> anonenumCls = loadClass("anonenum", anonenumJar);
 334             assertNotNull(anonenumCls);
 335             testEnumConstGetters(anonenumCls, List.of("RED", "GREEN", "BLUE"));
 336             testEnumConstGetters(anonenumCls, List.of(
 337                     "Java", "C", "CPP", "Python", "Ruby"));
 338             testEnumConstGetters(anonenumCls, List.of(
 339                     "XS", "S", "M", "L", "XL", "XXL"));
 340             testEnumConstGetters(anonenumCls, List.of(
 341                     "ONE", "TWO"));
 342 
 343             Class<?> enumClz[] = anonenumCls.getClasses();
 344             assert(enumClz.length >= 4);
 345 
 346             Class<?> enumCls = findClass(enumClz, "codetype_t");
 347             assertNotNull(enumCls);
 348 
 349             enumCls = findClass(enumClz, "SIZE");
 350             assertNotNull(enumCls);
 351 
 352             enumCls = findClass(enumClz, "temp");
 353             assertNotNull(enumCls);
 354 
 355             enumCls = findClass(enumClz, "temp_t");
 356             assertNotNull(enumCls);
 357         } finally {
 358             deleteFile(anonenumJar);
 359         }
 360     }
 361 
 362     @Test
 363     public void testExcludeSymbols() {
 364         Path helloJar = getOutputFilePath("hello.jar");
 365         deleteFile(helloJar);
 366         Path helloH = getInputFilePath("hello.h");
 367         run("-o", helloJar.toString(), helloH.toString()).checkSuccess();
 368         try {
 369             Class<?> cls = loadClass("hello", helloJar);
 370             // check a method for "void func()"
 371             assertNotNull(findMethod(cls, "func", Object[].class));
 372             assertNotNull(findMethod(cls, "func2", Object[].class));
 373             assertNotNull(findMethod(cls, "func3", Object[].class));
 374             // check a method for "void junk()"
 375             assertNotNull(findMethod(cls, "junk", Object[].class));
 376             assertNotNull(findMethod(cls, "junk2", Object[].class));
 377             assertNotNull(findMethod(cls, "junk3", Object[].class));
 378         } finally {
 379             deleteFile(helloJar);
 380         }
 381 
 382         // try with --exclude-symbols" this time.
 383         run("--exclude-symbols", "junk.*", "-o", helloJar.toString(), helloH.toString())
 384                 .checkSuccess();
 385         try {
 386             Class<?> cls = loadClass("hello", helloJar);
 387             // check a method for "void func()"
 388             assertNotNull(findMethod(cls, "func", Object[].class));
 389             assertNotNull(findMethod(cls, "func2", Object[].class));
 390             assertNotNull(findMethod(cls, "func3", Object[].class));
 391             // check a method for "void junk()"
 392             assertNull(findMethod(cls, "junk", Object[].class));
 393             assertNull(findMethod(cls, "junk2", Object[].class));
 394             assertNull(findMethod(cls, "junk3", Object[].class));
 395         } finally {
 396             deleteFile(helloJar);
 397         }
 398     }
 399 
 400     @Test
 401     public void testIncludeSymbols() {
 402         Path helloJar = getOutputFilePath("hello.jar");
 403         deleteFile(helloJar);
 404         Path helloH = getInputFilePath("hello.h");
 405         run("-o", helloJar.toString(), helloH.toString()).checkSuccess();
 406         try {
 407             Class<?> cls = loadClass("hello", helloJar);
 408             // check a method for "void func()"
 409             assertNotNull(findMethod(cls, "func", Object[].class));
 410             assertNotNull(findMethod(cls, "func2", Object[].class));
 411             assertNotNull(findMethod(cls, "func3", Object[].class));
 412             // check a method for "void junk()"
 413             assertNotNull(findMethod(cls, "junk", Object[].class));
 414             assertNotNull(findMethod(cls, "junk2", Object[].class));
 415             assertNotNull(findMethod(cls, "junk3", Object[].class));
 416         } finally {
 417             deleteFile(helloJar);
 418         }
 419 
 420         // try with --include-symbols" this time.
 421         run("--include-symbols", "junk.*", "-o", helloJar.toString(), helloH.toString()).checkSuccess();
 422         try {
 423             Class<?> cls = loadClass("hello", helloJar);
 424             // check a method for "void junk()"
 425             assertNotNull(findMethod(cls, "junk", Object[].class));
 426             assertNotNull(findMethod(cls, "junk2", Object[].class));
 427             assertNotNull(findMethod(cls, "junk3", Object[].class));
 428             // check a method for "void func()"
 429             assertNull(findMethod(cls, "func", Object[].class));
 430             assertNull(findMethod(cls, "func2", Object[].class));
 431             assertNull(findMethod(cls, "func3", Object[].class));
 432         } finally {
 433             deleteFile(helloJar);
 434         }
 435     }
 436 
 437     @Test
 438     public void testNoLocations() {
 439         Path simpleJar = getOutputFilePath("simple.jar");
 440         deleteFile(simpleJar);
 441         Path simpleH = getInputFilePath("simple.h");
 442         run("--no-locations", "-o", simpleJar.toString(), simpleH.toString()).checkSuccess();
 443         try {
 444             Class<?> simpleCls = loadClass("simple", simpleJar);
 445             Method func = findFirstMethod(simpleCls, "func");
 446             assertFalse(func.isAnnotationPresent(NativeLocation.class));
 447             Class<?> anonymousCls = loadClass("simple$anonymous", simpleJar);
 448             assertFalse(simpleCls.isAnnotationPresent(NativeLocation.class));
 449         } finally {
 450             deleteFile(simpleJar);
 451         }
 452     }
 453 
 454     @Test
 455     public void testIncludeExcludeSymbols() {
 456         Path helloJar = getOutputFilePath("hello.jar");
 457         deleteFile(helloJar);
 458         Path helloH = getInputFilePath("hello.h");
 459         run("-o", helloJar.toString(), helloH.toString()).checkSuccess();
 460         try {
 461             Class<?> cls = loadClass("hello", helloJar);
 462             // check a method for "void func()"
 463             assertNotNull(findMethod(cls, "func", Object[].class));
 464             assertNotNull(findMethod(cls, "func2", Object[].class));
 465             assertNotNull(findMethod(cls, "func3", Object[].class));
 466             // check a method for "void junk()"
 467             assertNotNull(findMethod(cls, "junk", Object[].class));
 468             assertNotNull(findMethod(cls, "junk2", Object[].class));
 469             assertNotNull(findMethod(cls, "junk3", Object[].class));
 470         } finally {
 471             deleteFile(helloJar);
 472         }
 473 
 474         // try with --include-symbols" this time.
 475         run("--include-symbols", "junk.*", "--exclude-symbols", "junk3",
 476              "-o", helloJar.toString(), helloH.toString()).checkSuccess();
 477         try {
 478             Class<?> cls = loadClass("hello", helloJar);
 479             // check a method for "void junk()"
 480             assertNotNull(findMethod(cls, "junk", Object[].class));
 481             assertNotNull(findMethod(cls, "junk2", Object[].class));
 482             // check a method for "void func()" - not included
 483             assertNull(findMethod(cls, "func", Object[].class));
 484             assertNull(findMethod(cls, "func2", Object[].class));
 485             assertNull(findMethod(cls, "func3", Object[].class));
 486             // excluded among the included set!
 487             assertNull(findMethod(cls, "junk3", Object[].class));
 488         } finally {
 489             deleteFile(helloJar);
 490         }
 491     }
 492 
 493     @Test
 494     public void testNestedStructsUnions() {
 495         Path nestedJar = getOutputFilePath("nested.jar");
 496         deleteFile(nestedJar);
 497         Path nestedH = getInputFilePath("nested.h");
 498         try {
 499             run("-o", nestedJar.toString(), nestedH.toString()).checkSuccess();
 500             Class<?> headerCls = loadClass("nested", nestedJar);
 501             assertNotNull(headerCls);
 502 
 503             Class<?> fooCls = loadClass("nested$Foo", nestedJar);
 504             assertNotNull(fooCls);
 505             // struct Foo has no getters for "x", "y" etc.
 506             assertNull(findStructFieldGet(fooCls, "x"));
 507             assertNull(findStructFieldGet(fooCls, "y"));
 508             // struct Foo has getters for bar and color
 509             assertNotNull(findStructFieldGet(fooCls, "bar"));
 510             assertNotNull(findStructFieldGet(fooCls, "color"));
 511             // make sure nested types are handled without nested namespace!
 512             assertNotNull(loadClass("nested$Bar", nestedJar));
 513             assertNotNull(loadClass("nested$Color", nestedJar));
 514 
 515             Class<?> uCls = loadClass("nested$U", nestedJar);
 516             assertNotNull(uCls);
 517             // union U has no getters for "x", "y" etc.
 518             assertNull(findStructFieldGet(uCls, "x"));
 519             assertNull(findStructFieldGet(uCls, "y"));


 566             assertNotNull(findStructFieldGet(myUnionCls, "k"));
 567             // "A", "B", "C" are enum constants -should not be in MyUnion
 568             assertNull(findStructFieldGet(myUnionCls, "A"));
 569             assertNull(findStructFieldGet(myUnionCls, "B"));
 570             assertNull(findStructFieldGet(myUnionCls, "C"));
 571             // anonymous enum constants are hoisted to containing scope
 572             assertNotNull(findEnumConstGet(headerCls, "A"));
 573             assertNotNull(findEnumConstGet(headerCls, "B"));
 574             assertNotNull(findEnumConstGet(headerCls, "C"));
 575         } finally {
 576             deleteFile(nestedJar);
 577         }
 578     }
 579 
 580     @Test
 581     public void testAnonymousStructTypeGlobalVar() {
 582         Path elaboratedTypeJar = getOutputFilePath("elaboratedtype.jar");
 583         deleteFile(elaboratedTypeJar);
 584         Path elaboratedTypeH = getInputFilePath("elaboratedtype.h");
 585         try {
 586             run("-o", elaboratedTypeJar.toString(), elaboratedTypeH.toString()).checkSuccess();
 587             Class<?> headerCls = loadClass("elaboratedtype", elaboratedTypeJar);
 588             assertNotNull(findGlobalVariableGet(headerCls, "point"));
 589             assertNotNull(findGlobalVariableGet(headerCls, "long_or_int"));
 590             assertNotNull(findMethod(headerCls, "func", Pointer.class));
 591         } finally {
 592             deleteFile(elaboratedTypeJar);
 593         }
 594     }
 595 
 596     private void testBuiltinInclude(String name) {
 597         Path fileJar = getOutputFilePath(name + "inc.jar");
 598         deleteFile(fileJar);
 599         Path fileH = getInputFilePath(name + "inc.h");
 600         run("-o", fileJar.toString(), fileH.toString()).checkSuccess();
 601         deleteFile(fileJar);
 602     }
 603 
 604     @Test
 605     public void testBuiltinHeader() {
 606         testBuiltinInclude("stdarg");
 607         testBuiltinInclude("stdbool");
 608     }
 609 
 610     @Test
 611     public void testGlobalFuncPointerCallback() {
 612         Path globalFuncPointerJar = getOutputFilePath("globalFuncPointer.jar");
 613         deleteFile(globalFuncPointerJar);
 614         Path globalFuncPointerH = getInputFilePath("globalFuncPointer.h");
 615         run("-o", globalFuncPointerJar.toString(), globalFuncPointerH.toString()).checkSuccess();
 616         Class<?> callbackCls = loadClass("globalFuncPointer$FI1", globalFuncPointerJar);
 617         Method callback = findFirstMethod(callbackCls, "fn");
 618         assertNotNull(callback);
 619         assertTrue(callback.isVarArgs());
 620         deleteFile(globalFuncPointerJar);
 621     }
 622 
 623     @Test
 624     public void testFuncPtrTypedef() {
 625         Path funcPtrTypedefJar = getOutputFilePath("funcPtrTypedef.jar");
 626         deleteFile(funcPtrTypedefJar);
 627         Path funcPtrTypedefH = getInputFilePath("funcPtrTypedef.h");
 628         run("-o", funcPtrTypedefJar.toString(), funcPtrTypedefH.toString()).checkSuccess();
 629         // force parsing of class, method
 630         Class<?> headerCls = loadClass("funcPtrTypedef", funcPtrTypedefJar);
 631         Method getter = findFirstMethod(headerCls, "my_function$get");
 632         assertNotNull(getter);
 633         assertNotNull(getter.getGenericParameterTypes());
 634         deleteFile(funcPtrTypedefJar);
 635     }
 636 
 637     @Test
 638     public void testDuplicatedecls() {
 639         Path duplicatedeclsJar = getOutputFilePath("duplicatedecls.jar");
 640         deleteFile(duplicatedeclsJar);
 641         Path duplicatedeclsH = getInputFilePath("duplicatedecls.h");
 642         run("-o", duplicatedeclsJar.toString(), duplicatedeclsH.toString()).checkSuccess();
 643         // load the class to make sure no duplicate methods generated in it
 644         Class<?> headerCls = loadClass("duplicatedecls", duplicatedeclsJar);
 645         assertNotNull(headerCls);
 646         deleteFile(duplicatedeclsJar);
 647     }
 648 }
< prev index next >