1/*
2 * Copyright (c) 2001, 2015, 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/**
25 * @test
26 * @bug 4439631
27 * @bug 4448721
28 * @bug 4448603
29 * @summary Test access to ranges within ArrayReferences
30 * @author Robert Field
31 *
32 * @run build TestScaffold VMConnection TargetListener TargetAdapter
33 * @run compile -g ArrayRangeTest.java
34 * @run driver ArrayRangeTest
35 */
36import com.sun.jdi.*;
37import com.sun.jdi.event.*;
38import com.sun.jdi.request.*;
39
40import java.util.*;
41
42    /********** target program **********/
43
44class ArrayRangeTarg {
45    static int[] emptyArray = {};
46    static int[] fullArray = {0, 100, 200, 300, 400};
47
48    public static void main(String[] args) {
49        System.out.println("Goodbye from ArrayRangeTarg!");
50    }
51}
52
53    /********** test program **********/
54
55public class ArrayRangeTest extends TestScaffold {
56    ReferenceType targetClass;
57
58    class Sample {
59        Sample(String name, ArrayReference arrRef, int[] expected) {
60            this.name = name;
61            this.arrRef = arrRef;
62            this.expected = expected;
63        }
64        String name;
65        ArrayReference arrRef;
66        int[] expected;
67    }
68
69    ArrayRangeTest (String args[]) {
70        super(args);
71    }
72
73    public static void main(String[] args)      throws Exception {
74        new ArrayRangeTest(args).startTests();
75    }
76
77    /********** test assist **********/
78
79    String arr(int a[]) {
80        StringBuffer buf = new StringBuffer();
81        buf.append('[');
82        if (a.length > 0) {
83            buf.append(a[0]);
84            for (int i = 1; i < a.length; ++i) {
85                buf.append(',');
86                buf.append(a[i]);
87            }
88        }
89        buf.append(']');
90        return buf.toString();
91    }
92
93    void getValueGood(Sample samp, int index) {
94        try {
95            Value val = samp.arrRef.getValue(index);
96            int ival = ((IntegerValue)val).value();
97            if (ival != samp.expected[index]) {
98                failure("FAIL - " + samp.name +
99                        ".getValue(" + index + ") - wrong value=" + ival);
100            } else {
101                println("pass - " + samp.name +
102                        ".getValue(" + index + ") - value=" + ival);
103            }
104        } catch (Throwable exc) {
105            failure("FAIL - " + samp.name +
106                    ".getValue(" + index + ") - unexpected: " + exc);
107        }
108    }
109
110    void getValueBad(Sample samp, int index) {
111        try {
112            Value val = samp.arrRef.getValue(index);
113            failure("FAIL - " + samp.name +
114                    ".getValue(" + index + ") - no expected exception");
115        } catch (IndexOutOfBoundsException exc) {
116            println("pass - " + samp.name +
117                    ".getValue(" + index + ") - got expected: " + exc);
118        } catch (Throwable exc) {
119            failure("FAIL - " + samp.name +
120                    ".getValue(" + index + ") - unexpected: " + exc);
121        }
122    }
123
124    void getValuesGood(Sample samp) {
125        String desc = samp.name + ".getValues()";
126        try {
127            List vals = samp.arrRef.getValues();
128            if (vals.size() != samp.expected.length) {
129                failure("FAIL - " + desc +
130                        " - wrong size=" + vals.size() +
131                        " , expected: " + samp.expected.length);
132            }
133            for (int index = 0; index < vals.size(); ++index) {
134                int ival = ((IntegerValue)vals.get(index)).value();
135                if (ival != samp.expected[index]) {
136                    failure("FAIL - " + desc +
137                            " - wrong value=" + ival);
138                    return;
139                }
140            }
141            println("pass - " + samp.name + ".getValues())");
142        } catch (Throwable exc) {
143            failure("FAIL - " + desc  +
144                    " - unexpected: " + exc);
145        }
146    }
147
148    void getValuesGood(Sample samp, int index, int length) {
149        try {
150            List vals = samp.arrRef.getValues(index, length);
151            if (vals.size() !=
152                 ((length==-1)? (samp.expected.length - index) : length)) {
153                failure("FAIL - " + samp.name + ".getValues(" +
154                        index + ", " + length + ") - wrong size=" +
155                        vals.size());
156            }
157            for (int i = 0; i < vals.size(); ++i) {
158                int ival = ((IntegerValue)vals.get(i)).value();
159                if (ival != samp.expected[index + i]) {
160                    failure("FAIL - " + samp.name + ".getValues(" +
161                            index + ", " + length + ") - wrong value=" +
162                            ival);
163                    return;
164                }
165            }
166            println("pass - " + samp.name + ".getValues(" +
167                    index + ", " + length + "))");
168        } catch (Throwable exc) {
169            failure("FAIL - " + samp.name + ".getValues(" +
170                    index + ", " + length + ") - unexpected: " + exc);
171        }
172    }
173
174    void getValuesBad(Sample samp, int index, int length) {
175        try {
176            List vals = samp.arrRef.getValues(index, length);
177            failure("FAIL - " + samp.name + ".getValues(" +
178                        index + ", " + length + ") - no expected exception");
179        } catch (IndexOutOfBoundsException exc) {
180            println("pass - " + samp.name + ".getValue(" +
181                    index + ", " + length + ") - got expected: " + exc);
182        } catch (Throwable exc) {
183            failure("FAIL - " + samp.name + ".getValues(" +
184                    index + ", " + length + ") - unexpected: " + exc);
185        }
186    }
187
188    void setValueGood(Sample samp, int index, int ival) {
189        try {
190            Value val = vm().mirrorOf(ival);
191            samp.arrRef.setValue(index, val);
192            println("pass - " + samp.name +
193                    ".setValue(" + index + ", ..)");
194        } catch (Throwable exc) {
195            failure("FAIL - " + samp.name +
196                    ".setValue(" + index + ",...) - unexpected: " + exc);
197        }
198    }
199
200    void setValueBad(Sample samp, int index, int ival) {
201        try {
202            Value val = vm().mirrorOf(ival);
203            samp.arrRef.setValue(index, val);
204            failure("FAIL - " + samp.name +
205                    ".setValue(" + index + ", ..) - no expected exception");
206        } catch (IndexOutOfBoundsException exc) {
207            println("pass - " + samp.name +
208                    ".setValue(" + index + ",...) - got expected: " + exc);
209        } catch (Throwable exc) {
210            failure("FAIL - " + samp.name +
211                    ".setValue(" + index + ",...) - unexpected: " + exc);
212        }
213    }
214
215    void setValuesGood(Sample samp, int[] valArray) {
216        String desc = samp.name + ".setValues(" + arr(valArray) + ")";
217        try {
218            List values = new ArrayList();
219            for (int i = 0; i < valArray.length; ++i) {
220                Value val = vm().mirrorOf(valArray[i]);
221                values.add(val);
222            }
223            samp.arrRef.setValues(values);
224            println("pass - " + desc);
225        } catch (Throwable exc) {
226            failure("FAIL - " + desc + " - unexpected: " + exc);
227        }
228    }
229
230    void setValuesGood(Sample samp, int index, int[] valArray,
231                       int srcInx, int length) {
232        String desc = samp.name + ".setValues(" + index + ", " +
233            arr(valArray) + ", " + srcInx + ", " + length + ")";
234        try {
235            List values = new ArrayList();
236            for (int i = 0; i < valArray.length; ++i) {
237                Value val = vm().mirrorOf(valArray[i]);
238                values.add(val);
239            }
240            samp.arrRef.setValues(index, values, srcInx, length);
241            println("pass - " + desc);
242        } catch (Throwable exc) {
243            failure("FAIL - " + desc + " - unexpected: " + exc);
244        }
245    }
246
247    void setValuesBad(Sample samp, int index, int[] valArray,
248                       int srcInx, int length) {
249        String desc = samp.name + ".setValues(" + index + ", " +
250            arr(valArray) + ", " + srcInx + ", " + length + ")";
251        try {
252            List values = new ArrayList();
253            for (int i = 0; i < valArray.length; ++i) {
254                Value val = vm().mirrorOf(valArray[i]);
255                values.add(val);
256            }
257            samp.arrRef.setValues(index, values, srcInx, length);
258            failure("FAIL - " + desc + " - no expected exception");
259        } catch (IndexOutOfBoundsException exc) {
260            println("pass - " + desc + " - got expected: " + exc);
261        } catch (Throwable exc) {
262            failure("FAIL - " + desc + " - unexpected: " + exc);
263        }
264    }
265
266    void check(Sample samp, int[] expectArray) {
267        String desc = samp.name + " - check - " + arr(expectArray);
268
269        try {
270            List vals = samp.arrRef.getValues();
271            if (vals.size() != expectArray.length) {
272                failure("FAIL - " + desc +
273                        " - wrong size=" + vals.size() +
274                        " , expected: " + expectArray.length);
275            }
276            for (int index = 0; index < vals.size(); ++index) {
277                int ival = ((IntegerValue)vals.get(index)).value();
278                if (ival != expectArray[index]) {
279                    failure("FAIL - " + desc +
280                            " - wrong value=" + ival);
281                    return;
282                }
283            }
284            println("pass - " + desc);
285        } catch (Throwable exc) {
286            failure("FAIL - " + desc  +
287                    " - unexpected: " + exc);
288        }
289    }
290
291    /********** test core **********/
292
293    protected void runTests() throws Exception {
294        /*
295         * Get to the top of main() to determine targetClass
296         */
297        BreakpointEvent bpe = startToMain("ArrayRangeTarg");
298        targetClass = bpe.location().declaringType();
299        Field fullField = targetClass.fieldByName("fullArray");
300        Field emptyField = targetClass.fieldByName("emptyArray");
301        ArrayReference emptyAR = (ArrayReference)targetClass.getValue(emptyField);
302        ArrayReference fullAR = (ArrayReference)targetClass.getValue(fullField);
303        Sample full = new Sample("full", fullAR, ArrayRangeTarg.fullArray);
304        Sample empty = new Sample("empty", emptyAR, ArrayRangeTarg.emptyArray);
305
306        getValueGood(full, 0);
307        getValueGood(full, 4);
308
309        // index < 0
310        getValueBad(full, -1);
311        getValueBad(full, -2);
312        getValueBad(empty, -1);
313        getValueBad(empty, -2);
314
315        // index >= length
316        getValueBad(full, 5);
317        getValueBad(empty, 0);
318        getValueBad(empty, 5);
319
320        getValuesGood(full);
321        getValuesGood(empty);
322
323        getValuesGood(full, 0, 5);
324        getValuesGood(full, 0, 4);
325        getValuesGood(full, 1, 4);
326        getValuesGood(full, 5, 0);
327        getValuesGood(full, 0, 0);
328        getValuesGood(full, 0, -1);
329        getValuesGood(full, 1, -1);
330        getValuesGood(full, 5, -1);
331
332        getValuesGood(empty, 0, 0);
333        getValuesGood(empty, 0, -1);
334
335        // index < 0
336        getValuesBad(full, -1, 0);
337        getValuesBad(full, -1, 3);
338        getValuesBad(full, -1, -1);
339        getValuesBad(empty, -1, 0);
340        getValuesBad(full, -2, 0);
341        getValuesBad(full, -2, 3);
342        getValuesBad(full, -2, -1);
343        getValuesBad(empty, -2, 0);
344
345        // index > length()
346        getValuesBad(full, 6, 0);
347        getValuesBad(full, 6, -1);
348        getValuesBad(empty, 1, 0);
349        getValuesBad(empty, 1, -1);
350
351        // length < 0
352        getValuesBad(full, 0, -2);
353        getValuesBad(empty, 0, -2);
354
355        // index + length > length()
356        getValuesBad(full, 0, 6);
357        getValuesBad(full, 1, 5);
358        getValuesBad(full, 2, 4);
359        getValuesBad(full, 5, 1);
360        getValuesBad(empty, 0, 1);
361
362        setValueGood(full, 0, 55);
363        setValueGood(full, 4, 66);
364
365        // index < 0
366        setValueBad(full, -1, 77);
367        setValueBad(full, -2, 77);
368
369        // index > length()
370        setValueBad(full, 5, 77);
371        setValueBad(full, 6, 77);
372
373        check(full, new int[] {55, 100, 200, 300, 66});
374
375        // index < 0
376        setValueBad(empty, -1, 77);
377        setValueBad(empty, -2, 77);
378
379        // index > length()
380        setValueBad(empty, 0, 77);
381        setValueBad(empty, 1, 77);
382
383        setValuesGood(full, new int[] {40, 41, 42});
384        setValuesGood(full, new int[] {});
385
386        check(full, new int[] {40, 41, 42, 300, 66});
387
388        setValuesGood(full, new int[] {99, 51, 52, 53, 54, 55});
389        setValuesGood(full, new int[] {50});
390
391        check(full, new int[] {50, 51, 52, 53, 54});
392
393        setValuesGood(empty, new int[] {});
394        setValuesGood(empty, new int[] {88});
395
396        setValuesGood(full, 2, new int[] {30, 31, 32, 33, 34, 35}, 0, 3);
397        setValuesGood(full, 0, new int[] {80}, 0, 1);
398
399        check(full, new int[] {80, 51, 30, 31, 32});
400
401        setValuesGood(full, 0, new int[] {90, 91, 92, 93, 94, 95}, 3, 3);
402        setValuesGood(full, 4, new int[] {81}, 0, 1);
403
404        check(full, new int[] {93, 94, 95, 31, 81});
405
406        setValuesGood(full, 3, new int[] {60, 61, 62, 63}, 0, -1);
407        setValuesGood(full, 0, new int[] {82}, 0, -1);
408
409        check(full, new int[] {82, 94, 95, 60, 61});
410
411        setValuesGood(full, 3, new int[] {20, 21, 22, 23}, 1, -1);
412        setValuesGood(full, 1, new int[] {83, 84}, 1, -1);
413        setValuesGood(full, 1, new int[] {}, 0, -1);
414        setValuesGood(full, 2, new int[] {}, 0, 0);
415        setValuesGood(full, 3, new int[] {99}, 0, 0);
416        setValuesGood(full, 4, new int[] {99, 98}, 1, 0);
417
418        check(full, new int[] {82, 84, 95, 21, 22});
419
420        setValuesGood(empty, 0, new int[] {}, 0, -1);
421        setValuesGood(empty, 0, new int[] {}, 0, 0);
422        setValuesGood(empty, 0, new int[] {99}, 0, 0);
423        setValuesGood(empty, 0, new int[] {99, 98}, 1, 0);
424
425        // index < 0
426        setValuesBad(full, -1, new int[] {30, 31, 32, 33, 34, 35}, 0, 0);
427        setValuesBad(full, -1, new int[] {30, 31, 32, 33, 34, 35}, 0, -1);
428        setValuesBad(full, -2, new int[] {30, 31, 32, 33, 34, 35}, 0, -1);
429        setValuesBad(empty, -1, new int[] {}, 0, 0);
430        setValuesBad(empty, -2, new int[] {}, 0, 0);
431
432        // index > length()
433        setValuesBad(full, 6, new int[] {30, 31, 32, 33, 34, 35}, 0, 1);
434        setValuesBad(full, 6, new int[] {30, 31, 32, 33, 34, 35}, 0, -1);
435        setValuesBad(empty, 1, new int[] {4}, 0, 0);
436        setValuesBad(empty, 1, new int[] {}, 0, 0);
437        setValuesBad(empty, 1, new int[] {}, 0, -1);
438
439        // srcIndex < 0
440        setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, 3);
441        setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, 0);
442        setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, -1);
443        setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -2, -1);
444        setValuesBad(full, 1, new int[] {}, -1, -1);
445        setValuesBad(full, 2, new int[] {}, -1, 0);
446        setValuesBad(empty, 0, new int[] {}, -1, 0);
447
448        // srcIndex > values.size()
449        setValuesBad(full, 0, new int[] {81}, 2, 0);
450        setValuesBad(full, 0, new int[] {81}, 2, 1);
451        setValuesBad(full, 0, new int[] {81}, 2, -1);
452        setValuesBad(full, 4, new int[] {}, 1, 0);
453        setValuesBad(full, 1, new int[] {}, 1, -1);
454        setValuesBad(full, 2, new int[] {}, 1, 0);
455        setValuesBad(empty, 0, new int[] {}, 1, 0);
456        setValuesBad(empty, 0, new int[] {5}, 2, 0);
457
458        // length < 0 (length != -1)
459        setValuesBad(full, 3, new int[] {60, 61, 62, 63}, 0, -2);
460        setValuesBad(full, 3, new int[] {}, 0, -2);
461
462        // index + length > length()
463        setValuesBad(full, 0, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 6);
464        setValuesBad(full, 1, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 5);
465        setValuesBad(full, 2, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 4);
466        setValuesBad(full, 3, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 3);
467        setValuesBad(full, 4, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 2);
468        setValuesBad(full, 5, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 1);
469        setValuesBad(full, 6, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 0);
470        setValuesBad(full, 2, new int[] {20, 21, 22, 23, 24, 25, 26}, 1, 4);
471        setValuesBad(full, 3, new int[] {20, 21, 22, 23, 24, 25, 26}, 1, 3);
472        setValuesBad(full, 4, new int[] {20, 21, 22, 23, 24, 25, 26}, 2, 2);
473        setValuesBad(full, 5, new int[] {20, 21, 22, 23, 24, 25, 26}, 3, 1);
474        setValuesBad(full, 6, new int[] {20, 21, 22, 23, 24, 25, 26}, 4, 0);
475        setValuesBad(empty, 0, new int[] {6}, 0, 1);
476
477        // srcIndex + length > values.size()
478        setValuesBad(full, 0, new int[] {82}, 0, 2);
479        setValuesBad(full, 0, new int[] {82}, 1, 1);
480        setValuesBad(full, 0, new int[] {82}, 2, 0);
481        setValuesBad(full, 0, new int[] {20, 21, 22}, 0, 4);
482        setValuesBad(full, 0, new int[] {20, 21, 22}, 1, 3);
483        setValuesBad(full, 0, new int[] {20, 21, 22}, 2, 2);
484        setValuesBad(full, 0, new int[] {20, 21, 22}, 3, 1);
485        setValuesBad(full, 0, new int[] {20, 21, 22}, 4, 0);
486
487        check(full, new int[] {82, 84, 95, 21, 22});
488
489        /*
490         * resume the target until end
491         */
492        listenUntilVMDisconnect();
493
494        /*
495         * deal with results of test
496         * if anything has called failure("foo") testFailed will be true
497         */
498        if (!testFailed) {
499            println("ArrayRangeTest: passed");
500        } else {
501            throw new Exception("ArrayRangeTest: failed");
502        }
503    }
504}
505