blob: 5433d4b375a28d57c697d6af99975631980c9d15 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.ignite.ci.analysis;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import org.apache.ignite.ci.tcbot.conf.BuildParameterSpec;
import org.apache.ignite.ci.tcbot.conf.ITcServerConfig;
import org.apache.ignite.ci.tcbot.conf.ParameterValueSpec;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.ProblemCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.TestCompacted;
import org.apache.ignite.ci.util.FutureUtil;
import org.jetbrains.annotations.Nullable;
/**
* Single build ocurrence,
*/
public class SingleBuildRunCtx implements ISuiteResults {
/** Build compacted. */
private FatBuildCompacted buildCompacted;
/** Compactor. */
private IStringCompactor compactor;
/** Changes. */
private List<ChangeCompacted> changes = new ArrayList<>();
/** Logger check result future. */
private CompletableFuture<LogCheckResult> logCheckResFut;
/** Tags found from filtering-enabled parameters. */
private Set<String> tags = new HashSet<>();
/**
* @param buildCompacted Build compacted.
* @param compactor Compactor.
*/
public SingleBuildRunCtx(FatBuildCompacted buildCompacted,
IStringCompactor compactor) {
this.buildCompacted = buildCompacted;
this.compactor = compactor;
}
/**
*
*/
public Integer buildId() {
Preconditions.checkNotNull(buildCompacted);
return buildCompacted.id() < 0 ? null : buildCompacted.id();
}
/** {@inheritDoc} */
@Override public boolean hasMetricProblem() {
return getProblemsStream().anyMatch(p -> p.isBuildFailureOnMetric(compactor));
}
/** {@inheritDoc} */
@Override public boolean hasCompilationProblem() {
return getProblemsStream().anyMatch(p -> p.isCompilationError(compactor));
}
public boolean hasTimeoutProblem() {
return getExecutionTimeoutCount() > 0;
}
private long getExecutionTimeoutCount() {
return getProblemsStream().filter(p -> p.isExecutionTimeout(compactor)).count();
}
Stream<ProblemCompacted> getProblemsStream() {
return buildCompacted.problems().stream();
}
@Override public boolean hasJvmCrashProblem() {
return getProblemsStream().anyMatch(p -> p.isJvmCrash(compactor));
}
@Override public boolean hasOomeProblem() {
return getProblemsStream().anyMatch(p -> p.isOome(compactor));
}
@Override public boolean hasExitCodeProblem() {
return getProblemsStream().anyMatch(p -> p.isExitCode(compactor));
}
@Override public String suiteId() {
return compactor.getStringFromId(buildCompacted.buildTypeId());
}
public void setLogCheckResFut(CompletableFuture<LogCheckResult> logCheckResFut) {
this.logCheckResFut = logCheckResFut;
}
@Nullable public String getCriticalFailLastStartedTest() {
LogCheckResult logCheckRes = getLogCheckIfFinished();
if (logCheckRes == null)
return null;
return logCheckRes.getLastStartedTest();
}
@Nullable public Map<String, TestLogCheckResult> getTestLogCheckResult() {
LogCheckResult logCheckRes = getLogCheckIfFinished();
if (logCheckRes == null)
return null;
return logCheckRes.getTestLogCheckResult();
}
@Nullable public Integer getBuildIdIfHasThreadDump() {
LogCheckResult logCheckRes = getLogCheckIfFinished();
if (logCheckRes == null)
return null;
return !Strings.isNullOrEmpty(logCheckRes.getLastThreadDump()) ? buildId() : null;
}
@Nullable public LogCheckResult getLogCheckIfFinished() {
if (logCheckResFut == null)
return null;
if (!logCheckResFut.isDone() || logCheckResFut.isCancelled())
return null;
LogCheckResult logCheckRes = FutureUtil.getResultSilent(logCheckResFut);
if (logCheckRes == null)
return null;
return logCheckRes;
}
public List<ChangeCompacted> getChanges() {
return Collections.unmodifiableList(changes);
}
public List<TestOccurrenceFull> getTests() {
if (isComposite())
return Collections.emptyList();
return buildCompacted.getTestOcurrences(compactor).getTests();
}
@Nonnull Stream<? extends Future<?>> getFutures() {
return logCheckResFut == null ? Stream.empty() : Stream.of((Future<?>)logCheckResFut);
}
public boolean isComposite() {
return buildCompacted.isComposite();
}
public String getBranch() {
return compactor.getStringFromId(buildCompacted.branchName());
}
/**
* @return Names of not muted or ignored test failed for non composite build
*/
public Stream<String> getFailedNotMutedTestNames() {
return isComposite() ? Stream.empty() : buildCompacted.getFailedNotMutedTestNames(compactor);
}
public Stream<TestCompacted> getFailedNotMutedTests() {
return isComposite() ? Stream.empty() : buildCompacted.getFailedNotMutedTests(compactor);
}
public Stream<String> getAllTestNames() {
return buildCompacted.getAllTestNames(compactor);
}
public Stream<TestCompacted> getAllTests() {
return isComposite() ? Stream.empty() : buildCompacted.getAllTests();
}
public String suiteName() {
return buildCompacted.buildTypeName(compactor);
}
public String projectId() {
return buildCompacted.projectId(compactor);
}
@Nullable public Long buildDuration() {
return buildCompacted.buildDuration(compactor);
}
@Nullable public Long buildDurationNetTime() {
return buildCompacted.buildDurationNetTime(compactor);
}
@Nullable public Long sourceUpdateDuration() {
return buildCompacted.sourceUpdateDuration(compactor);
}
@Nullable public Long artifcactPublishingDuration() {
return buildCompacted.artifcactPublishingDuration(compactor);
}
@Nullable public Long dependeciesResolvingDuration() {
return buildCompacted.dependeciesResolvingDuration(compactor);
}
public void setChanges(Collection<ChangeCompacted> changes) {
this.changes.clear();
this.changes.addAll(changes);
}
public boolean isCancelled() {
return buildCompacted.isCancelled(compactor);
}
/**
* @return Full run time required to run tests.
*/
public long testsDuration() {
return getAllTests()
.mapToLong(t -> {
Integer duration = t.getDuration();
if (duration == null)
return 0;
return duration;
}).sum();
}
public void addTag(String label) {
this.tags.add(label);
}
public Set<String> tags() {
return tags;
}
public void addTagsFromParameters(ParametersCompacted parameters, ITcServerConfig tcCfg,
IStringCompactor compactor) {
for (BuildParameterSpec parm : tcCfg.filteringParameters()) {
if (!parm.isFilled())
continue;
String propVal = parameters.getProperty(compactor, parm.name());
if (Strings.isNullOrEmpty(propVal))
continue;
parm.selection().stream()
.filter(v -> Objects.equals(v.value(), propVal))
.findAny()
.ifPresent(v -> addTag(v.label()));
}
}
}