com.teradata.benchto.driver.loader.BenchmarkLoader Maven / Gradle / Ivy
/*
* 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.teradata.benchto.driver.loader;
import com.facebook.presto.jdbc.internal.guava.collect.ImmutableList;
import com.teradata.benchto.driver.Benchmark;
import com.teradata.benchto.driver.Benchmark.BenchmarkBuilder;
import com.teradata.benchto.driver.BenchmarkExecutionException;
import com.teradata.benchto.driver.BenchmarkProperties;
import com.teradata.benchto.driver.Query;
import com.teradata.benchto.driver.service.BenchmarkServiceClient;
import com.teradata.benchto.driver.service.BenchmarkServiceClient.GenerateUniqueNamesRequestItem;
import com.teradata.benchto.driver.utils.NaturalOrderComparator;
import com.teradata.benchto.driver.utils.YamlUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static com.facebook.presto.jdbc.internal.guava.base.Preconditions.checkState;
import static com.facebook.presto.jdbc.internal.guava.collect.Lists.newArrayListWithCapacity;
import static com.facebook.presto.jdbc.internal.guava.collect.Sets.newLinkedHashSet;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Maps.newHashMap;
import static com.teradata.benchto.driver.loader.BenchmarkDescriptor.DATA_SOURCE_KEY;
import static com.teradata.benchto.driver.loader.BenchmarkDescriptor.QUERY_NAMES_KEY;
import static com.teradata.benchto.driver.loader.BenchmarkDescriptor.VARIABLES_KEY;
import static com.teradata.benchto.driver.service.BenchmarkServiceClient.GenerateUniqueNamesRequestItem.generateUniqueNamesRequestItem;
import static com.teradata.benchto.driver.utils.CartesianProductUtils.cartesianProduct;
import static com.teradata.benchto.driver.utils.FilterUtils.pathContainsAny;
import static com.teradata.benchto.driver.utils.YamlUtils.loadYamlFromString;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.isRegularFile;
import static java.nio.file.Files.readAllBytes;
import static java.util.UUID.randomUUID;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.io.FilenameUtils.removeExtension;
import static org.springframework.ui.freemarker.FreeMarkerTemplateUtils.processTemplateIntoString;
@Component
public class BenchmarkLoader
{
private static final Logger LOGGER = LoggerFactory.getLogger(BenchmarkLoader.class);
private static final Pattern VALUE_SUBSTITUTION_PATTERN = Pattern.compile(".*\\$\\{.+\\}.*");
private static final String BENCHMARK_FILE_SUFFIX = "yaml";
private static final int DEFAULT_RUNS = 3;
private static final int DEFAULT_CONCURRENCY = 1;
private static final int DEFAULT_PREWARM_RUNS = 0;
@Autowired
private BenchmarkProperties properties;
@Autowired
private BenchmarkServiceClient benchmarkServiceClient;
@Autowired
private QueryLoader queryLoader;
@Autowired
private Configuration freemarkerConfiguration;
public List loadBenchmarks(String sequenceId)
{
try {
List benchmarkFiles = findBenchmarkFiles();
benchmarkFiles = benchmarkFiles.stream()
.filter(activeBenchmarks())
.collect(toList());
benchmarkFiles.stream()
.forEach(path -> LOGGER.info("Benchmark file to be read: {}", path));
List allBenchmarks = loadBenchmarks(sequenceId, benchmarkFiles);
LOGGER.debug("All benchmarks: {}", allBenchmarks);
List includedBenchmarks = allBenchmarks.stream()
.filter(new BenchmarkByActiveVariablesFilter(properties))
.collect(toList());
Set excludedBenchmarks = newLinkedHashSet(allBenchmarks);
excludedBenchmarks.removeAll(includedBenchmarks);
String formatString = createFormatString(allBenchmarks);
LOGGER.info("Excluded Benchmarks:");
printFormattedBenchmarksInfo(formatString, excludedBenchmarks);
fillUniqueBenchmarkNames(includedBenchmarks);
List freshBenchmarks = ImmutableList.of();
if (properties.isFrequencyCheckEnabled()) {
freshBenchmarks = filterFreshBenchmarks(includedBenchmarks);
LOGGER.info("Recently tested benchmarks:");
printFormattedBenchmarksInfo(formatString, freshBenchmarks);
}
LOGGER.info("Selected Benchmarks:");
includedBenchmarks.removeAll(freshBenchmarks);
printFormattedBenchmarksInfo(formatString, includedBenchmarks);
checkState(allBenchmarks.size() == includedBenchmarks.size() + excludedBenchmarks.size() + freshBenchmarks.size());
return includedBenchmarks;
}
catch (IOException e) {
throw new BenchmarkExecutionException("Could not load benchmarks", e);
}
}
private List findBenchmarkFiles()
throws IOException
{
LOGGER.info("Searching for benchmarks in classpath ...");
List benchmarkFiles = Files
.walk(properties.benchmarksFilesPath())
.filter(file -> isRegularFile(file) && file.toString().endsWith(BENCHMARK_FILE_SUFFIX))
.collect(toList());
benchmarkFiles.stream().forEach((path) -> LOGGER.info("Benchmark found: {}", path.toString()));
return benchmarkFiles;
}
private List loadBenchmarks(String sequenceId, List benchmarkFiles)
{
return benchmarkFiles.stream()
.flatMap(file -> loadBenchmarks(sequenceId, file).stream())
.sorted((left, right) -> NaturalOrderComparator.forStrings().compare(left.getName(), right.getName()))
.collect(toList());
}
private List loadBenchmarks(String sequenceId, Path benchmarkFile)
{
try {
String content = new String(readAllBytes(benchmarkFile), UTF_8);
Map yaml = loadYamlFromString(content);
checkArgument(yaml.containsKey(DATA_SOURCE_KEY), "Mandatory variable %s not present in file %s", DATA_SOURCE_KEY, benchmarkFile);
checkArgument(yaml.containsKey(QUERY_NAMES_KEY), "Mandatory variable %s not present in file %s", QUERY_NAMES_KEY, benchmarkFile);
List benchmarkDescriptors = createBenchmarkDescriptors(yaml);
List benchmarks = newArrayListWithCapacity(benchmarkDescriptors.size());
for (BenchmarkDescriptor benchmarkDescriptor : benchmarkDescriptors) {
String benchmarkName = benchmarkName(benchmarkFile);
List queries = queryLoader.loadFromFiles(benchmarkDescriptor.getQueryNames());
Benchmark benchmark = new BenchmarkBuilder(benchmarkName, sequenceId, queries)
.withDataSource(benchmarkDescriptor.getDataSource())
.withEnvironment(properties.getEnvironmentName())
.withRuns(benchmarkDescriptor.getRuns().orElse(DEFAULT_RUNS))
.withPrewarmRuns(benchmarkDescriptor.getPrewarmRepeats().orElse(DEFAULT_PREWARM_RUNS))
.withConcurrency(benchmarkDescriptor.getConcurrency().orElse(DEFAULT_CONCURRENCY))
.withFrequency(benchmarkDescriptor.getFrequency().map(frequency -> Duration.ofDays(frequency)))
.withBeforeBenchmarkMacros(benchmarkDescriptor.getBeforeBenchmarkMacros())
.withAfterBenchmarkMacros(benchmarkDescriptor.getAfterBenchmarkMacros())
.withBeforeExecutionMacros(benchmarkDescriptor.getBeforeExecutionMacros())
.withAfterExecutionMacros(benchmarkDescriptor.getAfterExecutionMacros())
.withVariables(benchmarkDescriptor.getVariables())
.build();
benchmarks.add(benchmark);
}
return benchmarks;
}
catch (IOException e) {
throw new BenchmarkExecutionException("Could not load benchmark: " + benchmarkFile, e);
}
}
private List createBenchmarkDescriptors(Map yaml)
{
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy