1 /* 2 * Copyright (C) 2007 The Guava Authors 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 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.collect.Synchronized.SynchronizedCollection; 22 import com.google.common.collect.Synchronized.SynchronizedSet; 23 import com.google.common.testing.SerializableTester; 24 import java.io.Serializable; 25 import java.util.Collection; 26 import java.util.HashMap; 27 import java.util.Map; 28 import java.util.Map.Entry; 29 import java.util.Set; 30 import junit.framework.TestCase; 31 import org.checkerframework.checker.nullness.qual.Nullable; 32 33 /** 34 * Tests for {@code Synchronized#map}. 35 * 36 * @author Mike Bostock 37 */ 38 public class SynchronizedMapTest extends TestCase { 39 public final Object mutex = new Object[0]; // something Serializable 40 create()41 protected <K, V> Map<K, V> create() { 42 TestMap<K, V> inner = new TestMap<>(new HashMap<K, V>(), mutex); 43 Map<K, V> outer = Synchronized.map(inner, mutex); 44 return outer; 45 } 46 47 static class TestMap<K, V> extends ForwardingMap<K, V> implements Serializable { 48 public final Object mutex; 49 private Map<K, V> delegate; 50 TestMap(Map<K, V> delegate, Object mutex)51 public TestMap(Map<K, V> delegate, Object mutex) { 52 checkNotNull(mutex); 53 this.delegate = delegate; 54 this.mutex = mutex; 55 } 56 57 @Override delegate()58 protected Map<K, V> delegate() { 59 return delegate; 60 } 61 62 @Override size()63 public int size() { 64 assertTrue(Thread.holdsLock(mutex)); 65 return super.size(); 66 } 67 68 @Override isEmpty()69 public boolean isEmpty() { 70 assertTrue(Thread.holdsLock(mutex)); 71 return super.isEmpty(); 72 } 73 74 @Override remove(Object object)75 public @Nullable V remove(Object object) { 76 assertTrue(Thread.holdsLock(mutex)); 77 return super.remove(object); 78 } 79 80 @Override clear()81 public void clear() { 82 assertTrue(Thread.holdsLock(mutex)); 83 super.clear(); 84 } 85 86 @Override containsKey(Object key)87 public boolean containsKey(Object key) { 88 assertTrue(Thread.holdsLock(mutex)); 89 return super.containsKey(key); 90 } 91 92 @Override containsValue(Object value)93 public boolean containsValue(Object value) { 94 assertTrue(Thread.holdsLock(mutex)); 95 return super.containsValue(value); 96 } 97 98 @Override get(Object key)99 public @Nullable V get(Object key) { 100 assertTrue(Thread.holdsLock(mutex)); 101 return super.get(key); 102 } 103 104 @Override put(K key, V value)105 public @Nullable V put(K key, V value) { 106 assertTrue(Thread.holdsLock(mutex)); 107 return super.put(key, value); 108 } 109 110 @Override putAll(Map<? extends K, ? extends V> map)111 public void putAll(Map<? extends K, ? extends V> map) { 112 assertTrue(Thread.holdsLock(mutex)); 113 super.putAll(map); 114 } 115 116 @Override keySet()117 public Set<K> keySet() { 118 assertTrue(Thread.holdsLock(mutex)); 119 return super.keySet(); 120 } 121 122 @Override values()123 public Collection<V> values() { 124 assertTrue(Thread.holdsLock(mutex)); 125 return super.values(); 126 } 127 128 @Override entrySet()129 public Set<Entry<K, V>> entrySet() { 130 assertTrue(Thread.holdsLock(mutex)); 131 return super.entrySet(); 132 } 133 134 @Override equals(@ullable Object obj)135 public boolean equals(@Nullable Object obj) { 136 assertTrue(Thread.holdsLock(mutex)); 137 return super.equals(obj); 138 } 139 140 @Override hashCode()141 public int hashCode() { 142 assertTrue(Thread.holdsLock(mutex)); 143 return super.hashCode(); 144 } 145 146 @Override toString()147 public String toString() { 148 assertTrue(Thread.holdsLock(mutex)); 149 return super.toString(); 150 } 151 152 private static final long serialVersionUID = 0; 153 } 154 155 /* 156 * This is somewhat of a weak test; we verify that all of the methods are 157 * correct, but not that they're actually forwarding correctly. We also rely 158 * on the other tests (e.g., SynchronizedSetTest) to verify that the 159 * collection views are synchronized correctly. 160 */ 161 testSize()162 public void testSize() { 163 int unused = create().size(); 164 } 165 testIsEmpty()166 public void testIsEmpty() { 167 boolean unused = create().isEmpty(); 168 } 169 testRemove()170 public void testRemove() { 171 create().remove(null); 172 } 173 testClear()174 public void testClear() { 175 create().clear(); 176 } 177 testContainsKey()178 public void testContainsKey() { 179 boolean unused = create().containsKey(null); 180 } 181 testContainsValue()182 public void testContainsValue() { 183 boolean unused = create().containsValue(null); 184 } 185 testGet()186 public void testGet() { 187 create().get(null); 188 } 189 testPut()190 public void testPut() { 191 create().put(null, null); 192 } 193 testPutAll()194 public void testPutAll() { 195 create().putAll(new HashMap<String, Integer>()); 196 } 197 testKeySet()198 public void testKeySet() { 199 Map<String, Integer> map = create(); 200 Set<String> keySet = map.keySet(); 201 assertTrue(keySet instanceof SynchronizedSet); 202 assertSame(mutex, ((SynchronizedSet<?>) keySet).mutex); 203 } 204 testValues()205 public void testValues() { 206 Map<String, Integer> map = create(); 207 Collection<Integer> values = map.values(); 208 assertTrue(values instanceof SynchronizedCollection); 209 assertSame(mutex, ((SynchronizedCollection<?>) values).mutex); 210 } 211 testEntrySet()212 public void testEntrySet() { 213 Map<String, Integer> map = create(); 214 Set<Entry<String, Integer>> entrySet = map.entrySet(); 215 assertTrue(entrySet instanceof SynchronizedSet); 216 assertSame(mutex, ((SynchronizedSet<?>) entrySet).mutex); 217 } 218 testEquals()219 public void testEquals() { 220 boolean unused = create().equals(new HashMap<String, Integer>()); 221 } 222 testHashCode()223 public void testHashCode() { 224 int unused = create().hashCode(); 225 } 226 testToString()227 public void testToString() { 228 String unused = create().toString(); 229 } 230 testSerialization()231 public void testSerialization() { 232 SerializableTester.reserializeAndAssert(create()); 233 } 234 } 235