Index: base/trace_event/memory_dump_manager_unittest.cc |
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc |
index 15ae42444d1e0b0510e1c0fb13eb46eea8ee4ea7..f0ef18b3b3628f2d12c78deaba37acae3d954987 100644 |
--- a/base/trace_event/memory_dump_manager_unittest.cc |
+++ b/base/trace_event/memory_dump_manager_unittest.cc |
@@ -9,6 +9,7 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/run_loop.h" |
#include "base/strings/stringprintf.h" |
+#include "base/synchronization/waitable_event.h" |
#include "base/test/test_io_thread.h" |
#include "base/thread_task_runner_handle.h" |
#include "base/threading/thread.h" |
@@ -97,6 +98,8 @@ class MemoryDumpManagerTest : public testing::Test { |
TraceLog::DeleteForTesting(); |
} |
+ // Turns a Closure into a MemoryDumpCallback, keeping track of the callback |
+ // result and taking care of posting the closure on the correct task runner. |
void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, |
Closure closure, |
uint64 dump_guid, |
@@ -111,6 +114,16 @@ class MemoryDumpManagerTest : public testing::Test { |
mdm_->Initialize(delegate_.get(), is_coordinator); |
} |
+ void RequestGlobalDumpAndWait(MemoryDumpType dump_type, |
+ MemoryDumpLevelOfDetail level_of_detail) { |
+ RunLoop run_loop; |
+ MemoryDumpCallback callback = |
+ Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
+ MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
+ mdm_->RequestGlobalDump(dump_type, level_of_detail, callback); |
+ run_loop.Run(); |
+ } |
+ |
void EnableTracingWithLegacyCategories(const char* category) { |
TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), |
TraceLog::RECORDING_MODE); |
@@ -153,8 +166,8 @@ TEST_F(MemoryDumpManagerTest, SingleDumper) { |
EnableTracingWithLegacyCategories("foobar-but-not-memory"); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(0); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
// Now repeat enabling the memory category and check that the dumper is |
@@ -163,8 +176,8 @@ TEST_F(MemoryDumpManagerTest, SingleDumper) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(3); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
for (int i = 0; i < 3; ++i) |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
mdm_->UnregisterDumpProvider(&mdp); |
@@ -174,8 +187,8 @@ TEST_F(MemoryDumpManagerTest, SingleDumper) { |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
TraceLog::GetInstance()->SetDisabled(); |
} |
@@ -189,8 +202,8 @@ TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)).WillOnce(Return(true)); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
mdm_->UnregisterDumpProvider(&mdp); |
@@ -200,8 +213,8 @@ TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).WillOnce(Return(true)); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::LIGHT); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::LIGHT); |
DisableTracing(); |
mdm_->UnregisterDumpProvider(&mdp); |
} |
@@ -232,9 +245,10 @@ TEST_F(MemoryDumpManagerTest, SharedSessionState) { |
return true; |
})); |
- for (int i = 0; i < 2; ++i) |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ for (int i = 0; i < 2; ++i) { |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
+ } |
DisableTracing(); |
} |
@@ -251,8 +265,8 @@ TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true)); |
EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
// Invert: enable mdp1 and disable mdp2. |
@@ -262,8 +276,8 @@ TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true)); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
// Enable both mdp1 and mdp2. |
@@ -272,8 +286,8 @@ TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true)); |
EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true)); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
} |
@@ -289,8 +303,8 @@ TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true)); |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
} |
@@ -300,8 +314,8 @@ TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
} |
@@ -312,8 +326,8 @@ TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
} |
@@ -325,8 +339,8 @@ TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true)); |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
DisableTracing(); |
} |
} |
@@ -366,18 +380,9 @@ TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { |
while (!threads.empty()) { |
last_callback_success_ = false; |
- { |
- RunLoop run_loop; |
- MemoryDumpCallback callback = |
- Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
- MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
- EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED, callback); |
- // This nested message loop (|run_loop|) will quit if and only if the |
- // |callback| passed to RequestGlobalDump() is invoked. |
- run_loop.Run(); |
- } |
+ EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
EXPECT_TRUE(last_callback_success_); |
// Unregister a MDP and destroy one thread at each iteration to check the |
@@ -427,8 +432,8 @@ TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { |
.WillOnce(Return(false)); |
for (int i = 0; i < kNumDumps; i++) { |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
} |
DisableTracing(); |
@@ -463,8 +468,8 @@ TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
.WillRepeatedly(Return(true)); |
for (int i = 0; i < 4; i++) { |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
} |
DisableTracing(); |
@@ -499,8 +504,8 @@ TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
.WillRepeatedly(Return(true)); |
for (int i = 0; i < 4; i++) { |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
} |
DisableTracing(); |
@@ -520,7 +525,6 @@ TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { |
} |
int on_memory_dump_call_count = 0; |
- RunLoop run_loop; |
// When OnMemoryDump is called on either of the dump providers, it will |
// unregister the other one. |
@@ -545,18 +549,10 @@ TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { |
} |
last_callback_success_ = false; |
- MemoryDumpCallback callback = |
- Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
- MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
- |
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
- |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED, callback); |
- |
- run_loop.Run(); |
- |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
ASSERT_EQ(1, on_memory_dump_call_count); |
ASSERT_EQ(true, last_callback_success_); |
@@ -574,15 +570,8 @@ TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { |
EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
last_callback_success_ = true; |
- { |
- RunLoop run_loop; |
- MemoryDumpCallback callback = |
- Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
- MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED, callback); |
- run_loop.Run(); |
- } |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
EXPECT_FALSE(last_callback_success_); |
} |
@@ -598,13 +587,8 @@ TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { |
{ |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(0); |
- RunLoop run_loop; |
- MemoryDumpCallback callback = |
- Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
- MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED, callback); |
- run_loop.Run(); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
EXPECT_FALSE(last_callback_success_); |
} |
@@ -614,13 +598,8 @@ TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { |
EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); |
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
InitializeMemoryDumpManager(false /* is_coordinator */); |
- RunLoop run_loop; |
- MemoryDumpCallback callback = |
- Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
- MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
- mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
- MemoryDumpLevelOfDetail::DETAILED, callback); |
- run_loop.Run(); |
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED); |
EXPECT_TRUE(last_callback_success_); |
} |
DisableTracing(); |
@@ -718,5 +697,54 @@ TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { |
DisableTracing(); |
} |
+TEST_F(MemoryDumpManagerTest, DisableTracingWhileDumping) { |
+ base::WaitableEvent tracing_disabled_event(false, false); |
+ InitializeMemoryDumpManager(false /* is_coordinator */); |
+ |
+ // Register a bound dump provider. |
+ scoped_ptr<Thread> mdp_thread(new Thread("test thread")); |
+ mdp_thread->Start(); |
+ MockMemoryDumpProvider mdp_with_affinity; |
+ RegisterDumpProvider(&mdp_with_affinity, mdp_thread->task_runner()); |
+ |
+ // Register also an unbound dump provider. Unbound dump providers are always |
+ // invoked after bound ones. |
+ MockMemoryDumpProvider unbound_mdp; |
+ RegisterDumpProvider(&unbound_mdp); |
+ |
+ EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
+ EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
+ EXPECT_CALL(mdp_with_affinity, OnMemoryDump(_, _)) |
+ .Times(1) |
+ .WillOnce( |
+ Invoke([&tracing_disabled_event](const MemoryDumpArgs&, |
+ ProcessMemoryDump* pmd) -> bool { |
+ tracing_disabled_event.Wait(); |
+ |
+ // At this point tracing has been disabled and the |
+ // MemoryDumpManager.dump_thread_ has been shut down. |
+ return true; |
+ })); |
+ |
+ // |unbound_mdp| should never be invoked because the thread for unbound dump |
+ // providers has been shutdown in the meanwhile. |
+ EXPECT_CALL(unbound_mdp, OnMemoryDump(_, _)).Times(0); |
+ |
+ last_callback_success_ = true; |
+ RunLoop run_loop; |
+ MemoryDumpCallback callback = |
+ Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
+ MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
+ mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
+ MemoryDumpLevelOfDetail::DETAILED, callback); |
+ DisableTracing(); |
+ tracing_disabled_event.Signal(); |
+ run_loop.Run(); |
+ |
+ // The RequestGlobalMemoryDump() should be NACK-ed because one of the |
petrcermak
2015/10/30 17:43:04
nit: I'd drop the definite article at the beginnin
Primiano Tucci (use gerrit)
2015/11/02 10:22:23
Done.
|
+ // threads did die before we had a chance to PostTask onto them. |
petrcermak
2015/10/30 17:43:04
nit: s/did die/died/ (unless you are doing it for
Primiano Tucci (use gerrit)
2015/11/02 10:22:23
Done.
|
+ EXPECT_FALSE(last_callback_success_); |
+} |
+ |
} // namespace trace_event |
} // namespace base |