com.liferay.jenkins.results.parser.BaseParentBuild Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.jenkins.results.parser
Show all versions of com.liferay.jenkins.results.parser
Liferay Jenkins Results Parser
/**
* SPDX-FileCopyrightText: (c) 2023 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.jenkins.results.parser;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dom4j.Element;
/**
* @author Michael Hashimoto
*/
public abstract class BaseParentBuild extends BaseBuild implements ParentBuild {
@Override
public void addDownstreamBuilds(Map urlAxisNames) {
if (urlAxisNames.isEmpty()) {
return;
}
final Build thisBuild = this;
List> callables = new ArrayList<>(urlAxisNames.size());
for (Map.Entry urlEntry : urlAxisNames.entrySet()) {
String url = urlEntry.getKey();
try {
url = JenkinsResultsParserUtil.getLocalURL(
JenkinsResultsParserUtil.decode(url));
}
catch (UnsupportedEncodingException unsupportedEncodingException) {
throw new IllegalArgumentException(
"Unable to decode " + url, unsupportedEncodingException);
}
if (!hasBuildURL(url)) {
final String axisName = urlEntry.getValue();
final String buildURL = url;
Matcher matcher = _buildURLPattern.matcher(buildURL);
String hostname = null;
if (matcher.matches()) {
hostname = matcher.group("hostname");
}
ParallelExecutor.SequentialCallable callable =
new ParallelExecutor.SequentialCallable(hostname) {
@Override
public Build call() {
try {
return BuildFactory.newBuild(
buildURL, thisBuild, axisName);
}
catch (RuntimeException runtimeException) {
if (!isFromArchive()) {
NotificationUtil.sendSlackNotification(
runtimeException.getMessage() +
"\nBuild URL: " +
thisBuild.getBuildURL(),
"ci-notifications",
"Build Object Failure");
}
return null;
}
}
};
callables.add(callable);
}
}
ParallelExecutor parallelExecutor = new ParallelExecutor<>(
callables, true, getExecutorService(), "addDownstreamBuilds");
try {
addDownstreamBuilds(parallelExecutor.execute(60L * 30L));
}
catch (TimeoutException timeoutException) {
throw new RuntimeException(timeoutException);
}
}
@Override
public void addDownstreamBuilds(String... urls) {
Map urlAxisNames = new HashMap<>();
for (String url : urls) {
urlAxisNames.put(url, null);
}
addDownstreamBuilds(urlAxisNames);
}
@Override
public int getDownstreamBuildCount(String status) {
return getDownstreamBuildCount(null, status);
}
@Override
public int getDownstreamBuildCount(String result, String status) {
List downstreamBuilds = getDownstreamBuilds(result, status);
return downstreamBuilds.size();
}
@Override
public List getDownstreamBuilds() {
if (_downstreamBuilds != null) {
return new ArrayList<>(_downstreamBuilds);
}
_downstreamBuilds = new ArrayList<>();
return new ArrayList<>(_downstreamBuilds);
}
@Override
public List getDownstreamBuilds(String status) {
return getDownstreamBuilds(null, status);
}
@Override
public List getDownstreamBuilds(String result, String status) {
List filteredDownstreamBuilds = Collections.synchronizedList(
new ArrayList());
List downstreamBuilds = getDownstreamBuilds();
if ((result == null) && (status == null)) {
filteredDownstreamBuilds.addAll(downstreamBuilds);
return filteredDownstreamBuilds;
}
for (Build downstreamBuild : downstreamBuilds) {
if (((status == null) ||
status.equals(downstreamBuild.getStatus())) &&
((result == null) ||
result.equals(downstreamBuild.getResult()))) {
filteredDownstreamBuilds.add(downstreamBuild);
}
}
return filteredDownstreamBuilds;
}
@Override
public Long getLatestStartTimestamp() {
Long latestStartTimestamp = getStartTime();
if (latestStartTimestamp == null) {
return null;
}
for (Build downstreamBuild : getDownstreamBuilds(null)) {
Long downstreamBuildLatestStartTimestamp = null;
if (downstreamBuild instanceof ParentBuild) {
ParentBuild parentBuild = (ParentBuild)downstreamBuild;
downstreamBuildLatestStartTimestamp =
parentBuild.getLatestStartTimestamp();
}
else {
downstreamBuildLatestStartTimestamp =
downstreamBuild.getStartTime();
}
if (downstreamBuildLatestStartTimestamp == null) {
return null;
}
latestStartTimestamp = Math.max(
latestStartTimestamp, downstreamBuildLatestStartTimestamp);
}
return latestStartTimestamp;
}
@Override
public Build getLongestDelayedDownstreamBuild() {
List downstreamBuilds = getDownstreamBuilds(null);
if (downstreamBuilds.isEmpty()) {
return this;
}
Build longestDelayedBuild = downstreamBuilds.get(0);
for (Build downstreamBuild : downstreamBuilds) {
Build longestDelayedDownstreamBuild = downstreamBuild;
if (downstreamBuild instanceof ParentBuild) {
ParentBuild parentBuild = (ParentBuild)downstreamBuild;
longestDelayedDownstreamBuild =
parentBuild.getLongestDelayedDownstreamBuild();
}
if (downstreamBuild.getDelayTime() >
longestDelayedDownstreamBuild.getDelayTime()) {
longestDelayedDownstreamBuild = downstreamBuild;
}
if (longestDelayedDownstreamBuild.getDelayTime() >
longestDelayedBuild.getDelayTime()) {
longestDelayedBuild = longestDelayedDownstreamBuild;
}
}
return longestDelayedBuild;
}
@Override
public Build getLongestRunningDownstreamBuild() {
Build longestRunningDownstreamBuild = null;
for (Build downstreamBuild : getDownstreamBuilds(null)) {
if ((longestRunningDownstreamBuild == null) ||
(downstreamBuild.getDuration() >
longestRunningDownstreamBuild.getDuration())) {
longestRunningDownstreamBuild = downstreamBuild;
}
}
return longestRunningDownstreamBuild;
}
@Override
public List getModifiedDownstreamBuilds() {
return getModifiedDownstreamBuildsByStatus(null);
}
@Override
public List getModifiedDownstreamBuildsByStatus(String status) {
List modifiedDownstreamBuilds = new ArrayList<>();
for (Build downstreamBuild : getDownstreamBuilds()) {
if (downstreamBuild.isBuildModified()) {
modifiedDownstreamBuilds.add(downstreamBuild);
continue;
}
if (!(downstreamBuild instanceof ParentBuild)) {
continue;
}
ParentBuild parentBuild = (ParentBuild)downstreamBuild;
if (parentBuild.hasModifiedDownstreamBuilds()) {
modifiedDownstreamBuilds.add(parentBuild);
}
}
if (status != null) {
modifiedDownstreamBuilds.retainAll(getDownstreamBuilds(status));
}
return modifiedDownstreamBuilds;
}
@Override
public List getTestResults(String testStatus) {
List testResults = new ArrayList<>();
for (Build downstreamBuild : getDownstreamBuilds(null)) {
List downstreamTestResults =
downstreamBuild.getTestResults(testStatus);
if (!(downstreamTestResults == null)) {
testResults.addAll(downstreamTestResults);
}
}
return testResults;
}
@Override
public long getTotalDuration() {
long totalDuration = getDuration();
for (Build downstreamBuild :
JenkinsResultsParserUtil.flatten(getDownstreamBuilds(null))) {
totalDuration += downstreamBuild.getDuration();
}
return totalDuration;
}
@Override
public int getTotalSlavesUsedCount() {
return getTotalSlavesUsedCount(null, false);
}
@Override
public int getTotalSlavesUsedCount(
String status, boolean modifiedBuildsOnly) {
return getTotalSlavesUsedCount(status, modifiedBuildsOnly, false);
}
@Override
public int getTotalSlavesUsedCount(
String status, boolean modifiedBuildsOnly, boolean ignoreCurrentBuild) {
int totalSlavesUsedCount = 1;
if (ignoreCurrentBuild || (modifiedBuildsOnly && !isBuildModified()) ||
((status != null) && !status.equals(getStatus()))) {
totalSlavesUsedCount = 0;
}
List downstreamBuilds;
if (modifiedBuildsOnly) {
downstreamBuilds = getModifiedDownstreamBuildsByStatus(status);
}
else {
downstreamBuilds = getDownstreamBuilds(status);
}
return totalSlavesUsedCount + downstreamBuilds.size();
}
@Override
public List getUniqueFailureTestResults() {
List uniqueFailureTestResults = new ArrayList<>();
for (Build downstreamBuild : getFailedDownstreamBuilds()) {
uniqueFailureTestResults.addAll(
downstreamBuild.getUniqueFailureTestResults());
}
return uniqueFailureTestResults;
}
@Override
public List getUpstreamJobFailureTestResults() {
List upstreamFailureTestResults = new ArrayList<>();
for (Build downstreamBuild : getFailedDownstreamBuilds()) {
upstreamFailureTestResults.addAll(
downstreamBuild.getUpstreamJobFailureTestResults());
}
return upstreamFailureTestResults;
}
@Override
public boolean hasBuildURL(String buildURL) {
if (super.hasBuildURL(buildURL)) {
return true;
}
for (Build downstreamBuild : getDownstreamBuilds()) {
if (downstreamBuild.hasBuildURL(buildURL)) {
return true;
}
}
return false;
}
@Override
public boolean hasDownstreamBuilds() {
if (getDownstreamBuildCount(null, null) > 0) {
return true;
}
return false;
}
@Override
public boolean hasModifiedDownstreamBuilds() {
for (Build downstreamBuild : getDownstreamBuilds()) {
if (downstreamBuild.isBuildModified()) {
return true;
}
if (!(downstreamBuild instanceof ParentBuild)) {
continue;
}
ParentBuild parentBuild = (ParentBuild)downstreamBuild;
if (parentBuild.hasModifiedDownstreamBuilds()) {
return true;
}
}
return false;
}
@Override
public void removeDownstreamBuild(Build build) {
if (_downstreamBuilds == null) {
getDownstreamBuilds();
}
_downstreamBuilds.remove(build);
}
@Override
public String replaceBuildURL(String text) {
if (JenkinsResultsParserUtil.isNullOrEmpty(text)) {
return text;
}
text = super.replaceBuildURL(text);
for (Build downstreamBuild : getDownstreamBuilds("complete")) {
Build downstreamBaseBuild = downstreamBuild;
text = downstreamBaseBuild.replaceBuildURL(text);
}
return super.replaceBuildURL(text);
}
@Override
public void reset() {
super.reset();
if (_downstreamBuilds != null) {
_downstreamBuilds.clear();
}
}
@Override
public void update() {
if (skipUpdate()) {
return;
}
List downstreamBuilds = getDownstreamBuilds(null);
List> callables = new ArrayList<>();
for (final Build downstreamBuild : downstreamBuilds) {
String status = downstreamBuild.getStatus();
if (status.equals("completed")) {
continue;
}
JenkinsMaster jenkinsMaster = downstreamBuild.getJenkinsMaster();
ParallelExecutor.SequentialCallable