• 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 com.google.common.collect.testing.SetTestSuiteBuilder;
20 import com.google.common.collect.testing.TestStringSetGenerator;
21 import com.google.common.collect.testing.features.CollectionFeature;
22 import com.google.common.collect.testing.features.CollectionSize;
23 import java.io.Serializable;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.Set;
28 import junit.framework.Test;
29 import junit.framework.TestCase;
30 import org.checkerframework.checker.nullness.qual.Nullable;
31 
32 /**
33  * Tests for {@code Synchronized#set}.
34  *
35  * @author Mike Bostock
36  */
37 public class SynchronizedSetTest extends TestCase {
38 
39   public static final Object MUTEX = new Integer(1); // something Serializable
40 
41   // TODO(cpovirk): Resolve difference between branches in their choice of mutex:
42   // - The mainline uses `null` (even since the change in cl/99720576 was integrated).
43   // - The backport continued to use MUTEX.
suite()44   public static Test suite() {
45     return SetTestSuiteBuilder.using(
46             new TestStringSetGenerator() {
47               @Override
48               protected Set<String> create(String[] elements) {
49                 TestSet<String> inner = new TestSet<>(new HashSet<String>(), null);
50                 Set<String> outer = Synchronized.set(inner, null);
51                 inner.mutex = outer;
52                 Collections.addAll(outer, elements);
53                 return outer;
54               }
55             })
56         .named("Synchronized.set")
57         .withFeatures(
58             CollectionFeature.GENERAL_PURPOSE,
59             CollectionFeature.ALLOWS_NULL_VALUES,
60             CollectionSize.ANY,
61             CollectionFeature.SERIALIZABLE)
62         .createTestSuite();
63   }
64 
65   static class TestSet<E> extends ForwardingSet<E> implements Serializable {
66     final Set<E> delegate;
67     public Object mutex;
68 
69     public TestSet(Set<E> delegate, @Nullable Object mutex) {
70       this.delegate = delegate;
71       this.mutex = mutex;
72     }
73 
74     @Override
75     protected Set<E> delegate() {
76       return delegate;
77     }
78 
79     @Override
80     public String toString() {
81       assertTrue(Thread.holdsLock(mutex));
82       return super.toString();
83     }
84 
85     @Override
86     public boolean equals(@Nullable Object o) {
87       assertTrue(Thread.holdsLock(mutex));
88       return super.equals(o);
89     }
90 
91     @Override
92     public int hashCode() {
93       assertTrue(Thread.holdsLock(mutex));
94       return super.hashCode();
95     }
96 
97     @Override
98     public boolean add(@Nullable E o) {
99       assertTrue(Thread.holdsLock(mutex));
100       return super.add(o);
101     }
102 
103     @Override
104     public boolean addAll(Collection<? extends E> c) {
105       assertTrue(Thread.holdsLock(mutex));
106       return super.addAll(c);
107     }
108 
109     @Override
110     public void clear() {
111       assertTrue(Thread.holdsLock(mutex));
112       super.clear();
113     }
114 
115     @Override
116     public boolean contains(@Nullable Object o) {
117       assertTrue(Thread.holdsLock(mutex));
118       return super.contains(o);
119     }
120 
121     @Override
122     public boolean containsAll(Collection<?> c) {
123       assertTrue(Thread.holdsLock(mutex));
124       return super.containsAll(c);
125     }
126 
127     @Override
128     public boolean isEmpty() {
129       assertTrue(Thread.holdsLock(mutex));
130       return super.isEmpty();
131     }
132 
133     /* Don't test iterator(); it may or may not hold the mutex. */
134 
135     @Override
136     public boolean remove(@Nullable Object o) {
137       assertTrue(Thread.holdsLock(mutex));
138       return super.remove(o);
139     }
140 
141     @Override
142     public boolean removeAll(Collection<?> c) {
143       assertTrue(Thread.holdsLock(mutex));
144       return super.removeAll(c);
145     }
146 
147     @Override
148     public boolean retainAll(Collection<?> c) {
149       assertTrue(Thread.holdsLock(mutex));
150       return super.retainAll(c);
151     }
152 
153     @Override
154     public int size() {
155       assertTrue(Thread.holdsLock(mutex));
156       return super.size();
157     }
158 
159     @Override
160     public Object[] toArray() {
161       assertTrue(Thread.holdsLock(mutex));
162       return super.toArray();
163     }
164 
165     @Override
166     public <T> T[] toArray(T[] a) {
167       assertTrue(Thread.holdsLock(mutex));
168       return super.toArray(a);
169     }
170 
171     private static final long serialVersionUID = 0;
172   }
173 }
174