/* * 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.common.server.bo.codec.stat.strategy; import com.navercorp.pinpoint.common.buffer.AutomaticBuffer; import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.server.bo.codec.stat.AgentStatDataPointCodec; import com.navercorp.pinpoint.common.server.bo.codec.strategy.EncodingStrategy; import org.junit.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * @author HyunGil Jeong */ public abstract class EncodingStrategyTestBase<T extends Number> { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final AgentStatDataPointCodec codec = new AgentStatDataPointCodec(); protected static final int NUM_TEST_RUNS = 20; protected abstract StrategyAnalyzer.StrategyAnalyzerBuilder<T> getStrategyAnalyzerBuilder(); protected abstract List<EncodingStrategy<T>> getEncodingStrategies(); protected abstract void checkBuilder(StrategyAnalyzer.StrategyAnalyzerBuilder<T> analyzerBuilder, Map<EncodingStrategy<T>, Integer> bufferSizes); protected void testFor(List<T> testValues) { StrategyAnalyzer.StrategyAnalyzerBuilder<T> builder = this.getStrategyAnalyzerBuilder(); for (T testValue : testValues) { builder.addValue(testValue); } final StrategyAnalyzer<T> analyzer = builder.build(); logger.debug("Values : {}", analyzer.getValues()); Map<EncodingStrategy<T>, Integer> bufferSizes = this.getBufferSizes(testValues); checkBuilder(builder, bufferSizes); checkStrategy(analyzer, getBestEncodingStrategies(bufferSizes)); } private void checkStrategy(StrategyAnalyzer<T> analyzer, Set<? extends EncodingStrategy<T>> bestStrategies) { EncodingStrategy<T> chosenStrategy = analyzer.getBestStrategy(); List<T> values = analyzer.getValues(); logger.debug("Chosen : {}", analyzer.getBestStrategy()); Assert.assertTrue(createTestFailMessage(values, bestStrategies, chosenStrategy), bestStrategies.contains(chosenStrategy)); } private <S extends EncodingStrategy<T>> String createTestFailMessage(List<T> values, Set<S> bestStrategies, EncodingStrategy<T> chosenStrategy) { StringBuilder sb = new StringBuilder("Wrong strategy chosen - "); sb.append("expected one of ").append(bestStrategies); sb.append(", but got ").append(chosenStrategy); sb.append(". Value : ").append(values); return sb.toString(); } private Set<EncodingStrategy<T>> getBestEncodingStrategies(Map<EncodingStrategy<T>, Integer> bufferSizes) { int minimumBufferSize = Integer.MAX_VALUE; Set<EncodingStrategy<T>> bestStrategies = new HashSet<EncodingStrategy<T>>(); for (Map.Entry<EncodingStrategy<T>, Integer> entry : bufferSizes.entrySet()) { EncodingStrategy<T> strategy = entry.getKey(); int bufferSize = entry.getValue(); if (bufferSize < minimumBufferSize) { bestStrategies.clear(); bestStrategies.add(strategy); minimumBufferSize = bufferSize; } else if (bufferSize == minimumBufferSize) { bestStrategies.add(strategy); } } return bestStrategies; } private Map<EncodingStrategy<T>, Integer> getBufferSizes(List<T> values) { Map<EncodingStrategy<T>, Integer> bufferSizes = new HashMap<EncodingStrategy<T>, Integer>(); for (EncodingStrategy<T> strategy : getEncodingStrategies()) { Buffer encodedBuffer = new AutomaticBuffer(); codec.encodeValues(encodedBuffer, strategy, values); int encodedBufferSize = encodedBuffer.getBuffer().length; bufferSizes.put(strategy, encodedBufferSize); } logger.debug("Strategies : {}", bufferSizes); return bufferSizes; } }