Index: content/test/content_browser_test_test.cc |
diff --git a/content/test/content_browser_test_test.cc b/content/test/content_browser_test_test.cc |
index f574f0ce3513403137bfe2bb44bbebecc2fb5964..051a1325117d6ae3cc83ab654d4bc8a862fd6330 100644 |
--- a/content/test/content_browser_test_test.cc |
+++ b/content/test/content_browser_test_test.cc |
@@ -6,23 +6,125 @@ |
#include "base/command_line.h" |
#include "base/location.h" |
+#include "base/process/launch.h" |
#include "base/single_thread_task_runner.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/test/launcher/test_launcher.h" |
#include "base/thread_task_runner_handle.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/render_process_host_observer.h" |
+#include "content/public/browser/web_contents.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/test/browser_test_utils.h" |
#include "content/public/test/content_browser_test_utils.h" |
+#include "content/public/test/test_launcher.h" |
#include "content/public/test/test_utils.h" |
#include "content/shell/browser/shell.h" |
+#include "content/shell/common/shell_switches.h" |
#include "testing/gtest/include/gtest/gtest.h" |
namespace content { |
+// On Android symbolization happens in one step after all the tests ran, so this |
+// test doesn't work there. |
+// TODO(mac): figure out why symbolization doesn't happen in the renderer. |
+#if !defined(OS_ANDROID) && !defined(OS_MACOSX) |
+ |
IN_PROC_BROWSER_TEST_F(ContentBrowserTest, MANUAL_ShouldntRun) { |
// Ensures that tests with MANUAL_ prefix don't run automatically. |
ASSERT_TRUE(false); |
} |
+class CrashObserver : public RenderProcessHostObserver { |
+ public: |
+ CrashObserver(const base::Closure& quit_closure) |
+ : quit_closure_(quit_closure) {} |
+ void RenderProcessExited(RenderProcessHost* host, |
+ base::TerminationStatus status, |
+ int exit_code) override { |
+ ASSERT_TRUE(status == base::TERMINATION_STATUS_PROCESS_CRASHED || |
+ status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION); |
+ quit_closure_.Run(); |
+ } |
+ |
+ private: |
+ base::Closure quit_closure_; |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, MANUAL_RendererCrash) { |
+ scoped_refptr<MessageLoopRunner> message_loop_runner = new MessageLoopRunner; |
+ CrashObserver crash_observer(message_loop_runner->QuitClosure()); |
+ shell()->web_contents()->GetRenderProcessHost()->AddObserver(&crash_observer); |
+ |
+ NavigateToURL(shell(), GURL("chrome:crash")); |
+ message_loop_runner->Run(); |
+} |
+ |
+// Tests that browser tests print the callstack when a child process crashes. |
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, RendererCrashCallStack) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ base::CommandLine new_test = |
+ base::CommandLine(base::CommandLine::ForCurrentProcess()->GetProgram()); |
+ new_test.AppendSwitchASCII(base::kGTestFilterFlag, |
+ "ContentBrowserTest.MANUAL_RendererCrash"); |
+ new_test.AppendSwitch(kRunManualTestsFlag); |
+ new_test.AppendSwitch(kSingleProcessTestsFlag); |
+ |
+#if defined(ADDRESS_SANITIZER) |
+ // Per https://www.chromium.org/developers/testing/addresssanitizer, there are |
+ // ASAN bots that run without the sandbox which this test will pass for. The |
+ // other ones pipe the output to a symbolizer script. |
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox)) { |
+ new_test.AppendSwitch(switches::kNoSandbox); |
+ } else { |
+ LOG(INFO) << "Couldn't run ContentBrowserTest.RendererCrashCallStack since " |
+ << "sandbox is enabled and ASAN requires piping to an external " |
+ << "script."; |
+ return; |
+ } |
+#endif |
+ |
+ std::string output; |
+ base::GetAppOutputAndError(new_test, &output); |
+ |
+ std::string crash_string = |
+ "content::RenderFrameImpl::PrepareRenderViewForNavigation"; |
+ |
+ if (output.find(crash_string) == std::string::npos) { |
+ GTEST_FAIL() << "Couldn't find\n" << crash_string << "\n in output\n " |
+ << output; |
+ } |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, MANUAL_BrowserCrash) { |
+ CHECK(false); |
+} |
+ |
+// Tests that browser tests print the callstack on asserts. |
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, BrowserCrashCallStack) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ base::CommandLine new_test = |
+ base::CommandLine(base::CommandLine::ForCurrentProcess()->GetProgram()); |
+ new_test.AppendSwitchASCII(base::kGTestFilterFlag, |
+ "ContentBrowserTest.MANUAL_BrowserCrash"); |
+ new_test.AppendSwitch(kRunManualTestsFlag); |
+ new_test.AppendSwitch(kSingleProcessTestsFlag); |
+ std::string output; |
+ base::GetAppOutputAndError(new_test, &output); |
+ |
+ std::string crash_string = |
+ "content::ContentBrowserTest_MANUAL_BrowserCrash_Test::RunTestOnMainThread"; |
+ |
+ if (output.find(crash_string) == std::string::npos) { |
+ GTEST_FAIL() << "Couldn't find\n" << crash_string << "\n in output\n " |
+ << output; |
+ } |
+} |
+ |
+#endif |
+ |
class ContentBrowserTestSanityTest : public ContentBrowserTest { |
public: |
void SetUpCommandLine(base::CommandLine* command_line) override { |
@@ -59,7 +161,7 @@ void CallbackChecker(bool* non_nested_task_ran) { |
} // namespace |
-IN_PROC_BROWSER_TEST_F(ContentBrowserTestSanityTest, NonNestableTask) { |
+IN_PROC_BROWSER_TEST_F(ContentBrowserTest, NonNestableTask) { |
bool non_nested_task_ran = false; |
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask( |
FROM_HERE, base::Bind(&CallbackChecker, &non_nested_task_ran)); |