| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "base/bind.h" | 
 |    6 #include "base/command_line.h" | 
 |    7 #include "base/run_loop.h" | 
 |    8 #include "base/thread_task_runner_handle.h" | 
 |    9 #include "base/trace_event/memory_dump_manager.h" | 
 |   10 #include "base/trace_event/memory_dump_provider.h" | 
 |   11 #include "base/trace_event/memory_dump_request_args.h" | 
 |   12 #include "content/public/browser/tracing_controller.h" | 
 |   13 #include "content/public/common/content_switches.h" | 
 |   14 #include "content/public/test/browser_test_utils.h" | 
 |   15 #include "content/public/test/content_browser_test.h" | 
 |   16 #include "content/public/test/content_browser_test_utils.h" | 
 |   17 #include "content/shell/browser/shell.h" | 
 |   18 #include "testing/gmock/include/gmock/gmock.h" | 
 |   19  | 
 |   20 using base::trace_event::MemoryDumpArgs; | 
 |   21 using base::trace_event::MemoryDumpManager; | 
 |   22 using base::trace_event::MemoryDumpType; | 
 |   23 using base::trace_event::ProcessMemoryDump; | 
 |   24 using testing::_; | 
 |   25 using testing::Return; | 
 |   26  | 
 |   27 namespace content { | 
 |   28  | 
 |   29 // A mock dump provider, used to check that dump requests actually end up | 
 |   30 // creating memory dumps. | 
 |   31 class MockDumpProvider : public base::trace_event::MemoryDumpProvider { | 
 |   32  public: | 
 |   33   MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args, | 
 |   34                                   ProcessMemoryDump* pmd)); | 
 |   35 }; | 
 |   36  | 
 |   37 class MemoryTracingTest : public ContentBrowserTest { | 
 |   38  public: | 
 |   39   void DoRequestGlobalDump(const base::trace_event::MemoryDumpCallback& cb) { | 
 |   40     MemoryDumpArgs dump_args = { MemoryDumpArgs::LevelOfDetail::HIGH }; | 
 |   41     MemoryDumpManager::GetInstance()->RequestGlobalDump( | 
 |   42         MemoryDumpType::EXPLICITLY_TRIGGERED, dump_args, cb); | 
 |   43   } | 
 |   44  | 
 |   45   // Used as callback argument for MemoryDumpManager::RequestGlobalDump(): | 
 |   46   void OnGlobalMemoryDumpDone( | 
 |   47       scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 
 |   48       base::Closure closure, | 
 |   49       uint64 dump_guid, | 
 |   50       bool success) { | 
 |   51     // Make sure we run the RunLoop closure on the same thread that originated | 
 |   52     // the run loop (which is the IN_PROC_BROWSER_TEST_F main thread). | 
 |   53     if (!task_runner->RunsTasksOnCurrentThread()) { | 
 |   54       task_runner->PostTask( | 
 |   55           FROM_HERE, base::Bind(&MemoryTracingTest::OnGlobalMemoryDumpDone, | 
 |   56                                 base::Unretained(this), task_runner, closure, | 
 |   57                                 dump_guid, success)); | 
 |   58       return; | 
 |   59     } | 
 |   60     ++callback_call_count_; | 
 |   61     last_callback_dump_guid_ = dump_guid; | 
 |   62     last_callback_success_ = success; | 
 |   63     closure.Run(); | 
 |   64   } | 
 |   65  | 
 |   66  protected: | 
 |   67   void SetUp() override { | 
 |   68     callback_call_count_ = 0; | 
 |   69     last_callback_dump_guid_ = 0; | 
 |   70     last_callback_success_ = false; | 
 |   71     MemoryDumpManager::GetInstance()->Initialize(); | 
 |   72     mock_dump_provider_.reset(new MockDumpProvider()); | 
 |   73     MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 
 |   74         mock_dump_provider_.get()); | 
 |   75     ContentBrowserTest::SetUp(); | 
 |   76   } | 
 |   77  | 
 |   78   void TearDown() override { | 
 |   79     MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 
 |   80         mock_dump_provider_.get()); | 
 |   81     mock_dump_provider_.reset(); | 
 |   82     ContentBrowserTest::TearDown(); | 
 |   83   } | 
 |   84  | 
 |   85   void EnableMemoryTracing() { | 
 |   86     base::RunLoop run_loop; | 
 |   87     std::string category_filter = MemoryDumpManager::kTraceCategoryForTesting; | 
 |   88     base::trace_event::TraceConfig trace_config(category_filter, ""); | 
 |   89     bool success = TracingController::GetInstance()->EnableRecording( | 
 |   90       trace_config, run_loop.QuitClosure()); | 
 |   91     EXPECT_TRUE(success); | 
 |   92     run_loop.Run(); | 
 |   93   } | 
 |   94  | 
 |   95   void DisableTracing() { | 
 |   96     bool success = TracingController::GetInstance()->DisableRecording(NULL); | 
 |   97     EXPECT_TRUE(success); | 
 |   98     base::RunLoop().RunUntilIdle(); | 
 |   99   } | 
 |  100  | 
 |  101   void RequestGlobalDumpAndWait(bool from_renderer_thread) { | 
 |  102     base::RunLoop run_loop; | 
 |  103     base::trace_event::MemoryDumpCallback callback = base::Bind( | 
 |  104         &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this), | 
 |  105         base::ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); | 
 |  106     if (from_renderer_thread) { | 
 |  107       PostTaskToInProcessRendererAndWait( | 
 |  108           base::Bind(&MemoryTracingTest::DoRequestGlobalDump, | 
 |  109                      base::Unretained(this), callback)); | 
 |  110     } else { | 
 |  111       DoRequestGlobalDump(callback); | 
 |  112     } | 
 |  113     run_loop.Run(); | 
 |  114   } | 
 |  115  | 
 |  116   void Navigate(Shell* shell) { | 
 |  117     NavigateToURL(shell, GetTestUrl("", "title.html")); | 
 |  118   } | 
 |  119  | 
 |  120   base::Closure on_memory_dump_complete_closure_; | 
 |  121   scoped_ptr<MockDumpProvider> mock_dump_provider_; | 
 |  122   uint32 callback_call_count_; | 
 |  123   uint64 last_callback_dump_guid_; | 
 |  124   bool last_callback_success_; | 
 |  125 }; | 
 |  126  | 
 |  127 class SingleProcessMemoryTracingTest : public MemoryTracingTest { | 
 |  128  public: | 
 |  129   SingleProcessMemoryTracingTest() {} | 
 |  130  | 
 |  131   void SetUpCommandLine(base::CommandLine* command_line) override { | 
 |  132     command_line->AppendSwitch(switches::kSingleProcess); | 
 |  133   } | 
 |  134 }; | 
 |  135  | 
 |  136 // Checks that a memory dump initiated from a the main browser thread ends up in | 
 |  137 // a single dump even in single process mode. | 
 |  138 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, | 
 |  139                        BrowserInitiatedSingleDump) { | 
 |  140   Navigate(shell()); | 
 |  141  | 
 |  142   EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); | 
 |  143  | 
 |  144   EnableMemoryTracing(); | 
 |  145   RequestGlobalDumpAndWait(false /* from_renderer_thread */); | 
 |  146   EXPECT_EQ(1u, callback_call_count_); | 
 |  147   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  148   EXPECT_TRUE(last_callback_success_); | 
 |  149   DisableTracing(); | 
 |  150 } | 
 |  151  | 
 |  152 // Checks that a memory dump initiated from a renderer thread ends up in a | 
 |  153 // single dump even in single process mode. | 
 |  154 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, | 
 |  155                        RendererInitiatedSingleDump) { | 
 |  156   Navigate(shell()); | 
 |  157  | 
 |  158   EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); | 
 |  159  | 
 |  160   EnableMemoryTracing(); | 
 |  161   RequestGlobalDumpAndWait(true /* from_renderer_thread */); | 
 |  162   EXPECT_EQ(1u, callback_call_count_); | 
 |  163   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  164   EXPECT_TRUE(last_callback_success_); | 
 |  165   DisableTracing(); | 
 |  166 } | 
 |  167  | 
 |  168 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, ManyInterleavedDumps) { | 
 |  169   Navigate(shell()); | 
 |  170  | 
 |  171   EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)) | 
 |  172       .Times(4) | 
 |  173       .WillRepeatedly(Return(true)); | 
 |  174  | 
 |  175   EnableMemoryTracing(); | 
 |  176  | 
 |  177   RequestGlobalDumpAndWait(true /* from_renderer_thread */); | 
 |  178   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  179   EXPECT_TRUE(last_callback_success_); | 
 |  180  | 
 |  181   RequestGlobalDumpAndWait(false /* from_renderer_thread */); | 
 |  182   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  183   EXPECT_TRUE(last_callback_success_); | 
 |  184  | 
 |  185   RequestGlobalDumpAndWait(false /* from_renderer_thread */); | 
 |  186   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  187   EXPECT_TRUE(last_callback_success_); | 
 |  188  | 
 |  189   RequestGlobalDumpAndWait(true /* from_renderer_thread */); | 
 |  190   EXPECT_EQ(4u, callback_call_count_); | 
 |  191   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  192   EXPECT_TRUE(last_callback_success_); | 
 |  193  | 
 |  194   DisableTracing(); | 
 |  195 } | 
 |  196  | 
 |  197 // Checks that a memory dump initiated from a the main browser thread ends up in | 
 |  198 // a successful dump. | 
 |  199 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, BrowserInitiatedDump) { | 
 |  200   Navigate(shell()); | 
 |  201  | 
 |  202   EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); | 
 |  203  | 
 |  204   EnableMemoryTracing(); | 
 |  205   RequestGlobalDumpAndWait(false /* from_renderer_thread */); | 
 |  206   EXPECT_EQ(1u, callback_call_count_); | 
 |  207   EXPECT_NE(0u, last_callback_dump_guid_); | 
 |  208   EXPECT_TRUE(last_callback_success_); | 
 |  209   DisableTracing(); | 
 |  210 } | 
 |  211  | 
 |  212 }  // namespace content | 
| OLD | NEW |