Path: blob/master/test/jdk/java/util/ArrayList/ArrayManagement.java
41149 views
/*1* Copyright 2016 Google, Inc. 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 814656826* @summary brittle white box test of internal array management27* @modules java.base/java.util:open28* @run testng ArrayManagement29*/3031import java.lang.reflect.Field;32import java.util.AbstractList;33import java.util.ArrayList;34import java.util.Collections;35import java.util.List;36import java.util.SplittableRandom;3738import org.testng.annotations.Test;39import static org.testng.Assert.*;4041public class ArrayManagement {42static final int DEFAULT_CAPACITY = 10;43static final Field ELEMENT_DATA;44static final Field MODCOUNT;45static final SplittableRandom rnd = new SplittableRandom();4647static {48try {49ELEMENT_DATA = ArrayList.class.getDeclaredField("elementData");50ELEMENT_DATA.setAccessible(true);51MODCOUNT = AbstractList.class.getDeclaredField("modCount");52MODCOUNT.setAccessible(true);53} catch (ReflectiveOperationException huh) {54throw new AssertionError(huh);55}56}5758static Object[] elementData(ArrayList<?> list) {59try {60return (Object[]) ELEMENT_DATA.get(list);61} catch (ReflectiveOperationException huh) {62throw new AssertionError(huh);63}64}6566static int modCount(ArrayList<?> list) {67try {68return MODCOUNT.getInt(list);69} catch (ReflectiveOperationException huh) {70throw new AssertionError(huh);71}72}7374static int capacity(ArrayList<?> list) {75return elementData(list).length;76}7778static int newCapacity(int oldCapacity) {79return oldCapacity + (oldCapacity >> 1);80}8182static void ensureCapacity(ArrayList<Object> list, int capacity) {83int oldCapacity = capacity(list);84int oldModCount = modCount(list);85list.ensureCapacity(capacity);86assertTrue(capacity(list) >= capacity || capacity(list) == 0);87assertEquals(modCount(list),88(capacity(list) == oldCapacity)89? oldModCount90: oldModCount + 1);91}9293static List<Object> singletonList() {94return Collections.singletonList(Boolean.TRUE);95}9697/** Opportunistically randomly test various add operations. */98static void addOneElement(ArrayList<Object> list) {99int size = list.size();100int modCount = modCount(list);101switch (rnd.nextInt(4)) {102case 0: assertTrue(list.add(Boolean.TRUE)); break;103case 1: list.add(size, Boolean.TRUE); break;104case 2: assertTrue(list.addAll(singletonList())); break;105case 3: assertTrue(list.addAll(size, singletonList())); break;106default: throw new AssertionError();107}108assertEquals(modCount(list), modCount + 1);109assertEquals(list.size(), size + 1);110}111112@Test public void defaultCapacity() {113ArrayList<Object> list = new ArrayList<>();114assertEquals(capacity(new ArrayList<Object>()), 0);115for (int i = 0; i < DEFAULT_CAPACITY; i++) {116addOneElement(list);117assertEquals(capacity(list), DEFAULT_CAPACITY);118}119addOneElement(list);120assertEquals(capacity(list), newCapacity(DEFAULT_CAPACITY));121}122123@Test public void defaultCapacityEnsureCapacity() {124ArrayList<Object> list = new ArrayList<>();125for (int i = 0; i <= DEFAULT_CAPACITY; i++) {126ensureCapacity(list, i); // no-op!127assertEquals(capacity(list), 0);128}129for (int i = 0; i < DEFAULT_CAPACITY; i++) {130addOneElement(list);131assertEquals(capacity(list), DEFAULT_CAPACITY);132}133addOneElement(list);134assertEquals(capacity(list), newCapacity(DEFAULT_CAPACITY));135{136int capacity = capacity(list);137ensureCapacity(list, capacity + 1);138assertEquals(capacity(list), newCapacity(capacity));139}140{141int capacity = capacity(list);142ensureCapacity(list, 3 * capacity);143assertEquals(capacity(list), 3 * capacity);144}145}146147@Test public void ensureCapacityBeyondDefaultCapacity() {148ArrayList<Object> list = new ArrayList<>();149list.ensureCapacity(DEFAULT_CAPACITY + 1);150assertEquals(capacity(list), DEFAULT_CAPACITY + 1);151for (int i = 0; i < DEFAULT_CAPACITY + 1; i++) {152addOneElement(list);153assertEquals(capacity(list), DEFAULT_CAPACITY + 1);154}155addOneElement(list);156assertEquals(capacity(list), newCapacity(DEFAULT_CAPACITY + 1));157}158159@Test public void explicitZeroCapacity() {160ArrayList<Object> list = new ArrayList<>(0);161assertEquals(capacity(list), 0);162addOneElement(list);163assertEquals(capacity(list), 1);164addOneElement(list);165assertEquals(capacity(list), 2);166addOneElement(list);167assertEquals(capacity(list), 3);168addOneElement(list);169assertEquals(capacity(list), 4);170addOneElement(list);171assertEquals(capacity(list), 6);172addOneElement(list);173assertEquals(capacity(list), 6);174addOneElement(list);175assertEquals(capacity(list), 9);176list.clear();177assertEquals(capacity(list), 9);178}179180@Test public void explicitLargeCapacity() {181int n = DEFAULT_CAPACITY * 3;182ArrayList<Object> list = new ArrayList<>(n);183assertEquals(capacity(list), n);184ensureCapacity(list, 0);185ensureCapacity(list, n);186for (int i = 0; i < n; i++) addOneElement(list);187assertEquals(capacity(list), n);188189addOneElement(list);190assertEquals(capacity(list), newCapacity(n));191}192193@Test public void emptyArraysAreShared() {194assertSame(elementData(new ArrayList<Object>()),195elementData(new ArrayList<Object>()));196assertSame(elementData(new ArrayList<Object>(0)),197elementData(new ArrayList<Object>(0)));198}199200@Test public void emptyArraysDifferBetweenDefaultAndExplicit() {201assertNotSame(elementData(new ArrayList<Object>()),202elementData(new ArrayList<Object>(0)));203}204205@Test public void negativeCapacity() {206for (int capacity : new int[] { -1, Integer.MIN_VALUE }) {207try {208new ArrayList<Object>(capacity);209fail("should throw");210} catch (IllegalArgumentException success) {}211}212}213}214215216