Faster bugreports (2/n)

- Having a system property to disable parallel run function.
- Post 'DumpTraces' to the thread pool. 3% is
  improved compared with single thread run.

Bug: 136262402
Test: atest dumpstate_test
Test: atest dumpstate_smoke_test
Test: Manual enable and disable parallel run
Test: Manual trigger report using hardware key
Test: Manual trigger using bugreport shortcut
Change-Id: I2185cc3e2f429a150605d6268324c52d137db385
Merged-In: I2185cc3e2f429a150605d6268324c52d137db385
(cherry picked from commit 5377d797fff94e0e070fdbbadc89288d90cc5f2c)
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index d0a4826..b3cb434 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -97,6 +97,10 @@
         PropertiesHelper::unroot_ = unroot;
     }
 
+    void SetParallelRun(bool parallel_run) const {
+        PropertiesHelper::parallel_run_ = parallel_run;
+    }
+
     bool IsStandalone() const {
         return calls_ == 1;
     }
@@ -544,6 +548,10 @@
         ds.options_.reset(new Dumpstate::DumpOptions());
     }
 
+    void TearDown() {
+        ds.ShutdownDumpPool();
+    }
+
     // Runs a command and capture `stdout` and `stderr`.
     int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
                    const CommandOptions& options = CommandOptions::DEFAULT) {
@@ -571,6 +579,10 @@
         ds.progress_.reset(new Progress(initial_max, progress, 1.2));
     }
 
+    void EnableParallelRunIfNeeded() {
+        ds.EnableParallelRunIfNeeded();
+    }
+
     std::string GetProgressMessage(int progress, int max,
             int old_max = 0, bool update_progress = true) {
         EXPECT_EQ(progress, ds.progress_->Get()) << "invalid progress";
@@ -1009,6 +1021,27 @@
     ds.listener_.clear();
 }
 
+TEST_F(DumpstateTest, DumpPool_withOutputToFileAndParallelRunEnabled_notNull) {
+    ds.options_->use_socket = false;
+    SetParallelRun(true);
+    EnableParallelRunIfNeeded();
+    EXPECT_TRUE(ds.options_->OutputToFile());
+    EXPECT_TRUE(ds.dump_pool_);
+}
+
+TEST_F(DumpstateTest, DumpPool_withNotOutputToFile_isNull) {
+    ds.options_->use_socket = true;
+    EnableParallelRunIfNeeded();
+    EXPECT_FALSE(ds.options_->OutputToFile());
+    EXPECT_FALSE(ds.dump_pool_);
+}
+
+TEST_F(DumpstateTest, DumpPool_withParallelRunDisabled_isNull) {
+    SetParallelRun(false);
+    EnableParallelRunIfNeeded();
+    EXPECT_FALSE(ds.dump_pool_);
+}
+
 class DumpstateServiceTest : public DumpstateBaseTest {
   public:
     DumpstateService dss;
@@ -1623,6 +1656,7 @@
 class DumpPoolTest : public DumpstateBaseTest {
   public:
     void SetUp() {
+        dump_pool_ = std::make_unique<DumpPool>(kTestDataPath);
         DumpstateBaseTest::SetUp();
         CreateOutputFile();
     }
@@ -1662,12 +1696,16 @@
         return count;
     }
 
+    void setLogDuration(bool log_duration) {
+        dump_pool_->setLogDuration(log_duration);
+    }
+
+    std::unique_ptr<DumpPool> dump_pool_;
     android::base::unique_fd out_fd_;
     std::string out_path_;
 };
 
-TEST_F(DumpPoolTest, EnqueueTask) {
-    DumpPool pool(kTestDataPath);
+TEST_F(DumpPoolTest, EnqueueTaskWithFd) {
     auto dump_func_1 = [](int out_fd) {
         dprintf(out_fd, "A");
     };
@@ -1678,19 +1716,37 @@
     auto dump_func_3 = [](int out_fd) {
         dprintf(out_fd, "C");
     };
-    pool.enqueueTask(/* task_name = */"1", dump_func_1, std::placeholders::_1);
-    pool.enqueueTask(/* task_name = */"2", dump_func_2, std::placeholders::_1);
-    pool.enqueueTask(/* task_name = */"3", dump_func_3, std::placeholders::_1);
+    setLogDuration(/* log_duration = */false);
+    dump_pool_->enqueueTaskWithFd(/* task_name = */"1", dump_func_1, std::placeholders::_1);
+    dump_pool_->enqueueTaskWithFd(/* task_name = */"2", dump_func_2, std::placeholders::_1);
+    dump_pool_->enqueueTaskWithFd(/* task_name = */"3", dump_func_3, std::placeholders::_1);
 
-    pool.waitForTask("1", "", out_fd_.get());
-    pool.waitForTask("2", "", out_fd_.get());
-    pool.waitForTask("3", "", out_fd_.get());
+    dump_pool_->waitForTask("1", "", out_fd_.get());
+    dump_pool_->waitForTask("2", "", out_fd_.get());
+    dump_pool_->waitForTask("3", "", out_fd_.get());
+    dump_pool_->shutdown();
 
     std::string result;
     ReadFileToString(out_path_, &result);
     EXPECT_THAT(result, StrEq("A\nB\nC\n"));
     EXPECT_THAT(getTempFileCounts(kTestDataPath), Eq(0));
-    pool.shutdown();
+}
+
+TEST_F(DumpPoolTest, EnqueueTask_withDurationLog) {
+    bool run_1 = false;
+    auto dump_func_1 = [&]() {
+        run_1 = true;
+    };
+
+    dump_pool_->enqueueTask(/* task_name = */"1", dump_func_1);
+    dump_pool_->waitForTask("1", "", out_fd_.get());
+    dump_pool_->shutdown();
+
+    std::string result;
+    ReadFileToString(out_path_, &result);
+    EXPECT_TRUE(run_1);
+    EXPECT_THAT(result, StrEq("------ 0.000s was the duration of '1' ------\n"));
+    EXPECT_THAT(getTempFileCounts(kTestDataPath), Eq(0));
 }