1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Random;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.atomic.AtomicBoolean;
27
28 import junit.framework.Test;
29 import junit.framework.TestCase;
30 import junit.framework.TestSuite;
31
32 import org.apache.hadoop.hbase.util.PoolMap.PoolType;
33
34 public class TestPoolMap {
35 public abstract static class TestPoolType extends TestCase {
36 protected PoolMap<String, String> poolMap;
37 protected Random random = new Random();
38
39 protected static final int POOL_SIZE = 3;
40
41 @Override
42 protected void setUp() throws Exception {
43 this.poolMap = new PoolMap<String, String>(getPoolType(), POOL_SIZE);
44 }
45
46 protected abstract PoolType getPoolType();
47
48 @Override
49 protected void tearDown() throws Exception {
50 this.poolMap.clear();
51 }
52
53 protected void runThread(final String randomKey, final String randomValue,
54 final String expectedValue) throws InterruptedException {
55 final AtomicBoolean matchFound = new AtomicBoolean(false);
56 Thread thread = new Thread(new Runnable() {
57 @Override
58 public void run() {
59 poolMap.put(randomKey, randomValue);
60 String actualValue = poolMap.get(randomKey);
61 matchFound.set(expectedValue == null ? actualValue == null
62 : expectedValue.equals(actualValue));
63 }
64 });
65 thread.start();
66 thread.join();
67 assertTrue(matchFound.get());
68 }
69 }
70
71 public static class TestRoundRobinPoolType extends TestPoolType {
72 @Override
73 protected PoolType getPoolType() {
74 return PoolType.RoundRobin;
75 }
76
77 public void testSingleThreadedClient() throws InterruptedException,
78 ExecutionException {
79 String randomKey = String.valueOf(random.nextInt());
80 String randomValue = String.valueOf(random.nextInt());
81
82
83
84 runThread(randomKey, randomValue, null);
85 assertEquals(1, poolMap.size(randomKey));
86 }
87
88 public void testMultiThreadedClients() throws InterruptedException,
89 ExecutionException {
90 for (int i = 0; i < POOL_SIZE; i++) {
91 String randomKey = String.valueOf(random.nextInt());
92 String randomValue = String.valueOf(random.nextInt());
93
94 runThread(randomKey, randomValue, null);
95
96 assertEquals(1, poolMap.size(randomKey));
97 }
98 poolMap.clear();
99 String randomKey = String.valueOf(random.nextInt());
100 for (int i = 0; i < POOL_SIZE - 1; i++) {
101 String randomValue = String.valueOf(random.nextInt());
102
103 runThread(randomKey, randomValue, null);
104
105 assertEquals(i + 1, poolMap.size(randomKey));
106 }
107
108 assertEquals(POOL_SIZE - 1, poolMap.size(randomKey));
109 }
110
111 public void testPoolCap() throws InterruptedException, ExecutionException {
112 String randomKey = String.valueOf(random.nextInt());
113 List<String> randomValues = new ArrayList<String>();
114 for (int i = 0; i < POOL_SIZE * 2; i++) {
115 String randomValue = String.valueOf(random.nextInt());
116 randomValues.add(randomValue);
117 if (i < POOL_SIZE - 1) {
118
119 runThread(randomKey, randomValue, null);
120 } else {
121
122
123 runThread(randomKey, randomValue,
124 randomValues.get((i - POOL_SIZE + 1) % POOL_SIZE));
125 }
126 }
127 assertEquals(POOL_SIZE, poolMap.size(randomKey));
128 }
129
130 }
131
132 public static class TestThreadLocalPoolType extends TestPoolType {
133 @Override
134 protected PoolType getPoolType() {
135 return PoolType.ThreadLocal;
136 }
137
138 public void testSingleThreadedClient() throws InterruptedException,
139 ExecutionException {
140 String randomKey = String.valueOf(random.nextInt());
141 String randomValue = String.valueOf(random.nextInt());
142
143 runThread(randomKey, randomValue, randomValue);
144 assertEquals(1, poolMap.size(randomKey));
145 }
146
147 public void testMultiThreadedClients() throws InterruptedException,
148 ExecutionException {
149
150 for (int i = 0; i < POOL_SIZE; i++) {
151 String randomKey = String.valueOf(random.nextInt());
152 String randomValue = String.valueOf(random.nextInt());
153 runThread(randomKey, randomValue, randomValue);
154 assertEquals(1, poolMap.size(randomKey));
155 }
156 String randomKey = String.valueOf(random.nextInt());
157 for (int i = 0; i < POOL_SIZE; i++) {
158 String randomValue = String.valueOf(random.nextInt());
159 runThread(randomKey, randomValue, randomValue);
160 assertEquals(i + 1, poolMap.size(randomKey));
161 }
162 }
163
164 public void testPoolCap() throws InterruptedException, ExecutionException {
165 String randomKey = String.valueOf(random.nextInt());
166 for (int i = 0; i < POOL_SIZE * 2; i++) {
167 String randomValue = String.valueOf(random.nextInt());
168
169 runThread(randomKey, randomValue, randomValue);
170 }
171 assertEquals(POOL_SIZE * 2, poolMap.size(randomKey));
172 }
173
174 }
175
176 public static class TestReusablePoolType extends TestPoolType {
177 @Override
178 protected PoolType getPoolType() {
179 return PoolType.Reusable;
180 }
181
182 public void testSingleThreadedClient() throws InterruptedException,
183 ExecutionException {
184 String randomKey = String.valueOf(random.nextInt());
185 String randomValue = String.valueOf(random.nextInt());
186
187 runThread(randomKey, randomValue, randomValue);
188 assertEquals(0, poolMap.size(randomKey));
189 }
190
191 public void testMultiThreadedClients() throws InterruptedException,
192 ExecutionException {
193
194 for (int i = 0; i < POOL_SIZE; i++) {
195 String randomKey = String.valueOf(random.nextInt());
196 String randomValue = String.valueOf(random.nextInt());
197 runThread(randomKey, randomValue, randomValue);
198 assertEquals(0, poolMap.size(randomKey));
199 }
200 poolMap.clear();
201 String randomKey = String.valueOf(random.nextInt());
202 for (int i = 0; i < POOL_SIZE - 1; i++) {
203 String randomValue = String.valueOf(random.nextInt());
204 runThread(randomKey, randomValue, randomValue);
205 assertEquals(0, poolMap.size(randomKey));
206 }
207 assertEquals(0, poolMap.size(randomKey));
208 }
209
210 public void testPoolCap() throws InterruptedException, ExecutionException {
211
212 String randomKey = String.valueOf(random.nextInt());
213 List<String> randomValues = new ArrayList<String>();
214 for (int i = 0; i < POOL_SIZE * 2; i++) {
215 String randomValue = String.valueOf(random.nextInt());
216 randomValues.add(randomValue);
217 runThread(randomKey, randomValue, randomValue);
218 }
219 assertEquals(0, poolMap.size(randomKey));
220 }
221
222 }
223
224 public static Test suite() {
225 TestSuite suite = new TestSuite();
226 suite.addTestSuite(TestRoundRobinPoolType.class);
227 suite.addTestSuite(TestThreadLocalPoolType.class);
228 suite.addTestSuite(TestReusablePoolType.class);
229 return suite;
230 }
231
232 }