All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.internal.operations.TestBuildOperationExecutor Maven / Gradle / Ivy

There is a newer version: 8.11.1
Show newest version
/*
 * 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.ImmutableList;
import com.google.common.collect.Iterables;
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.Collections;
import java.util.List;

/**
 * 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 runAll(Action> generator) {
        generator.execute(new TestBuildOperationQueue(log));
    }

    @Override
    public  void runAll(BuildOperationWorker worker, Action> schedulingAction) {
        throw new UnsupportedOperationException();
    }


    private static class TestBuildOperationContext implements BuildOperationContext {

        private Object result;
        private String status;
        private Throwable failure;

        @Override
        public void failed(@Nullable Throwable failure) {
            this.failure = failure;
        }

        @Override
        public void setResult(@Nullable Object result) {
            this.result = result;
        }

        @Override
        public void setStatus(String status) {
            this.status = 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 List records = Collections.synchronizedList(new ArrayList());

        public List getDescriptors() {
            return Lists.transform(new ArrayList(records), new Function() {
                @Override
                public BuildOperationDescriptor apply(@javax.annotation.Nullable Record input) {
                    return input.descriptor;
                }
            });
        }

        private > Record mostRecent(Class type) {
            Class detailsType = BuildOperationTypes.detailsType(type);
            ImmutableList copy = ImmutableList.copyOf(this.records).reverse();
            for (Record record : copy) {
                Object details = record.descriptor.getDetails();
                if (detailsType.isInstance(details)) {
                    return record;
                }
            }

            throw new AssertionError("Did not find operation with details of type: " + detailsType.getName());
        }

        public > List all(Class type) {
            final Class detailsType = BuildOperationTypes.detailsType(type);
            return ImmutableList.copyOf(Iterables.filter(records, new Predicate() {
                @Override
                public boolean apply(Record input) {
                    return detailsType.isInstance(input.descriptor.getDetails());
                }
            }));
        }

        public > D mostRecentDetails(Class type) {
            Class detailsType = BuildOperationTypes.detailsType(type);
            return detailsType.cast(mostRecent(type).descriptor.getDetails());
        }

        public > R mostRecentResult(Class type) {
            Record record = mostRecent(type);
            Object result = record.result;
            Class resultType = BuildOperationTypes.resultType(type);
            if (resultType.isInstance(result)) {
                return resultType.cast(result);
            } else {
                throw new AssertionError("Expected result type " + resultType.getName() + ", got " + result.getClass().getName());
            }
        }

        public > Throwable mostRecentFailure(Class type) {
            return mostRecent(type).failure;
        }

        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 void run(RunnableBuildOperation buildOperation) {
            Record record = new Record(buildOperation.description().build());
            records.add(record);
            TestBuildOperationContext context = new TestBuildOperationContext();
            try {
                buildOperation.run(context);
            } catch (Throwable failure) {
                if (record.result == null) {
                    record.result = context.result;
                }
                if (record.failure == null) {
                    record.failure = failure;
                }
                throw UncheckedException.throwAsUncheckedException(failure);
            }
            record.result = context.result;
            if (context.failure != null) {
                record.failure = context.failure;
            }
        }

        private  T call(CallableBuildOperation buildOperation) {
            Record record = new Record(buildOperation.description().build());
            records.add(record);
            TestBuildOperationContext context = new TestBuildOperationContext();
            T t;
            try {
                t = buildOperation.call(context);
            } catch (Throwable failure) {
                if (record.failure == null) {
                    record.failure = failure;
                }
                throw UncheckedException.throwAsUncheckedException(failure);
            }
            record.result = context.result;
            return t;
        }
    }

    public void reset() {
        log.records.clear();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy