Allow passing a comma-separated list of strategies to the strategy flags.

Any strategy except the first one in a list is currently ignored. This
feature will be used in follow up changes to implement a new way of
specifying execution strategies and to improve the configurability of
execution fallback (e.g. remote to local, sandboxed to non-sandboxed).

RELNOTES: None.
PiperOrigin-RevId: 234849292
diff --git a/src/test/java/com/google/devtools/build/lib/exec/BlazeExecutorTest.java b/src/test/java/com/google/devtools/build/lib/exec/BlazeExecutorTest.java
index 1dcd3b0..41c7a94 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/BlazeExecutorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/BlazeExecutorTest.java
@@ -86,6 +86,6 @@
             });
     assertThat(event).isNotNull();
     assertThat(event.getMessage())
-        .contains("\"mock\" = " + mockStrategy.getClass().getSimpleName());
+        .contains("\"mock\" = [" + mockStrategy.getClass().getSimpleName() + "]");
   }
 }
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
index bcd0244..a676256 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
@@ -53,12 +53,15 @@
   private final EventBus bus = new EventBus();
   private final Reporter reporter = new Reporter(bus);
 
+  private static final AC1 ac1 = new AC1();
+  private static final AC2 ac2 = new AC2();
+
   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());
+              return ImmutableList.of(ac1, ac2, new ACTest());
             }
           });
 
@@ -68,44 +71,48 @@
   }
 
   @Test
-  public void duplicateMnemonics_lastOneWins() throws Exception {
-    builder.strategyByMnemonicMap().put("Spawn1", "ac1").put("Spawn1", "ac2");
+  public void duplicateMnemonics_bothGetStored() throws Exception {
+    builder.strategyByMnemonicMap().put("Spawn1", "ac1");
+    builder.strategyByMnemonicMap().put("Spawn1", "ac2");
     SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
-    SpawnActionContext result = maps.getSpawnActionContext(mockSpawn("Spawn1", null), reporter);
-    assertThat(result).isInstanceOf(AC2.class);
+    List<SpawnActionContext> result =
+        maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
+    assertThat(result).containsExactly(ac1, ac2);
   }
 
   @Test
   public void emptyStrategyFallsBackToEmptyMnemonicNotToDefault() throws Exception {
-    builder.strategyByMnemonicMap().put("Spawn1", "").put("", "ac2");
+    builder.strategyByMnemonicMap().put("Spawn1", "");
+    builder.strategyByMnemonicMap().put("", "ac2");
     SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
-    SpawnActionContext result = maps.getSpawnActionContext(mockSpawn("Spawn1", null), reporter);
-    assertThat(result).isInstanceOf(AC2.class);
+    List<SpawnActionContext> result =
+        maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
+    assertThat(result).containsExactly(ac2);
   }
 
   @Test
   public void multipleRegexps_firstMatchWins() throws Exception {
-    builder.addStrategyByRegexp(converter.convert("foo"), "ac1");
-    builder.addStrategyByRegexp(converter.convert("foo/bar"), "ac2");
+    builder.addStrategyByRegexp(converter.convert("foo"), ImmutableList.of("ac1"));
+    builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
     SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
 
-    SpawnActionContext result =
-        maps.getSpawnActionContext(mockSpawn(null, "Doing something with foo/bar/baz"), reporter);
+    List<SpawnActionContext> result =
+        maps.getSpawnActionContexts(mockSpawn(null, "Doing something with foo/bar/baz"), reporter);
 
-    assertThat(result).isInstanceOf(AC1.class);
+    assertThat(result).containsExactly(ac1);
   }
 
   @Test
   public void regexpAndMnemonic_regexpWins() throws Exception {
     builder.strategyByMnemonicMap().put("Spawn1", "ac1");
-    builder.addStrategyByRegexp(converter.convert("foo/bar"), "ac2");
+    builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
     SpawnActionContextMaps maps = builder.build(PROVIDERS, "actest");
 
-    SpawnActionContext result =
-        maps.getSpawnActionContext(
+    List<SpawnActionContext> result =
+        maps.getSpawnActionContexts(
             mockSpawn("Spawn1", "Doing something with foo/bar/baz"), reporter);
 
-    assertThat(result).isInstanceOf(AC2.class);
+    assertThat(result).containsExactly(ac2);
   }
 
   @Test
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 532971b..21fab38 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
@@ -53,7 +53,7 @@
   private Reporter reporter = new Reporter(bus);
   private OptionsParser optionsParser = OptionsParser.newOptionsParser(DEFAULT_OPTIONS);
   private List<ActionContext> strategies = new ArrayList<>();
-  private Map<String, SpawnActionContext> spawnStrategyMap =
+  private final Map<String, List<SpawnActionContext>> spawnStrategyMap =
       new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
 
   public TestExecutorBuilder(
@@ -96,7 +96,7 @@
   }
 
   public TestExecutorBuilder setExecution(String mnemonic, SpawnActionContext strategy) {
-    spawnStrategyMap.put(mnemonic, strategy);
+    spawnStrategyMap.put(mnemonic, ImmutableList.of(strategy));
     strategies.add(strategy);
     return this;
   }
@@ -110,6 +110,6 @@
         BlazeClock.instance(),
         optionsParser,
         SpawnActionContextMaps.createStub(strategies, spawnStrategyMap),
-        ImmutableList.<ActionContextProvider>of());
+        ImmutableList.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 8272493..2dbcced 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
@@ -39,7 +39,6 @@
 import com.google.devtools.build.lib.clock.BlazeClock;
 import com.google.devtools.build.lib.events.PrintingEventHandler;
 import com.google.devtools.build.lib.events.Reporter;
-import com.google.devtools.build.lib.exec.ActionContextProvider;
 import com.google.devtools.build.lib.exec.BinTools;
 import com.google.devtools.build.lib.exec.BlazeExecutor;
 import com.google.devtools.build.lib.exec.ExecutionOptions;
@@ -137,17 +136,19 @@
             optionsParser,
             SpawnActionContextMaps.createStub(
                 ImmutableList.of(),
-                ImmutableMap.<String, SpawnActionContext>of(
+                ImmutableMap.of(
                     "",
-                    new StandaloneSpawnStrategy(
-                        execRoot,
-                        new LocalSpawnRunner(
+                    ImmutableList.of(
+                        new StandaloneSpawnStrategy(
                             execRoot,
-                            localExecutionOptions,
-                            resourceManager,
-                            LocalEnvProvider.UNMODIFIED,
-                            BinTools.forIntegrationTesting(directories, ImmutableList.of()))))),
-            ImmutableList.<ActionContextProvider>of());
+                            new LocalSpawnRunner(
+                                execRoot,
+                                localExecutionOptions,
+                                resourceManager,
+                                LocalEnvProvider.UNMODIFIED,
+                                BinTools.forIntegrationTesting(
+                                    directories, ImmutableList.of())))))),
+            ImmutableList.of());
 
     executor.getExecRoot().createDirectoryAndParents();
   }
@@ -193,7 +194,7 @@
         null,
         outErr,
         executor.getEventHandler(),
-        ImmutableMap.<String, String>of(),
+        ImmutableMap.of(),
         ImmutableMap.of(),
         SIMPLE_ARTIFACT_EXPANDER,
         /*actionFileSystem=*/ null,