Package com.netflix.servo.publish

Source Code of com.netflix.servo.publish.NormalizationTransformTest$TimeVal

/**
* Copyright 2014 Netflix, Inc.
*
* Licensed 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 com.netflix.servo.publish;

import com.beust.jcommander.internal.Lists;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.netflix.servo.Metric;
import com.netflix.servo.monitor.AbstractMonitor;
import com.netflix.servo.monitor.BasicCounter;
import com.netflix.servo.monitor.LongGauge;
import com.netflix.servo.monitor.MonitorConfig;
import com.netflix.servo.monitor.StepCounter;
import com.netflix.servo.util.Clock;
import com.netflix.servo.util.ManualClock;
import org.testng.annotations.Test;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.testng.Assert.assertEquals;

public class NormalizationTransformTest {
    Metric newMetric(long t, double v) {
        return new Metric(MonitorConfig.builder("test").build(), t, v);
    }

    static class TimeVal {
        final long t;
        final double v;

        static TimeVal from(long t, double v) {
            return new TimeVal(t, v);
        }

        static TimeVal from(Metric m) {
            return new TimeVal(m.getTimestamp(), m.getNumberValue().doubleValue());
        }

        TimeVal(long t, double v) {
            this.t = t;
            this.v = v;
        }

        @Override
        public String toString() {
            return "TimeVal{t=" + t + ", v=" + v + '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            TimeVal timeVal = (TimeVal) o;
            return t == timeVal.t && Double.compare(timeVal.v, v) == 0;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(t, v);
        }
    }

    void assertMetrics(long step, long heartbeat, List<Metric> input, List<TimeVal> expected) {
        ManualClock clock = new ManualClock(0);
        MemoryMetricObserver mmo = new MemoryMetricObserver("m", 1);
        MetricObserver transform = new NormalizationTransform(mmo, step, heartbeat,
                TimeUnit.MILLISECONDS, clock);

        int i = 0;
        for (Metric m : input) {
            transform.update(ImmutableList.of(m));
            Metric result = mmo.getObservations().get(0).get(0);
            assertEquals(TimeVal.from(result), expected.get(i));
            i++;
        }
    }

    @Test
    public void testBasic() throws Exception {
        List<Metric> inputList = ImmutableList.of(
                newMetric(5, 1.0),
                newMetric(15, 2.0),
                newMetric(25, 2.0),
                newMetric(35, 1.0),
                newMetric(85, 1.0),
                newMetric(95, 2.0),
                newMetric(105, 2.0));
        List<TimeVal> expected = ImmutableList.of(
                TimeVal.from(0, 0.5),
                TimeVal.from(10, 1.5),
                TimeVal.from(20, 2.0),
                TimeVal.from(30, 1.5),
                TimeVal.from(80, 0.5),
                TimeVal.from(90, 1.5),
                TimeVal.from(100, 2.0)
        );

        assertMetrics(10, 20, inputList, expected);
    }

    @Test
    public void testAlreadyNormalized() throws Exception {
        List<Metric> inputList = ImmutableList.of(
                newMetric(0, 10.0),
                newMetric(10, 20.0),
                newMetric(20, 30.0),
                newMetric(30, 10.0));
        List<TimeVal> expected = ImmutableList.of(
                TimeVal.from(0, 10.0),
                TimeVal.from(10, 20.0),
                TimeVal.from(20, 30.0),
                TimeVal.from(30, 10.0));
        assertMetrics(10, 20, inputList, expected);
    }

    @Test
    public void testNormalizedMissedHeartbeat() throws Exception {
        List<Metric> inputList = ImmutableList.of(
                newMetric(0, 10.0),
                newMetric(10, 10.0),
                newMetric(30, 10.0));
        List<TimeVal> expected = ImmutableList.of(
                TimeVal.from(0, 10.0),
                TimeVal.from(10, 10.0),
                TimeVal.from(30, 10.0));
        assertMetrics(10, 20, inputList, expected);
    }

    long t(int m, int s) {
        return (m * 60 + s) * 1000L;
    }

    @Test
    public void testRandomOffset() throws Exception {
        List<Metric> inputList = ImmutableList.of(
                newMetric(t(1, 13), 1.0),
                newMetric(t(2, 13), 1.0),
                newMetric(t(3, 13), 1.0));

        List<TimeVal> expected = ImmutableList.of(
                TimeVal.from(t(1, 0), 47.0 / 60.0),
                TimeVal.from(t(2, 0), 1.0),
                TimeVal.from(t(3, 0), 1.0));

        assertMetrics(60000, 120000, inputList, expected);
    }

    private List<Metric> getValue(List<? extends AbstractMonitor<Number>> monitors, Clock clock) {
        List<Metric> result = Lists.newArrayList();
        for (AbstractMonitor<Number> m : monitors) {
            Number n = m.getValue(0);
            Metric metric = new Metric(m.getConfig(), clock.now(), n);
            result.add(metric);
        }
        return result;
    }

    private static final double DELTA = 1e-6;

    @Test
    public void testUpdate() throws Exception {
        BasicCounter basicCounter = new BasicCounter(MonitorConfig.builder("basicCounter").build());
        ManualClock manualClock = new ManualClock(0);
        StepCounter stepCounter = new StepCounter(MonitorConfig.builder("stepCounter").build(),
                manualClock);
        LongGauge gauge = new LongGauge(MonitorConfig.builder("longGauge").build());

        ImmutableList<? extends AbstractMonitor<Number>> monitors = ImmutableList.of(basicCounter,
                stepCounter, gauge);

        MemoryMetricObserver observer = new MemoryMetricObserver("normalization-test", 1);
        NormalizationTransform normalizationTransform = new NormalizationTransform(observer, 60,
                120, TimeUnit.SECONDS, manualClock);
        CounterToRateMetricTransform toRateMetricTransform =
                new CounterToRateMetricTransform(normalizationTransform, 60,
                        120, TimeUnit.SECONDS, manualClock);

        double[] rates = {0.5 / 60.0, 2 / 60.0, 3 / 60.0, 4 / 60.0};
        double[] expectedNormalized = {
                rates[0] * (2.0 / 3.0), // 20000L over stepBoundary
                rates[0] * (1.0 / 3.0) + rates[1] * (2.0 / 3.0),
                rates[1] * (1.0 / 3.0) + rates[2] * (2.0 / 3.0),
                rates[2] * (1.0 / 3.0) + rates[3] * (2.0 / 3.0)};

        for (int i = 1; i < 5; ++i) {
            long now = 20000L + i * 60000L;
            long stepBoundary = i * 60000L;
            manualClock.set(now);
            basicCounter.increment(i);
            stepCounter.increment(i);
            gauge.set((long) i);
            List<Metric> metrics = getValue(monitors, manualClock);
            toRateMetricTransform.update(metrics);

            List<Metric> o = observer.getObservations().get(0);
            assertEquals(o.size(), 3);
            double basicCounterVal = o.get(0).getNumberValue().doubleValue();
            double stepCounterVal = o.get(1).getNumberValue().doubleValue();
            double gaugeVal = o.get(2).getNumberValue().doubleValue();
            assertEquals(gaugeVal, (double) i, DELTA);
            // rate per second for the prev interval
            assertEquals(stepCounterVal, (i - 1) / 60.0, DELTA);
            assertEquals(basicCounterVal, expectedNormalized[i - 1], DELTA);

            for (Metric m : o) {
                assertEquals(m.getTimestamp(), stepBoundary);
            }
        }

        // no updates to anything, just clock forward
        int i = 5;
        manualClock.set(i * 60000L + 20000L);
        List<Metric> metrics = getValue(monitors, manualClock);
        toRateMetricTransform.update(metrics);
        List<Metric> o = observer.getObservations().get(0);
        assertEquals(o.size(), 3);

        double basicCounterVal = o.get(0).getNumberValue().doubleValue();
        double stepCounterVal = o.get(1).getNumberValue().doubleValue();
        double gaugeVal = o.get(2).getNumberValue().doubleValue();

        assertEquals(gaugeVal, (double) 4, DELTA); // last set value
        assertEquals(stepCounterVal, 4 / 60.0, DELTA);
        assertEquals(basicCounterVal, (1 / 3.0) * rates[3]);
    }

    @Test
    public void testExpiration() {
        BasicCounter c1 = new BasicCounter(MonitorConfig.builder("c1").build());
        BasicCounter c2 = new BasicCounter(MonitorConfig.builder("c2").build());
        BasicCounter c3 = new BasicCounter(MonitorConfig.builder("c3").build());
        ManualClock manualClock = new ManualClock(0);

        MemoryMetricObserver observer = new MemoryMetricObserver("normalization-test", 1);
        NormalizationTransform normalizationTransform = new NormalizationTransform(observer, 60,
                120, TimeUnit.SECONDS, manualClock);
        CounterToRateMetricTransform toRateMetricTransform =
                new CounterToRateMetricTransform(normalizationTransform, 60,
                        120, TimeUnit.SECONDS, manualClock);

        manualClock.set(30000L);
        c1.increment();
        Metric m1 = new Metric(c1.getConfig(), manualClock.now(), c1.getValue(0));

        toRateMetricTransform.update(ImmutableList.of(m1));
        assertEquals(NormalizationTransform.HEARTBEAT_EXCEEDED.getValue(0).longValue(), 0);
        List<Metric> o = observer.getObservations().get(0);
        assertEquals(o.size(), 1);

        manualClock.set(100000L);
        Metric m2 = new Metric(c2.getConfig(), manualClock.now(), c2.getValue());
        toRateMetricTransform.update(ImmutableList.of(m2));
        assertEquals(NormalizationTransform.HEARTBEAT_EXCEEDED.getValue(0).longValue(), 0);

        manualClock.set(160000L);
        Metric m3 = new Metric(c3.getConfig(), manualClock.now(), c3.getValue());
        toRateMetricTransform.update(ImmutableList.of(m3));
        assertEquals(NormalizationTransform.HEARTBEAT_EXCEEDED.getValue(0).longValue(), 1);

    }
}
TOP

Related Classes of com.netflix.servo.publish.NormalizationTransformTest$TimeVal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.