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.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertNull; 023import static org.junit.Assert.assertTrue; 024 025import java.io.IOException; 026import java.util.ArrayList; 027import java.util.List; 028import java.util.Optional; 029import org.apache.hadoop.conf.Configuration; 030import org.apache.hadoop.hbase.CompatibilityFactory; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HBaseTestingUtil; 033import org.apache.hadoop.hbase.HConstants; 034import org.apache.hadoop.hbase.HRegionLocation; 035import org.apache.hadoop.hbase.NamespaceDescriptor; 036import org.apache.hadoop.hbase.SingleProcessHBaseCluster; 037import org.apache.hadoop.hbase.TableName; 038import org.apache.hadoop.hbase.client.Admin; 039import org.apache.hadoop.hbase.client.Append; 040import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 041import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 042import org.apache.hadoop.hbase.client.Connection; 043import org.apache.hadoop.hbase.client.Durability; 044import org.apache.hadoop.hbase.client.Get; 045import org.apache.hadoop.hbase.client.Increment; 046import org.apache.hadoop.hbase.client.Put; 047import org.apache.hadoop.hbase.client.RegionInfo; 048import org.apache.hadoop.hbase.client.RegionLocator; 049import org.apache.hadoop.hbase.client.Result; 050import org.apache.hadoop.hbase.client.ResultScanner; 051import org.apache.hadoop.hbase.client.Scan; 052import org.apache.hadoop.hbase.client.Scan.ReadType; 053import org.apache.hadoop.hbase.client.Table; 054import org.apache.hadoop.hbase.client.TableDescriptor; 055import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 056import org.apache.hadoop.hbase.regionserver.compactions.CompactionContext; 057import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker; 058import org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController; 059import org.apache.hadoop.hbase.security.User; 060import org.apache.hadoop.hbase.test.MetricsAssertHelper; 061import org.apache.hadoop.hbase.testclassification.LargeTests; 062import org.apache.hadoop.hbase.testclassification.RegionServerTests; 063import org.apache.hadoop.hbase.util.Bytes; 064import org.apache.hadoop.hbase.util.Threads; 065import org.junit.After; 066import org.junit.AfterClass; 067import org.junit.Before; 068import org.junit.BeforeClass; 069import org.junit.ClassRule; 070import org.junit.Ignore; 071import org.junit.Rule; 072import org.junit.Test; 073import org.junit.experimental.categories.Category; 074import org.junit.rules.TestName; 075import org.slf4j.Logger; 076import org.slf4j.LoggerFactory; 077 078@Category({ RegionServerTests.class, LargeTests.class }) 079public class TestRegionServerMetrics { 080 081 @ClassRule 082 public static final HBaseClassTestRule CLASS_RULE = 083 HBaseClassTestRule.forClass(TestRegionServerMetrics.class); 084 085 private static final Logger LOG = LoggerFactory.getLogger(TestRegionServerMetrics.class); 086 087 @Rule 088 public TestName testName = new TestName(); 089 090 private static MetricsAssertHelper metricsHelper; 091 private static SingleProcessHBaseCluster cluster; 092 private static HRegionServer rs; 093 private static Configuration conf; 094 private static HBaseTestingUtil TEST_UTIL; 095 private static Connection connection; 096 private static MetricsRegionServer metricsRegionServer; 097 private static MetricsRegionServerSource serverSource; 098 private static final int NUM_SCAN_NEXT = 30; 099 private static int numScanNext = 0; 100 private static byte[] cf = Bytes.toBytes("cf"); 101 private static byte[] row = Bytes.toBytes("row"); 102 private static byte[] qualifier = Bytes.toBytes("qual"); 103 private static byte[] val = Bytes.toBytes("val"); 104 private static Admin admin; 105 106 @BeforeClass 107 public static void startCluster() throws Exception { 108 metricsHelper = CompatibilityFactory.getInstance(MetricsAssertHelper.class); 109 TEST_UTIL = new HBaseTestingUtil(); 110 conf = TEST_UTIL.getConfiguration(); 111 conf.getLong("hbase.splitlog.max.resubmit", 0); 112 // Make the failure test faster 113 conf.setInt("zookeeper.recovery.retry", 0); 114 // testMobMetrics creates few hfiles and manages compaction manually. 115 conf.setInt("hbase.hstore.compactionThreshold", 100); 116 conf.setInt("hbase.hstore.compaction.max", 100); 117 conf.setInt("hbase.regionserver.periodicmemstoreflusher.rangeofdelayseconds", 4 * 60); 118 conf.setInt(HConstants.REGIONSERVER_INFO_PORT, -1); 119 120 TEST_UTIL.startMiniCluster(); 121 cluster = TEST_UTIL.getHBaseCluster(); 122 cluster.waitForActiveAndReadyMaster(); 123 admin = TEST_UTIL.getAdmin(); 124 connection = TEST_UTIL.getConnection(); 125 126 while ( 127 cluster.getLiveRegionServerThreads().isEmpty() && cluster.getRegionServer(0) == null 128 && rs.getMetrics() == null 129 ) { 130 Threads.sleep(100); 131 } 132 rs = cluster.getRegionServer(0); 133 metricsRegionServer = rs.getMetrics(); 134 serverSource = metricsRegionServer.getMetricsSource(); 135 } 136 137 @AfterClass 138 public static void after() throws Exception { 139 if (TEST_UTIL != null) { 140 TEST_UTIL.shutdownMiniCluster(); 141 } 142 } 143 144 TableName tableName; 145 Table table; 146 147 @Before 148 public void beforeTestMethod() throws Exception { 149 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 150 tableName = TableName.valueOf(testName.getMethodName()); 151 table = TEST_UTIL.createTable(tableName, cf); 152 } 153 154 @After 155 public void afterTestMethod() throws Exception { 156 admin.disableTable(tableName); 157 admin.deleteTable(tableName); 158 } 159 160 private void assertCounter(String metric, long expectedValue) { 161 metricsHelper.assertCounter(metric, expectedValue, serverSource); 162 } 163 164 private void assertGauge(String metric, long expectedValue) { 165 metricsHelper.assertGauge(metric, expectedValue, serverSource); 166 } 167 168 // Aggregates metrics from regions and assert given list of metrics and expected values. 169 private void assertRegionMetrics(String metric, long expectedValue) throws Exception { 170 try (RegionLocator locator = connection.getRegionLocator(tableName)) { 171 for (HRegionLocation location : locator.getAllRegionLocations()) { 172 RegionInfo hri = location.getRegion(); 173 MetricsRegionAggregateSource agg = 174 rs.getRegion(hri.getRegionName()).getMetrics().getSource().getAggregateSource(); 175 String prefix = "namespace_" + NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR + "_table_" 176 + tableName.getNameAsString() + "_region_" + hri.getEncodedName() + "_metric_"; 177 metricsHelper.assertCounter(prefix + metric, expectedValue, agg); 178 } 179 } 180 } 181 182 private void doNPuts(int n, boolean batch) throws Exception { 183 if (batch) { 184 List<Put> puts = new ArrayList<>(); 185 for (int i = 0; i < n; i++) { 186 Put p = new Put(Bytes.toBytes("" + i + "row")).addColumn(cf, qualifier, val); 187 puts.add(p); 188 } 189 table.put(puts); 190 } else { 191 for (int i = 0; i < n; i++) { 192 Put p = new Put(row).addColumn(cf, qualifier, val); 193 table.put(p); 194 } 195 } 196 } 197 198 private void doNGets(int n, boolean batch) throws Exception { 199 if (batch) { 200 List<Get> gets = new ArrayList<>(); 201 for (int i = 0; i < n; i++) { 202 gets.add(new Get(row)); 203 } 204 table.get(gets); 205 } else { 206 for (int i = 0; i < n; i++) { 207 table.get(new Get(row)); 208 } 209 } 210 } 211 212 private void doScan(int n, boolean caching) throws IOException { 213 Scan scan = new Scan(); 214 if (caching) { 215 scan.setCaching(n); 216 } else { 217 scan.setCaching(1); 218 } 219 ResultScanner scanner = table.getScanner(scan); 220 for (int i = 0; i < n; i++) { 221 Result res = scanner.next(); 222 LOG.debug("Result row: " + Bytes.toString(res.getRow()) + ", value: " 223 + Bytes.toString(res.getValue(cf, qualifier))); 224 } 225 } 226 227 @Test 228 public void testRegionCount() throws Exception { 229 metricsHelper.assertGauge("regionCount", 2, serverSource); 230 } 231 232 @Test 233 public void testLocalFiles() throws Exception { 234 assertGauge("percentFilesLocal", 0); 235 assertGauge("percentFilesLocalSecondaryRegions", 0); 236 } 237 238 @Test 239 public void testRequestCount() throws Exception { 240 // Do a first put to be sure that the connection is established, meta is there and so on. 241 doNPuts(1, false); 242 243 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 244 long requests = metricsHelper.getCounter("totalRequestCount", serverSource); 245 long rowActionRequests = metricsHelper.getCounter("totalRowActionRequestCount", serverSource); 246 long readRequests = metricsHelper.getCounter("readRequestCount", serverSource); 247 long writeRequests = metricsHelper.getCounter("writeRequestCount", serverSource); 248 249 doNPuts(30, false); 250 251 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 252 assertCounter("totalRequestCount", requests + 30); 253 assertCounter("totalRowActionRequestCount", rowActionRequests + 30); 254 assertCounter("readRequestCount", readRequests); 255 assertCounter("writeRequestCount", writeRequests + 30); 256 257 doNGets(10, false); 258 259 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 260 assertCounter("totalRequestCount", requests + 40); 261 assertCounter("totalRowActionRequestCount", rowActionRequests + 40); 262 assertCounter("readRequestCount", readRequests + 10); 263 assertCounter("writeRequestCount", writeRequests + 30); 264 265 assertRegionMetrics("getCount", 10); 266 assertRegionMetrics("putCount", 31); 267 268 doNGets(10, true); // true = batch 269 270 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 271 272 assertCounter("writeRequestCount", writeRequests + 30); 273 274 doNPuts(30, true); 275 276 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 277 assertCounter("writeRequestCount", writeRequests + 60); 278 279 doScan(10, false); // test after batch put so we have enough lines 280 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 281 assertCounter("writeRequestCount", writeRequests + 60); 282 numScanNext += 10; 283 284 doScan(10, true); // true = caching 285 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 286 assertCounter("writeRequestCount", writeRequests + 60); 287 numScanNext += 1; 288 } 289 290 @Test 291 public void testGet() throws Exception { 292 // Do a first put to be sure that the connection is established, meta is there and so on. 293 doNPuts(1, false); 294 doNGets(10, false); 295 assertRegionMetrics("getCount", 10); 296 metricsHelper.assertCounterGt("Get_num_ops", 10, serverSource); 297 } 298 299 @Test 300 public void testMutationsWithoutWal() throws Exception { 301 Put p = new Put(row).addColumn(cf, qualifier, val).setDurability(Durability.SKIP_WAL); 302 table.put(p); 303 304 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 305 assertGauge("mutationsWithoutWALCount", 1); 306 long minLength = row.length + cf.length + qualifier.length + val.length; 307 metricsHelper.assertGaugeGt("mutationsWithoutWALSize", minLength, serverSource); 308 } 309 310 @Test 311 public void testStoreCount() throws Exception { 312 // Force a hfile. 313 doNPuts(1, false); 314 TEST_UTIL.getAdmin().flush(tableName); 315 316 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 317 assertGauge("storeCount", 5); 318 assertGauge("storeFileCount", 1); 319 } 320 321 @Test 322 public void testStoreFileAge() throws Exception { 323 // Force a hfile. 324 doNPuts(1, false); 325 TEST_UTIL.getAdmin().flush(tableName); 326 327 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 328 assertTrue(metricsHelper.getGaugeLong("maxStoreFileAge", serverSource) > 0); 329 assertTrue(metricsHelper.getGaugeLong("minStoreFileAge", serverSource) > 0); 330 assertTrue(metricsHelper.getGaugeLong("avgStoreFileAge", serverSource) > 0); 331 } 332 333 @Test 334 public void testCheckAndPutCount() throws Exception { 335 byte[] valOne = Bytes.toBytes("Value"); 336 byte[] valTwo = Bytes.toBytes("ValueTwo"); 337 byte[] valThree = Bytes.toBytes("ValueThree"); 338 339 Put p = new Put(row); 340 p.addColumn(cf, qualifier, valOne); 341 table.put(p); 342 343 Put pTwo = new Put(row); 344 pTwo.addColumn(cf, qualifier, valTwo); 345 table.checkAndMutate(row, cf).qualifier(qualifier).ifEquals(valOne).thenPut(pTwo); 346 347 Put pThree = new Put(row); 348 pThree.addColumn(cf, qualifier, valThree); 349 table.checkAndMutate(row, cf).qualifier(qualifier).ifEquals(valOne).thenPut(pThree); 350 351 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 352 assertCounter("checkMutateFailedCount", 1); 353 assertCounter("checkMutatePassedCount", 1); 354 } 355 356 @Test 357 public void testIncrement() throws Exception { 358 Put p = new Put(row).addColumn(cf, qualifier, Bytes.toBytes(0L)); 359 table.put(p); 360 361 for (int count = 0; count < 13; count++) { 362 Increment inc = new Increment(row); 363 inc.addColumn(cf, qualifier, 100); 364 table.increment(inc); 365 } 366 367 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 368 assertCounter("incrementNumOps", 13); 369 } 370 371 @Test 372 public void testAppend() throws Exception { 373 doNPuts(1, false); 374 375 for (int count = 0; count < 73; count++) { 376 Append append = new Append(row); 377 append.addColumn(cf, qualifier, Bytes.toBytes(",Test")); 378 table.append(append); 379 } 380 381 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 382 assertCounter("appendNumOps", 73); 383 } 384 385 @Test 386 public void testScanSize() throws Exception { 387 doNPuts(100, true); // batch put 388 Scan s = new Scan(); 389 s.setBatch(1).setCaching(1).setLimit(NUM_SCAN_NEXT).setReadType(ReadType.STREAM); 390 try (ResultScanner resultScanners = table.getScanner(s)) { 391 for (int nextCount = 0; nextCount < NUM_SCAN_NEXT; nextCount++) { 392 Result result = resultScanners.next(); 393 assertNotNull(result); 394 assertEquals(1, result.size()); 395 } 396 numScanNext += NUM_SCAN_NEXT; 397 assertRegionMetrics("scanCount", NUM_SCAN_NEXT); 398 } 399 } 400 401 @Test 402 public void testScanTime() throws Exception { 403 doNPuts(100, true); 404 Scan s = new Scan(); 405 s.setBatch(1).setCaching(1).setLimit(NUM_SCAN_NEXT); 406 try (ResultScanner resultScanners = table.getScanner(s)) { 407 for (int nextCount = 0; nextCount < NUM_SCAN_NEXT; nextCount++) { 408 Result result = resultScanners.next(); 409 assertNotNull(result); 410 assertEquals(1, result.size()); 411 } 412 } 413 numScanNext += NUM_SCAN_NEXT; 414 assertRegionMetrics("scanCount", NUM_SCAN_NEXT); 415 } 416 417 @Test 418 public void testScanSizeForSmallScan() throws Exception { 419 doNPuts(100, true); 420 Scan s = new Scan(); 421 s.setCaching(1).setLimit(NUM_SCAN_NEXT).setReadType(ReadType.PREAD); 422 try (ResultScanner resultScanners = table.getScanner(s)) { 423 for (int nextCount = 0; nextCount < NUM_SCAN_NEXT; nextCount++) { 424 Result result = resultScanners.next(); 425 assertNotNull(result); 426 } 427 assertNull(resultScanners.next()); 428 } 429 numScanNext += NUM_SCAN_NEXT; 430 assertRegionMetrics("scanCount", NUM_SCAN_NEXT); 431 } 432 433 @Test 434 public void testMobMetrics() throws IOException, InterruptedException { 435 TableName tableName = TableName.valueOf("testMobMetricsLocal"); 436 int numHfiles = 5; 437 TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName) 438 .setColumnFamily( 439 ColumnFamilyDescriptorBuilder.newBuilder(cf).setMobEnabled(true).setMobThreshold(0).build()) 440 .build(); 441 byte[] val = Bytes.toBytes("mobdata"); 442 try { 443 Table table = TEST_UTIL.createTable(htd, new byte[0][0], conf); 444 HRegion region = rs.getRegions(tableName).get(0); 445 for (int insertCount = 0; insertCount < numHfiles; insertCount++) { 446 Put p = new Put(Bytes.toBytes(insertCount)); 447 p.addColumn(cf, qualifier, val); 448 table.put(p); 449 admin.flush(tableName); 450 } 451 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 452 assertCounter("mobFlushCount", numHfiles); 453 Scan scan = new Scan().withStartRow(Bytes.toBytes(0)).withStopRow(Bytes.toBytes(numHfiles)); 454 ResultScanner scanner = table.getScanner(scan); 455 scanner.next(100); 456 numScanNext++; // this is an ugly construct 457 scanner.close(); 458 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 459 assertCounter("mobScanCellsCount", numHfiles); 460 461 setMobThreshold(region, cf, 100); 462 // metrics are reset by the region initialization 463 region.initialize(); 464 // This is how we MOB compact region 465 List<HStore> stores = region.getStores(); 466 for (HStore store : stores) { 467 // Force major compaction 468 store.triggerMajorCompaction(); 469 Optional<CompactionContext> context = store.requestCompaction(HStore.PRIORITY_USER, 470 CompactionLifeCycleTracker.DUMMY, User.getCurrent()); 471 if (!context.isPresent()) { 472 continue; 473 } 474 region.compact(context.get(), store, NoLimitThroughputController.INSTANCE, 475 User.getCurrent()); 476 } 477 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 478 assertCounter("cellsCountCompactedFromMob", numHfiles); 479 assertCounter("cellsCountCompactedToMob", 0); 480 481 scanner = table.getScanner(scan); 482 scanner.next(100); 483 numScanNext++; // this is an ugly construct 484 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 485 assertCounter("mobScanCellsCount", 0); 486 487 for (int insertCount = numHfiles; insertCount < 2 * numHfiles; insertCount++) { 488 Put p = new Put(Bytes.toBytes(insertCount)); 489 p.addColumn(cf, qualifier, val); 490 table.put(p); 491 admin.flush(tableName); 492 } 493 setMobThreshold(region, cf, 0); 494 495 // closing the region forces the compaction.discharger to archive the compacted hfiles 496 region.close(); 497 498 // metrics are reset by the region initialization 499 region.initialize(); 500 region.compact(true); 501 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 502 // metrics are reset by the region initialization 503 assertCounter("cellsCountCompactedFromMob", 0); 504 assertCounter("cellsCountCompactedToMob", 2 * numHfiles); 505 } finally { 506 admin.disableTable(tableName); 507 admin.deleteTable(tableName); 508 } 509 } 510 511 private static Region setMobThreshold(Region region, byte[] cfName, long modThreshold) { 512 ColumnFamilyDescriptor cfd = 513 ColumnFamilyDescriptorBuilder.newBuilder(region.getTableDescriptor().getColumnFamily(cfName)) 514 .setMobThreshold(modThreshold).build(); 515 TableDescriptor td = TableDescriptorBuilder.newBuilder(region.getTableDescriptor()) 516 .removeColumnFamily(cfName).setColumnFamily(cfd).build(); 517 ((HRegion) region).setTableDescriptor(td); 518 return region; 519 } 520 521 @Test 522 @Ignore 523 public void testRangeCountMetrics() throws Exception { 524 final long[] timeranges = 525 { 1, 3, 10, 30, 100, 300, 1000, 3000, 10000, 30000, 60000, 120000, 300000, 600000 }; 526 final String timeRangeType = "TimeRangeCount"; 527 final String timeRangeMetricName = "Mutate"; 528 boolean timeRangeCountUpdated = false; 529 530 // Do a first put to be sure that the connection is established, meta is there and so on. 531 Put p = new Put(row); 532 p.addColumn(cf, qualifier, val); 533 table.put(p); 534 535 // do some puts and gets 536 for (int i = 0; i < 10; i++) { 537 table.put(p); 538 } 539 540 Get g = new Get(row); 541 for (int i = 0; i < 10; i++) { 542 table.get(g); 543 } 544 545 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 546 547 // Check some time range counters were updated 548 long prior = 0; 549 550 String dynamicMetricName; 551 for (int i = 0; i < timeranges.length; i++) { 552 dynamicMetricName = 553 timeRangeMetricName + "_" + timeRangeType + "_" + prior + "-" + timeranges[i]; 554 if (metricsHelper.checkCounterExists(dynamicMetricName, serverSource)) { 555 long count = metricsHelper.getGaugeLong(dynamicMetricName, serverSource); 556 if (count > 0) { 557 timeRangeCountUpdated = true; 558 break; 559 } 560 } 561 prior = timeranges[i]; 562 } 563 dynamicMetricName = 564 timeRangeMetricName + "_" + timeRangeType + "_" + timeranges[timeranges.length - 1] + "-inf"; 565 if (metricsHelper.checkCounterExists(dynamicMetricName, serverSource)) { 566 long count = metricsHelper.getCounter(dynamicMetricName, serverSource); 567 if (count > 0) { 568 timeRangeCountUpdated = true; 569 } 570 } 571 assertEquals(true, timeRangeCountUpdated); 572 } 573 574 @Test 575 public void testAverageRegionSize() throws Exception { 576 // Force a hfile. 577 doNPuts(1, false); 578 TEST_UTIL.getAdmin().flush(tableName); 579 580 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 581 assertTrue(metricsHelper.getGaugeDouble("averageRegionSize", serverSource) > 0.0); 582 } 583 584 @Test 585 public void testReadBytes() throws Exception { 586 // Do a first put to be sure that the connection is established, meta is there and so on. 587 doNPuts(1, false); 588 doNGets(10, false); 589 TEST_UTIL.getAdmin().flush(tableName); 590 metricsRegionServer.getRegionServerWrapper().forceRecompute(); 591 592 assertTrue("Total read bytes should be larger than 0", 593 metricsRegionServer.getRegionServerWrapper().getTotalBytesRead() > 0); 594 assertTrue("Total local read bytes should be larger than 0", 595 metricsRegionServer.getRegionServerWrapper().getLocalBytesRead() > 0); 596 assertEquals("Total short circuit read bytes should be equal to 0", 0, 597 metricsRegionServer.getRegionServerWrapper().getShortCircuitBytesRead()); 598 assertEquals("Total zero-byte read bytes should be equal to 0", 0, 599 metricsRegionServer.getRegionServerWrapper().getZeroCopyBytesRead()); 600 } 601}