View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertNotNull;
24  import static org.junit.Assert.assertNull;
25  import static org.junit.Assert.assertTrue;
26  
27  import org.apache.hadoop.hbase.testclassification.SmallTests;
28  import org.junit.Test;
29  import org.junit.experimental.categories.Category;
30  
31  @Category(SmallTests.class)
32  public class TestRegionLocations {
33  
34    ServerName sn0 = ServerName.valueOf("host0", 10, 10);
35    ServerName sn1 = ServerName.valueOf("host1", 10, 10);
36    ServerName sn2 = ServerName.valueOf("host2", 10, 10);
37    ServerName sn3 = ServerName.valueOf("host3", 10, 10);
38  
39    HRegionInfo info0 = hri(0);
40    HRegionInfo info1 = hri(1);
41    HRegionInfo info2 = hri(2);
42    HRegionInfo info9 = hri(9);
43  
44    long regionId1 = 1000;
45    long regionId2 = 2000;
46  
47    @Test
48    public void testSizeMethods() {
49      RegionLocations list = new RegionLocations();
50      assertTrue(list.isEmpty());
51      assertEquals(0, list.size());
52      assertEquals(0, list.numNonNullElements());
53  
54      list = hrll((HRegionLocation)null);
55      assertTrue(list.isEmpty());
56      assertEquals(1, list.size());
57      assertEquals(0, list.numNonNullElements());
58  
59      HRegionInfo info0 = hri(0);
60      list = hrll(hrl(info0, null));
61      assertTrue(list.isEmpty());
62      assertEquals(1, list.size());
63      assertEquals(0, list.numNonNullElements());
64  
65      HRegionInfo info9 = hri(9);
66      list = hrll(hrl(info9, null));
67      assertTrue(list.isEmpty());
68      assertEquals(10, list.size());
69      assertEquals(0, list.numNonNullElements());
70  
71      list = hrll(hrl(info0, null), hrl(info9, null));
72      assertTrue(list.isEmpty());
73      assertEquals(10, list.size());
74      assertEquals(0, list.numNonNullElements());
75    }
76  
77    private HRegionInfo hri(int replicaId) {
78      return hri(regionId1, replicaId);
79    }
80  
81    private HRegionInfo hri(long regionId, int replicaId) {
82      TableName table = TableName.valueOf("table");
83      byte[] startKey = HConstants.EMPTY_START_ROW;
84      byte[] endKey = HConstants.EMPTY_END_ROW;
85      HRegionInfo info = new HRegionInfo(table, startKey, endKey, false, regionId, replicaId);
86      return info;
87    }
88  
89    private HRegionLocation hrl(HRegionInfo hri, ServerName sn) {
90      return new HRegionLocation(hri, sn);
91    }
92  
93    private HRegionLocation hrl(HRegionInfo hri, ServerName sn, long seqNum) {
94      return new HRegionLocation(hri, sn, seqNum);
95    }
96  
97    private RegionLocations hrll(HRegionLocation ... locations) {
98      return new RegionLocations(locations);
99    }
100 
101   @Test
102   public void testRemoveByServer() {
103     RegionLocations list;
104 
105     // test remove from empty list
106     list = new RegionLocations();
107     assertTrue(list == list.removeByServer(sn0));
108 
109     // test remove from single element list
110     list = hrll(hrl(info0, sn0));
111     assertTrue(list == list.removeByServer(sn1));
112     list = list.removeByServer(sn0);
113     assertEquals(0, list.numNonNullElements());
114 
115     // test remove from multi element list
116     list = hrll(hrl(info0, sn0), hrl(info1, sn1), hrl(info2, sn2), hrl(info9, sn2));
117     assertTrue(list == list.removeByServer(sn3)); // no region is mapped to sn3
118     list = list.removeByServer(sn0);
119     assertNull(list.getRegionLocation(0));
120     assertEquals(sn1, list.getRegionLocation(1).getServerName());
121     assertEquals(sn2, list.getRegionLocation(2).getServerName());
122     assertNull(list.getRegionLocation(5));
123     assertEquals(sn2, list.getRegionLocation(9).getServerName());
124 
125     // test multi-element remove from multi element list
126     list = hrll(hrl(info0, sn1), hrl(info1, sn1), hrl(info2, sn0), hrl(info9, sn0));
127     list = list.removeByServer(sn0);
128     assertEquals(sn1, list.getRegionLocation(0).getServerName());
129     assertEquals(sn1, list.getRegionLocation(1).getServerName());
130     assertNull(list.getRegionLocation(2));
131     assertNull(list.getRegionLocation(5));
132     assertNull(list.getRegionLocation(9));
133   }
134 
135   @Test
136   public void testRemove() {
137     RegionLocations list;
138 
139     // test remove from empty list
140     list = new RegionLocations();
141     assertTrue(list == list.remove(hrl(info0, sn0)));
142 
143     // test remove from single element list
144     list = hrll(hrl(info0, sn0));
145     assertTrue(list == list.remove(hrl(info0, sn1)));
146     list = list.remove(hrl(info0, sn0));
147     assertTrue(list.isEmpty());
148 
149     // test remove from multi element list
150     list = hrll(hrl(info0, sn0), hrl(info1, sn1), hrl(info2, sn2), hrl(info9, sn2));
151     assertTrue(list == list.remove(hrl(info1, sn3))); // no region is mapped to sn3
152     list = list.remove(hrl(info0, sn0));
153     assertNull(list.getRegionLocation(0));
154     assertEquals(sn1, list.getRegionLocation(1).getServerName());
155     assertEquals(sn2, list.getRegionLocation(2).getServerName());
156     assertNull(list.getRegionLocation(5));
157     assertEquals(sn2, list.getRegionLocation(9).getServerName());
158 
159     list = list.remove(hrl(info9, sn2));
160     assertNull(list.getRegionLocation(0));
161     assertEquals(sn1, list.getRegionLocation(1).getServerName());
162     assertEquals(sn2, list.getRegionLocation(2).getServerName());
163     assertNull(list.getRegionLocation(5));
164     assertNull(list.getRegionLocation(9));
165 
166 
167     // test multi-element remove from multi element list
168     list = hrll(hrl(info0, sn1), hrl(info1, sn1), hrl(info2, sn0), hrl(info9, sn0));
169     list = list.remove(hrl(info9, sn0));
170     assertEquals(sn1, list.getRegionLocation(0).getServerName());
171     assertEquals(sn1, list.getRegionLocation(1).getServerName());
172     assertEquals(sn0, list.getRegionLocation(2).getServerName());
173     assertNull(list.getRegionLocation(5));
174     assertNull(list.getRegionLocation(9));
175   }
176 
177   @Test
178   public void testUpdateLocation() {
179     RegionLocations list;
180 
181     // test add to empty list
182     list = new RegionLocations();
183     list = list.updateLocation(hrl(info0, sn1), false, false);
184     assertEquals(sn1, list.getRegionLocation(0).getServerName());
185 
186     // test add to non-empty list
187     list = list.updateLocation(hrl(info9, sn3, 10), false, false);
188     assertEquals(sn3, list.getRegionLocation(9).getServerName());
189     assertEquals(10, list.size());
190     list = list.updateLocation(hrl(info2, sn2, 10), false, false);
191     assertEquals(sn2, list.getRegionLocation(2).getServerName());
192     assertEquals(10, list.size());
193 
194     // test update greater SeqNum
195     list = list.updateLocation(hrl(info2, sn3, 11), false, false);
196     assertEquals(sn3, list.getRegionLocation(2).getServerName());
197     assertEquals(sn3, list.getRegionLocation(9).getServerName());
198 
199     // test update equal SeqNum
200     list = list.updateLocation(hrl(info2, sn1, 11), false, false); // should not update
201     assertEquals(sn3, list.getRegionLocation(2).getServerName());
202     assertEquals(sn3, list.getRegionLocation(9).getServerName());
203     list = list.updateLocation(hrl(info2, sn1, 11), true, false); // should update
204     assertEquals(sn1, list.getRegionLocation(2).getServerName());
205     assertEquals(sn3, list.getRegionLocation(9).getServerName());
206 
207     // test force update
208     list = list.updateLocation(hrl(info2, sn2, 9), false, true); // should update
209     assertEquals(sn2, list.getRegionLocation(2).getServerName());
210     assertEquals(sn3, list.getRegionLocation(9).getServerName());
211   }
212 
213   @Test
214   public void testMergeLocations() {
215     RegionLocations list1, list2;
216 
217     // test merge empty lists
218     list1 = new RegionLocations();
219     list2 = new RegionLocations();
220 
221     assertTrue(list1 == list1.mergeLocations(list2));
222 
223     // test merge non-empty and empty
224     list2 = hrll(hrl(info0, sn0));
225     list1 = list1.mergeLocations(list2);
226     assertEquals(sn0, list1.getRegionLocation(0).getServerName());
227 
228     // test merge empty and non empty
229     list1 = hrll();
230     list1 = list2.mergeLocations(list1);
231     assertEquals(sn0, list1.getRegionLocation(0).getServerName());
232 
233     // test merge non intersecting
234     list1 = hrll(hrl(info0, sn0), hrl(info1, sn1));
235     list2 = hrll(hrl(info2, sn2));
236     list1 = list2.mergeLocations(list1);
237     assertEquals(sn0, list1.getRegionLocation(0).getServerName());
238     assertEquals(sn1, list1.getRegionLocation(1).getServerName());
239     assertEquals(2, list1.size()); // the size is taken from the argument list to merge
240 
241     // do the other way merge as well
242     list1 = hrll(hrl(info0, sn0), hrl(info1, sn1));
243     list2 = hrll(hrl(info2, sn2));
244     list1 = list1.mergeLocations(list2);
245     assertEquals(sn0, list1.getRegionLocation(0).getServerName());
246     assertEquals(sn1, list1.getRegionLocation(1).getServerName());
247     assertEquals(sn2, list1.getRegionLocation(2).getServerName());
248 
249     // test intersecting lists same seqNum
250     list1 = hrll(hrl(info0, sn0), hrl(info1, sn1));
251     list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3));
252     list1 = list2.mergeLocations(list1); // list1 should override
253     assertEquals(2, list1.size());
254     assertEquals(sn0, list1.getRegionLocation(0).getServerName());
255     assertEquals(sn1, list1.getRegionLocation(1).getServerName());
256 
257     // do the other way
258     list1 = hrll(hrl(info0, sn0), hrl(info1, sn1));
259     list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3));
260     list1 = list1.mergeLocations(list2); // list2 should override
261     assertEquals(10, list1.size());
262     assertEquals(sn2, list1.getRegionLocation(0).getServerName());
263     assertEquals(sn2, list1.getRegionLocation(1).getServerName());
264     assertEquals(sn3, list1.getRegionLocation(9).getServerName());
265 
266     // test intersecting lists different seqNum
267     list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10));
268     list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11));
269     list1 = list1.mergeLocations(list2); // list2 should override because of seqNum
270     assertEquals(10, list1.size());
271     assertEquals(sn2, list1.getRegionLocation(0).getServerName());
272     assertEquals(sn2, list1.getRegionLocation(1).getServerName());
273     assertEquals(sn3, list1.getRegionLocation(9).getServerName());
274 
275     // do the other way
276     list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10));
277     list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11));
278     list1 = list1.mergeLocations(list2); // list2 should override
279     assertEquals(10, list1.size());
280     assertEquals(sn2, list1.getRegionLocation(0).getServerName());
281     assertEquals(sn2, list1.getRegionLocation(1).getServerName());
282     assertEquals(sn3, list1.getRegionLocation(9).getServerName());
283   }
284 
285   @Test
286   public void testMergeLocationsWithDifferentRegionId() {
287     RegionLocations list1, list2;
288 
289     // test merging two lists. But the list2 contains region replicas with a different region id
290     HRegionInfo info0 = hri(regionId1, 0);
291     HRegionInfo info1 = hri(regionId1, 1);
292     HRegionInfo info2 = hri(regionId2, 2);
293 
294     list1 = hrll(hrl(info2, sn1));
295     list2 = hrll(hrl(info0, sn2), hrl(info1, sn2));
296     list1 = list2.mergeLocations(list1);
297     assertNull(list1.getRegionLocation(0));
298     assertNull(list1.getRegionLocation(1));
299     assertNotNull(list1.getRegionLocation(2));
300     assertEquals(sn1, list1.getRegionLocation(2).getServerName());
301     assertEquals(3, list1.size());
302 
303     // try the other way merge
304     list1 = hrll(hrl(info2, sn1));
305     list2 = hrll(hrl(info0, sn2), hrl(info1, sn2));
306     list2 = list1.mergeLocations(list2);
307     assertNotNull(list2.getRegionLocation(0));
308     assertNotNull(list2.getRegionLocation(1));
309     assertNull(list2.getRegionLocation(2));
310   }
311 
312   @Test
313   public void testUpdateLocationWithDifferentRegionId() {
314     RegionLocations list;
315 
316     HRegionInfo info0 = hri(regionId1, 0);
317     HRegionInfo info1 = hri(regionId2, 1);
318     HRegionInfo info2 = hri(regionId1, 2);
319 
320     list = new RegionLocations(hrl(info0, sn1), hrl(info2, sn1));
321 
322     list = list.updateLocation(hrl(info1, sn2), false, true); // force update
323 
324     // the other locations should be removed now
325     assertNull(list.getRegionLocation(0));
326     assertNotNull(list.getRegionLocation(1));
327     assertNull(list.getRegionLocation(2));
328     assertEquals(sn2, list.getRegionLocation(1).getServerName());
329     assertEquals(3, list.size());
330   }
331 
332 
333   @Test
334   public void testConstructWithNullElements() {
335     // RegionLocations can contain null elements as well. These null elements can
336 
337     RegionLocations list = new RegionLocations((HRegionLocation)null);
338     assertTrue(list.isEmpty());
339     assertEquals(1, list.size());
340     assertEquals(0, list.numNonNullElements());
341 
342     list = new RegionLocations(null, hrl(info1, sn0));
343     assertFalse(list.isEmpty());
344     assertEquals(2, list.size());
345     assertEquals(1, list.numNonNullElements());
346 
347     list = new RegionLocations(hrl(info0, sn0), null);
348     assertEquals(2, list.size());
349     assertEquals(1, list.numNonNullElements());
350 
351     list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0));
352     assertEquals(10, list.size());
353     assertEquals(2, list.numNonNullElements());
354 
355     list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null);
356     assertEquals(11, list.size());
357     assertEquals(2, list.numNonNullElements());
358 
359     list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null, null);
360     assertEquals(12, list.size());
361     assertEquals(2, list.numNonNullElements());
362   }
363 }