/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.metrics2.lib; import org.junit.Test; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import org.apache.hadoop.metrics2.MetricsCollector; import org.apache.hadoop.metrics2.MetricsException; import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.hadoop.metrics2.MetricsSource; import org.apache.hadoop.metrics2.annotation.Metric; import org.apache.hadoop.metrics2.annotation.Metric.*; import org.apache.hadoop.metrics2.annotation.Metrics; import org.apache.hadoop.metrics2.impl.MsInfo; import static org.apache.hadoop.metrics2.lib.Interns.*; import static org.apache.hadoop.test.MetricsAsserts.*; public class TestMetricsAnnotations { static class MyMetrics { @Metric MutableCounterInt c1; @Metric({"Counter2", "Counter2 desc"}) MutableCounterLong c2; @Metric MutableGaugeInt g1, g2; @Metric("g3 desc") MutableGaugeLong g3; @Metric MutableRate r1; @Metric MutableStat s1; @Metric MutableRates rs1; } @Test public void testFields() { MyMetrics metrics = new MyMetrics(); MetricsSource source = MetricsAnnotations.makeSource(metrics); metrics.c1.incr(); metrics.c2.incr(); metrics.g1.incr(); metrics.g2.incr(); metrics.g3.incr(); metrics.r1.add(1); metrics.s1.add(1); metrics.rs1.add("rs1", 1); MetricsRecordBuilder rb = getMetrics(source); verify(rb).addCounter(info("C1", "C1"), 1); verify(rb).addCounter(info("Counter2", "Counter2 desc"), 1L); verify(rb).addGauge(info("G1", "G1"), 1); verify(rb).addGauge(info("G2", "G2"), 1); verify(rb).addGauge(info("G3", "g3 desc"), 1L); verify(rb).addCounter(info("R1NumOps", "Number of ops for r1"), 1L); verify(rb).addGauge(info("R1AvgTime", "Average time for r1"), 1.0); verify(rb).addCounter(info("S1NumOps", "Number of ops for s1"), 1L); verify(rb).addGauge(info("S1AvgTime", "Average time for s1"), 1.0); verify(rb).addCounter(info("Rs1NumOps", "Number of ops for rs1"), 1L); verify(rb).addGauge(info("Rs1AvgTime", "Average time for rs1"), 1.0); } static class BadMetrics { @Metric Integer i0; } @Test(expected=MetricsException.class) public void testBadFields() { MetricsAnnotations.makeSource(new BadMetrics()); } static class MyMetrics2 { @Metric int getG1() { return 1; } @Metric long getG2() { return 2; } @Metric float getG3() { return 3; } @Metric double getG4() { return 4; } @Metric(type=Type.COUNTER) int getC1() { return 1; } @Metric(type=Type.COUNTER) long getC2() { return 2; } @Metric(type=Type.TAG) String getT1() { return "t1"; } } @Test public void testMethods() { MyMetrics2 metrics = new MyMetrics2(); MetricsSource source = MetricsAnnotations.makeSource(metrics); MetricsRecordBuilder rb = getMetrics(source); verify(rb).addGauge(info("G1", "G1"), 1); verify(rb).addGauge(info("G2", "G2"), 2L); verify(rb).addGauge(info("G3", "G3"), 3.0f); verify(rb).addGauge(info("G4", "G4"), 4.0); verify(rb).addCounter(info("C1", "C1"), 1); verify(rb).addCounter(info("C2", "C2"), 2L); verify(rb).tag(info("T1", "T1"), "t1"); } static class BadMetrics2 { @Metric int foo(int i) { return i; } } @Test(expected=IllegalArgumentException.class) public void testBadMethodWithArgs() { MetricsAnnotations.makeSource(new BadMetrics2()); } static class BadMetrics3 { @Metric boolean foo() { return true; } } @Test(expected=MetricsException.class) public void testBadMethodReturnType() { MetricsAnnotations.makeSource(new BadMetrics3()); } @Metrics(about="My metrics", context="foo") static class MyMetrics3 { @Metric int getG1() { return 1; } } @Test public void testClasses() { MetricsRecordBuilder rb = getMetrics( MetricsAnnotations.makeSource(new MyMetrics3())); MetricsCollector collector = rb.parent(); verify(collector).addRecord(info("MyMetrics3", "My metrics")); verify(rb).add(tag(MsInfo.Context, "foo")); } static class HybridMetrics implements MetricsSource { final MetricsRegistry registry = new MetricsRegistry("HybridMetrics") .setContext("hybrid"); @Metric("C0 desc") MutableCounterInt C0; @Metric int getG0() { return 0; } @Override public void getMetrics(MetricsCollector collector, boolean all) { collector.addRecord("foo") .setContext("foocontext") .addCounter(info("C1", "C1 desc"), 1) .endRecord() .addRecord("bar") .setContext("barcontext") .addGauge(info("G1", "G1 desc"), 1); registry.snapshot(collector.addRecord(registry.info()), all); } } @Test public void testHybrid() { HybridMetrics metrics = new HybridMetrics(); MetricsSource source = MetricsAnnotations.makeSource(metrics); assertSame(metrics, source); metrics.C0.incr(); MetricsRecordBuilder rb = getMetrics(source); MetricsCollector collector = rb.parent(); verify(collector).addRecord("foo"); verify(collector).addRecord("bar"); verify(collector).addRecord(info("HybridMetrics", "HybridMetrics")); verify(rb).setContext("foocontext"); verify(rb).addCounter(info("C1", "C1 desc"), 1); verify(rb).setContext("barcontext"); verify(rb).addGauge(info("G1", "G1 desc"), 1); verify(rb).add(tag(MsInfo.Context, "hybrid")); verify(rb).addCounter(info("C0", "C0 desc"), 1); verify(rb).addGauge(info("G0", "G0"), 0); } @Metrics(context="hybrid") static class BadHybridMetrics implements MetricsSource { @Metric MutableCounterInt c1; @Override public void getMetrics(MetricsCollector collector, boolean all) { collector.addRecord("foo"); } } @Test(expected=MetricsException.class) public void testBadHybrid() { MetricsAnnotations.makeSource(new BadHybridMetrics()); } static class EmptyMetrics { int foo; } @Test(expected=MetricsException.class) public void testEmptyMetrics() { MetricsAnnotations.makeSource(new EmptyMetrics()); } }