ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/MapTest.java
Revision: 1.7
Committed: Mon Jul 8 21:17:16 2019 UTC (4 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +1 -0 lines
Log Message:
never run testBug8186171 on jdk older than jdk10

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea and Martin Buchholz with assistance from
3     * members of JCP JSR-166 Expert Group and released to the public
4     * domain, as explained at
5     * http://creativecommons.org/publicdomain/zero/1.0/
6     */
7    
8     import junit.framework.Test;
9    
10     import java.util.ArrayList;
11     import java.util.Iterator;
12     import java.util.List;
13     import java.util.Map;
14     import java.util.concurrent.ThreadLocalRandom;
15    
16     /**
17     * Contains tests applicable to all Map implementations.
18     */
19     public class MapTest extends JSR166TestCase {
20     final MapImplementation impl;
21    
22     /** Tests are parameterized by a Map implementation. */
23     MapTest(MapImplementation impl, String methodName) {
24     super(methodName);
25     this.impl = impl;
26     }
27    
28     public static Test testSuite(MapImplementation impl) {
29     return newTestSuite(
30     parameterizedTestSuite(MapTest.class,
31     MapImplementation.class,
32     impl));
33     }
34    
35     public void testImplSanity() {
36     final ThreadLocalRandom rnd = ThreadLocalRandom.current();
37     {
38     Map m = impl.emptyMap();
39     assertTrue(m.isEmpty());
40     assertEquals(0, m.size());
41     Object k = impl.makeKey(rnd.nextInt());
42     Object v = impl.makeValue(rnd.nextInt());
43     m.put(k, v);
44     assertFalse(m.isEmpty());
45     assertEquals(1, m.size());
46     assertTrue(m.containsKey(k));
47     assertTrue(m.containsValue(v));
48     }
49     {
50     Map m = impl.emptyMap();
51     Object v = impl.makeValue(rnd.nextInt());
52     if (impl.permitsNullKeys()) {
53     m.put(null, v);
54     assertTrue(m.containsKey(null));
55     assertTrue(m.containsValue(v));
56     } else {
57     assertThrows(NullPointerException.class, () -> m.put(null, v));
58     }
59     }
60     {
61     Map m = impl.emptyMap();
62     Object k = impl.makeKey(rnd.nextInt());
63     if (impl.permitsNullValues()) {
64     m.put(k, null);
65     assertTrue(m.containsKey(k));
66     assertTrue(m.containsValue(null));
67     } else {
68     assertThrows(NullPointerException.class, () -> m.put(k, null));
69     }
70     }
71     {
72     Map m = impl.emptyMap();
73     Object k = impl.makeKey(rnd.nextInt());
74     Object v1 = impl.makeValue(rnd.nextInt());
75     Object v2 = impl.makeValue(rnd.nextInt());
76     m.put(k, v1);
77     if (impl.supportsSetValue()) {
78     ((Map.Entry)(m.entrySet().iterator().next())).setValue(v2);
79     assertSame(v2, m.get(k));
80     assertTrue(m.containsKey(k));
81     assertTrue(m.containsValue(v2));
82     assertFalse(m.containsValue(v1));
83     } else {
84     assertThrows(UnsupportedOperationException.class,
85     () -> ((Map.Entry)(m.entrySet().iterator().next())).setValue(v2));
86     }
87     }
88     }
89    
90     /**
91     * Tests and extends the scenario reported in
92     * https://bugs.openjdk.java.net/browse/JDK-8186171
93     * HashMap: Entry.setValue may not work after Iterator.remove() called for previous entries
94     * ant -Djsr166.tckTestClass=HashMapTest -Djsr166.methodFilter=testBug8186171 -Djsr166.runsPerTest=1000 tck
95     */
96     public void testBug8186171() {
97     if (!impl.supportsSetValue()) return;
98 jsr166 1.7 if (!atLeastJava10()) return; // jdk9 is abandoned
99 jsr166 1.1 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
100     final boolean permitsNullValues = impl.permitsNullValues();
101     final Object v1 = (permitsNullValues && rnd.nextBoolean())
102     ? null : impl.makeValue(1);
103     final Object v2 = (permitsNullValues && rnd.nextBoolean() && v1 != null)
104     ? null : impl.makeValue(2);
105    
106 jsr166 1.2 // If true, always lands in first bucket in hash tables.
107 jsr166 1.1 final boolean poorHash = rnd.nextBoolean();
108     class Key implements Comparable<Key> {
109     final int i;
110     Key(int i) { this.i = i; }
111     public int hashCode() { return poorHash ? 0 : super.hashCode(); }
112     public int compareTo(Key x) {
113     return Integer.compare(this.i, x.i);
114     }
115     }
116    
117     // Both HashMap and ConcurrentHashMap have:
118     // TREEIFY_THRESHOLD = 8; UNTREEIFY_THRESHOLD = 6;
119     final int size = rnd.nextInt(1, 25);
120    
121     List<Key> keys = new ArrayList<>();
122     for (int i = size; i-->0; ) keys.add(new Key(i));
123     Key keyToFrob = keys.get(rnd.nextInt(keys.size()));
124    
125     Map<Key, Object> m = impl.emptyMap();
126     for (Key key : keys) m.put(key, v1);
127    
128     for (Iterator<Map.Entry<Key, Object>> it = m.entrySet().iterator();
129     it.hasNext(); ) {
130     Map.Entry<Key, Object> entry = it.next();
131     if (entry.getKey() == keyToFrob)
132     entry.setValue(v2); // does this have the expected effect?
133     else
134     it.remove();
135     }
136    
137     assertFalse(m.containsValue(v1));
138     assertTrue(m.containsValue(v2));
139     assertTrue(m.containsKey(keyToFrob));
140     assertEquals(1, m.size());
141     }
142    
143 jsr166 1.3 /**
144     * "Missing" test found while investigating JDK-8210280.
145 jsr166 1.4 * ant -Djsr166.tckTestClass=HashMapTest -Djsr166.methodFilter=testBug8210280 -Djsr166.runsPerTest=1000000 tck
146 jsr166 1.3 */
147     public void testBug8210280() {
148 jsr166 1.4 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
149     final int size1 = rnd.nextInt(32);
150     final int size2 = rnd.nextInt(128);
151    
152     final Map m1 = impl.emptyMap();
153     for (int i = 0; i < size1; i++) {
154     int elt = rnd.nextInt(1024 * i, 1024 * (i + 1));
155     assertNull(m1.put(impl.makeKey(elt), impl.makeValue(elt)));
156     }
157    
158     final Map m2 = impl.emptyMap();
159     for (int i = 0; i < size2; i++) {
160     int elt = rnd.nextInt(Integer.MIN_VALUE + 1024 * i,
161     Integer.MIN_VALUE + 1024 * (i + 1));
162     assertNull(m2.put(impl.makeKey(elt), impl.makeValue(-elt)));
163     }
164    
165     final Map m1Copy = impl.emptyMap();
166     m1Copy.putAll(m1);
167    
168     m1.putAll(m2);
169    
170     for (Object elt : m2.keySet())
171     assertEquals(m2.get(elt), m1.get(elt));
172     for (Object elt : m1Copy.keySet())
173     assertSame(m1Copy.get(elt), m1.get(elt));
174     assertEquals(size1 + size2, m1.size());
175 jsr166 1.3 }
176    
177 jsr166 1.5 /**
178     * 8222930: ConcurrentSkipListMap.clone() shares size variable between original and clone
179     */
180     public void testClone() {
181     final ThreadLocalRandom rnd = ThreadLocalRandom.current();
182     final int size = rnd.nextInt(4);
183     final Map map = impl.emptyMap();
184 jsr166 1.6 for (int i = 0; i < size; i++)
185 jsr166 1.5 map.put(impl.makeKey(i), impl.makeValue(i));
186     final Map clone = cloneableClone(map);
187     if (clone == null) return; // not cloneable?
188    
189     assertEquals(size, map.size());
190     assertEquals(size, clone.size());
191     assertEquals(map.isEmpty(), clone.isEmpty());
192    
193     clone.put(impl.makeKey(-1), impl.makeValue(-1));
194     assertEquals(size, map.size());
195     assertEquals(size + 1, clone.size());
196    
197     clone.clear();
198     assertEquals(size, map.size());
199     assertEquals(0, clone.size());
200     assertTrue(clone.isEmpty());
201     }
202    
203 jsr166 1.1 // public void testFailsIntentionallyForDebugging() {
204     // fail(impl.klazz().getSimpleName());
205     // }
206     }