org.gradle.internal.operations.TestBuildOperationExecutor 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 2017 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.internal.operations;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import org.gradle.api.Action;
import org.gradle.internal.UncheckedException;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
/**
* A BuildOperationExecutor for tests.
* Simply execute given operations, does not support current/parent operations.
*/
public class TestBuildOperationExecutor implements BuildOperationExecutor {
public final Log log = new Log();
@Override
public BuildOperationRef getCurrentOperation() {
return new BuildOperationRef() {
@Override
public OperationIdentifier getId() {
return new OperationIdentifier(1L);
}
@Override
public OperationIdentifier getParentId() {
return null;
}
};
}
public List getOperations() {
return log.getDescriptors();
}
@Override
public void run(RunnableBuildOperation buildOperation) {
log.run(buildOperation);
}
@Override
public T call(CallableBuildOperation buildOperation) {
return log.call(buildOperation);
}
@Override
public void execute(O buildOperation, BuildOperationWorker worker, @Nullable BuildOperationState defaultParent) {
log.execute(buildOperation, worker);
}
@Override
public BuildOperationContext start(BuildOperationDescriptor.Builder descriptor) {
return log.start(descriptor);
}
@Override
public void runAll(Action> generator) {
generator.execute(new TestBuildOperationQueue(log));
}
@Override
public void runAllWithAccessToProjectState(Action> schedulingAction) {
runAll(schedulingAction);
}
@Override
public void runAll(BuildOperationWorker worker, Action> schedulingAction) {
throw new UnsupportedOperationException();
}
private static class TestBuildOperationContext implements BuildOperationContext {
private final Log.Record record;
public TestBuildOperationContext(Log.Record record) {
this.record = record;
}
@Override
public void failed(@Nullable Throwable failure) {
this.record.failure = failure;
}
@Override
public void setResult(@Nullable Object result) {
this.record.result = result;
}
@Override
public void setStatus(String status) {
}
}
public static class TestBuildOperationQueue implements BuildOperationQueue {
public final Log log;
public TestBuildOperationQueue() {
this(new Log());
}
private TestBuildOperationQueue(Log log) {
this.log = log;
}
@Override
public void add(O operation) {
log.run(operation);
}
@Override
public void cancel() {
throw new UnsupportedOperationException();
}
@Override
public void waitForCompletion() throws MultipleBuildOperationFailures {
throw new UnsupportedOperationException();
}
@Override
public void setLogLocation(String logLocation) {
throw new UnsupportedOperationException();
}
}
public static class Log {
public final Deque records = new LinkedBlockingDeque();
public List getDescriptors() {
return Lists.transform(new ArrayList(records), new Function() {
@Override
public BuildOperationDescriptor apply(Record input) {
return input.descriptor;
}
});
}
public > TypedRecord mostRecent(Class type) {
Class detailsType = BuildOperationTypes.detailsType(type);
Iterator iterator = records.descendingIterator();
while (iterator.hasNext()) {
Record record = iterator.next();
Object details = record.descriptor.getDetails();
if (detailsType.isInstance(details)) {
return record.asTyped(type);
}
}
throw new AssertionError("Did not find operation with details of type: " + detailsType.getName());
}
public > List> all(final Class type) {
final Class detailsType = BuildOperationTypes.detailsType(type);
return FluentIterable.from(records)
.filter(new Predicate() {
@Override
public boolean apply(Record input) {
return detailsType.isInstance(input.descriptor.getDetails());
}
})
.transform(new Function>() {
@Override
public TypedRecord apply(Record input) {
return input.asTyped(type);
}
})
.toList();
}
public > D mostRecentDetails(Class type) {
return mostRecent(type).details;
}
public > R mostRecentResult(Class type) {
return mostRecent(type).result;
}
public > Throwable mostRecentFailure(Class type) {
return mostRecent(type).failure;
}
@Override
public String toString() {
return records.toString();
}
public static class Record {
public final BuildOperationDescriptor descriptor;
public Object result;
public Throwable failure;
private Record(BuildOperationDescriptor descriptor) {
this.descriptor = descriptor;
}
@Override
public String toString() {
return descriptor.getDisplayName();
}
private > TypedRecord asTyped(Class extends T> buildOperationType) {
if (descriptor.getDetails() == null) {
throw new IllegalStateException("operation has null details");
}
return new TypedRecord(
descriptor,
BuildOperationTypes.detailsType(buildOperationType).cast(descriptor.getDetails()),
BuildOperationTypes.resultType(buildOperationType).cast(result),
failure
);
}
}
public static class TypedRecord {
public final BuildOperationDescriptor descriptor;
public final D details;
public final R result;
public final Throwable failure;
private TypedRecord(BuildOperationDescriptor descriptor, D details, R result, Throwable failure) {
this.descriptor = descriptor;
this.details = details;
this.result = result;
this.failure = failure;
}
@Override
public String toString() {
return descriptor.getDisplayName();
}
}
private void run(RunnableBuildOperation buildOperation) {
Record record = new Record(buildOperation.description().build());
records.add(record);
TestBuildOperationContext context = new TestBuildOperationContext(record);
try {
buildOperation.run(context);
} catch (Throwable failure) {
if (record.failure == null) {
record.failure = failure;
}
throw UncheckedException.throwAsUncheckedException(failure);
}
}
private T call(CallableBuildOperation buildOperation) {
Record record = new Record(buildOperation.description().build());
records.add(record);
TestBuildOperationContext context = new TestBuildOperationContext(record);
T t;
try {
t = buildOperation.call(context);
} catch (Throwable failure) {
if (record.failure == null) {
record.failure = failure;
}
throw UncheckedException.throwAsUncheckedException(failure);
}
return t;
}
private void execute(O buildOperation, BuildOperationWorker worker) {
Record record = new Record(buildOperation.description().build());
records.add(record);
TestBuildOperationContext context = new TestBuildOperationContext(record);
try {
worker.execute(buildOperation, context);
} catch (Throwable failure) {
if (record.failure == null) {
record.failure = failure;
}
throw UncheckedException.throwAsUncheckedException(failure);
}
}
private BuildOperationContext start(final BuildOperationDescriptor.Builder descriptor) {
Record record = new Record(descriptor.build());
records.add(record);
final TestBuildOperationContext context = new TestBuildOperationContext(record);
return new BuildOperationContext() {
@Override
public void failed(@Nullable Throwable failure) {
context.failed(failure);
}
@Override
public void setResult(Object result) {
context.setResult(result);
}
@Override
public void setStatus(String status) {
context.setStatus(status);
}
};
}
}
public void reset() {
log.records.clear();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy