• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.junit.contrib.truth.Truth.ASSERT;
20 
21 import java.io.Serializable;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Map;
25 import java.util.RandomAccess;
26 import java.util.Set;
27 
28 import javax.annotation.Nullable;
29 
30 /**
31  * Tests for {@code Synchronized#multimap}.
32  *
33  * @author Mike Bostock
34  */
35 public class SynchronizedMultimapTest extends AbstractSetMultimapTest {
36 
create()37   @Override protected Multimap<String, Integer> create() {
38     TestMultimap<String, Integer> inner = new TestMultimap<String, Integer>();
39     Multimap<String, Integer> outer = Synchronized.multimap(inner, inner.mutex);
40     return outer;
41   }
42 
43   private static final class TestMultimap<K, V> extends ForwardingMultimap<K, V>
44       implements Serializable {
45     final Multimap<K, V> delegate = HashMultimap.create();
46     public final Object mutex = new Integer(1); // something Serializable
47 
delegate()48     @Override protected Multimap<K, V> delegate() {
49       return delegate;
50     }
51 
toString()52     @Override public String toString() {
53       assertTrue(Thread.holdsLock(mutex));
54       return super.toString();
55     }
56 
equals(@ullable Object o)57     @Override public boolean equals(@Nullable Object o) {
58       assertTrue(Thread.holdsLock(mutex));
59       return super.equals(o);
60     }
61 
hashCode()62     @Override public int hashCode() {
63       assertTrue(Thread.holdsLock(mutex));
64       return super.hashCode();
65     }
66 
size()67     @Override public int size() {
68       assertTrue(Thread.holdsLock(mutex));
69       return super.size();
70     }
71 
isEmpty()72     @Override public boolean isEmpty() {
73       assertTrue(Thread.holdsLock(mutex));
74       return super.isEmpty();
75     }
76 
containsKey(@ullable Object key)77     @Override public boolean containsKey(@Nullable Object key) {
78       assertTrue(Thread.holdsLock(mutex));
79       return super.containsKey(key);
80     }
81 
containsValue(@ullable Object value)82     @Override public boolean containsValue(@Nullable Object value) {
83       assertTrue(Thread.holdsLock(mutex));
84       return super.containsValue(value);
85     }
86 
containsEntry(@ullable Object key, @Nullable Object value)87     @Override public boolean containsEntry(@Nullable Object key,
88         @Nullable Object value) {
89       assertTrue(Thread.holdsLock(mutex));
90       return super.containsEntry(key, value);
91     }
92 
get(@ullable K key)93     @Override public Collection<V> get(@Nullable K key) {
94       assertTrue(Thread.holdsLock(mutex));
95       /* TODO: verify that the Collection is also synchronized? */
96       return super.get(key);
97     }
98 
put(K key, V value)99     @Override public boolean put(K key, V value) {
100       assertTrue(Thread.holdsLock(mutex));
101       return super.put(key, value);
102     }
103 
putAll(@ullable K key, Iterable<? extends V> values)104     @Override public boolean putAll(@Nullable K key,
105         Iterable<? extends V> values) {
106       assertTrue(Thread.holdsLock(mutex));
107       return super.putAll(key, values);
108     }
109 
putAll(Multimap<? extends K, ? extends V> map)110     @Override public boolean putAll(Multimap<? extends K, ? extends V> map) {
111       assertTrue(Thread.holdsLock(mutex));
112       return super.putAll(map);
113     }
114 
replaceValues(@ullable K key, Iterable<? extends V> values)115     @Override public Collection<V> replaceValues(@Nullable K key,
116         Iterable<? extends V> values) {
117       assertTrue(Thread.holdsLock(mutex));
118       return super.replaceValues(key, values);
119     }
120 
remove(@ullable Object key, @Nullable Object value)121     @Override public boolean remove(@Nullable Object key,
122         @Nullable Object value) {
123       assertTrue(Thread.holdsLock(mutex));
124       return super.remove(key, value);
125     }
126 
removeAll(@ullable Object key)127     @Override public Collection<V> removeAll(@Nullable Object key) {
128       assertTrue(Thread.holdsLock(mutex));
129       return super.removeAll(key);
130     }
131 
clear()132     @Override public void clear() {
133       assertTrue(Thread.holdsLock(mutex));
134       super.clear();
135     }
136 
keySet()137     @Override public Set<K> keySet() {
138       assertTrue(Thread.holdsLock(mutex));
139       /* TODO: verify that the Set is also synchronized? */
140       return super.keySet();
141     }
142 
keys()143     @Override public Multiset<K> keys() {
144       assertTrue(Thread.holdsLock(mutex));
145       /* TODO: verify that the Set is also synchronized? */
146       return super.keys();
147     }
148 
values()149     @Override public Collection<V> values() {
150       assertTrue(Thread.holdsLock(mutex));
151       /* TODO: verify that the Collection is also synchronized? */
152       return super.values();
153     }
154 
entries()155     @Override public Collection<Map.Entry<K, V>> entries() {
156       assertTrue(Thread.holdsLock(mutex));
157       /* TODO: verify that the Collection is also synchronized? */
158       return super.entries();
159     }
160 
asMap()161     @Override public Map<K, Collection<V>> asMap() {
162       assertTrue(Thread.holdsLock(mutex));
163       /* TODO: verify that the Map is also synchronized? */
164       return super.asMap();
165     }
166 
167     private static final long serialVersionUID = 0;
168   }
169 
testSynchronizedListMultimap()170   public void testSynchronizedListMultimap() {
171     ListMultimap<String, Integer> multimap
172         = Multimaps.synchronizedListMultimap(
173             ArrayListMultimap.<String, Integer>create());
174     multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
175     multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
176     ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(3, -1, 2, 4, 1);
177     assertFalse(multimap.containsKey("foo"));
178     ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
179         .hasContentsInOrder(1, 2, 3, 1);
180     ASSERT.that(multimap.get("bar")).hasContentsInOrder(6, 5);
181   }
182 
testSynchronizedSortedSetMultimap()183   public void testSynchronizedSortedSetMultimap() {
184     SortedSetMultimap<String, Integer> multimap
185         = Multimaps.synchronizedSortedSetMultimap(
186             TreeMultimap.<String, Integer>create());
187     multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
188     multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
189     ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(-1, 1, 2, 3, 4);
190     assertFalse(multimap.containsKey("foo"));
191     ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
192         .hasContentsInOrder(1, 2, 3);
193     ASSERT.that(multimap.get("bar")).hasContentsInOrder(5, 6);
194   }
195 
testSynchronizedArrayListMultimapRandomAccess()196   public void testSynchronizedArrayListMultimapRandomAccess() {
197     ListMultimap<String, Integer> delegate = ArrayListMultimap.create();
198     delegate.put("foo", 1);
199     delegate.put("foo", 3);
200     ListMultimap<String, Integer> multimap
201         = Multimaps.synchronizedListMultimap(delegate);
202     assertTrue(multimap.get("foo") instanceof RandomAccess);
203     assertTrue(multimap.get("bar") instanceof RandomAccess);
204   }
205 
testSynchronizedLinkedListMultimapRandomAccess()206   public void testSynchronizedLinkedListMultimapRandomAccess() {
207     ListMultimap<String, Integer> delegate = LinkedListMultimap.create();
208     delegate.put("foo", 1);
209     delegate.put("foo", 3);
210     ListMultimap<String, Integer> multimap
211         = Multimaps.synchronizedListMultimap(delegate);
212     assertFalse(multimap.get("foo") instanceof RandomAccess);
213     assertFalse(multimap.get("bar") instanceof RandomAccess);
214   }
215 }
216