Path: blob/master/test/jdk/java/util/AbstractCollection/ToArrayTest.java
41149 views
/*1* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 712131426* @summary AbstractCollection.toArray(T[]) doesn't return the given array27* in concurrent modification.28* @author Ulf Zibis, David Holmes29*/3031import java.util.AbstractCollection;32import java.util.Arrays;33import java.util.Iterator;3435public class ToArrayTest {3637static class TestCollection<E> extends AbstractCollection<E> {38private final E[] elements;39private int[] sizes;40private int nextSize;4142public TestCollection(E[] elements) {43this.elements = elements;44setSizeSequence(new int[] { elements.length });45}4647/*48* Sets the values that size() will return on each use. The next49* call to size will return sizes[0], then sizes[1] etc. This allows us50* to emulate a concurrent change to the contents of the collection51* without having to perform concurrent changes. If sizes[n+1] contains52* a larger value, the collection will appear to have shrunk when53* iterated; if a smaller value then the collection will appear to have54* grown when iterated.55*/56void setSizeSequence(int... sizes) {57this.sizes = sizes;58nextSize = 0;59}6061/* can change collection's size after each invocation */62@Override63public int size() {64return sizes[nextSize == sizes.length - 1 ? nextSize : nextSize++];65}6667@Override68public Iterator<E> iterator() {69return new Iterator<E>() {70int pos = 0;7172public boolean hasNext() {73return pos < sizes[nextSize];74}75public E next() {76return elements[pos++];77}78public void remove() {79throw new UnsupportedOperationException(80"Not supported yet.");81}82};83}84}8586static final Object[] OBJECTS = { new Object(), new Object(), new Object() };87static final TestCollection<?> CANDIDATE = new TestCollection<Object>(OBJECTS);88static final int CAP = OBJECTS.length; // capacity of the CANDIDATE89static final int LAST = CAP - 1; // last possible array index90Object[] a;91Object[] res;9293int last() {94return a.length - 1;95}9697protected void test() throws Throwable {98// Check array type conversion99res = new TestCollection<>(new Object[] { "1", "2" }).toArray(new String[0]);100check(res instanceof String[]);101check(res.length == 2);102check(res[1] == "2");103104// Check incompatible type of target array105try {106res = CANDIDATE.toArray(new String[CAP]);107check(false);108} catch (Throwable t) {109check(t instanceof ArrayStoreException);110}111112// Check more elements than a.length113a = new Object[CAP - 1]; // appears too small114res = CANDIDATE.toArray(a);115check(res != a);116check(res[LAST] != null);117118// Check equal elements as a.length119a = new Object[CAP]; // appears to match120res = CANDIDATE.toArray(a);121check(res == a);122check(res[last()] != null);123124// Check equal elements as a.length125a = new Object[CAP + 1]; // appears too big126res = CANDIDATE.toArray(a);127check(res == a);128check(res[last()] == null);129130// Check less elements than expected, but more than a.length131a = new Object[CAP - 2]; // appears too small132CANDIDATE.setSizeSequence(CAP, CAP - 1);133res = CANDIDATE.toArray(a);134check(res != a);135check(res.length == CAP - 1);136check(res[LAST - 1] != null);137138// Check less elements than expected, but equal as a.length139a = Arrays.copyOf(OBJECTS, CAP); // appears to match140CANDIDATE.setSizeSequence(CAP, CAP - 1);141res = CANDIDATE.toArray(a);142check(res == a);143check(res[last()] == null);144145// Check more elements than expected and more than a.length146a = new Object[CAP - 1]; // appears to match147CANDIDATE.setSizeSequence(CAP - 1, CAP);148res = CANDIDATE.toArray(a);149check(res != a);150check(res[LAST] != null);151152// Check more elements than expected, but equal as a.length153a = new Object[CAP - 1]; // appears to match154CANDIDATE.setSizeSequence(CAP - 2, CAP - 1);155res = CANDIDATE.toArray(a);156check(res == a);157check(res[last()] != null);158159// Check more elements than expected, but less than a.length160a = Arrays.copyOf(OBJECTS, CAP); // appears to match161CANDIDATE.setSizeSequence(CAP - 2, CAP - 1);162res = CANDIDATE.toArray(a);163check(res == a);164check(res[last()] == null);165166test_7121314();167}168169/*170* Major target of this testcase, bug 7121314.171*/172protected void test_7121314() throws Throwable {173// Check equal elements as a.length, but less than expected174a = new Object[CAP - 1]; // appears too small175CANDIDATE.setSizeSequence(CAP, CAP - 1);176res = CANDIDATE.toArray(a);177check(res == a);178check(res[last()] != null);179180// Check less elements than a.length and less than expected181a = Arrays.copyOf(OBJECTS, CAP - 1); // appears too small182CANDIDATE.setSizeSequence(CAP, CAP - 2);183res = CANDIDATE.toArray(a);184check(res == a);185check(res[last()] == null);186187}188189public static void main(String[] args) throws Throwable {190ToArrayTest testcase = new ToArrayTest();191try {192testcase.test();193} catch (Throwable t) {194unexpected(t);195}196197System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);198if (failed > 0) throw new Exception("Some tests failed");199}200201//--------------------- Infrastructure ---------------------------202static volatile int passed = 0, failed = 0;203static void pass() { passed++; }204static void fail() { failed++; Thread.dumpStack(); }205static void fail(String msg) { System.out.println(msg); fail(); }206static void unexpected(Throwable t) { failed++; t.printStackTrace(); }207static void check(boolean cond) { if (cond) pass(); else fail(); }208static void equal(Object x, Object y) {209if (x == null ? y == null : x.equals(y)) pass();210else {System.out.println(x + " not equal to " + y); fail(); }211}212}213214215