1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.metrics;
20  
21  import java.util.Arrays;
22  import java.util.Random;
23  
24  import org.apache.hadoop.hbase.metrics.histogram.MetricsHistogram;
25  import org.apache.hadoop.hbase.SmallTests;
26  import com.yammer.metrics.stats.Snapshot;
27  import org.junit.Assert;
28  import org.junit.Test;
29  import org.junit.experimental.categories.Category;
30  
31  @Category(SmallTests.class)
32  public class TestMetricsHistogram {
33  
34    @Test
35    public void testBasicUniform() {
36      MetricsHistogram h = new MetricsHistogram("testHistogram", null);
37  
38      for (int i = 0; i < 100; i++) {
39        h.update(i);
40      }
41  
42      Assert.assertEquals(100, h.getCount());
43      Assert.assertEquals(0, h.getMin());
44      Assert.assertEquals(99, h.getMax());
45    }
46  
47    private static int safeIndex(int i, int len) {
48      if (i < len && i>= 0) {
49        return i;
50      } else if (i >= len) {
51        return len - 1; 
52      } else {
53        return 0;
54      }    
55    }
56    
57    @Test
58    public void testRandom() {
59      final Random r = new Random();
60      final MetricsHistogram h = new MetricsHistogram("testHistogram", null);
61  
62      final long[] data = new long[1000];
63  
64      for (int i = 0; i < data.length; i++) {
65        data[i] = (long) (r.nextGaussian() * 10000.0);
66        h.update(data[i]);
67      }
68  
69      final Snapshot s = h.getSnapshot();
70      Arrays.sort(data);
71  
72      // as long as the histogram chooses an item with index N+/-slop, accept it
73      final int slop = 20;
74  
75      // make sure the median, 75th percentile and 95th percentile are good
76      final int medianIndex = data.length / 2;
77      final long minAcceptableMedian = data[safeIndex(medianIndex - slop, 
78          data.length)];
79      final long maxAcceptableMedian = data[safeIndex(medianIndex + slop, 
80          data.length)];
81      Assert.assertTrue(s.getMedian() >= minAcceptableMedian 
82          && s.getMedian() <= maxAcceptableMedian);
83  
84      final int seventyFifthIndex = (int) (data.length * 0.75);
85      final long minAcceptableseventyFifth = data[safeIndex(seventyFifthIndex 
86          - slop, data.length)];
87      final long maxAcceptableseventyFifth = data[safeIndex(seventyFifthIndex 
88          + slop, data.length)];
89      Assert.assertTrue(s.get75thPercentile() >= minAcceptableseventyFifth 
90          && s.get75thPercentile() <= maxAcceptableseventyFifth);
91  
92      final int ninetyFifthIndex = (int) (data.length * 0.95);
93      final long minAcceptableninetyFifth = data[safeIndex(ninetyFifthIndex 
94          - slop, data.length)];
95      final long maxAcceptableninetyFifth = data[safeIndex(ninetyFifthIndex 
96          + slop, data.length)];
97      Assert.assertTrue(s.get95thPercentile() >= minAcceptableninetyFifth 
98          && s.get95thPercentile() <= maxAcceptableninetyFifth);
99  
100   }
101 }