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