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