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