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