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