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