/* * Copyright 2016 Naver Corp. * * 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.navercorp.pinpoint.web.mapper.stat; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatType; import com.navercorp.pinpoint.web.mapper.stat.sampling.sampler.AgentStatSampler; import com.navercorp.pinpoint.web.util.TimeWindow; import com.navercorp.pinpoint.web.util.TimeWindowSampler; import com.navercorp.pinpoint.web.vo.Range; import com.navercorp.pinpoint.web.vo.stat.SampledAgentStatDataPoint; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.mockito.Mockito.when; /** * @author HyunGil Jeong */ @RunWith(MockitoJUnitRunner.class) public class SampledAgentStatResultExtractorTest { private static final long DEFAULT_TIME_INTERVAL = 5 * 1000L; private static final TimeWindowSampler ONE_TO_ONE_SAMPLER = new TimeWindowSampler() { @Override public long getWindowSize(Range range) { return DEFAULT_TIME_INTERVAL; } }; private static final TimeWindowSampler TWO_TO_ONE_SAMPLER = new TimeWindowSampler() { @Override public long getWindowSize(Range range) { return DEFAULT_TIME_INTERVAL * 2; } }; private static final TimeWindowSampler TEN_TO_ONE_SAMPLER = new TimeWindowSampler() { @Override public long getWindowSize(Range range) { return DEFAULT_TIME_INTERVAL * 10; } }; @Mock private ResultScanner resultScanner; @Mock private Result result; @Mock private AgentStatMapperV2<TestAgentStatDataPoint> rowMapper; @Before public void setUp() { MockitoAnnotations.initMocks(this.getClass()); when(this.resultScanner.iterator()).thenReturn(Arrays.asList(this.result).iterator()); } @Test public void one_to_one_sampler_should_not_down_sample_data_points() throws Exception { // Given final int numValues = 10; final long initialTimestamp = System.currentTimeMillis(); final long finalTimestamp = initialTimestamp + (DEFAULT_TIME_INTERVAL * numValues); final TimeWindow timeWindow = new TimeWindow(new Range(initialTimestamp, finalTimestamp), ONE_TO_ONE_SAMPLER); final List<TestAgentStatDataPoint> dataPoints = createDataPoints(finalTimestamp, DEFAULT_TIME_INTERVAL, numValues); final Map<Long, List<TestAgentStatDataPoint>> expectedDataPointSlotMap = getExpectedDataPointSlotMap(timeWindow, dataPoints); when(this.rowMapper.mapRow(this.result, 0)).thenReturn(dataPoints); TestAgentStatSampler testAgentStatSampler = new TestAgentStatSampler(); SampledAgentStatResultExtractor<TestAgentStatDataPoint, TestSampledAgentStatDataPoint> resultExtractor = new SampledAgentStatResultExtractor<>(timeWindow, this.rowMapper, testAgentStatSampler); // When List<TestSampledAgentStatDataPoint> sampledDataPoints = resultExtractor.extractData(this.resultScanner); // Then for (TestSampledAgentStatDataPoint sampledDataPoint : sampledDataPoints) { List<TestAgentStatDataPoint> expectedSampledDataPoints = expectedDataPointSlotMap.get(sampledDataPoint.getBaseTimestamp()); Assert.assertEquals(expectedSampledDataPoints, sampledDataPoint.getDataPointsToSample()); } } @Test public void two_to_one_sample_should_down_sample_correctly() throws Exception { // Given final int numValues = 20; final long initialTimestamp = System.currentTimeMillis(); final long finalTimestamp = initialTimestamp + (DEFAULT_TIME_INTERVAL * numValues); final TimeWindow timeWindow = new TimeWindow(new Range(initialTimestamp, finalTimestamp), TWO_TO_ONE_SAMPLER); final List<TestAgentStatDataPoint> dataPoints = createDataPoints(finalTimestamp, DEFAULT_TIME_INTERVAL, numValues); final Map<Long, List<TestAgentStatDataPoint>> expectedDataPointSlotMap = getExpectedDataPointSlotMap(timeWindow, dataPoints); when(this.rowMapper.mapRow(this.result, 0)).thenReturn(dataPoints); TestAgentStatSampler testAgentStatSampler = new TestAgentStatSampler(); SampledAgentStatResultExtractor<TestAgentStatDataPoint, TestSampledAgentStatDataPoint> resultExtractor = new SampledAgentStatResultExtractor<>(timeWindow, this.rowMapper, testAgentStatSampler); // When List<TestSampledAgentStatDataPoint> sampledDataPoints = resultExtractor.extractData(this.resultScanner); // Then for (TestSampledAgentStatDataPoint sampledDataPoint : sampledDataPoints) { List<TestAgentStatDataPoint> expectedSampledDataPoints = expectedDataPointSlotMap.get(sampledDataPoint.getBaseTimestamp()); Assert.assertEquals(expectedSampledDataPoints, sampledDataPoint.getDataPointsToSample()); } } @Test public void ten_to_one_sample_should_down_sample_correctly() throws Exception { // Given final int numValues = 100; final long initialTimestamp = System.currentTimeMillis(); final long finalTimestamp = initialTimestamp + (DEFAULT_TIME_INTERVAL * numValues); final TimeWindow timeWindow = new TimeWindow(new Range(initialTimestamp, finalTimestamp), TEN_TO_ONE_SAMPLER); final List<TestAgentStatDataPoint> dataPoints = createDataPoints(finalTimestamp, DEFAULT_TIME_INTERVAL, numValues); final Map<Long, List<TestAgentStatDataPoint>> expectedDataPointSlotMap = getExpectedDataPointSlotMap(timeWindow, dataPoints); when(this.rowMapper.mapRow(this.result, 0)).thenReturn(dataPoints); TestAgentStatSampler testAgentStatSampler = new TestAgentStatSampler(); SampledAgentStatResultExtractor<TestAgentStatDataPoint, TestSampledAgentStatDataPoint> resultExtractor = new SampledAgentStatResultExtractor<>(timeWindow, this.rowMapper, testAgentStatSampler); // When List<TestSampledAgentStatDataPoint> sampledDataPoints = resultExtractor.extractData(this.resultScanner); // Then for (TestSampledAgentStatDataPoint sampledDataPoint : sampledDataPoints) { List<TestAgentStatDataPoint> expectedSampledDataPoints = expectedDataPointSlotMap.get(sampledDataPoint.getBaseTimestamp()); Assert.assertEquals(expectedSampledDataPoints, sampledDataPoint.getDataPointsToSample()); } } private Map<Long, List<TestAgentStatDataPoint>> getExpectedDataPointSlotMap(TimeWindow timeWindow, List<TestAgentStatDataPoint> dataPoints) { Map<Long, List<TestAgentStatDataPoint>> slotMap = new HashMap<>(); for (long timeslotTimestamp : timeWindow) { slotMap.put(timeslotTimestamp, new ArrayList<TestAgentStatDataPoint>()); } for (TestAgentStatDataPoint dataPoint : dataPoints) { slotMap.get(timeWindow.refineTimestamp(dataPoint.getTimestamp())).add(dataPoint); } return slotMap; } private List<TestAgentStatDataPoint> createDataPoints(long finalTimestamp, long timeInterval, int numDataPoints) { List<TestAgentStatDataPoint> dataPoints = new ArrayList<>(numDataPoints); for (int i = 0; i < numDataPoints; ++i) { TestAgentStatDataPoint dataPoint = new TestAgentStatDataPoint(); dataPoint.setTimestamp(finalTimestamp - (timeInterval * i)); dataPoint.setValue(i); dataPoints.add(dataPoint); } return dataPoints; } private static class TestAgentStatSampler implements AgentStatSampler<TestAgentStatDataPoint, TestSampledAgentStatDataPoint> { @Override public TestSampledAgentStatDataPoint sampleDataPoints(int timeWindowIndex, long timestamp, List<TestAgentStatDataPoint> dataPoints, TestAgentStatDataPoint previousDataPoint) { return new TestSampledAgentStatDataPoint(timestamp, dataPoints); } } private static class TestAgentStatDataPoint implements AgentStatDataPoint { private String agentId; private long startTimestamp; private long timestamp; private int value; @Override public String getAgentId() { return agentId; } @Override public void setAgentId(String agentId) { this.agentId = agentId; } @Override public long getStartTimestamp() { return startTimestamp; } @Override public void setStartTimestamp(long startTimestamp) { this.startTimestamp = startTimestamp; } @Override public long getTimestamp() { return timestamp; } @Override public void setTimestamp(long timestamp) { this.timestamp = timestamp; } @Override public AgentStatType getAgentStatType() { return AgentStatType.UNKNOWN; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public String toString() { return "TestAgentStatDataPoint{" + "agentId='" + agentId + '\'' + ", startTimestamp=" + startTimestamp + ", timestamp=" + timestamp + ", value=" + value + '}'; } } private static class TestSampledAgentStatDataPoint implements SampledAgentStatDataPoint { private final long baseTimestamp; private final List<TestAgentStatDataPoint> dataPointsToSample; private TestSampledAgentStatDataPoint(long baseTimestamp, List<TestAgentStatDataPoint> dataPointsToSample) { this.baseTimestamp = baseTimestamp; this.dataPointsToSample = dataPointsToSample; } public long getBaseTimestamp() { return baseTimestamp; } public List<TestAgentStatDataPoint> getDataPointsToSample() { return dataPointsToSample; } @Override public String toString() { return "TestSampledAgentStatDataPoint{" + "baseTimestamp=" + baseTimestamp + ", dataPointsToSample=" + dataPointsToSample + '}'; } } }