public Meter(MetricName rateMetricName, MetricName totalMetricName) {
        this(TimeUnit.SECONDS, new WindowedSum(), rateMetricName, totalMetricName);
    }
@Test
    public void testMeter() {
        Map<String, String> emptyTags = Collections.emptyMap();
        MetricName rateMetricName = new MetricName("rate", "test", "", emptyTags);
        MetricName totalMetricName = new MetricName("total", "test", "", emptyTags);
        Meter meter = new Meter(rateMetricName, totalMetricName);
        List<NamedMeasurable> stats = meter.stats();
        assertEquals(2, stats.size());
        NamedMeasurable total = stats.get(0);
        NamedMeasurable rate = stats.get(1);
        assertEquals(rateMetricName, rate.name());
        assertEquals(totalMetricName, total.name());
        Rate rateStat = (Rate) rate.stat();
        CumulativeSum totalStat = (CumulativeSum) total.stat();

        MetricConfig config = new MetricConfig();
        double nextValue = 0.0;
        double expectedTotal = 0.0;
        long now = 0;
        int intervalMs = 100;
        double delta = 5.0;

        // Record values in multiple windows and verify that rates are reported
        // for time windows and that the total is cumulative.
        for (int i = 1; i <= 100; i++) {
            for (; now < i * 1000; now += intervalMs, nextValue += delta) {
                expectedTotal += nextValue;
                meter.record(config, nextValue, now);
            }
            assertEquals(expectedTotal, totalStat.measure(config, now), EPS);
            long windowSizeMs = rateStat.windowSize(config, now);
            long windowStartMs = Math.max(now - windowSizeMs, 0);
            double sampledTotal = 0.0;
            double prevValue = nextValue - delta;
            for (long timeMs = now - 100; timeMs >= windowStartMs; timeMs -= intervalMs, prevValue -= delta)
                sampledTotal += prevValue;
            assertEquals(sampledTotal * 1000 / windowSizeMs, rateStat.measure(config, now), EPS);
        }
    }