001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024import static org.junit.Assert.assertTrue; 025 026import org.apache.hadoop.hbase.client.RegionInfo; 027import org.apache.hadoop.hbase.client.RegionInfoBuilder; 028import org.apache.hadoop.hbase.testclassification.ClientTests; 029import org.apache.hadoop.hbase.testclassification.SmallTests; 030import org.junit.ClassRule; 031import org.junit.Test; 032import org.junit.experimental.categories.Category; 033 034@Category({ ClientTests.class, SmallTests.class }) 035public class TestRegionLocations { 036 037 @ClassRule 038 public static final HBaseClassTestRule CLASS_RULE = 039 HBaseClassTestRule.forClass(TestRegionLocations.class); 040 041 ServerName sn0 = ServerName.valueOf("host0", 10, 10); 042 ServerName sn1 = ServerName.valueOf("host1", 10, 10); 043 ServerName sn2 = ServerName.valueOf("host2", 10, 10); 044 ServerName sn3 = ServerName.valueOf("host3", 10, 10); 045 046 RegionInfo info0 = hri(0); 047 RegionInfo info1 = hri(1); 048 RegionInfo info2 = hri(2); 049 RegionInfo info9 = hri(9); 050 051 long regionId1 = 1000; 052 long regionId2 = 2000; 053 054 @Test 055 public void testSizeMethods() { 056 RegionLocations list = new RegionLocations(); 057 assertTrue(list.isEmpty()); 058 assertEquals(0, list.size()); 059 assertEquals(0, list.numNonNullElements()); 060 061 list = hrll((HRegionLocation) null); 062 assertTrue(list.isEmpty()); 063 assertEquals(1, list.size()); 064 assertEquals(0, list.numNonNullElements()); 065 066 RegionInfo info0 = hri(0); 067 list = hrll(hrl(info0, null)); 068 assertTrue(list.isEmpty()); 069 assertEquals(1, list.size()); 070 assertEquals(0, list.numNonNullElements()); 071 072 RegionInfo info9 = hri(9); 073 list = hrll(hrl(info9, null)); 074 assertTrue(list.isEmpty()); 075 assertEquals(10, list.size()); 076 assertEquals(0, list.numNonNullElements()); 077 078 list = hrll(hrl(info0, null), hrl(info9, null)); 079 assertTrue(list.isEmpty()); 080 assertEquals(10, list.size()); 081 assertEquals(0, list.numNonNullElements()); 082 } 083 084 private RegionInfo hri(int replicaId) { 085 return hri(regionId1, replicaId); 086 } 087 088 private RegionInfo hri(long regionId, int replicaId) { 089 TableName table = TableName.valueOf("table"); 090 byte[] startKey = HConstants.EMPTY_START_ROW; 091 byte[] endKey = HConstants.EMPTY_END_ROW; 092 RegionInfo info = RegionInfoBuilder.newBuilder(table).setStartKey(startKey).setEndKey(endKey) 093 .setRegionId(regionId).setReplicaId(replicaId).build(); 094 return info; 095 } 096 097 private HRegionLocation hrl(RegionInfo hri, ServerName sn) { 098 return new HRegionLocation(hri, sn); 099 } 100 101 private HRegionLocation hrl(RegionInfo hri, ServerName sn, long seqNum) { 102 return new HRegionLocation(hri, sn, seqNum); 103 } 104 105 private RegionLocations hrll(HRegionLocation... locations) { 106 return new RegionLocations(locations); 107 } 108 109 @Test 110 public void testRemoveByServer() { 111 RegionLocations list; 112 113 // test remove from empty list 114 list = new RegionLocations(); 115 assertTrue(list == list.removeByServer(sn0)); 116 117 // test remove from single element list 118 list = hrll(hrl(info0, sn0)); 119 assertTrue(list == list.removeByServer(sn1)); 120 list = list.removeByServer(sn0); 121 assertEquals(0, list.numNonNullElements()); 122 123 // test remove from multi element list 124 list = hrll(hrl(info0, sn0), hrl(info1, sn1), hrl(info2, sn2), hrl(info9, sn2)); 125 assertTrue(list == list.removeByServer(sn3)); // no region is mapped to sn3 126 list = list.removeByServer(sn0); 127 assertNull(list.getRegionLocation(0)); 128 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 129 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 130 assertNull(list.getRegionLocation(5)); 131 assertEquals(sn2, list.getRegionLocation(9).getServerName()); 132 133 // test multi-element remove from multi element list 134 list = hrll(hrl(info0, sn1), hrl(info1, sn1), hrl(info2, sn0), hrl(info9, sn0)); 135 list = list.removeByServer(sn0); 136 assertEquals(sn1, list.getRegionLocation(0).getServerName()); 137 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 138 assertNull(list.getRegionLocation(2)); 139 assertNull(list.getRegionLocation(5)); 140 assertNull(list.getRegionLocation(9)); 141 } 142 143 @Test 144 public void testRemove() { 145 RegionLocations list; 146 147 // test remove from empty list 148 list = new RegionLocations(); 149 assertTrue(list == list.remove(hrl(info0, sn0))); 150 151 // test remove from single element list 152 list = hrll(hrl(info0, sn0)); 153 assertTrue(list == list.remove(hrl(info0, sn1))); 154 list = list.remove(hrl(info0, sn0)); 155 assertTrue(list.isEmpty()); 156 157 // test remove from multi element list 158 list = hrll(hrl(info0, sn0), hrl(info1, sn1), hrl(info2, sn2), hrl(info9, sn2)); 159 assertTrue(list == list.remove(hrl(info1, sn3))); // no region is mapped to sn3 160 list = list.remove(hrl(info0, sn0)); 161 assertNull(list.getRegionLocation(0)); 162 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 163 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 164 assertNull(list.getRegionLocation(5)); 165 assertEquals(sn2, list.getRegionLocation(9).getServerName()); 166 167 list = list.remove(hrl(info9, sn2)); 168 assertNull(list.getRegionLocation(0)); 169 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 170 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 171 assertNull(list.getRegionLocation(5)); 172 assertNull(list.getRegionLocation(9)); 173 174 // test multi-element remove from multi element list 175 list = hrll(hrl(info0, sn1), hrl(info1, sn1), hrl(info2, sn0), hrl(info9, sn0)); 176 list = list.remove(hrl(info9, sn0)); 177 assertEquals(sn1, list.getRegionLocation(0).getServerName()); 178 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 179 assertEquals(sn0, list.getRegionLocation(2).getServerName()); 180 assertNull(list.getRegionLocation(5)); 181 assertNull(list.getRegionLocation(9)); 182 } 183 184 @Test 185 public void testUpdateLocation() { 186 RegionLocations list; 187 188 // test add to empty list 189 list = new RegionLocations(); 190 list = list.updateLocation(hrl(info0, sn1), false, false); 191 assertEquals(sn1, list.getRegionLocation(0).getServerName()); 192 193 // test add to non-empty list 194 list = list.updateLocation(hrl(info9, sn3, 10), false, false); 195 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 196 assertEquals(10, list.size()); 197 list = list.updateLocation(hrl(info2, sn2, 10), false, false); 198 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 199 assertEquals(10, list.size()); 200 201 // test update greater SeqNum 202 list = list.updateLocation(hrl(info2, sn3, 11), false, false); 203 assertEquals(sn3, list.getRegionLocation(2).getServerName()); 204 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 205 206 // test update equal SeqNum 207 list = list.updateLocation(hrl(info2, sn1, 11), false, false); // should not update 208 assertEquals(sn3, list.getRegionLocation(2).getServerName()); 209 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 210 list = list.updateLocation(hrl(info2, sn1, 11), true, false); // should update 211 assertEquals(sn1, list.getRegionLocation(2).getServerName()); 212 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 213 214 // test force update 215 list = list.updateLocation(hrl(info2, sn2, 9), false, true); // should update 216 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 217 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 218 } 219 220 @Test 221 public void testMergeLocations() { 222 RegionLocations list1, list2; 223 224 // test merge empty lists 225 list1 = new RegionLocations(); 226 list2 = new RegionLocations(); 227 228 assertTrue(list1 == list1.mergeLocations(list2)); 229 230 // test merge non-empty and empty 231 list2 = hrll(hrl(info0, sn0)); 232 list1 = list1.mergeLocations(list2); 233 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 234 235 // test merge empty and non empty 236 list1 = hrll(); 237 list1 = list2.mergeLocations(list1); 238 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 239 240 // test merge non intersecting 241 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 242 list2 = hrll(hrl(info2, sn2)); 243 list1 = list2.mergeLocations(list1); 244 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 245 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 246 assertEquals(2, list1.size()); // the size is taken from the argument list to merge 247 248 // do the other way merge as well 249 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 250 list2 = hrll(hrl(info2, sn2)); 251 list1 = list1.mergeLocations(list2); 252 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 253 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 254 assertEquals(sn2, list1.getRegionLocation(2).getServerName()); 255 256 // test intersecting lists same seqNum 257 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 258 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3)); 259 list1 = list2.mergeLocations(list1); // list1 should override 260 assertEquals(2, list1.size()); 261 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 262 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 263 264 // do the other way 265 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 266 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3)); 267 list1 = list1.mergeLocations(list2); // list2 should override 268 assertEquals(10, list1.size()); 269 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 270 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 271 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 272 273 // test intersecting lists different seqNum 274 list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10)); 275 list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11)); 276 list1 = list1.mergeLocations(list2); // list2 should override because of seqNum 277 assertEquals(10, list1.size()); 278 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 279 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 280 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 281 282 // do the other way 283 list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10)); 284 list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11)); 285 list1 = list1.mergeLocations(list2); // list2 should override 286 assertEquals(10, list1.size()); 287 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 288 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 289 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 290 } 291 292 @Test 293 public void testMergeLocationsWithDifferentRegionId() { 294 RegionLocations list1, list2; 295 296 // test merging two lists. But the list2 contains region replicas with a different region id 297 RegionInfo info0 = hri(regionId1, 0); 298 RegionInfo info1 = hri(regionId1, 1); 299 RegionInfo info2 = hri(regionId2, 2); 300 301 list1 = hrll(hrl(info2, sn1)); 302 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2)); 303 list1 = list2.mergeLocations(list1); 304 assertNull(list1.getRegionLocation(0)); 305 assertNull(list1.getRegionLocation(1)); 306 assertNotNull(list1.getRegionLocation(2)); 307 assertEquals(sn1, list1.getRegionLocation(2).getServerName()); 308 assertEquals(3, list1.size()); 309 310 // try the other way merge 311 list1 = hrll(hrl(info2, sn1)); 312 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2)); 313 list2 = list1.mergeLocations(list2); 314 assertNotNull(list2.getRegionLocation(0)); 315 assertNotNull(list2.getRegionLocation(1)); 316 assertNull(list2.getRegionLocation(2)); 317 } 318 319 @Test 320 public void testUpdateLocationWithDifferentRegionId() { 321 RegionLocations list; 322 323 RegionInfo info0 = hri(regionId1, 0); 324 RegionInfo info1 = hri(regionId2, 1); 325 RegionInfo info2 = hri(regionId1, 2); 326 327 list = new RegionLocations(hrl(info0, sn1), hrl(info2, sn1)); 328 329 list = list.updateLocation(hrl(info1, sn2), false, true); // force update 330 331 // the other locations should be removed now 332 assertNull(list.getRegionLocation(0)); 333 assertNotNull(list.getRegionLocation(1)); 334 assertNull(list.getRegionLocation(2)); 335 assertEquals(sn2, list.getRegionLocation(1).getServerName()); 336 assertEquals(3, list.size()); 337 } 338 339 @Test 340 public void testConstructWithNullElements() { 341 // RegionLocations can contain null elements as well. These null elements can 342 343 RegionLocations list = new RegionLocations((HRegionLocation) null); 344 assertTrue(list.isEmpty()); 345 assertEquals(1, list.size()); 346 assertEquals(0, list.numNonNullElements()); 347 348 list = new RegionLocations(null, hrl(info1, sn0)); 349 assertFalse(list.isEmpty()); 350 assertEquals(2, list.size()); 351 assertEquals(1, list.numNonNullElements()); 352 353 list = new RegionLocations(hrl(info0, sn0), null); 354 assertEquals(2, list.size()); 355 assertEquals(1, list.numNonNullElements()); 356 357 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0)); 358 assertEquals(10, list.size()); 359 assertEquals(2, list.numNonNullElements()); 360 361 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null); 362 assertEquals(11, list.size()); 363 assertEquals(2, list.numNonNullElements()); 364 365 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null, null); 366 assertEquals(12, list.size()); 367 assertEquals(2, list.numNonNullElements()); 368 } 369}