Skip to content

Commit ed21311

Browse files
committed
8229186: Improve error messages for TestStringIntrinsics failures
1 parent c8257ea commit ed21311

File tree

6 files changed

+1077
-12
lines changed

6 files changed

+1077
-12
lines changed

test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,16 @@
2525
* @test
2626
* @bug 8054307
2727
* @summary Tests correctness of string related intrinsics and C2 optimizations.
28+
* @library /test/lib
2829
*
2930
* @run main/timeout=240 compiler.intrinsics.string.TestStringIntrinsics
3031
*/
3132

3233
package compiler.intrinsics.string;
3334

35+
import jdk.test.lib.format.Format;
36+
import jdk.test.lib.format.ArrayCodec;
37+
3438
import java.lang.annotation.ElementType;
3539
import java.lang.annotation.Retention;
3640
import java.lang.annotation.RetentionPolicy;
@@ -77,8 +81,8 @@ public void run() throws Exception {
7781
for (Method m : TestStringIntrinsics.class.getMethods()) {
7882
if (m.isAnnotationPresent(Test.class)) {
7983
System.out.print("Checking " + m.getName() + "... ");
80-
Operation op = m.getAnnotation(Test.class).op();
8184
Test antn = m.getAnnotation(Test.class);
85+
Operation op = antn.op();
8286
if (isStringConcatTest(op)) {
8387
checkStringConcat(op, m, antn);
8488
} else {
@@ -121,13 +125,13 @@ private void checkIntrinsics(Operation op, Method m, String latin1, String utf16
121125

122126
switch (op) {
123127
case ARR_EQUALS_B:
124-
invokeAndCheck(m, (incL == 0), latin1.getBytes("ISO-8859-1"), latin1Copy.getBytes("ISO-8859-1"));
125-
invokeAndCheck(m, true, new byte[] {1, 2, 3}, new byte[] {1, 2, 3});
126-
invokeAndCheck(m, true, new byte[] {1}, new byte[] {1});
127-
invokeAndCheck(m, true, new byte[] {}, new byte[] {});
128+
invokeAndCompareArrays(m, (incL == 0), latin1.getBytes("ISO-8859-1"), latin1Copy.getBytes("ISO-8859-1"));
129+
invokeAndCompareArrays(m, true, new byte[] {1, 2, 3}, new byte[] {1, 2, 3});
130+
invokeAndCompareArrays(m, true, new byte[] {1}, new byte[] {1});
131+
invokeAndCompareArrays(m, true, new byte[] {}, new byte[] {});
128132
break;
129133
case ARR_EQUALS_C:
130-
invokeAndCheck(m, (incU == 0), utf16.toCharArray(), arrU);
134+
invokeAndCompareArrays(m, (incU == 0), utf16.toCharArray(), arrU);
131135
break;
132136
case EQUALS:
133137
invokeAndCheck(m, (incL == 0), latin1, latin1Copy);
@@ -240,18 +244,44 @@ private void checkStringConcat(Operation op, Method m, Test antn) throws Excepti
240244
}
241245
}
242246

247+
/**
248+
* Invokes method 'm' by passing arguments the two 'args' (which are supposed to be arrays)
249+
* checks if the returned value. In case of error and arrays being not equal, prints their difference.
250+
*/
251+
private void invokeAndCompareArrays(Method m, boolean expectedResult, Object arg0, Object arg1) throws Exception {
252+
boolean result = (Boolean)m.invoke(null, arg0, arg1);
253+
if (expectedResult == result)
254+
return;
255+
256+
String cause = String.format("Result: (%b) of '%s' is not equal to expected (%b)",
257+
result, m.getName(), expectedResult);
258+
259+
if (expectedResult == true) {
260+
System.err.println(cause);
261+
System.err.println(Format.arrayDiff(arg0, arg1));
262+
} else {
263+
System.err.println(cause);
264+
System.err.printf("First array argument: %n %s%n", ArrayCodec.format(arg0));
265+
}
266+
267+
throw new RuntimeException(cause);
268+
}
269+
243270
/**
244271
* Invokes method 'm' by passing arguments 'args' and checks if the
245272
* returned value equals 'expectedResult'.
246273
*/
247274
private void invokeAndCheck(Method m, Object expectedResult, Object... args) throws Exception {
248275
Object result = m.invoke(null, args);
249276
if (!result.equals(expectedResult)) {
250-
// System.out.println("Expected:");
251-
// System.out.println(expectedResult);
252-
// System.out.println("Returned:");
253-
// System.out.println(result);
254-
throw new RuntimeException("Result of '" + m.getName() + "' not equal to expected value.");
277+
String message = "Result of '" + m.getName() + "' not equal to expected value.";
278+
System.err.println(message);
279+
System.err.println("Expected: " + Format.asLiteral(expectedResult));
280+
System.err.println("Result: " + Format.asLiteral(result));
281+
for (int i = 0; i < args.length; i++) {
282+
System.err.println("Arg" + i + ": " + Format.asLiteral(args[i]));
283+
}
284+
throw new RuntimeException(message);
255285
}
256286
}
257287

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
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+
package jdk.test.lib.format;
25+
26+
import org.testng.annotations.Test;
27+
28+
import static org.testng.Assert.assertTrue;
29+
import static org.testng.Assert.assertFalse;
30+
import static org.testng.Assert.assertEquals;
31+
32+
/*
33+
* @test
34+
* @summary Check ArrayDiff formatting
35+
* @library /test/lib
36+
* @run testng jdk.test.lib.format.ArrayDiffTest
37+
*/
38+
public class ArrayDiffTest {
39+
40+
@Test
41+
public void testEqualArrays() {
42+
char[] first = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
43+
char[] second = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
44+
45+
assertTrue(ArrayDiff.of(first, second).areEqual());
46+
}
47+
48+
@Test
49+
public void testOutputFitsWidth() {
50+
byte[] first = new byte[] {7, 8, 9, 10, 11, 12, 13};
51+
byte[] second = new byte[] {7, 8, 9, 10, 125, 12, 13};
52+
53+
ArrayDiff diff = ArrayDiff.of(first, second);
54+
String expected = String.format(
55+
"Arrays differ starting from [index: 4]:%n" +
56+
"[7, 8, 9, 10, 11, 12, 13]%n" +
57+
"[7, 8, 9, 10, 125, 12, 13]%n" +
58+
" ^^^^");
59+
60+
assertFalse(diff.areEqual());
61+
assertEquals(diff.format(), expected);
62+
}
63+
64+
@Test
65+
public void testIntegers() {
66+
int[] first = new int[] {7, 8, 10, 11, 12};
67+
int[] second = new int[] {7, 8, 9, 10, 11, 12, 13};
68+
69+
ArrayDiff diff = ArrayDiff.of(first, second);
70+
String expected = String.format(
71+
"Arrays differ starting from [index: 2]:%n" +
72+
"[7, 8, 10, 11, 12]%n" +
73+
"[7, 8, 9, 10, 11, 12, 13]%n" +
74+
" ^^^");
75+
76+
assertFalse(diff.areEqual());
77+
assertEquals(diff.format(), expected);
78+
}
79+
80+
@Test
81+
public void testLongs() {
82+
long[] first = new long[] {1, 2, 3, 4};
83+
long[] second = new long[] {1, 2, 3, 10};
84+
85+
ArrayDiff diff = ArrayDiff.of(first, second);
86+
String expected = String.format(
87+
"Arrays differ starting from [index: 3]:%n" +
88+
"[1, 2, 3, 4]%n" +
89+
"[1, 2, 3, 10]%n" +
90+
" ^^^");
91+
92+
assertFalse(diff.areEqual());
93+
assertEquals(diff.format(), expected);
94+
}
95+
96+
@Test
97+
public void testFirstElementIsWrong() {
98+
byte[] first = new byte[] {122};
99+
byte[] second = new byte[] {7, 8, 9, 10, 125, 12, 13};
100+
101+
ArrayDiff diff = ArrayDiff.of(first, second);
102+
String expected = String.format(
103+
"Arrays differ starting from [index: 0]:%n" +
104+
"[122]%n" +
105+
"[ 7, 8, 9, 10, 125, 12, 13]%n" +
106+
" ^^^");
107+
108+
assertFalse(diff.areEqual());
109+
assertEquals(diff.format(), expected);
110+
}
111+
112+
@Test
113+
public void testOneElementIsEmpty() {
114+
byte[] first = new byte[] {7, 8, 9, 10, 125, 12, 13};
115+
byte[] second = new byte[] {};
116+
117+
ArrayDiff diff = ArrayDiff.of(first, second);
118+
String expected = String.format(
119+
"Arrays differ starting from [index: 0]:%n" +
120+
"[7, 8, 9, 10, 125, 12, 13]%n" +
121+
"[]%n" +
122+
" ^");
123+
124+
assertFalse(diff.areEqual());
125+
assertEquals(diff.format(), expected);
126+
}
127+
128+
@Test
129+
public void testOutputDoesntFitWidth() {
130+
char[] first = new char[] {'1', '2', '3', '4', '5', '6', '7'};
131+
char[] second = new char[] {'1', 'F', '3', '4', '5', '6', '7'};
132+
133+
ArrayDiff diff = ArrayDiff.of(first, second, 20, Integer.MAX_VALUE);
134+
String expected = String.format(
135+
"Arrays differ starting from [index: 1]:%n" +
136+
"[1, 2, 3, 4, 5, ...%n" +
137+
"[1, F, 3, 4, 5, ...%n" +
138+
" ^^");
139+
140+
assertFalse(diff.areEqual());
141+
assertEquals(diff.format(), expected);
142+
}
143+
144+
@Test
145+
public void testVariableElementWidthOutputDoesntFitWidth() {
146+
byte[] first = new byte[] {1, 2, 3, 4, 5, 6, 7};
147+
byte[] second = new byte[] {1, 112, 3, 4, 5, 6, 7};
148+
149+
ArrayDiff diff = ArrayDiff.of(first, second, 20, Integer.MAX_VALUE);
150+
String expected = String.format(
151+
"Arrays differ starting from [index: 1]:%n" +
152+
"[1, 2, 3, 4, 5, ...%n" +
153+
"[1, 112, 3, 4, 5, ...%n" +
154+
" ^^^^");
155+
156+
assertFalse(diff.areEqual());
157+
assertEquals(diff.format(), expected);
158+
}
159+
160+
@Test
161+
public void testContextBefore() {
162+
char[] first = new char[] {'1', '2', '3', '4', '5', '6', '7'};
163+
char[] second = new char[] {'1', '2', '3', '4', 'F', '6', '7'};
164+
165+
ArrayDiff diff = ArrayDiff.of(first, second, 20, 2);
166+
String expected = String.format(
167+
"Arrays differ starting from [index: 4]:%n" +
168+
"... 3, 4, 5, 6, 7]%n" +
169+
"... 3, 4, F, 6, 7]%n" +
170+
" ^^");
171+
172+
assertFalse(diff.areEqual());
173+
assertEquals(diff.format(), expected);
174+
}
175+
176+
@Test
177+
public void testBoundedBytesWithDifferentWidth() {
178+
byte[] first = new byte[] {0, 1, 2, 3, 125, 5, 6, 7};
179+
byte[] second = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
180+
181+
ArrayDiff diff = ArrayDiff.of(first, second, 24, 2);
182+
String expected = String.format(
183+
"Arrays differ starting from [index: 4]:%n" +
184+
"... 2, 3, 125, 5, 6, 7]%n" +
185+
"... 2, 3, 4, 5, 6, 7]%n" +
186+
" ^^^^");
187+
188+
assertFalse(diff.areEqual());
189+
assertEquals(diff.format(), expected);
190+
}
191+
192+
@Test
193+
public void testBoundedFirstElementIsWrong() {
194+
byte[] first = new byte[] {101, 102, 103, 104, 105, 110};
195+
byte[] second = new byte[] {2};
196+
197+
ArrayDiff diff = ArrayDiff.of(first, second, 25, 2);
198+
String expected = String.format(
199+
"Arrays differ starting from [index: 0]:%n" +
200+
"[101, 102, 103, 104, ...%n" +
201+
"[ 2]%n" +
202+
" ^^^");
203+
204+
assertFalse(diff.areEqual());
205+
assertEquals(diff.format(), expected);
206+
}
207+
208+
@Test
209+
public void testBoundedOneArchiveIsEmpty() {
210+
char[] first = new char[] {'a', 'b', 'c', 'd', 'e'};
211+
char[] second = new char[] {};
212+
213+
ArrayDiff diff = ArrayDiff.of(first, second, 10, 2);
214+
String expected = String.format(
215+
"Arrays differ starting from [index: 0]:%n" +
216+
"[a, b, ...%n" +
217+
"[]%n" +
218+
" ^");
219+
220+
assertFalse(diff.areEqual());
221+
assertEquals(diff.format(), expected);
222+
}
223+
224+
@Test
225+
public void testUnboundedOneArchiveIsEmpty() {
226+
char[] first = new char[] {'a', 'b', 'c', 'd', 'e'};
227+
char[] second = new char[] {};
228+
229+
ArrayDiff diff = ArrayDiff.of(first, second);
230+
String expected = String.format(
231+
"Arrays differ starting from [index: 0]:%n" +
232+
"[a, b, c, d, e]%n" +
233+
"[]%n" +
234+
" ^");
235+
236+
assertFalse(diff.areEqual());
237+
assertEquals(diff.format(), expected);
238+
}
239+
240+
@Test
241+
public void testUnprintableCharFormatting() {
242+
char[] first = new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
243+
char[] second = new char[] {0, 1, 2, 3, 4, 5, 6, 125, 8, 9, 10, 11, 12, 13, 14, 15, 16};
244+
245+
ArrayDiff diff = ArrayDiff.of(first, second);
246+
247+
// Lines in the code look like aren't aligned due to slashes taking more space than spaces.
248+
var nl = System.lineSeparator();
249+
String expected = "Arrays differ starting from [index: 7]:" + nl +
250+
"... \\u0005, \\u0006, \\u0007, \\u0008, \\u0009, \\n, \\u000B, \\u000C, \\r, \\u000E, ..." + nl +
251+
"... \\u0005, \\u0006, }, \\u0008, \\u0009, \\n, \\u000B, \\u000C, \\r, \\u000E, ..." + nl +
252+
" ^^^^^^^";
253+
assertFalse(diff.areEqual());
254+
assertEquals(diff.format(), expected);
255+
}
256+
257+
@Test
258+
public void testStringElements() {
259+
String[] first = new String[] {"first", "second", "third", "u\nprintable"};
260+
String[] second = new String[] {"first", "second", "incorrect", "u\nprintable"};
261+
262+
ArrayDiff diff = ArrayDiff.of(first, second);
263+
String expected = String.format(
264+
"Arrays differ starting from [index: 2]:%n" +
265+
"[\"first\", \"second\", \"third\", \"u\\nprintable\"]%n" +
266+
"[\"first\", \"second\", \"incorrect\", \"u\\nprintable\"]%n" +
267+
" ^^^^^^^^^^^^");
268+
269+
assertFalse(diff.areEqual());
270+
assertEquals(diff.format(), expected);
271+
}
272+
273+
@Test
274+
public void testToStringableObjects() {
275+
class StrObj {
276+
private final String value;
277+
public boolean equals(Object another) { return ((StrObj)another).value.equals(value); }
278+
public StrObj(String value) { this.value = value; }
279+
public String toString() { return value; }
280+
}
281+
282+
StrObj[] first = new StrObj[] {new StrObj("1"), new StrObj("Unp\rintable"), new StrObj("5")};
283+
StrObj[] second = new StrObj[] {new StrObj("1"), new StrObj("2"), new StrObj("5")};
284+
285+
ArrayDiff diff = ArrayDiff.of(first, second);
286+
String expected = String.format(
287+
"Arrays differ starting from [index: 1]:%n" +
288+
"[1, Unp\\rintable, 5]%n" +
289+
"[1, 2, 5]%n" +
290+
" ^^^^^^^^^^^^^");
291+
292+
assertFalse(diff.areEqual());
293+
assertEquals(diff.format(), expected);
294+
}
295+
296+
}

0 commit comments

Comments
 (0)