Simplified ActionContextConsumer by having it operate on a new class which holds a variety of strategy/context maps.

PiperOrigin-RevId: 190491357
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 3f55bd0..330c8d7 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -1385,6 +1385,7 @@
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs",
         "//src/main/java/com/google/devtools/common/options",
+        "//src/main/protobuf:test_status_java_proto",
         "//third_party:mockito",
         "//third_party/protobuf:protobuf_java",
     ],
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/DummyExecutor.java b/src/test/java/com/google/devtools/build/lib/actions/util/DummyExecutor.java
index 34f6283..d9d78cd 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/DummyExecutor.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/DummyExecutor.java
@@ -16,6 +16,7 @@
 import com.google.common.eventbus.EventBus;
 import com.google.devtools.build.lib.actions.ActionContext;
 import com.google.devtools.build.lib.actions.Executor;
+import com.google.devtools.build.lib.actions.Spawn;
 import com.google.devtools.build.lib.actions.SpawnActionContext;
 import com.google.devtools.build.lib.clock.BlazeClock;
 import com.google.devtools.build.lib.clock.Clock;
@@ -83,7 +84,7 @@
   }
 
   @Override
-  public SpawnActionContext getSpawnActionContext(String mnemonic) {
+  public SpawnActionContext getSpawnActionContext(String mnemonic, Spawn spawn) {
     throw new UnsupportedOperationException();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
new file mode 100644
index 0000000..8e9f610
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
@@ -0,0 +1,151 @@
+// Copyright 2018 The Bazel Authors. All Rights Reserved.
+//
+// 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.google.devtools.build.lib.exec;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.eventbus.EventBus;
+import com.google.devtools.build.lib.actions.ActionContext;
+import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
+import com.google.devtools.build.lib.actions.ExecException;
+import com.google.devtools.build.lib.actions.ExecutionStrategy;
+import com.google.devtools.build.lib.actions.Spawn;
+import com.google.devtools.build.lib.actions.SpawnActionContext;
+import com.google.devtools.build.lib.actions.SpawnResult;
+import com.google.devtools.build.lib.analysis.test.TestActionContext;
+import com.google.devtools.build.lib.analysis.test.TestResult;
+import com.google.devtools.build.lib.analysis.test.TestRunnerAction;
+import com.google.devtools.build.lib.events.Reporter;
+import com.google.devtools.build.lib.testutil.Suite;
+import com.google.devtools.build.lib.testutil.TestSpec;
+import com.google.devtools.build.lib.util.RegexFilter.RegexFilterConverter;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.view.test.TestStatus.TestResultData;
+import java.io.IOException;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mockito;
+
+/** Tests of {@link SpawnActionContextMaps}. */
+@RunWith(JUnit4.class)
+@TestSpec(size = Suite.SMALL_TESTS)
+public class SpawnActionContextMapsTest {
+
+  private SpawnActionContextMaps.Builder builder;
+  private final RegexFilterConverter converter = new RegexFilterConverter();
+  private final EventBus bus = new EventBus();
+  private final Reporter reporter = new Reporter(bus);
+
+  private static final ImmutableList<ActionContextProvider> PROVIDERS =
+      ImmutableList.of(
+          new ActionContextProvider() {
+            @Override
+            public Iterable<? extends ActionContext> getActionContexts() {
+              return ImmutableList.of(new AC1(), new AC2(), new ACTest());
+            }
+          });
+
+  @Before
+  public void setUp() {
+    builder = new SpawnActionContextMaps.Builder();
+  }
+
+  @Test
+  public void duplicateMnemonics_lastOneWins() throws Exception {
+    builder.strategyByMnemonicMap().put("Spawn1", "ac1").put("Spawn1", "ac2");
+    SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
+    SpawnActionContext result = maps.getSpawnActionContext("Spawn1", null, reporter);
+    assertThat(result).isInstanceOf(AC2.class);
+  }
+
+  @Test
+  public void multipleRegexps_firstMatchWins() throws Exception {
+    builder.addStrategyByRegexp(converter.convert("foo"), "ac1");
+    builder.addStrategyByRegexp(converter.convert("foo/bar"), "ac2");
+    SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
+
+    SpawnActionContext result =
+        maps.getSpawnActionContext("", mockSpawn("Doing something with foo/bar/baz"), reporter);
+
+    assertThat(result).isInstanceOf(AC1.class);
+  }
+
+  @Test
+  public void regexpAndMnemonic_regexpWins() throws Exception {
+    builder.strategyByMnemonicMap().put("Spawn1", "ac1");
+    builder.addStrategyByRegexp(converter.convert("foo/bar"), "ac2");
+    SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
+
+    SpawnActionContext result =
+        maps.getSpawnActionContext(
+            "Spawn1", mockSpawn("Doing something with foo/bar/baz"), reporter);
+
+    assertThat(result).isInstanceOf(AC2.class);
+  }
+
+  @Test
+  public void duplicateContext_noException() throws Exception {
+    builder.strategyByContextMap().put(AC1.class, "one");
+    builder.strategyByContextMap().put(AC1.class, "two");
+    builder.strategyByContextMap().put(AC1.class, "");
+  }
+
+  private Spawn mockSpawn(String message) {
+    Spawn mockSpawn = Mockito.mock(Spawn.class);
+    ActionExecutionMetadata mockOwner = Mockito.mock(ActionExecutionMetadata.class);
+    when(mockOwner.getProgressMessage()).thenReturn(message);
+    when(mockSpawn.getResourceOwner()).thenReturn(mockOwner);
+    return mockSpawn;
+  }
+
+  @ExecutionStrategy(contextType = SpawnActionContext.class, name = "ac1")
+  private static class AC1 implements SpawnActionContext {
+    @Override
+    public List<SpawnResult> exec(Spawn spawn, ActionExecutionContext actionExecutionContext)
+        throws ExecException, InterruptedException {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @ExecutionStrategy(contextType = SpawnActionContext.class, name = "ac2")
+  private static class AC2 implements SpawnActionContext {
+    @Override
+    public List<SpawnResult> exec(Spawn spawn, ActionExecutionContext actionExecutionContext)
+        throws ExecException, InterruptedException {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @ExecutionStrategy(contextType = TestActionContext.class, name = "actest")
+  private static class ACTest implements TestActionContext {
+    @Override
+    public List<SpawnResult> exec(
+        TestRunnerAction action, ActionExecutionContext actionExecutionContext)
+        throws ExecException, InterruptedException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public TestResult newCachedTestResult(
+        Path execRoot, TestRunnerAction action, TestResultData cached) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java b/src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java
index 57ad243..9ebe4aa 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java
@@ -128,7 +128,7 @@
             .build();
     when(spawnActionContext.exec(any(), any())).thenReturn(ImmutableList.of(expectedSpawnResult));
 
-    when(actionExecutionContext.getSpawnActionContext(any())).thenReturn(spawnActionContext);
+    when(actionExecutionContext.getSpawnActionContext(any(), any())).thenReturn(spawnActionContext);
 
     // actual StandaloneTestStrategy execution
     List<SpawnResult> spawnResults =
@@ -208,7 +208,7 @@
                 expectedSpawnResult,
                 /*forciblyRunRemotely=*/ false,
                 /*catastrophe=*/ false));
-    when(actionExecutionContext.getSpawnActionContext(any())).thenReturn(spawnActionContext);
+    when(actionExecutionContext.getSpawnActionContext(any(), any())).thenReturn(spawnActionContext);
 
     // actual StandaloneTestStrategy execution
     List<SpawnResult> spawnResults =
@@ -285,7 +285,7 @@
 
     SpawnResult expectedSpawnResult = new SpawnResult.Builder().setStatus(Status.SUCCESS).build();
     when(spawnActionContext.exec(any(), any())).thenReturn(ImmutableList.of(expectedSpawnResult));
-    when(actionExecutionContext.getSpawnActionContext(any())).thenReturn(spawnActionContext);
+    when(actionExecutionContext.getSpawnActionContext(any(), any())).thenReturn(spawnActionContext);
 
     // actual StandaloneTestStrategy execution
     List<SpawnResult> spawnResults =
diff --git a/src/test/java/com/google/devtools/build/lib/exec/util/TestExecutorBuilder.java b/src/test/java/com/google/devtools/build/lib/exec/util/TestExecutorBuilder.java
index 70bd8e6..db3214f 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/util/TestExecutorBuilder.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/util/TestExecutorBuilder.java
@@ -14,7 +14,6 @@
 package com.google.devtools.build.lib.exec.util;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.eventbus.EventBus;
 import com.google.devtools.build.lib.actions.ActionContext;
@@ -28,6 +27,7 @@
 import com.google.devtools.build.lib.exec.BlazeExecutor;
 import com.google.devtools.build.lib.exec.ExecutionOptions;
 import com.google.devtools.build.lib.exec.FileWriteStrategy;
+import com.google.devtools.build.lib.exec.SpawnActionContextMaps;
 import com.google.devtools.build.lib.exec.SymlinkTreeStrategy;
 import com.google.devtools.build.lib.runtime.CommonCommandOptions;
 import com.google.devtools.build.lib.testutil.TestConstants;
@@ -107,8 +107,7 @@
         bus,
         BlazeClock.instance(),
         optionsParser,
-        strategies,
-        ImmutableMap.copyOf(spawnStrategyMap),
+        SpawnActionContextMaps.createStub(strategies, spawnStrategyMap),
         ImmutableList.<ActionContextProvider>of());
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
index 37fd188..0e93ff2 100644
--- a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java
@@ -21,7 +21,6 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import com.google.common.eventbus.EventBus;
-import com.google.devtools.build.lib.actions.ActionContext;
 import com.google.devtools.build.lib.actions.ActionExecutionContext;
 import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
@@ -44,6 +43,7 @@
 import com.google.devtools.build.lib.exec.BlazeExecutor;
 import com.google.devtools.build.lib.exec.ExecutionOptions;
 import com.google.devtools.build.lib.exec.SingleBuildFileCache;
+import com.google.devtools.build.lib.exec.SpawnActionContextMaps;
 import com.google.devtools.build.lib.exec.local.LocalEnvProvider;
 import com.google.devtools.build.lib.exec.local.LocalExecutionOptions;
 import com.google.devtools.build.lib.exec.local.LocalSpawnRunner;
@@ -134,16 +134,17 @@
             bus,
             BlazeClock.instance(),
             optionsParser,
-            ImmutableList.<ActionContext>of(),
-            ImmutableMap.<String, SpawnActionContext>of(
-                "",
-                new StandaloneSpawnStrategy(
-                    execRoot,
-                    new LocalSpawnRunner(
+            SpawnActionContextMaps.createStub(
+                ImmutableList.of(),
+                ImmutableMap.<String, SpawnActionContext>of(
+                    "",
+                    new StandaloneSpawnStrategy(
                         execRoot,
-                        localExecutionOptions,
-                        resourceManager,
-                        LocalEnvProvider.UNMODIFIED))),
+                        new LocalSpawnRunner(
+                            execRoot,
+                            localExecutionOptions,
+                            resourceManager,
+                            LocalEnvProvider.UNMODIFIED)))),
             ImmutableList.<ActionContextProvider>of());
 
     executor.getExecRoot().createDirectoryAndParents();
@@ -170,14 +171,14 @@
   @Test
   public void testBinTrueExecutesFine() throws Exception {
     Spawn spawn = createSpawn(getTrueCommand());
-    executor.getSpawnActionContext(spawn.getMnemonic()).exec(spawn, createContext());
+    executor.getSpawnActionContext(spawn.getMnemonic(), spawn).exec(spawn, createContext());
 
     assertThat(out()).isEmpty();
     assertThat(err()).isEmpty();
   }
 
   private List<SpawnResult> run(Spawn spawn) throws Exception {
-    return executor.getSpawnActionContext(spawn.getMnemonic()).exec(spawn, createContext());
+    return executor.getSpawnActionContext(spawn.getMnemonic(), spawn).exec(spawn, createContext());
   }
 
   private ActionExecutionContext createContext() {