1 /* 2 * Copyright (c) 2018, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 import org.testng.annotations.*; 27 28 import java.lang.invoke.MethodHandles; 29 import java.lang.reflect.Proxy; 30 import java.nio.file.Path; 31 import java.util.stream.Stream; 32 33 import static org.testng.Assert.assertEquals; 34 import static org.testng.Assert.assertNotNull; 35 import static org.testng.Assert.assertTrue; 36 37 38 /* 39 * @test 40 * @modules jdk.jextract 41 * @build ConstantsTest 42 * @run testng ConstantsTest 43 */ 44 public class ConstantsTest extends JextractToolRunner { 45 46 Object[] constants; 47 Path clzPath; 48 Path dirPath; 49 50 @BeforeTest 51 public void setup() { 52 clzPath = getOutputFilePath("ConstantsTest.c.jar"); 53 dirPath = getOutputFilePath("ConstantsTest.c.dir"); 54 checkSuccess(null,"-o", clzPath.toString(), "-d", dirPath.toString(), 55 getInputFilePath("constants.h").toString()); 56 Class<?>[] cls = { 57 loadClass("constants", clzPath), 58 loadClass("constants", dirPath) 59 }; 60 constants = new Object[cls.length]; 61 for (int i = 0 ; i < cls.length ; i++) { 62 Class<?> cl = cls[i]; 63 constants[i] = Proxy.newProxyInstance(cl.getClassLoader(), 64 new Class<?>[]{ cl }, 65 (proxy, method, args) -> MethodHandles.privateLookupIn(cl, MethodHandles.lookup()) 66 .unreflectSpecial(method, cl) 67 .bindTo(proxy) 68 .invokeWithArguments(args)); 69 } 70 } 71 72 @AfterTest 73 public void cleanup() { 74 deleteFile(clzPath); 75 deleteDir(dirPath); 76 } 77 78 79 @Test(dataProvider = "definedConstants") 80 public void checkConstantsSignatures(String name, Class<?> type, Object value) { 81 for (Object c : constants) { 82 checkMethod(c.getClass(), name, type); 83 } 84 } 85 86 @Test(dataProvider = "definedConstants") 87 public void checkConstantsValues(String name, Class<?> type, Object value) throws ReflectiveOperationException { 88 for (Object c : constants) { 89 Object actual = c.getClass().getDeclaredMethod(name).invoke(c); 90 assertEquals(actual, value); 91 } 92 } 93 94 @Test(dataProvider = "missingConstants") 95 public void checkMissingConstants(String name) { 96 for (Object c : constants) { 97 assertTrue(Stream.of(c.getClass().getDeclaredMethods()) 98 .noneMatch(m -> m.getName().equals(name))); 99 } 100 } 101 102 @DataProvider 103 public static Object[][] definedConstants() { 104 return new Object[][] { 105 { "ZERO", int.class, 0 }, 106 { "ONE", int.class, 1 }, 107 { "TWO", int.class, 2 }, 108 { "THREE", int.class, 3 }, 109 { "FOUR", long.class, 4L }, 110 { "FIVE", long.class, 5L }, 111 { "SIX", int.class, 6 }, 112 { "STR", String.class, "Hello" }, 113 { "FLOAT_VALUE", float.class, 1.32f }, 114 { "DOUBLE_VALUE", double.class, 1.32 }, 115 { "QUOTE", String.class, "QUOTE" }, 116 { "CHAR_VALUE", char.class, 'h'}, 117 { "SUB", int.class, 7 } 118 }; 119 } 120 121 @DataProvider 122 public static Object[][] missingConstants() { 123 return new Object[][] { 124 { "ID" }, 125 { "SUM" }, 126 { "BLOCK_BEGIN" }, 127 { "BLOCK_END" }, 128 { "INTEGER_MAX_VALUE" }, 129 { "CYCLIC_1" }, 130 { "CYCLIC_2" }, 131 { "SUP" }, 132 { "UNUSED" } 133 }; 134 } 135 }