/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.jenkins.results.parser;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dom4j.Element;
import org.json.JSONObject;
/**
* @author Peter Yoo
*/
public class AxisBuild extends BaseBuild {
@Override
public void findDownstreamBuilds() {
}
@Override
public String getAppServer() {
Build parentBuild = getParentBuild();
return parentBuild.getAppServer();
}
@Override
public String getArchivePath() {
if (archiveName == null) {
System.out.println(
"Build URL " + getBuildURL() + " has a null archive name");
}
StringBuilder sb = new StringBuilder(archiveName);
if (!archiveName.endsWith("/")) {
sb.append("/");
}
sb.append(getMaster());
sb.append("/");
sb.append(getJobName());
sb.append("/");
sb.append(getAxisVariable());
sb.append("/");
sb.append(getBuildNumber());
return sb.toString();
}
public String getAxisNumber() {
Matcher matcher = _axisVariablePattern.matcher(getAxisVariable());
if (matcher.find()) {
return matcher.group("axisNumber");
}
throw new RuntimeException(
"Invalid axis variable: " + getAxisVariable());
}
public String getAxisVariable() {
return axisVariable;
}
@Override
public String getBrowser() {
Build parentBuild = getParentBuild();
return parentBuild.getBrowser();
}
public String getBuildDescriptionTestRayReports() {
Element unorderedListElement = Dom4JUtil.getNewElement("ul");
for (TestResult testResult : getTestResults(null)) {
String displayName = testResult.getDisplayName();
if (displayName.contains("JenkinsLogAsserterTest")) {
continue;
}
Element listItemElement = Dom4JUtil.getNewElement(
"li", unorderedListElement);
Dom4JUtil.getNewElement("strong", listItemElement, displayName);
Element reportLinksUnorderedListElement = Dom4JUtil.getNewElement(
"ul", listItemElement);
Element poshiReportListItemElement = Dom4JUtil.getNewElement(
"li", reportLinksUnorderedListElement);
Dom4JUtil.getNewAnchorElement(
testResult.getPoshiReportURL(), poshiReportListItemElement,
"Poshi Report");
Element poshiSummaryListItemElement = Dom4JUtil.getNewElement(
"li", reportLinksUnorderedListElement);
Dom4JUtil.getNewAnchorElement(
testResult.getPoshiSummaryURL(), poshiSummaryListItemElement,
"Poshi Summary");
}
Dom4JUtil.addToElement(
unorderedListElement, Dom4JUtil.getNewElement("br"));
try {
return Dom4JUtil.format(unorderedListElement, false);
}
catch (IOException ioe) {
throw new RuntimeException("Unable to generate html", ioe);
}
}
@Override
public String getBuildURL() {
String jobURL = getJobURL();
int buildNumber = getBuildNumber();
if ((jobURL == null) || (buildNumber == -1)) {
return null;
}
if (fromArchive) {
return JenkinsResultsParserUtil.combine(
jobURL, "/", axisVariable, "/", Integer.toString(buildNumber),
"/");
}
try {
jobURL = JenkinsResultsParserUtil.decode(jobURL);
}
catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Unable to decode " + jobURL, uee);
}
String buildURL = JenkinsResultsParserUtil.combine(
jobURL, "/", axisVariable, "/", Integer.toString(buildNumber), "/");
try {
return JenkinsResultsParserUtil.encode(buildURL);
}
catch (MalformedURLException murle) {
throw new RuntimeException("Could not encode " + buildURL, murle);
}
catch (URISyntaxException urise) {
throw new RuntimeException("Could not encode " + buildURL, urise);
}
}
@Override
public String getBuildURLRegex() {
StringBuffer sb = new StringBuffer();
sb.append("http[s]*:\\/\\/");
sb.append(JenkinsResultsParserUtil.getRegexLiteral(getMaster()));
sb.append("[^\\/]*");
sb.append("[\\/]+job[\\/]+");
String jobNameRegexLiteral = JenkinsResultsParserUtil.getRegexLiteral(
getJobName());
jobNameRegexLiteral = jobNameRegexLiteral.replace("\\(", "(\\(|%28)");
jobNameRegexLiteral = jobNameRegexLiteral.replace("\\)", "(\\)|%29)");
sb.append(jobNameRegexLiteral);
sb.append("[\\/]+");
sb.append(JenkinsResultsParserUtil.getRegexLiteral(getAxisVariable()));
sb.append("[\\/]+");
sb.append(getBuildNumber());
sb.append("[\\/]*");
return sb.toString();
}
@Override
public String getDatabase() {
Build parentBuild = getParentBuild();
return parentBuild.getDatabase();
}
@Override
public String getDisplayName() {
return JenkinsResultsParserUtil.combine(
getAxisVariable(), " #", Integer.toString(getBuildNumber()));
}
@Override
public Element getGitHubMessageElement() {
String status = getStatus();
if (!status.equals("completed") && (getParentBuild() != null)) {
return null;
}
String result = getResult();
if (result.equals("SUCCESS")) {
return null;
}
Element messageElement = Dom4JUtil.getNewElement(
"div", null,
Dom4JUtil.getNewAnchorElement(
getBuildURL(), null, getDisplayName()));
if (result.equals("ABORTED")) {
messageElement.add(
Dom4JUtil.toCodeSnippetElement("Build was aborted"));
}
if (result.equals("FAILURE")) {
Element failureMessageElement = getFailureMessageElement();
if (failureMessageElement != null) {
messageElement.add(failureMessageElement);
}
}
if (result.equals("UNSTABLE")) {
Element downstreamBuildOrderedListElement = Dom4JUtil.getNewElement(
"ol", messageElement);
int failureCount = 0;
for (TestResult testResult : getTestResults(null)) {
String testStatus = testResult.getStatus();
if (testStatus.equals("PASSED") ||
testStatus.equals("SKIPPED")) {
continue;
}
Element downstreamBuildListItemElement =
Dom4JUtil.getNewElement(
"li", downstreamBuildOrderedListElement);
if (failureCount < 3) {
String testReportURL = testResult.getTestReportURL();
downstreamBuildListItemElement.add(
Dom4JUtil.getNewAnchorElement(
testReportURL, testResult.getDisplayName()));
if (testReportURL.contains(
"com.liferay.poshi.runner/PoshiRunner")) {
Dom4JUtil.addToElement(
downstreamBuildListItemElement, " - ",
Dom4JUtil.getNewAnchorElement(
testResult.getPoshiReportURL(), "Poshi Report"),
" - ",
Dom4JUtil.getNewAnchorElement(
testResult.getPoshiSummaryURL(),
"Poshi Summary"),
" - ",
Dom4JUtil.getNewAnchorElement(
testResult.getConsoleOutputURL(),
"Console Output"));
if (testResult.hasLiferayLog()) {
Dom4JUtil.addToElement(
downstreamBuildListItemElement, " - ",
Dom4JUtil.getNewAnchorElement(
testResult.getLiferayLogURL(),
"Liferay Log"));
}
}
failureCount++;
continue;
}
downstreamBuildListItemElement.addText("...");
break;
}
}
return messageElement;
}
@Override
public String getJDK() {
Build parentBuild = getParentBuild();
return parentBuild.getJDK();
}
@Override
public String getOperatingSystem() {
Build parentBuild = getParentBuild();
return parentBuild.getOperatingSystem();
}
public String getTestRayLogsURL() {
Properties buildProperties = null;
try {
buildProperties = JenkinsResultsParserUtil.getBuildProperties();
}
catch (IOException ioe) {
throw new RuntimeException("Unable to get build properties", ioe);
}
String logBaseURL = null;
if (buildProperties.containsKey("log.base.url")) {
logBaseURL = buildProperties.getProperty("log.base.url");
}
if (logBaseURL == null) {
logBaseURL = defaultLogBaseURL;
}
Map<String, String> startPropertiesTempMap =
getStartPropertiesTempMap();
return JenkinsResultsParserUtil.combine(
logBaseURL, "/",
startPropertiesTempMap.get("TOP_LEVEL_MASTER_HOSTNAME"), "/",
startPropertiesTempMap.get("TOP_LEVEL_START_TIME"), "/",
startPropertiesTempMap.get("TOP_LEVEL_JOB_NAME"), "/",
startPropertiesTempMap.get("TOP_LEVEL_BUILD_NUMBER"), "/",
getParameterValue("JOB_VARIANT"), "/", getAxisNumber());
}
@Override
public List<TestResult> getTestResults(String testStatus) {
String status = getStatus();
if (!status.equals("completed")) {
return Collections.emptyList();
}
JSONObject testReportJSONObject = getTestReportJSONObject();
return TestResult.getTestResults(
this, testReportJSONObject.getJSONArray("suites"), testStatus);
}
@Override
public void reinvoke() {
throw new RuntimeException("Axis builds cannot be reinvoked");
}
protected AxisBuild(String url) {
this(url, null);
}
protected AxisBuild(String url, BatchBuild parentBuild) {
super(JenkinsResultsParserUtil.getLocalURL(url), parentBuild);
}
@Override
protected void checkForReinvocation(String consoleText) {
}
@Override
protected FailureMessageGenerator[] getFailureMessageGenerators() {
return _FAILURE_MESSAGE_GENERATORS;
}
@Override
protected Element getGitHubMessageJobResultsElement() {
return null;
}
@Override
protected String getStopPropertiesTempMapURL() {
if (fromArchive) {
return getBuildURL() + "/stop-properties.json";
}
TopLevelBuild topLevelBuild = getTopLevelBuild();
return JenkinsResultsParserUtil.combine(
"http://cloud-10-0-0-31.lax.liferay.com/osb-jenkins-web/map/",
topLevelBuild.getMaster(), "/", topLevelBuild.getJobName(), "/",
Integer.toString(topLevelBuild.getBuildNumber()), "/", getJobName(),
"/", getAxisVariable(), "/", getParameterValue("JOB_VARIANT"), "/",
"stop.properties");
}
@Override
protected void setBuildURL(String buildURL) {
try {
buildURL = JenkinsResultsParserUtil.decode(buildURL);
}
catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(
"Unable to decode " + buildURL, uee);
}
try {
String archiveMarkerContent = JenkinsResultsParserUtil.toString(
buildURL + "/archive-marker", false, 0, 0, 0);
if ((archiveMarkerContent != null) &&
!archiveMarkerContent.isEmpty()) {
fromArchive = true;
}
else {
fromArchive = false;
}
}
catch (IOException ioe) {
fromArchive = false;
}
Matcher matcher = buildURLPattern.matcher(buildURL);
if (!matcher.find()) {
matcher = archiveBuildURLPattern.matcher(buildURL);
if (!matcher.find()) {
throw new IllegalArgumentException(
"Invalid build URL " + buildURL);
}
archiveName = matcher.group("archiveName");
}
axisVariable = matcher.group("axisVariable");
jobName = matcher.group("jobName");
master = matcher.group("master");
setBuildNumber(Integer.parseInt(matcher.group("buildNumber")));
loadParametersFromBuildJSONObject();
setStatus("running");
}
protected static final Pattern archiveBuildURLPattern = Pattern.compile(
JenkinsResultsParserUtil.combine(
"(", Pattern.quote("${dependencies.url}"), "|",
Pattern.quote(JenkinsResultsParserUtil.DEPENDENCIES_URL_FILE), "|",
Pattern.quote(JenkinsResultsParserUtil.DEPENDENCIES_URL_HTTP),
")/*(?<archiveName>.*)/(?<master>[^/]+)/+(?<jobName>[^/]+)/",
"(?<axisVariable>AXIS_VARIABLE=[^,]+,[^/]+)/",
"(?<buildNumber>\\d+)/?"));
protected static final Pattern buildURLPattern = Pattern.compile(
JenkinsResultsParserUtil.combine(
"\\w+://(?<master>[^/]+)/+job/+(?<jobName>[^/]+)/",
"(?<axisVariable>AXIS_VARIABLE=[^,]+,[^/]+)/",
"(?<buildNumber>\\d+)/?"));
protected static final String defaultLogBaseURL =
"https://testray.liferay.com/reports/production/logs";
protected String axisVariable;
private static final FailureMessageGenerator[] _FAILURE_MESSAGE_GENERATORS =
{
new CompileFailureMessageGenerator(),
new IntegrationTestTimeoutFailureMessageGenerator(),
new LocalGitMirrorFailureMessageGenerator(),
new PluginFailureMessageGenerator(),
new PluginGitIDFailureMessageGenerator(),
new SemanticVersioningFailureMessageGenerator(),
new SourceFormatFailureMessageGenerator(),
new GenericFailureMessageGenerator()
};
private static final Pattern _axisVariablePattern = Pattern.compile(
"AXIS_VARIABLE=(?<axisNumber>[^,]+),.*");
}