1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * @test 19 * @bug 6612102 20 * @summary Test Map implementations for mutual compatibility 21 * @key randomness 22 */ 23 package test.java.util.Map; 24 25 import java.util.Collections; 26 import java.util.HashMap; 27 import java.util.Hashtable; 28 import java.util.IdentityHashMap; 29 import java.util.Iterator; 30 import java.util.LinkedHashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.Random; 34 import java.util.TreeMap; 35 import java.util.WeakHashMap; 36 import java.util.concurrent.ConcurrentHashMap; 37 import java.util.concurrent.ConcurrentSkipListMap; 38 39 import org.testng.annotations.Test; 40 import org.testng.Assert; 41 42 /** 43 * Based on the strange scenario required to reproduce 44 * (coll) IdentityHashMap.iterator().remove() might decrement size twice 45 * 46 * It would be good to add more "Lockstep-style" tests to this file. 47 */ 48 public class LockStep { mapsEqual(Map m1, Map m2)49 void mapsEqual(Map m1, Map m2) { 50 Assert.assertEquals(m1, m2); 51 Assert.assertEquals(m2, m1); 52 Assert.assertEquals(m1.size(), m2.size()); 53 Assert.assertEquals(m1.isEmpty(), m2.isEmpty()); 54 Assert.assertEquals(m1.keySet(), m2.keySet()); 55 Assert.assertEquals(m2.keySet(), m1.keySet()); 56 } 57 mapsEqual(List<Map> maps)58 void mapsEqual(List<Map> maps) { 59 Map first = maps.get(0); 60 for (Map map : maps) 61 mapsEqual(first, map); 62 } 63 put(List<Map> maps, Object key, Object val)64 void put(List<Map> maps, Object key, Object val) { 65 for (Map map : maps) 66 map.put(key, val); 67 mapsEqual(maps); 68 } 69 removeLastTwo(List<Map> maps)70 void removeLastTwo(List<Map> maps) { 71 Map first = maps.get(0); 72 int size = first.size(); 73 Iterator fit = first.keySet().iterator(); 74 for (int j = 0; j < size - 2; j++) 75 fit.next(); 76 Object x1 = fit.next(); 77 Object x2 = fit.next(); 78 79 for (Map map : maps) { 80 Iterator it = map.keySet().iterator(); 81 while (it.hasNext()) { 82 Object x = it.next(); 83 if (x == x1 || x == x2) 84 it.remove(); 85 } 86 } 87 mapsEqual(maps); 88 } 89 90 @Test testLockStep()91 public void testLockStep() throws Throwable { 92 final int iterations = 100; 93 final Random r = new Random(); 94 95 for (int i = 0; i < iterations; i++) { 96 List<Map> maps = List.of( 97 new IdentityHashMap(11), 98 new HashMap(16), 99 new LinkedHashMap(16), 100 new WeakHashMap(16), 101 new Hashtable(16), 102 new TreeMap(), 103 new ConcurrentHashMap(16), 104 new ConcurrentSkipListMap(), 105 Collections.checkedMap(new HashMap(16), Integer.class, Integer.class), 106 Collections.checkedSortedMap(new TreeMap(), Integer.class, Integer.class), 107 Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class), 108 Collections.synchronizedMap(new HashMap(16)), 109 Collections.synchronizedSortedMap(new TreeMap()), 110 Collections.synchronizedNavigableMap(new TreeMap())); 111 112 for (int j = 0; j < 10; j++) 113 put(maps, r.nextInt(100), r.nextInt(100)); 114 removeLastTwo(maps); 115 } 116 } 117 }