void-packages/srcpkgs/electron7/files/patches/chromium-003-upstream_move_...

731 lines
28 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 726cbfcfaa521e9e5098829195a7d9a9c19ca391 Mon Sep 17 00:00:00 2001
From: Joe Mason <joenotcharles@google.com>
Date: Wed, 4 Dec 2019 18:15:36 +0000
Subject: [PATCH] Move child process log capture to a ChildProcessLogger class.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Update comments to clarify how the child process log interacts with
ScopedLogging.
Use the new class to capture logs in cleaner_test.cc,
secure_dll_loading_test.cc and proto_chrome_prompt_ipc_unittest.cc.
R=proberge
(cherry picked from commit 063600229fb7dc472ff66839ba2657bf99b98850)
Bug: 1030333
Change-Id: I88f538ff360bb8ed9da6743dc5d6c4b263af992c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1947986
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Reviewed-by: proberge <proberge@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#721184}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1949631
Reviewed-by: Joe Mason <joenotcharles@chromium.org>
Cr-Commit-Position: refs/branch-heads/3904@{#914}
Cr-Branched-From: 675968a8c657a3bd9c1c2c20c5d2935577bbc5e6-refs/heads/master@{#693954}
---
chrome/chrome_cleaner/ipc/BUILD.gn | 1 +
chrome/chrome_cleaner/ipc/ipc_test_util.cc | 98 +++----------------
chrome/chrome_cleaner/ipc/ipc_test_util.h | 17 ++--
.../ipc/proto_chrome_prompt_ipc_unittest.cc | 26 +++--
chrome/chrome_cleaner/test/BUILD.gn | 3 +
.../test/child_process_logger.cc | 90 +++++++++++++++++
.../test/child_process_logger.h | 62 ++++++++++++
chrome/chrome_cleaner/test/cleaner_test.cc | 14 ++-
.../test/secure_dll_loading_test.cc | 57 ++---------
9 files changed, 207 insertions(+), 161 deletions(-)
create mode 100644 chrome/chrome_cleaner/test/child_process_logger.cc
create mode 100644 chrome/chrome_cleaner/test/child_process_logger.h
diff --git a/chrome/chrome_cleaner/ipc/BUILD.gn b/chrome/chrome_cleaner/ipc/BUILD.gn
index 03fddfd8736e1..4d81803a24df6 100644
--- a/chrome/chrome_cleaner/ipc/BUILD.gn
+++ b/chrome/chrome_cleaner/ipc/BUILD.gn
@@ -77,6 +77,7 @@ source_set("ipc_test_util") {
"//base/test:test_support",
"//chrome/chrome_cleaner/ipc:sandbox",
"//chrome/chrome_cleaner/logging:common",
+ "//chrome/chrome_cleaner/test:test_util",
"//mojo/public/cpp/system",
"//sandbox/win:sandbox",
"//testing/gtest",
diff --git a/chrome/chrome_cleaner/ipc/ipc_test_util.cc b/chrome/chrome_cleaner/ipc/ipc_test_util.cc
index 0d03a6870fb07..ea2bb2145bfdd 100644
--- a/chrome/chrome_cleaner/ipc/ipc_test_util.cc
+++ b/chrome/chrome_cleaner/ipc/ipc_test_util.cc
@@ -12,14 +12,10 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/win/win_util.h"
@@ -34,11 +30,8 @@ constexpr char kMojoPipeTokenSwitch[] = "mojo-pipe-token";
class MojoSandboxSetupHooks : public SandboxSetupHooks {
public:
- explicit MojoSandboxSetupHooks(
- SandboxedParentProcess* parent_process,
- base::win::ScopedHandle child_stdout_write_handle)
- : parent_process_(parent_process),
- child_stdout_write_handle_(std::move(child_stdout_write_handle)) {}
+ explicit MojoSandboxSetupHooks(SandboxedParentProcess* parent_process)
+ : parent_process_(parent_process) {}
~MojoSandboxSetupHooks() override = default;
// SandboxSetupHooks
@@ -50,8 +43,7 @@ class MojoSandboxSetupHooks : public SandboxSetupHooks {
parent_process_->CreateMojoPipe(command_line, &handles_to_inherit);
for (HANDLE handle : handles_to_inherit)
policy->AddHandleToShare(handle);
- policy->SetStdoutHandle(child_stdout_write_handle_.Get());
- policy->SetStderrHandle(child_stdout_write_handle_.Get());
+ parent_process_->child_process_logger().UpdateSandboxPolicy(policy);
return RESULT_CODE_SUCCESS;
}
@@ -69,38 +61,6 @@ class MojoSandboxSetupHooks : public SandboxSetupHooks {
} // namespace
-namespace internal {
-
-void PrintChildProcessLogs(const base::FilePath& log_path) {
- if (log_path.empty()) {
- LOG(ERROR) << "Child process log path is empty";
- return;
- }
-
- if (!base::PathExists(log_path)) {
- LOG(ERROR) << "Child process log file doesn't exist";
- return;
- }
-
- // Collect the child process log file, and dump the contents, to help
- // debugging failures.
- std::string log_file_contents;
- if (!base::ReadFileToString(log_path, &log_file_contents)) {
- LOG(ERROR) << "Failed to read child process log file";
- return;
- }
-
- std::vector<base::StringPiece> lines =
- base::SplitStringPiece(log_file_contents, "\n", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- LOG(ERROR) << "Dumping child process logs";
- for (const auto& line : lines) {
- LOG(ERROR) << "Child process: " << line;
- }
-}
-
-} // namespace internal
-
ParentProcess::ParentProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner)
: command_line_(base::GetMultiProcessTestChildBaseCommandLine()),
mojo_task_runner_(mojo_task_runner) {}
@@ -158,36 +118,10 @@ bool ParentProcess::LaunchConnectedChildProcess(
const std::string& child_main_function,
base::TimeDelta timeout,
int32_t* exit_code) {
- // Adapted from
- // https://cs.chromium.org/chromium/src/sandbox/win/src/handle_inheritance_test.cc
- base::ScopedTempDir temp_dir;
- if (!temp_dir.CreateUniqueTempDir()) {
- PLOG(ERROR) << "Could not create temp dir for child stdout";
+ if (!child_process_logger_.Initialize())
return false;
- }
-
- base::FilePath temp_file_name;
- if (!CreateTemporaryFileInDir(temp_dir.GetPath(), &temp_file_name)) {
- PLOG(ERROR) << "Could not create temp file for child stdout";
- return false;
- }
-
- SECURITY_ATTRIBUTES attrs = {};
- attrs.nLength = sizeof(attrs);
- attrs.bInheritHandle = true;
-
- base::win::ScopedHandle child_stdout_write_handle(
- ::CreateFile(temp_file_name.value().c_str(), GENERIC_WRITE,
- FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
- &attrs, OPEN_EXISTING, 0, nullptr));
- if (!child_stdout_write_handle.IsValid()) {
- PLOG(ERROR) << "Could not open child stdout file";
- return false;
- }
-
- if (!PrepareAndLaunchTestChildProcess(child_main_function,
- std::move(child_stdout_write_handle))) {
- internal::PrintChildProcessLogs(temp_file_name);
+ if (!PrepareAndLaunchTestChildProcess(child_main_function)) {
+ child_process_logger_.DumpLogs();
return false;
}
@@ -201,31 +135,22 @@ bool ParentProcess::LaunchConnectedChildProcess(
DestroyImplOnIPCThread();
if (!success || *exit_code != 0) {
- internal::PrintChildProcessLogs(temp_file_name);
+ child_process_logger_.DumpLogs();
}
return success;
}
bool ParentProcess::PrepareAndLaunchTestChildProcess(
- const std::string& child_main_function,
- base::win::ScopedHandle child_stdout_write_handle) {
+ const std::string& child_main_function) {
base::LaunchOptions launch_options;
launch_options.handles_to_inherit = extra_handles_to_inherit_;
- launch_options.handles_to_inherit.push_back(child_stdout_write_handle.Get());
- launch_options.stdin_handle = INVALID_HANDLE_VALUE;
- launch_options.stdout_handle = child_stdout_write_handle.Get();
- launch_options.stderr_handle = child_stdout_write_handle.Get();
-
+ child_process_logger_.UpdateLaunchOptions(&launch_options);
CreateMojoPipe(&command_line_, &launch_options.handles_to_inherit);
base::Process child_process = base::SpawnMultiProcessTestChild(
child_main_function, command_line_, launch_options);
- // Now that it's been passed to the child process,
- // |child_stdout_write_handle| can be closed in this process as it goes out
- // of scope.
-
ConnectMojoPipe(std::move(child_process));
return true;
}
@@ -257,9 +182,8 @@ SandboxedParentProcess::SandboxedParentProcess(
SandboxedParentProcess::~SandboxedParentProcess() {}
bool SandboxedParentProcess::PrepareAndLaunchTestChildProcess(
- const std::string& child_main_function,
- base::win::ScopedHandle child_stdout_write_handle) {
- MojoSandboxSetupHooks hooks(this, std::move(child_stdout_write_handle));
+ const std::string& child_main_function) {
+ MojoSandboxSetupHooks hooks(this);
// This switch usage is copied from SpawnMultiProcessTestChild.
//
diff --git a/chrome/chrome_cleaner/ipc/ipc_test_util.h b/chrome/chrome_cleaner/ipc/ipc_test_util.h
index 1b2e5598ed52a..1526a42701353 100644
--- a/chrome/chrome_cleaner/ipc/ipc_test_util.h
+++ b/chrome/chrome_cleaner/ipc/ipc_test_util.h
@@ -14,9 +14,9 @@
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/time/time.h"
-#include "base/win/scoped_handle.h"
#include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h"
#include "chrome/chrome_cleaner/ipc/mojo_task_runner.h"
+#include "chrome/chrome_cleaner/test/child_process_logger.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -58,6 +58,10 @@ class ParentProcess : public base::RefCountedThreadSafe<ParentProcess> {
return extra_handles_to_inherit_;
}
+ const ChildProcessLogger& child_process_logger() const {
+ return child_process_logger_;
+ }
+
protected:
friend base::RefCountedThreadSafe<ParentProcess>;
virtual ~ParentProcess();
@@ -70,13 +74,13 @@ class ParentProcess : public base::RefCountedThreadSafe<ParentProcess> {
// as in the sandbox. Subclasses should call CreateMojoPipe before the
// subprocess is spawned and ConnectMojoPipe afterward.
virtual bool PrepareAndLaunchTestChildProcess(
- const std::string& child_main_function,
- base::win::ScopedHandle child_stdout_write_handle);
+ const std::string& child_main_function);
scoped_refptr<MojoTaskRunner> mojo_task_runner();
base::CommandLine command_line_;
base::HandlesToInheritVector extra_handles_to_inherit_;
+ ChildProcessLogger child_process_logger_;
private:
scoped_refptr<MojoTaskRunner> mojo_task_runner_;
@@ -96,8 +100,7 @@ class SandboxedParentProcess : public ParentProcess {
~SandboxedParentProcess() override;
bool PrepareAndLaunchTestChildProcess(
- const std::string& child_main_function,
- base::win::ScopedHandle child_stdout_write_handle) override;
+ const std::string& child_main_function) override;
};
class ChildProcess : public base::RefCountedThreadSafe<ChildProcess> {
@@ -143,10 +146,6 @@ class ChromePromptIPCTestErrorHandler : public ChromePromptIPC::ErrorHandler {
base::OnceClosure on_closed_after_done_;
};
-namespace internal {
-void PrintChildProcessLogs(const base::FilePath& log_file);
-} // namespace internal
-
} // namespace chrome_cleaner
#endif // CHROME_CHROME_CLEANER_IPC_IPC_TEST_UTIL_H_
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
index f867df58f96ea..e3ce2ab6c27fe 100644
--- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
+++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
@@ -5,7 +5,6 @@
#include <windows.h>
#include "base/command_line.h"
-#include "base/files/file_util.h"
#include "base/process/process.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
@@ -19,7 +18,7 @@
#include "base/win/win_util.h"
#include "chrome/chrome_cleaner/ipc/ipc_test_util.h"
#include "chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h"
-#include "chrome/chrome_cleaner/logging/scoped_logging.h"
+#include "chrome/chrome_cleaner/test/child_process_logger.h"
#include "components/chrome_cleaner/public/constants/constants.h"
#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h"
#include "components/chrome_cleaner/public/proto/chrome_prompt_for_tests.pb.h"
@@ -42,7 +41,6 @@ constexpr char kExpectedPromptResultSwitch[] = "expected-prompt-result";
constexpr char kExpectedChromeDisconnectPointSwitch[] =
"expected-parent-disconnected";
-constexpr base::char16 kLogSuffix[] = L"prompt-ipc-test";
constexpr base::char16 kInvalidUTF16String[] = {0xDC00, 0xD800, 0xD800, 0xDFFF,
0xDFFF, 0xDBFF, 0};
const base::FilePath kInvalidFilePath(kInvalidUTF16String);
@@ -421,8 +419,7 @@ class MockChrome {
// Gtest to log.
class ChildProcess {
public:
- ChildProcess()
- : scopped_logging_(std::make_unique<ScopedLogging>(kLogSuffix)) {
+ ChildProcess() {
mock_chrome_ = std::make_unique<MockChrome>(
ExtractHandleFromCommandLine(chrome_cleaner::kChromeReadHandleSwitch),
ExtractHandleFromCommandLine(chrome_cleaner::kChromeWriteHandleSwitch));
@@ -571,7 +568,6 @@ class ChildProcess {
private:
std::unique_ptr<MockChrome> mock_chrome_;
- std::unique_ptr<ScopedLogging> scopped_logging_;
ChromeDisconnectPoint expected_disconnect_point_ =
ChromeDisconnectPoint::kUnspecified;
@@ -603,6 +599,9 @@ class ProtoChromePromptIPCTest
class ParentProcess {
public:
bool Initialize() {
+ if (!child_process_logger_.Initialize())
+ return false;
+
// Inject the flags related to the the config in the command line.
test_config_.EnhanceCommandLine(&command_line_);
@@ -631,14 +630,13 @@ class ParentProcess {
}
void Run() {
- // Delete the child process log file if existing.
- const base::FilePath log_path = ScopedLogging::GetLogFilePath(kLogSuffix);
- ASSERT_TRUE(base::DeleteFile(log_path, false))
- << "Can't delete log file from previous run: " << log_path.value();
+ child_process_logger_.UpdateLaunchOptions(&launch_options_);
// Pass the command to the child process and launch the child process.
base::Process child_process = base::SpawnMultiProcessTestChild(
"ProtoChromePromptIPCClientMain", command_line_, launch_options_);
+ if (!child_process.IsRunning())
+ child_process_logger_.DumpLogs();
ASSERT_TRUE(child_process.IsRunning());
// Close our references to the handles as they are now handled by the child
@@ -705,10 +703,8 @@ class ParentProcess {
EXPECT_EQ(expected_exit_code, rv);
- if (!success || rv != 0) {
- internal::PrintChildProcessLogs(
- ScopedLogging::GetLogFilePath(kLogSuffix));
- }
+ if (!success || rv != 0)
+ child_process_logger_.DumpLogs();
}
TestConfig& GetTestConfig() { return test_config_; }
@@ -732,6 +728,8 @@ class ParentProcess {
// Blocks until we receive the response from Chrome or an error occurs.
base::RunLoop main_runloop_;
bool error_occurred_ = false;
+
+ ChildProcessLogger child_process_logger_;
};
// This contains calls to the chrome_cleaner_ipc implementation.
diff --git a/chrome/chrome_cleaner/test/BUILD.gn b/chrome/chrome_cleaner/test/BUILD.gn
index 118454c2bdcd2..4b053fdcaf182 100644
--- a/chrome/chrome_cleaner/test/BUILD.gn
+++ b/chrome/chrome_cleaner/test/BUILD.gn
@@ -148,6 +148,8 @@ source_set("test_util") {
testonly = true
sources = [
+ "child_process_logger.cc",
+ "child_process_logger.h",
"file_remover_test_util.cc",
"file_remover_test_util.h",
"reboot_deletion_helper.cc",
@@ -228,6 +230,7 @@ source_set("integration_test_sources") {
"//chrome/chrome_cleaner/os:common_os",
"//chrome/chrome_cleaner/pup_data:pup_data_base",
"//chrome/chrome_cleaner/pup_data:test_uws",
+ "//chrome/chrome_cleaner/test:test_util",
"//chrome/chrome_cleaner/zip_archiver:common",
"//components/chrome_cleaner/public/constants",
"//components/chrome_cleaner/test:test_name_helper",
diff --git a/chrome/chrome_cleaner/test/child_process_logger.cc b/chrome/chrome_cleaner/test/child_process_logger.cc
new file mode 100644
index 0000000000000..9f4836267aea6
--- /dev/null
+++ b/chrome/chrome_cleaner/test/child_process_logger.cc
@@ -0,0 +1,90 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/chrome_cleaner/test/child_process_logger.h"
+
+#include <vector>
+
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+
+namespace chrome_cleaner {
+
+ChildProcessLogger::ChildProcessLogger() = default;
+
+ChildProcessLogger::~ChildProcessLogger() = default;
+
+bool ChildProcessLogger::Initialize() {
+ // Adapted from
+ // https://cs.chromium.org/chromium/src/sandbox/win/src/handle_inheritance_test.cc
+ if (!temp_dir_.CreateUniqueTempDir()) {
+ PLOG(ERROR) << "Could not create temp dir for child stdout";
+ return false;
+ }
+
+ if (!CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file_name_)) {
+ PLOG(ERROR) << "Could not create temp file for child stdout";
+ return false;
+ }
+
+ SECURITY_ATTRIBUTES attrs = {};
+ attrs.nLength = sizeof(attrs);
+ attrs.bInheritHandle = true;
+
+ child_stdout_handle_.Set(
+ ::CreateFile(temp_file_name_.value().c_str(), GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
+ &attrs, OPEN_EXISTING, 0, nullptr));
+ if (!child_stdout_handle_.IsValid()) {
+ PLOG(ERROR) << "Could not open child stdout file";
+ return false;
+ }
+
+ return true;
+}
+
+void ChildProcessLogger::UpdateLaunchOptions(
+ base::LaunchOptions* options) const {
+ DCHECK(child_stdout_handle_.IsValid());
+ options->handles_to_inherit.push_back(child_stdout_handle_.Get());
+ options->stdin_handle = INVALID_HANDLE_VALUE;
+ options->stdout_handle = child_stdout_handle_.Get();
+ options->stderr_handle = child_stdout_handle_.Get();
+}
+
+void ChildProcessLogger::UpdateSandboxPolicy(
+ sandbox::TargetPolicy* policy) const {
+ DCHECK(child_stdout_handle_.IsValid());
+ policy->SetStdoutHandle(child_stdout_handle_.Get());
+ policy->SetStderrHandle(child_stdout_handle_.Get());
+}
+
+void ChildProcessLogger::DumpLogs() const {
+ DCHECK(!temp_file_name_.empty());
+
+ if (!base::PathExists(temp_file_name_)) {
+ LOG(ERROR) << "Child process log file doesn't exist";
+ return;
+ }
+
+ // Collect the child process log file, and dump the contents, to help
+ // debugging failures.
+ std::string log_file_contents;
+ if (!base::ReadFileToString(temp_file_name_, &log_file_contents)) {
+ LOG(ERROR) << "Failed to read child process log file";
+ return;
+ }
+
+ std::vector<base::StringPiece> lines =
+ base::SplitStringPiece(log_file_contents, "\n", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+ LOG(ERROR) << "Dumping child process logs";
+ for (const auto& line : lines) {
+ LOG(ERROR) << "Child process: " << line;
+ }
+}
+
+} // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/test/child_process_logger.h b/chrome/chrome_cleaner/test/child_process_logger.h
new file mode 100644
index 0000000000000..215fa911d7899
--- /dev/null
+++ b/chrome/chrome_cleaner/test/child_process_logger.h
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_CHROME_CLEANER_TEST_CHILD_PROCESS_LOGGER_H_
+#define CHROME_CHROME_CLEANER_TEST_CHILD_PROCESS_LOGGER_H_
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/process/launch.h"
+#include "base/win/scoped_handle.h"
+#include "sandbox/win/src/sandbox_policy.h"
+
+namespace chrome_cleaner {
+
+// Redirects stdin and stdout of a child process to a temp file. Tests that
+// spawn children can add the contents of the temp file to the test output.
+//
+// Note that if the child process sets up ScopedLogging, ERROR and FATAL level
+// logs will still be captured by this, but other logs will start going to the
+// ScopedLogging log file. test_main.cc sets up ScopedLogging so usually this
+// class will capture:
+//
+// 1. All log lines from before the ScopedLogging constructor.
+// 2. ERROR and FATAL log lines from after that.
+// 3. stdout and stderr output that doesn't go through the logging system.
+// 4. Stack traces from any crashes.
+//
+// This should be all that's needed to diagnose errors in tests.
+class ChildProcessLogger {
+ public:
+ ChildProcessLogger();
+ ~ChildProcessLogger();
+
+ // Creates a temp file for child processes to log to. Logs an error and
+ // returns false on failure.
+ bool Initialize();
+
+ // Updates |options| to direct the child stdout and stderr to the temp file.
+ // For use with base::LaunchProcess and base::SpawnMultiProcessTestChild.
+ void UpdateLaunchOptions(base::LaunchOptions* options) const;
+
+ // Updates |policy| to direct the child stdout and stderr to the temp file.
+ // For use with sandbox::BrokerServices::SpawnTarget.
+ void UpdateSandboxPolicy(sandbox::TargetPolicy* policy) const;
+
+ // Writes every line in the temp file using LOG(ERROR) so that all lines are
+ // captured in the test suite output. The class-level comment above describes
+ // which log lines from the child will be captured.
+ void DumpLogs() const;
+
+ private:
+ ChildProcessLogger(const ChildProcessLogger& other) = delete;
+ ChildProcessLogger& operator=(const ChildProcessLogger& other) = delete;
+
+ base::ScopedTempDir temp_dir_;
+ base::FilePath temp_file_name_;
+ base::win::ScopedHandle child_stdout_handle_;
+};
+
+} // namespace chrome_cleaner
+
+#endif // CHROME_CHROME_CLEANER_TEST_CHILD_PROCESS_LOGGER_H_
diff --git a/chrome/chrome_cleaner/test/cleaner_test.cc b/chrome/chrome_cleaner/test/cleaner_test.cc
index d6df17e3516f1..f778103bfdad3 100644
--- a/chrome/chrome_cleaner/test/cleaner_test.cc
+++ b/chrome/chrome_cleaner/test/cleaner_test.cc
@@ -24,6 +24,7 @@
#include "chrome/chrome_cleaner/os/pre_fetched_paths.h"
#include "chrome/chrome_cleaner/pup_data/pup_data.h"
#include "chrome/chrome_cleaner/pup_data/test_uws.h"
+#include "chrome/chrome_cleaner/test/child_process_logger.h"
#include "chrome/chrome_cleaner/test/test_util.h"
#include "chrome/chrome_cleaner/zip_archiver/sandboxed_zip_archiver.h"
#include "components/chrome_cleaner/public/constants/constants.h"
@@ -311,8 +312,14 @@ class CleanerTest
void ExpectExitCode(const base::CommandLine& command_line,
int expected_exit_code) {
- base::Process process(
- base::LaunchProcess(command_line, base::LaunchOptions()));
+ chrome_cleaner::ChildProcessLogger logger;
+ ASSERT_TRUE(logger.Initialize());
+
+ base::LaunchOptions options;
+ logger.UpdateLaunchOptions(&options);
+ base::Process process(base::LaunchProcess(command_line, options));
+ if (!process.IsValid())
+ logger.DumpLogs();
ASSERT_TRUE(process.IsValid());
int exit_code = -1;
@@ -320,7 +327,8 @@ class CleanerTest
base::TimeDelta::FromMinutes(10), &exit_code);
EXPECT_TRUE(exited_within_timeout);
EXPECT_EQ(expected_exit_code, exit_code);
-
+ if (!exited_within_timeout || expected_exit_code != exit_code)
+ logger.DumpLogs();
if (!exited_within_timeout)
process.Terminate(/*exit_code=*/-1, /*wait=*/false);
}
diff --git a/chrome/chrome_cleaner/test/secure_dll_loading_test.cc b/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
index fe10c44346b5e..92e2db19fde6c 100644
--- a/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
+++ b/chrome/chrome_cleaner/test/secure_dll_loading_test.cc
@@ -8,22 +8,17 @@
#include <memory>
#include <set>
-#include <string>
#include <vector>
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
@@ -32,54 +27,16 @@
#include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h"
#include "chrome/chrome_cleaner/os/inheritable_event.h"
#include "chrome/chrome_cleaner/os/process.h"
+#include "chrome/chrome_cleaner/test/child_process_logger.h"
#include "chrome/chrome_cleaner/test/test_util.h"
#include "components/chrome_cleaner/public/constants/constants.h"
#include "components/chrome_cleaner/test/test_name_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace {
-
-void PrintChildProcessLogs(const base::FilePath& log_dir,
- base::StringPiece16 file_name) {
- base::string16 base_name;
- if (file_name == L"software_reporter_tool") {
- base_name = L"software_reporter_tool";
- } else if (file_name == L"chrome_cleanup_tool") {
- base_name = L"chrome_cleanup";
- } else {
- LOG(ERROR) << "Unknown file name " << file_name.data();
- return;
- }
-
- base::FilePath log_path = log_dir.Append(base_name).AddExtension(L"log");
-
- if (!base::PathExists(log_path)) {
- LOG(ERROR) << "Child process log file doesn't exist";
- return;
- }
-
- // Collect the child process log file, and dump the contents, to help
- // debugging failures.
- std::string log_file_contents;
- if (!base::ReadFileToString(log_path, &log_file_contents)) {
- LOG(ERROR) << "Failed to read child process log file";
- return;
- }
-
- std::vector<base::StringPiece> lines =
- base::SplitStringPiece(log_file_contents, "\n", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- LOG(ERROR) << "Dumping child process logs";
- for (const auto& line : lines) {
- LOG(ERROR) << "Child process: " << line;
- }
-}
-
-} // namespace
-
class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
protected:
void SetUp() override {
+ ASSERT_TRUE(child_process_logger_.Initialize());
base::FilePath out_dir;
ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &out_dir));
exe_path_ = out_dir.Append(GetParam() + L".exe");
@@ -104,8 +61,6 @@ class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
base::NumberToString16(
base::win::HandleToUint32(init_done_notifier->handle())));
command_line.AppendSwitch(chrome_cleaner::kLoadEmptyDLLSwitch);
- command_line.AppendSwitchPath(chrome_cleaner::kTestLoggingPathSwitch,
- log_dir.GetPath());
#if !BUILDFLAG(IS_OFFICIAL_CHROME_CLEANER_BUILD)
if (disable_secure_dll_loading)
@@ -121,7 +76,12 @@ class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
base::LaunchOptions options;
options.handles_to_inherit.push_back(init_done_notifier->handle());
+ child_process_logger_.UpdateLaunchOptions(&options);
base::Process process = base::LaunchProcess(command_line, options);
+ if (!process.IsValid()) {
+ child_process_logger_.DumpLogs();
+ return process;
+ }
// Make sure the process has finished its initialization (including loading
// DLLs). Also check the process handle in case it exits with an error.
@@ -136,7 +96,7 @@ class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
PLOG_IF(ERROR, !::GetExitCodeProcess(process.Handle(), &exit_code));
ADD_FAILURE() << "Process exited with " << exit_code
<< " before signalling init_done_notifier";
- PrintChildProcessLogs(log_dir.GetPath(), GetParam());
+ child_process_logger_.DumpLogs();
} else {
EXPECT_EQ(wait_result, WAIT_OBJECT_0);
}
@@ -157,6 +117,7 @@ class SecureDLLLoadingTest : public testing::TestWithParam<base::string16> {
}
private:
+ chrome_cleaner::ChildProcessLogger child_process_logger_;
base::FilePath exe_path_;
base::FilePath empty_dll_path_;
};