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 // test multi-element remove from multi element list 172 list = hrll(hrl(info0, sn1), hrl(info1, sn1), hrl(info2, sn0), hrl(info9, sn0)); 173 list = list.remove(hrl(info9, sn0)); 174 assertEquals(sn1, list.getRegionLocation(0).getServerName()); 175 assertEquals(sn1, list.getRegionLocation(1).getServerName()); 176 assertEquals(sn0, list.getRegionLocation(2).getServerName()); 177 assertNull(list.getRegionLocation(5)); 178 assertNull(list.getRegionLocation(9)); 179 } 180 181 @Test 182 public void testUpdateLocation() { 183 RegionLocations list; 184 185 // test add to empty list 186 list = new RegionLocations(); 187 list = list.updateLocation(hrl(info0, sn1), false, false); 188 assertEquals(sn1, list.getRegionLocation(0).getServerName()); 189 190 // test add to non-empty list 191 list = list.updateLocation(hrl(info9, sn3, 10), false, false); 192 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 193 assertEquals(10, list.size()); 194 list = list.updateLocation(hrl(info2, sn2, 10), false, false); 195 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 196 assertEquals(10, list.size()); 197 198 // test update greater SeqNum 199 list = list.updateLocation(hrl(info2, sn3, 11), false, false); 200 assertEquals(sn3, list.getRegionLocation(2).getServerName()); 201 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 202 203 // test update equal SeqNum 204 list = list.updateLocation(hrl(info2, sn1, 11), false, false); // should not update 205 assertEquals(sn3, list.getRegionLocation(2).getServerName()); 206 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 207 list = list.updateLocation(hrl(info2, sn1, 11), true, false); // should update 208 assertEquals(sn1, list.getRegionLocation(2).getServerName()); 209 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 210 211 // test force update 212 list = list.updateLocation(hrl(info2, sn2, 9), false, true); // should update 213 assertEquals(sn2, list.getRegionLocation(2).getServerName()); 214 assertEquals(sn3, list.getRegionLocation(9).getServerName()); 215 } 216 217 @Test 218 public void testMergeLocations() { 219 RegionLocations list1, list2; 220 221 // test merge empty lists 222 list1 = new RegionLocations(); 223 list2 = new RegionLocations(); 224 225 assertTrue(list1 == list1.mergeLocations(list2)); 226 227 // test merge non-empty and empty 228 list2 = hrll(hrl(info0, sn0)); 229 list1 = list1.mergeLocations(list2); 230 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 231 232 // test merge empty and non empty 233 list1 = hrll(); 234 list1 = list2.mergeLocations(list1); 235 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 236 237 // test merge non intersecting 238 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 239 list2 = hrll(hrl(info2, sn2)); 240 list1 = list2.mergeLocations(list1); 241 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 242 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 243 assertEquals(2, list1.size()); // the size is taken from the argument list to merge 244 245 // do the other way merge as well 246 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 247 list2 = hrll(hrl(info2, sn2)); 248 list1 = list1.mergeLocations(list2); 249 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 250 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 251 assertEquals(sn2, list1.getRegionLocation(2).getServerName()); 252 253 // test intersecting lists same seqNum 254 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 255 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3)); 256 list1 = list2.mergeLocations(list1); // list1 should override 257 assertEquals(2, list1.size()); 258 assertEquals(sn0, list1.getRegionLocation(0).getServerName()); 259 assertEquals(sn1, list1.getRegionLocation(1).getServerName()); 260 261 // do the other way 262 list1 = hrll(hrl(info0, sn0), hrl(info1, sn1)); 263 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2), hrl(info9, sn3)); 264 list1 = list1.mergeLocations(list2); // list2 should override 265 assertEquals(10, list1.size()); 266 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 267 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 268 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 269 270 // test intersecting lists different seqNum 271 list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10)); 272 list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11)); 273 list1 = list1.mergeLocations(list2); // list2 should override because of seqNum 274 assertEquals(10, list1.size()); 275 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 276 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 277 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 278 279 // do the other way 280 list1 = hrll(hrl(info0, sn0, 10), hrl(info1, sn1, 10)); 281 list2 = hrll(hrl(info0, sn2, 11), hrl(info1, sn2, 11), hrl(info9, sn3, 11)); 282 list1 = list1.mergeLocations(list2); // list2 should override 283 assertEquals(10, list1.size()); 284 assertEquals(sn2, list1.getRegionLocation(0).getServerName()); 285 assertEquals(sn2, list1.getRegionLocation(1).getServerName()); 286 assertEquals(sn3, list1.getRegionLocation(9).getServerName()); 287 } 288 289 @Test 290 public void testMergeLocationsWithDifferentRegionId() { 291 RegionLocations list1, list2; 292 293 // test merging two lists. But the list2 contains region replicas with a different region id 294 HRegionInfo info0 = hri(regionId1, 0); 295 HRegionInfo info1 = hri(regionId1, 1); 296 HRegionInfo info2 = hri(regionId2, 2); 297 298 list1 = hrll(hrl(info2, sn1)); 299 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2)); 300 list1 = list2.mergeLocations(list1); 301 assertNull(list1.getRegionLocation(0)); 302 assertNull(list1.getRegionLocation(1)); 303 assertNotNull(list1.getRegionLocation(2)); 304 assertEquals(sn1, list1.getRegionLocation(2).getServerName()); 305 assertEquals(3, list1.size()); 306 307 // try the other way merge 308 list1 = hrll(hrl(info2, sn1)); 309 list2 = hrll(hrl(info0, sn2), hrl(info1, sn2)); 310 list2 = list1.mergeLocations(list2); 311 assertNotNull(list2.getRegionLocation(0)); 312 assertNotNull(list2.getRegionLocation(1)); 313 assertNull(list2.getRegionLocation(2)); 314 } 315 316 @Test 317 public void testUpdateLocationWithDifferentRegionId() { 318 RegionLocations list; 319 320 HRegionInfo info0 = hri(regionId1, 0); 321 HRegionInfo info1 = hri(regionId2, 1); 322 HRegionInfo info2 = hri(regionId1, 2); 323 324 list = new RegionLocations(hrl(info0, sn1), hrl(info2, sn1)); 325 326 list = list.updateLocation(hrl(info1, sn2), false, true); // force update 327 328 // the other locations should be removed now 329 assertNull(list.getRegionLocation(0)); 330 assertNotNull(list.getRegionLocation(1)); 331 assertNull(list.getRegionLocation(2)); 332 assertEquals(sn2, list.getRegionLocation(1).getServerName()); 333 assertEquals(3, list.size()); 334 } 335 336 @Test 337 public void testConstructWithNullElements() { 338 // RegionLocations can contain null elements as well. These null elements can 339 340 RegionLocations list = new RegionLocations((HRegionLocation) null); 341 assertTrue(list.isEmpty()); 342 assertEquals(1, list.size()); 343 assertEquals(0, list.numNonNullElements()); 344 345 list = new RegionLocations(null, hrl(info1, sn0)); 346 assertFalse(list.isEmpty()); 347 assertEquals(2, list.size()); 348 assertEquals(1, list.numNonNullElements()); 349 350 list = new RegionLocations(hrl(info0, sn0), null); 351 assertEquals(2, list.size()); 352 assertEquals(1, list.numNonNullElements()); 353 354 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0)); 355 assertEquals(10, list.size()); 356 assertEquals(2, list.numNonNullElements()); 357 358 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null); 359 assertEquals(11, list.size()); 360 assertEquals(2, list.numNonNullElements()); 361 362 list = new RegionLocations(null, hrl(info2, sn0), null, hrl(info9, sn0), null, null); 363 assertEquals(12, list.size()); 364 assertEquals(2, list.numNonNullElements()); 365 } 366}