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 */ 018 019package org.apache.hadoop.hbase.test; 020 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertTrue; 024 025import java.util.HashMap; 026import java.util.Locale; 027import java.util.Map; 028 029import org.apache.hadoop.hbase.metrics.BaseSource; 030import org.apache.hadoop.metrics2.AbstractMetric; 031import org.apache.hadoop.metrics2.MetricsCollector; 032import org.apache.hadoop.metrics2.MetricsInfo; 033import org.apache.hadoop.metrics2.MetricsRecordBuilder; 034import org.apache.hadoop.metrics2.MetricsSource; 035import org.apache.hadoop.metrics2.MetricsTag; 036import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; 037 038/** 039 * A helper class that will allow tests to get into hadoop2's metrics2 values. 040 */ 041public class MetricsAssertHelperImpl implements MetricsAssertHelper { 042 private Map<String, String> tags = new HashMap<>(); 043 private Map<String, Number> gauges = new HashMap<>(); 044 private Map<String, Long> counters = new HashMap<>(); 045 046 public class MockMetricsBuilder implements MetricsCollector { 047 048 @Override 049 public MetricsRecordBuilder addRecord(String s) { 050 return new MockRecordBuilder(this); 051 } 052 053 @Override 054 public MetricsRecordBuilder addRecord(MetricsInfo metricsInfo) { 055 return new MockRecordBuilder(this); 056 } 057 } 058 059 public class MockRecordBuilder extends MetricsRecordBuilder { 060 061 private final MetricsCollector mockMetricsBuilder; 062 063 public MockRecordBuilder(MetricsCollector mockMetricsBuilder) { 064 065 this.mockMetricsBuilder = mockMetricsBuilder; 066 } 067 068 @Override 069 public MetricsRecordBuilder tag(MetricsInfo metricsInfo, String s) { 070 071 tags.put(canonicalizeMetricName(metricsInfo.name()), s); 072 return this; 073 } 074 075 @Override 076 public MetricsRecordBuilder add(MetricsTag metricsTag) { 077 tags.put(canonicalizeMetricName(metricsTag.name()), metricsTag.value()); 078 return this; 079 } 080 081 @Override 082 public MetricsRecordBuilder add(AbstractMetric abstractMetric) { 083 gauges.put(canonicalizeMetricName(abstractMetric.name()), abstractMetric.value()); 084 return this; 085 } 086 087 @Override 088 public MetricsRecordBuilder setContext(String s) { 089 return this; 090 } 091 092 @Override 093 public MetricsRecordBuilder addCounter(MetricsInfo metricsInfo, int i) { 094 counters.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(i)); 095 return this; 096 } 097 098 @Override 099 public MetricsRecordBuilder addCounter(MetricsInfo metricsInfo, long l) { 100 counters.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(l)); 101 return this; 102 } 103 104 @Override 105 public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, int i) { 106 gauges.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(i)); 107 return this; 108 } 109 110 @Override 111 public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, long l) { 112 gauges.put(canonicalizeMetricName(metricsInfo.name()), Long.valueOf(l)); 113 return this; 114 } 115 116 @Override 117 public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, float v) { 118 gauges.put(canonicalizeMetricName(metricsInfo.name()), Double.valueOf(v)); 119 return this; 120 } 121 122 @Override 123 public MetricsRecordBuilder addGauge(MetricsInfo metricsInfo, double v) { 124 gauges.put(canonicalizeMetricName(metricsInfo.name()), Double.valueOf(v)); 125 return this; 126 } 127 128 @Override 129 public MetricsCollector parent() { 130 return mockMetricsBuilder; 131 } 132 } 133 134 @Override 135 public void init() { 136 // Make sure that the metrics system doesn't throw an exception when 137 // registering a source with the same name 138 DefaultMetricsSystem.setMiniClusterMode(true); 139 } 140 141 @Override 142 public void assertTag(String name, String expected, BaseSource source) { 143 getMetrics(source); 144 String cName = canonicalizeMetricName(name); 145 assertEquals("Tags should be equal", expected, tags.get(cName)); 146 } 147 148 @Override 149 public void assertGauge(String name, long expected, BaseSource source) { 150 long found = getGaugeLong(name, source); 151 assertEquals("Metrics Should be equal", (long) Long.valueOf(expected), found); 152 } 153 154 @Override 155 public void assertGaugeGt(String name, long expected, BaseSource source) { 156 double found = getGaugeDouble(name, source); 157 assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected); 158 } 159 160 @Override 161 public void assertGaugeLt(String name, long expected, BaseSource source) { 162 double found = getGaugeDouble(name, source); 163 assertTrue(name + "(" + found + ") should be less than " + expected, found < expected); 164 } 165 166 @Override 167 public void assertGauge(String name, double expected, BaseSource source) { 168 double found = getGaugeDouble(name, source); 169 assertEquals("Metrics Should be equal", (double) Double.valueOf(expected), found, 0.01); 170 } 171 172 @Override 173 public void assertGaugeGt(String name, double expected, BaseSource source) { 174 double found = getGaugeDouble(name, source); 175 assertTrue(name + "(" + found + ") should be greater than " + expected, found > expected); 176 } 177 178 @Override 179 public void assertGaugeLt(String name, double expected, BaseSource source) { 180 double found = getGaugeDouble(name, source); 181 assertTrue(name + "(" + found + ") should be less than " + expected, found < expected); 182 } 183 184 @Override 185 public void assertCounter(String name, long expected, BaseSource source) { 186 long found = getCounter(name, source); 187 assertEquals("Metrics Counters should be equal", (long) Long.valueOf(expected), found); 188 } 189 190 @Override 191 public void assertCounterGt(String name, long expected, BaseSource source) { 192 long found = getCounter(name, source); 193 assertTrue(name + " (" + found + ") should be greater than " + expected, found > expected); 194 } 195 196 @Override 197 public void assertCounterLt(String name, long expected, BaseSource source) { 198 long found = getCounter(name, source); 199 assertTrue(name + "(" + found + ") should be less than " + expected, found < expected); 200 } 201 202 @Override 203 public long getCounter(String name, BaseSource source) { 204 getMetrics(source); 205 String cName = canonicalizeMetricName(name); 206 assertNotNull("Should get counter "+cName + " but did not",counters.get(cName)); 207 return counters.get(cName).longValue(); 208 } 209 210 @Override 211 public boolean checkCounterExists(String name, BaseSource source) { 212 getMetrics(source); 213 String cName = canonicalizeMetricName(name); 214 return (counters.get(cName) != null) ? true : false; 215 } 216 217 @Override 218 public double getGaugeDouble(String name, BaseSource source) { 219 getMetrics(source); 220 String cName = canonicalizeMetricName(name); 221 assertNotNull("Should get gauge "+cName + " but did not",gauges.get(cName)); 222 return gauges.get(cName).doubleValue(); 223 } 224 225 @Override 226 public long getGaugeLong(String name, BaseSource source) { 227 getMetrics(source); 228 String cName = canonicalizeMetricName(name); 229 assertNotNull("Should get gauge " + cName + " but did not", gauges.get(cName)); 230 return gauges.get(cName).longValue(); 231 } 232 233 @Override 234 public String toDebugString(BaseSource source) { 235 getMetrics(source); 236 StringBuilder sb = new StringBuilder(); 237 sb.append("Tags=").append(tags).append(", Counters=").append(counters); 238 return sb.append(", Gauges=").append(gauges).toString(); 239 } 240 241 private void reset() { 242 tags.clear(); 243 gauges.clear(); 244 counters.clear(); 245 } 246 247 private void getMetrics(BaseSource source) { 248 reset(); 249 if (!(source instanceof MetricsSource)) { 250 assertTrue("The Source passed must be a MetricsSource", false); 251 } 252 MetricsSource impl = (MetricsSource) source; 253 254 impl.getMetrics(new MockMetricsBuilder(), true); 255 256 } 257 258 private String canonicalizeMetricName(String in) { 259 return in.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9 ]", ""); 260 } 261}