1 /*
  2  * Copyright (c) 2024, 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 jdk.incubator.code.CodeReflection;
 25 import jdk.incubator.code.Op;
 26 import jdk.incubator.code.OpTransformer;
 27 import jdk.incubator.code.dialect.core.CoreOp;
 28 import jdk.incubator.code.interpreter.Interpreter;
 29 import org.junit.jupiter.api.Assertions;
 30 import org.junit.jupiter.api.Test;
 31 
 32 import java.lang.invoke.MethodHandles;
 33 import java.lang.reflect.Method;
 34 import java.util.List;
 35 
 36 /*
 37  * @test
 38  * @modules jdk.incubator.code
 39  * @run junit/othervm -ea TestAssert
 40  */
 41 public class TestAssert {
 42 
 43     public static final String FAILURESTRING = "failure";
 44     public static final char FAILURECHAR = 'o';
 45 
 46     public static final float FAILUREFLOAT = -1.0f;
 47     public static final double FAILUREDOUBLE = -1.0d;
 48     public static final byte FAILUREBYTE = -1;
 49     public static final short FAILURESHORT = -1;
 50     public static final int FAILUREINT = -1;
 51 
 52     public static final long FAILURELONG = -1;
 53 
 54     public static final String FAILUREOBJECTMSG = "FAILURE OBJECT";
 55 
 56     public static final Object FAILUREOBJECT = new FailureObject();
 57 
 58 
 59     @Test
 60     public void testAssertThrows(){
 61         testThrows("assertThrow");
 62     }
 63 
 64     @Test
 65     public void testAssertString(){
 66         AssertionError ae = testThrows("assertThrowWithMessage");
 67         if (ae.getMessage() == null || !ae.getMessage().equals(FAILURESTRING)) {
 68             Assertions.fail("Assertion failure messages do not match.");
 69         }
 70     }
 71 
 72     @Test
 73     public void testAssertChar() {
 74         AssertionError ae = testThrows("assertChar");
 75         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILURECHAR))){
 76             Assertions.fail("Assertion failure messages do not match.");
 77         }
 78     }
 79 
 80     @Test
 81     public void testAssertFloat() {
 82         AssertionError ae = testThrows("assertFloat");
 83         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREFLOAT))){
 84             Assertions.fail("Assertion failure messages do not match.");
 85         }
 86     }
 87 
 88     @Test
 89     public void testAssertDouble() {
 90         AssertionError ae = testThrows("assertDouble");
 91         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREDOUBLE))){
 92             Assertions.fail("Assertion failure messages do not match.");
 93         }
 94     }
 95 
 96     @Test
 97     public void testAssertByte() {
 98         AssertionError ae = testThrows("assertByte");
 99         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREBYTE))){
100             Assertions.fail("Assertion failure messages do not match.");
101         }
102     }
103 
104     @Test
105     public void testAssertShort() {
106         AssertionError ae = testThrows("assertShort");
107         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILURESHORT))){
108             Assertions.fail("Assertion failure messages do not match.");
109         }
110     }
111 
112     @Test
113     public void testAssertInt() {
114         AssertionError ae = testThrows("assertInt");
115         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREINT))){
116             Assertions.fail("Assertion failure messages do not match.");
117         }
118     }
119 
120     @Test
121     public void testAssertLong() {
122         AssertionError ae = testThrows("assertLong");
123         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILURELONG))){
124             Assertions.fail("Assertion failure messages do not match.");
125         }
126     }
127 
128     @Test
129     public void testAssertObject() {
130         AssertionError ae = testThrows("assertObject");
131         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREOBJECT))){
132             Assertions.fail("Assertion failure messages do not match.");
133         }
134     }
135 
136     @Test
137     public void testAssertExpr1() {
138         AssertionError ae = testThrows("assertExpr1");
139         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREINT + FAILURELONG))){
140             Assertions.fail("Assertion failure messages do not match.");
141         }
142     }
143 
144     @Test
145     public void testAssertExpr2() {
146         AssertionError ae = testThrows("assertExpr2", List.of(int.class), 52);
147         if (ae.getMessage() == null || !ae.getMessage().equals(String.valueOf(FAILUREINT))){
148             Assertions.fail("Assertion failure messages do not match.");
149         }
150     }
151 
152     @Test
153     public void testAssertExpr3() {
154          testRun("assertExpr3", List.of(int.class), 52);
155     }
156 
157     private static AssertionError testThrows(String methodName) {
158         return testThrows(methodName, List.of());
159     }
160     private static void testRun(String methodName, List<Class<?>> params, Object...args) {
161         try {
162             Class<TestAssert> clazz = TestAssert.class;
163             Method method = clazz.getDeclaredMethod(methodName,params.toArray(new Class[params.size()]));
164             CoreOp.FuncOp f = Op.ofMethod(method).orElseThrow();
165 
166             //Ensure we're fully lowered before testing.
167             final var fz = f.transform(OpTransformer.LOWERING_TRANSFORMER);
168 
169             Interpreter.invoke(MethodHandles.lookup(), fz ,args);
170         } catch (NoSuchMethodException e) {
171             throw new RuntimeException(e);
172         }
173     }
174 
175     private static AssertionError testThrows(String methodName, List<Class<?>> params, Object...args) {
176         try {
177             Class<TestAssert> clazz = TestAssert.class;
178             Method method = clazz.getDeclaredMethod(methodName,params.toArray(new Class[params.size()]));
179             CoreOp.FuncOp f = Op.ofMethod(method).orElseThrow();
180 
181             //Ensure we're fully lowered before testing.
182             final var fz = f.transform(OpTransformer.LOWERING_TRANSFORMER);
183 
184 
185             AssertionError ae = (AssertionError) retCatch(() -> Interpreter.invoke(MethodHandles.lookup(), fz ,args));
186             Assertions.assertNotNull(ae);
187             return ae;
188         } catch (NoSuchMethodException e) {
189             throw new RuntimeException(e);
190         }
191     }
192 
193     private static Throwable retCatch(Runnable r) {
194         try {
195             r.run();
196         } catch (Throwable t) {
197             return t;
198         }
199         return null;
200     }
201 
202 
203 
204     @CodeReflection
205     public static void assertThrow() {
206         assert false;
207     }
208 
209     @CodeReflection
210     public static void assertThrowWithMessage() {
211         assert false : FAILURESTRING;
212     }
213 
214     @CodeReflection
215     public static void assertChar() {
216         char c = FAILURECHAR;
217         assert false : c;
218     }
219 
220     @CodeReflection
221     public static void assertFloat() {
222         float f = FAILUREFLOAT;
223         assert false : f;
224     }
225 
226     @CodeReflection
227     public static void assertDouble() {
228         double d = FAILUREDOUBLE;
229         assert false : d;
230     }
231 
232     @CodeReflection
233     public static void assertByte() {
234         byte b = FAILUREBYTE;
235         assert false : b;
236     }
237 
238     @CodeReflection
239     public static void assertShort() {
240         short s = FAILURESHORT;
241         assert false : s;
242     }
243 
244     @CodeReflection
245     public static void assertInt() {
246         int i = FAILUREINT;
247         assert false : i;
248     }
249 
250     @CodeReflection
251     public static void assertLong() {
252         long l = FAILURELONG;
253         assert false : l;
254     }
255 
256     @CodeReflection
257     public static void assertObject() {
258         Object o = FAILUREOBJECT;
259         assert false : o;
260     }
261 
262     @CodeReflection
263     public static void assertExpr1() {
264         int i = FAILUREINT;
265         long l = FAILURELONG;
266         assert false : i + l;
267         String y = "test";
268     }
269 
270     @CodeReflection
271     public static void assertExpr2(int iz) {
272         int i = FAILUREINT;
273         long l = FAILURELONG;
274         assert false : (i > iz) ? i + l : i;
275         String s = "";
276     }
277 
278     @CodeReflection
279     public static void assertExpr3(int iz) {
280         int i = FAILUREINT;
281         long l = FAILURELONG;
282         assert true : (i > iz) ? i + l : i;
283         String s = "";
284     }
285 
286     static class FailureObject {
287         @Override
288         public String toString(){
289            return FAILUREOBJECTMSG;
290         }
291     }
292 }