Path: blob/master/test/jdk/java/util/ArrayDeque/WhiteBox.java
41149 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation.6*7* This code is distributed in the hope that it will be useful, but WITHOUT8* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or9* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License10* version 2 for more details (a copy is included in the LICENSE file that11* accompanied this code).12*13* You should have received a copy of the GNU General Public License version14* 2 along with this work; if not, write to the Free Software Foundation,15* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.16*17* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA18* or visit www.oracle.com if you need additional information or have any19* questions.20*/2122/*23* This file is available under and governed by the GNU General Public24* License version 2 only, as published by the Free Software Foundation.25* However, the following notice accompanied the original version of this26* file:27*28* Written by Martin Buchholz with assistance from members of JCP29* JSR-166 Expert Group and released to the public domain, as30* explained at http://creativecommons.org/publicdomain/zero/1.0/31*/3233/*34* @test35* @modules java.base/java.util:open36* @run testng WhiteBox37* @summary White box tests of implementation details38*/3940import static org.testng.Assert.*;41import org.testng.annotations.Test;4243import java.io.ByteArrayInputStream;44import java.io.ByteArrayOutputStream;45import java.io.ObjectInputStream;46import java.io.ObjectOutputStream;47import java.lang.invoke.MethodHandles;48import java.lang.invoke.VarHandle;49import java.util.ArrayDeque;50import java.util.concurrent.ThreadLocalRandom;5152@Test53public class WhiteBox {54final ThreadLocalRandom rnd = ThreadLocalRandom.current();55final VarHandle ELEMENTS, HEAD, TAIL;5657WhiteBox() throws ReflectiveOperationException {58Class<?> klazz = ArrayDeque.class;59MethodHandles.Lookup lookup60= MethodHandles.privateLookupIn(klazz, MethodHandles.lookup());61ELEMENTS = lookup.findVarHandle(klazz, "elements", Object[].class);62HEAD = lookup.findVarHandle(klazz, "head", int.class);63TAIL = lookup.findVarHandle(klazz, "tail", int.class);64}6566Object[] elements(ArrayDeque d) { return (Object[]) ELEMENTS.get(d); }67int head(ArrayDeque d) { return (int) HEAD.get(d); }68int tail(ArrayDeque d) { return (int) TAIL.get(d); }6970void checkCapacity(ArrayDeque d, int capacity) {71assertTrue(d.isEmpty());72assertEquals(0, head(d));73assertEquals(0, tail(d));74Object[] initialElements = elements(d);7576assertInvariants(d);77for (int i = capacity; i--> 0; ) {78d.add(rnd.nextInt(42));79assertSame(elements(d), initialElements);80assertInvariants(d);81}8283d.add(rnd.nextInt(42));84assertNotSame(elements(d), initialElements);85assertInvariants(d);86}8788@Test89public void defaultConstructor() {90checkCapacity(new ArrayDeque(), 16);91}9293@Test94public void shouldNotResizeWhenInitialCapacityProvided() {95int initialCapacity = rnd.nextInt(20);96checkCapacity(new ArrayDeque(initialCapacity), initialCapacity);97}9899byte[] serialBytes(Object o) {100try {101ByteArrayOutputStream bos = new ByteArrayOutputStream();102ObjectOutputStream oos = new ObjectOutputStream(bos);103oos.writeObject(o);104oos.flush();105oos.close();106return bos.toByteArray();107} catch (Exception fail) {108throw new AssertionError(fail);109}110}111112@SuppressWarnings("unchecked")113<T> T serialClone(T o) {114try {115ObjectInputStream ois = new ObjectInputStream116(new ByteArrayInputStream(serialBytes(o)));117T clone = (T) ois.readObject();118assertNotSame(o, clone);119assertSame(o.getClass(), clone.getClass());120return clone;121} catch (Exception fail) {122throw new AssertionError(fail);123}124}125126@Test127public void testSerialization() {128ArrayDeque[] ds = { new ArrayDeque(), new ArrayDeque(rnd.nextInt(20)) };129for (ArrayDeque d : ds) {130if (rnd.nextBoolean()) d.add(99);131ArrayDeque clone = serialClone(d);132assertInvariants(clone);133assertNotSame(elements(d), elements(clone));134assertEquals(d, clone);135}136}137138/** Checks conditions which should always be true. */139void assertInvariants(ArrayDeque d) {140final Object[] elements = elements(d);141final int head = head(d);142final int tail = tail(d);143final int capacity = elements.length;144assertTrue(0 <= head && head < capacity);145assertTrue(0 <= tail && tail < capacity);146assertTrue(capacity > 0);147assertTrue(d.size() < capacity);148assertTrue((head == tail) ^ (elements[head] != null));149assertNull(elements[tail]);150assertTrue((head == tail) ^ (elements[Math.floorMod(tail - 1, capacity)] != null));151}152}153154155