/* * Copyright 2012-present Facebook, Inc. * * 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 com.facebook.buck.util; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.io.PrintStream; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; public class FakeProcessExecutor extends DefaultProcessExecutor { private final Function<? super ProcessExecutorParams, FakeProcess> processFunction; private final Set<ProcessExecutorParams> launchedProcesses; public FakeProcessExecutor() { this(ImmutableMap.of()); } public FakeProcessExecutor(Map<ProcessExecutorParams, FakeProcess> processMap) { this(processMap, new Console(Verbosity.ALL, System.out, System.err, Ansi.withoutTty())); } public FakeProcessExecutor( Iterable<Map.Entry<ProcessExecutorParams, FakeProcess>> processIterable) { this(processIterable, new Console(Verbosity.ALL, System.out, System.err, Ansi.withoutTty())); } public FakeProcessExecutor( final Iterable<Map.Entry<ProcessExecutorParams, FakeProcess>> processIterable, Console console) { this( new Function<ProcessExecutorParams, FakeProcess>() { final Iterator<Map.Entry<ProcessExecutorParams, FakeProcess>> processIterator = processIterable.iterator(); @Override public FakeProcess apply(ProcessExecutorParams params) { Preconditions.checkState( processIterator.hasNext(), "Ran out of fake processes when asked to run %s", params); Map.Entry<ProcessExecutorParams, FakeProcess> nextProcess = processIterator.next(); Preconditions.checkState( nextProcess.getKey().equals(params), "Mismatch when asked to run process %s (expecting %s)", params, nextProcess.getKey()); return nextProcess.getValue(); } }, console); } public FakeProcessExecutor(Map<ProcessExecutorParams, FakeProcess> processMap, Console console) { this(Functions.forMap(processMap), console); } public FakeProcessExecutor( Function<? super ProcessExecutorParams, FakeProcess> processFunction, Console console) { this(processFunction, console.getStdOut(), console.getStdErr(), console.getAnsi()); } public FakeProcessExecutor( Function<? super ProcessExecutorParams, FakeProcess> processFunction, PrintStream stdOutStream, PrintStream stdErrStream, Ansi ansi) { super( stdOutStream, stdErrStream, ansi, ProcessHelper.getInstance(), ProcessRegistry.getInstance()); this.processFunction = processFunction; this.launchedProcesses = new HashSet<>(); } @Override public LaunchedProcess launchProcess(ProcessExecutorParams params) throws IOException { try { FakeProcess fakeProcess = processFunction.apply(params); launchedProcesses.add(params); return new LaunchedProcessImpl(fakeProcess); } catch (IllegalArgumentException e) { throw new IOException( String.format( "FakeProcessExecutor not configured to run process with params %s", params)); } } @Override public LaunchedProcess launchProcess( ProcessExecutorParams params, ImmutableMap<String, String> context) throws IOException { return launchProcess(params); } public boolean isProcessLaunched(ProcessExecutorParams params) { return launchedProcesses.contains(params); } @Override public ProcessExecutor cloneWithOutputStreams( PrintStream newStdOutStream, PrintStream newStdErrStream) { return new FakeProcessExecutor( processFunction, newStdOutStream, newStdErrStream, Ansi.withoutTty()); } }