Support pool for action_foreach

This is follow up of pool support in action
https://codereview.chromium.org/2926013002

Using action pool can remove some overhead of many running process.
Pool support of action_foreach gives better control for some python generator step when using goma.
e.g. https://codereview.chromium.org/2726103005

Bug: 695864
Change-Id: Ibd0bbaffc59513db42119138520aee3505762eee
Reviewed-on: https://chromium-review.googlesource.com/882625
Reviewed-by: Dirk Pranke <dpranke@chromium.org>
Commit-Queue: Takuto Ikuta <tikuta@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#531844}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 4c48a35125352ab95d8660d2039864ba49f9f7d2
diff --git a/tools/gn/ninja_action_target_writer.cc b/tools/gn/ninja_action_target_writer.cc
index 97b8653..bc7b69d 100644
--- a/tools/gn/ninja_action_target_writer.cc
+++ b/tools/gn/ninja_action_target_writer.cc
@@ -206,6 +206,12 @@
       WriteDepfile(sources[i]);
       out_ << std::endl;
     }
+    if (target_->action_values().pool().ptr) {
+      out_ << "  pool = ";
+      out_ << target_->action_values().pool().ptr->GetNinjaName(
+          settings_->default_toolchain_label());
+      out_ << std::endl;
+    }
   }
 }
 
diff --git a/tools/gn/ninja_action_target_writer_unittest.cc b/tools/gn/ninja_action_target_writer_unittest.cc
index 159c29c..7f0d911 100644
--- a/tools/gn/ninja_action_target_writer_unittest.cc
+++ b/tools/gn/ninja_action_target_writer_unittest.cc
@@ -359,3 +359,54 @@
       "build obj/foo/bar.stamp: stamp input1.out\n";
   EXPECT_EQ(expected_linux, out.str());
 }
+
+TEST(NinjaActionTargetWriter, ForEachWithPool) {
+  Err err;
+  TestWithScope setup;
+
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+  target.set_output_type(Target::ACTION_FOREACH);
+
+  target.sources().push_back(SourceFile("//foo/input1.txt"));
+  target.action_values().set_script(SourceFile("//foo/script.py"));
+
+  Pool pool(setup.settings(),
+            Label(SourceDir("//foo/"), "pool", setup.toolchain()->label().dir(),
+                  setup.toolchain()->label().name()));
+  pool.set_depth(5);
+  target.action_values().set_pool(LabelPtrPair<Pool>(&pool));
+
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  // Make sure we get interesting substitutions for both the args and the
+  // response file contents.
+  target.action_values().args() =
+      SubstitutionList::MakeForTest("{{source}}", "{{source_file_part}}");
+  target.action_values().outputs() =
+      SubstitutionList::MakeForTest("//out/Debug/{{source_name_part}}.out");
+
+  setup.build_settings()->set_python_path(
+      base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
+
+  std::ostringstream out;
+  NinjaActionTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected_linux[] =
+      "rule __foo_bar___rule\n"
+      // These come from the args.
+      "  command = /usr/bin/python ../../foo/script.py ${in} "
+      "${source_file_part}\n"
+      "  description = ACTION //foo:bar()\n"
+      "  restat = 1\n"
+      "\n"
+      "build input1.out: __foo_bar___rule ../../foo/input1.txt"
+      " | ../../foo/script.py\n"
+      // Substitution for the args.
+      "  source_file_part = input1.txt\n"
+      "  pool = foo_pool\n"
+      "\n"
+      "build obj/foo/bar.stamp: stamp input1.out\n";
+  EXPECT_EQ(expected_linux, out.str());
+}