@Test
  public void reportsTimerValues() throws Exception {
    final Timer timer = mock(Timer.class);
    when(timer.getCount()).thenReturn(1L);
    when(timer.getMax()).thenReturn(TimeUnit.MILLISECONDS.toNanos(100));
    when(timer.getMean()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(200));
    when(timer.getMin()).thenReturn(TimeUnit.MILLISECONDS.toNanos(300));
    when(timer.getStdDev()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(400));

    when(timer.getMeanRate()).thenReturn(2.0);
    when(timer.getOneMinuteRate()).thenReturn(3.0);
    when(timer.getFiveMinuteRate()).thenReturn(4.0);
    when(timer.getFifteenMinuteRate()).thenReturn(5.0);

    final Snapshot snapshot = mock(Snapshot.class);
    when(snapshot.getMedian()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(500));
    when(snapshot.get75thPercentile()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(600));
    when(snapshot.get95thPercentile()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(700));
    when(snapshot.get98thPercentile()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(800));
    when(snapshot.get99thPercentile()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(900));
    when(snapshot.get999thPercentile()).thenReturn((double) TimeUnit.MILLISECONDS.toNanos(1000));

    when(timer.getSnapshot()).thenReturn(snapshot);

    reporter.report(
        this.<Gauge>map(),
        this.<Counter>map(),
        this.<Histogram>map(),
        this.<Meter>map(),
        map("test.another.timer", timer));

    verify(ganglia)
        .announce(
            "test.another.timer.max",
            "100.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.mean",
            "200.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.min",
            "300.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.stddev",
            "400.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p50",
            "500.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p75",
            "600.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p95",
            "700.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p98",
            "800.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p99",
            "900.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.p999",
            "1000.0",
            GMetricType.DOUBLE,
            "milliseconds",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");

    verify(ganglia)
        .announce(
            "test.another.timer.count",
            "1",
            GMetricType.DOUBLE,
            "calls",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.mean_rate",
            "2.0",
            GMetricType.DOUBLE,
            "calls/second",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.m1_rate",
            "3.0",
            GMetricType.DOUBLE,
            "calls/second",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.m5_rate",
            "4.0",
            GMetricType.DOUBLE,
            "calls/second",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");
    verify(ganglia)
        .announce(
            "test.another.timer.m15_rate",
            "5.0",
            GMetricType.DOUBLE,
            "calls/second",
            GMetricSlope.BOTH,
            60,
            0,
            "test.another");

    verifyNoMoreInteractions(ganglia);
  }
  @Test
  public void reportsHistogramValues() throws Exception {
    final Histogram histogram = mock(Histogram.class);
    when(histogram.getCount()).thenReturn(1L);
    when(histogram.getMax()).thenReturn(2L);
    when(histogram.getMean()).thenReturn(3.0);
    when(histogram.getMin()).thenReturn(4L);
    when(histogram.getStdDev()).thenReturn(5.0);

    final Snapshot snapshot = mock(Snapshot.class);
    when(snapshot.getMedian()).thenReturn(6.0);
    when(snapshot.get75thPercentile()).thenReturn(7.0);
    when(snapshot.get95thPercentile()).thenReturn(8.0);
    when(snapshot.get98thPercentile()).thenReturn(9.0);
    when(snapshot.get99thPercentile()).thenReturn(10.0);
    when(snapshot.get999thPercentile()).thenReturn(11.0);

    when(histogram.getSnapshot()).thenReturn(snapshot);

    reporter.report(
        this.<Gauge>map(),
        this.<Counter>map(),
        map("test.histogram", histogram),
        this.<Meter>map(),
        this.<Timer>map());

    verify(ganglia)
        .announce(
            "test.histogram.count", "1", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.max", "2", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.mean", "3.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.min", "4", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.stddev",
            "5.0",
            GMetricType.DOUBLE,
            "",
            GMetricSlope.BOTH,
            60,
            0,
            "test");
    verify(ganglia)
        .announce(
            "test.histogram.p50", "6.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.p75", "7.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.p95", "8.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.p98", "9.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.p99", "10.0", GMetricType.DOUBLE, "", GMetricSlope.BOTH, 60, 0, "test");
    verify(ganglia)
        .announce(
            "test.histogram.p999",
            "11.0",
            GMetricType.DOUBLE,
            "",
            GMetricSlope.BOTH,
            60,
            0,
            "test");
    verifyNoMoreInteractions(ganglia);
  }