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