org.gradle.performance.results.TestPageGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2013 the original author or authors.
*
* 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 org.gradle.performance.results;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.googlecode.jatl.Html;
import org.apache.commons.lang.StringUtils;
import org.gradle.api.Nullable;
import org.gradle.api.Transformer;
import org.gradle.performance.measure.DataSeries;
import org.gradle.performance.measure.Duration;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
public class TestPageGenerator extends HtmlPageGenerator {
@Override
protected int getDepth() {
return 1;
}
@Override
public void render(final PerformanceTestHistory testHistory, Writer writer) throws IOException {
// TODO: Add test name to the report
new MetricsHtml(writer) {{
html();
head();
headSection(this);
title().text(String.format("Performance test %s", testHistory.getDisplayName())).end();
end();
body();
div().id("content");
h2().text(String.format("Test: %s", testHistory.getDisplayName())).end();
text(getReproductionInstructions(testHistory));
p().text("Tasks: " + getTasks(testHistory)).end();
addPerformanceGraph("Average total time", "totalTimeChart", "totalTime", "total time", "s");
div().id("tooltip").end();
div().id("controls").end();
h3().text("Test details").end();
table().classAttr("test-details");
tr();
th().text("Scenario").end();
th().text("Test project").end();
th().text("Tasks").end();
th().text("Gradle args").end();
th().text("Gradle JVM args").end();
th().text("Daemon").end();
end();
for (ScenarioDefinition scenario : testHistory.getScenarios()) {
tr();
textCell(scenario.getDisplayName());
textCell(scenario.getTestProject());
textCell(scenario.getTasks());
textCell(scenario.getArgs());
textCell(scenario.getGradleOpts());
textCell(scenario.getDaemon());
end();
}
end();
h3().text("Test history").end();
table().classAttr("history");
tr().classAttr("control-groups");
th().colspan("3").end();
final String colspanForField = String.valueOf(testHistory.getScenarioCount() * getColumnsForSamples());
th().colspan(colspanForField).text("Average build time").end();
th().colspan("8").text("Details").end();
end();
tr();
th().text("Date").end();
th().text("Branch").end();
th().text("Git commit").end();
for (String label : testHistory.getScenarioLabels()) {
renderHeaderForSamples(label);
}
th().text("Test version").end();
th().text("Operating System").end();
th().text("JVM").end();
th().text("Test project").end();
th().text("Tasks").end();
th().text("Gradle args").end();
th().text("Gradle JVM opts").end();
th().text("Daemon").end();
end();
final int executionsLen = testHistory.getExecutions().size();
for (int i = 0; i < executionsLen; i++) {
PerformanceTestExecution results = testHistory.getExecutions().get(i);
tr();
id("result" + results.getExecutionId());
textCell(format.timestamp(new Date(results.getStartTime())));
textCell(results.getVcsBranch());
td();
renderVcsLinks(results, findPreviousExecutionInSameBranch(results, testHistory, i));
end();
final List scenarios = results.getScenarios();
renderSamplesForExperiment(scenarios, new Transformer, MeasuredOperationList>() {
public DataSeries transform(MeasuredOperationList original) {
return original.getTotalTime();
}
});
textCell(results.getVersionUnderTest());
textCell(results.getOperatingSystem());
textCell(results.getJvm());
textCell(results.getTestProject());
textCell(results.getTasks());
textCell(results.getArgs());
textCell(results.getGradleOpts());
textCell(results.getDaemon());
end();
}
end();
end();
footer(this);
endAll();
}
private void renderVcsLinks(PerformanceTestExecution results, PerformanceTestExecution previousResults) {
List vcsCommits = createGitHubLinks(results.getVcsCommits());
for (int i = 0; i < vcsCommits.size(); i++) {
GitHubLink vcsCommit = vcsCommits.get(i);
vcsCommit.renderCommitLink(this);
if (previousResults != null) {
text(" ");
vcsCommit.renderCompareLink(this, previousResults.getVcsCommits().get(i));
}
if (i != vcsCommits.size() - 1) {
text(" | ");
}
}
}
@Nullable
private PerformanceTestExecution findPreviousExecutionInSameBranch(PerformanceTestExecution results, PerformanceTestHistory testHistory, int currentIndex) {
int executionsLen = testHistory.getExecutions().size();
PerformanceTestExecution previousResults = null;
if (currentIndex < executionsLen - 1 && results.getVcsBranch() != null) {
for (PerformanceTestExecution execution : testHistory.getExecutions().subList(currentIndex + 1, executionsLen)) {
if (results.getVcsBranch().equals(execution.getVcsBranch())) {
previousResults = execution;
break;
}
}
}
return previousResults;
}
private void addPerformanceGraph(String heading, String chartId, String jsonFieldName, String fieldLabel, String fieldUnit) {
h3().text(heading).end();
div().id(chartId).classAttr("chart");
p().text("Loading...").end();
script();
text("performanceTests.createPerformanceGraph('" + testHistory.getId() + ".json', function(data) { return data." + jsonFieldName + "}, '" + fieldLabel + "', '" + fieldUnit + "', '" + chartId + "');");
end();
end();
}
};
}
private String getTasks(PerformanceTestHistory testHistory) {
List extends PerformanceTestExecution> executions = testHistory.getExecutions();
if (executions.isEmpty()) {
return "";
}
PerformanceTestExecution performanceTestExecution = executions.get(0);
if (performanceTestExecution == null || performanceTestExecution.getTasks() == null) {
return "";
}
return Joiner.on(" ").join(performanceTestExecution.getTasks());
}
private String getReproductionInstructions(PerformanceTestHistory history) {
Set templates = Sets.newHashSet();
Set cleanTasks = Sets.newHashSet();
for (ScenarioDefinition scenario : history.getScenarios()) {
templates.add(scenario.getTestProject());
cleanTasks.add("clean" + StringUtils.capitalize(scenario.getTestProject()));
}
return "To reproduce, run ./gradlew "
+ Joiner.on(' ').join(cleanTasks)
+ " "
+ Joiner.on(' ').join(templates)
+ " cleanPerformanceAdhocTest performanceAdhocTest --scenarios "
+ "'" + history.getDisplayName() + "'"
+ " -x prepareSamples";
}
private static class GitHubLink {
private final String repo;
private final String hash;
public GitHubLink(String repo, String hash) {
this.repo = repo;
this.hash = hash;
}
public void renderCommitLink(Html html) {
html.a().classAttr("commit-link").href(getUrl()).text(getLabel()).end();
}
public String getUrl() {
return String.format("https://github.com/%s/commit/%s", repo, formatHash(hash));
}
public String getLabel() {
return formatHash(hash);
}
private String formatHash(String hash) {
return shorten(hash, 7);
}
public void renderCompareLink(Html html, String previousHash) {
String range = String.format("%s...%s", formatHash(previousHash), formatHash(hash));
html.a().classAttr("compare-link").href(String.format("https://github.com/%s/compare/%s", repo, range)).text("changes").end();
}
}
private List createGitHubLinks(List commits) {
if (null == commits || commits.size() == 0) {
return Collections.emptyList();
}
GitHubLink gradleUrl = new GitHubLink("gradle/gradle", commits.get(0));
if (commits.size() == 1) {
return Collections.singletonList(gradleUrl);
} else if (commits.size() == 2) {
GitHubLink dotComUrl = new GitHubLink("gradle/dotcom", commits.get(1));
List links = Lists.newArrayList();
links.add(gradleUrl);
links.add(dotComUrl);
return links;
} else {
throw new IllegalArgumentException("No more than 2 commit SHAs are supported");
}
}
private static String shorten(String string, int maxLength) {
return string.substring(0, Math.min(maxLength, string.length()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy