Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(630)

Side by Side Diff: base/trace_event/memory_dump_manager_unittest.cc

Issue 2582453002: [tracing] Implement polling in MemoryDumpManager (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/trace_event/memory_dump_manager.h" 5 #include "base/trace_event/memory_dump_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/memory/ref_counted_memory.h" 14 #include "base/memory/ref_counted_memory.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/synchronization/waitable_event.h" 18 #include "base/synchronization/waitable_event.h"
19 #include "base/test/sequenced_worker_pool_owner.h" 19 #include "base/test/sequenced_worker_pool_owner.h"
20 #include "base/test/test_io_thread.h" 20 #include "base/test/test_io_thread.h"
21 #include "base/test/trace_event_analyzer.h" 21 #include "base/test/trace_event_analyzer.h"
22 #include "base/threading/platform_thread.h" 22 #include "base/threading/platform_thread.h"
23 #include "base/threading/sequenced_task_runner_handle.h" 23 #include "base/threading/sequenced_task_runner_handle.h"
24 #include "base/threading/sequenced_worker_pool.h" 24 #include "base/threading/sequenced_worker_pool.h"
25 #include "base/threading/thread.h" 25 #include "base/threading/thread.h"
26 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
27 #include "base/trace_event/memory_dump_provider.h" 27 #include "base/trace_event/memory_dump_provider.h"
28 #include "base/trace_event/memory_dump_trigger.h"
28 #include "base/trace_event/memory_infra_background_whitelist.h" 29 #include "base/trace_event/memory_infra_background_whitelist.h"
29 #include "base/trace_event/process_memory_dump.h" 30 #include "base/trace_event/process_memory_dump.h"
30 #include "base/trace_event/trace_buffer.h" 31 #include "base/trace_event/trace_buffer.h"
31 #include "base/trace_event/trace_config_memory_test_util.h" 32 #include "base/trace_event/trace_config_memory_test_util.h"
32 #include "testing/gmock/include/gmock/gmock.h" 33 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
34 35
35 using testing::_; 36 using testing::_;
36 using testing::AnyNumber; 37 using testing::AnyNumber;
37 using testing::AtMost; 38 using testing::AtMost;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 TraceLog::RECORDING_MODE); 264 TraceLog::RECORDING_MODE);
264 } 265 }
265 266
266 void EnableTracingWithTraceConfig(const std::string& trace_config) { 267 void EnableTracingWithTraceConfig(const std::string& trace_config) {
267 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), 268 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config),
268 TraceLog::RECORDING_MODE); 269 TraceLog::RECORDING_MODE);
269 } 270 }
270 271
271 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } 272 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }
272 273
273 bool IsPeriodicDumpingEnabled() const {
274 return mdm_->periodic_dump_timer_.IsRunning();
275 }
276
277 int GetMaxConsecutiveFailuresCount() const { 274 int GetMaxConsecutiveFailuresCount() const {
278 return MemoryDumpManager::kMaxConsecutiveFailuresCount; 275 return MemoryDumpManager::kMaxConsecutiveFailuresCount;
279 } 276 }
280 277
281 scoped_refptr<SequencedTaskRunner> GetPollingTaskRunnerUnsafe() { 278 MemoryDumpTrigger* GetDumpTrigger() { return mdm_->dump_trigger_.get(); }
282 return mdm_->dump_thread_->task_runner();
283 }
284 279
285 const MemoryDumpProvider::Options kDefaultOptions; 280 const MemoryDumpProvider::Options kDefaultOptions;
286 std::unique_ptr<MemoryDumpManager> mdm_; 281 std::unique_ptr<MemoryDumpManager> mdm_;
287 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_; 282 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_;
288 bool last_callback_success_; 283 bool last_callback_success_;
289 284
290 private: 285 private:
291 std::unique_ptr<MessageLoop> message_loop_; 286 std::unique_ptr<MessageLoop> message_loop_;
292 287
293 // We want our singleton torn down after each test. 288 // We want our singleton torn down after each test.
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); 750 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider());
756 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); 751 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider());
757 mdp1->enable_mock_destructor = true; 752 mdp1->enable_mock_destructor = true;
758 mdp2->enable_mock_destructor = true; 753 mdp2->enable_mock_destructor = true;
759 754
760 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1); 755 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1);
761 EXPECT_CALL(*mdp2, SuspendFastMemoryPolling()).Times(1); 756 EXPECT_CALL(*mdp2, SuspendFastMemoryPolling()).Times(1);
762 EXPECT_CALL(*mdp1, Destructor()); 757 EXPECT_CALL(*mdp1, Destructor());
763 EXPECT_CALL(*mdp2, Destructor()); 758 EXPECT_CALL(*mdp2, Destructor());
764 759
760 MemoryDumpProvider::Options options;
761 options.is_fast_polling_supported = true;
762 RegisterDumpProvider(mdp1.get(), nullptr, options);
763
765 RunLoop run_loop; 764 RunLoop run_loop;
766 scoped_refptr<SingleThreadTaskRunner> test_task_runner = 765 scoped_refptr<SingleThreadTaskRunner> test_task_runner =
767 ThreadTaskRunnerHandle::Get(); 766 ThreadTaskRunnerHandle::Get();
768 auto quit_closure = run_loop.QuitClosure(); 767 auto quit_closure = run_loop.QuitClosure();
769 768
769 const int kPollsToQuit = 10;
770 int call_count = 0; 770 int call_count = 0;
771 MemoryDumpManager* mdm = mdm_.get();
772 const auto poll_function1 = [&call_count, &test_task_runner, quit_closure,
773 &mdp2, mdm, &options,
774 this](uint64_t* total) -> void {
775 ++call_count;
776 if (call_count == 1)
777 RegisterDumpProvider(mdp2.get(), nullptr, options, kMDPName);
778 else if (call_count == 4)
779 mdm->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2));
780 else if (call_count == kPollsToQuit)
781 test_task_runner->PostTask(FROM_HERE, quit_closure);
782
783 // Record increase of 10s of GiB of memory.
784 *total = call_count * 10lu * 1024 * 1024 * 1024;
785 };
771 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) 786 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_))
772 .Times(4) 787 .Times(testing::AtLeast(kPollsToQuit))
773 .WillRepeatedly(Invoke([&call_count, &test_task_runner, 788 .WillRepeatedly(Invoke(poll_function1));
774 quit_closure](uint64_t* total) -> void {
775 ++call_count;
776 if (call_count == 4)
777 test_task_runner->PostTask(FROM_HERE, quit_closure);
778 }));
779 789
780 // Depending on the order of PostTask calls the mdp2 might be registered after 790 // Depending on the order of PostTask calls the mdp2 might be registered after
781 // all polls or in between polls. 791 // all polls or in between polls.
782 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)) 792 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_))
783 .Times(Between(0, 4)) 793 .Times(Between(0, kPollsToQuit - 1))
784 .WillRepeatedly(Return()); 794 .WillRepeatedly(Return());
785 795
786 MemoryDumpProvider::Options options; 796 MemoryDumpTrigger::SetPollingIntervalForTesting(1);
787 options.is_fast_polling_supported = true;
788 RegisterDumpProvider(mdp1.get(), nullptr, options);
789 EnableTracingWithTraceConfig( 797 EnableTracingWithTraceConfig(
790 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); 798 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(3));
791 scoped_refptr<SequencedTaskRunner> polling_task_runner =
792 GetPollingTaskRunnerUnsafe().get();
793 ASSERT_TRUE(polling_task_runner);
794 799
795 uint64_t value = 0; 800 int last_poll_to_request_dump = -2;
796 for (int i = 0; i < 4; i++) { 801 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _))
797 if (i == 0) 802 .Times(testing::AtLeast(2))
798 RegisterDumpProvider(mdp2.get(), nullptr, options); 803 .WillRepeatedly(Invoke([&last_poll_to_request_dump, &call_count](
799 if (i == 2) 804 const MemoryDumpRequestArgs& args,
800 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); 805 const MemoryDumpCallback& callback) -> void {
801 polling_task_runner->PostTask( 806 // Minimum number of polls between dumps must be 3 (polling interval is
802 FROM_HERE, Bind(&MemoryDumpManagerTest::PollFastMemoryTotal, 807 // 1ms).
803 Unretained(this), &value)); 808 EXPECT_GE(call_count - last_poll_to_request_dump, 3);
804 } 809 last_poll_to_request_dump = call_count;
810 }));
805 811
806 run_loop.Run(); 812 run_loop.Run();
807 DisableTracing(); 813 DisableTracing();
808 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); 814 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1));
809 } 815 }
810 816
811 // If a thread (with a dump provider living on it) is torn down during a dump 817 // If a thread (with a dump provider living on it) is torn down during a dump
812 // its dump provider should be skipped but the dump itself should succeed. 818 // its dump provider should be skipped but the dump itself should succeed.
813 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { 819 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) {
814 InitializeMemoryDumpManager(false /* is_coordinator */); 820 InitializeMemoryDumpManager(false /* is_coordinator */);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 // Don't trigger the default behavior of the mock delegate in this test, 923 // Don't trigger the default behavior of the mock delegate in this test,
918 // which would short-circuit the dump request to the actual 924 // which would short-circuit the dump request to the actual
919 // CreateProcessDump(). 925 // CreateProcessDump().
920 // We don't want to create any dump in this test, only check whether the dumps 926 // We don't want to create any dump in this test, only check whether the dumps
921 // are requested or not. 927 // are requested or not.
922 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); 928 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return());
923 929
924 // Enabling memory-infra in a non-coordinator process should not trigger any 930 // Enabling memory-infra in a non-coordinator process should not trigger any
925 // periodic dumps. 931 // periodic dumps.
926 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 932 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
927 EXPECT_FALSE(IsPeriodicDumpingEnabled()); 933 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
928 DisableTracing(); 934 DisableTracing();
929 935
930 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator 936 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator
931 // process with a fully defined trigger config should NOT enable any periodic 937 // process with a fully defined trigger config should NOT enable any periodic
932 // dumps. 938 // dumps.
933 EnableTracingWithTraceConfig( 939 EnableTracingWithTraceConfig(
934 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); 940 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5));
935 EXPECT_FALSE(IsPeriodicDumpingEnabled()); 941 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
936 DisableTracing(); 942 DisableTracing();
937 } 943 }
938 944
939 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { 945 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) {
940 InitializeMemoryDumpManager(true /* is_coordinator */); 946 InitializeMemoryDumpManager(true /* is_coordinator */);
941 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; 947 MemoryDumpManagerDelegateForTesting& delegate = *delegate_;
942 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); 948 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return());
943 949
944 // Enabling memory-infra with the legacy TraceConfig (category filter) in 950 // Enabling memory-infra with the legacy TraceConfig (category filter) in
945 // a coordinator process should enable periodic dumps. 951 // a coordinator process should enable periodic dumps.
946 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 952 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
947 EXPECT_TRUE(IsPeriodicDumpingEnabled()); 953 EXPECT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
948 DisableTracing(); 954 DisableTracing();
949 955
950 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator 956 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator
951 // process without specifying any "memory_dump_config" section should enable 957 // process without specifying any "memory_dump_config" section should enable
952 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that 958 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that
953 // is: ticking memory-infra should dump periodically with the default config. 959 // is: ticking memory-infra should dump periodically with the default config.
954 EnableTracingWithTraceConfig( 960 EnableTracingWithTraceConfig(
955 TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); 961 TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers());
956 EXPECT_TRUE(IsPeriodicDumpingEnabled()); 962 EXPECT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
957 DisableTracing(); 963 DisableTracing();
958 964
959 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator 965 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator
960 // process with an empty "memory_dump_config" should NOT enable periodic 966 // process with an empty "memory_dump_config" should NOT enable periodic
961 // dumps. This is the way telemetry is supposed to use memory-infra with 967 // dumps. This is the way telemetry is supposed to use memory-infra with
962 // only explicitly triggered dumps. 968 // only explicitly triggered dumps.
963 EnableTracingWithTraceConfig( 969 EnableTracingWithTraceConfig(
964 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); 970 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers());
965 EXPECT_FALSE(IsPeriodicDumpingEnabled()); 971 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
966 DisableTracing(); 972 DisableTracing();
967 973
968 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator 974 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator
969 // process with a fully defined trigger config should cause periodic dumps to 975 // process with a fully defined trigger config should cause periodic dumps to
970 // be performed in the correct order. 976 // be performed in the correct order.
971 RunLoop run_loop; 977 RunLoop run_loop;
972 auto quit_closure = run_loop.QuitClosure(); 978 auto quit_closure = run_loop.QuitClosure();
973 979
974 const int kHeavyDumpRate = 5; 980 const int kHeavyDumpRate = 5;
975 const int kLightDumpPeriodMs = 1; 981 const int kLightDumpPeriodMs = 1;
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 RegisterDumpProvider(mdp1.get()); 1222 RegisterDumpProvider(mdp1.get());
1217 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider); 1223 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider);
1218 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions, 1224 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions,
1219 kWhitelistedMDPName); 1225 kWhitelistedMDPName);
1220 1226
1221 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0); 1227 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0);
1222 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true)); 1228 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true));
1223 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); 1229 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1);
1224 1230
1225 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 1231 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
1226 EXPECT_FALSE(IsPeriodicDumpingEnabled()); 1232 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
1227 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 1233 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
1228 MemoryDumpLevelOfDetail::BACKGROUND); 1234 MemoryDumpLevelOfDetail::BACKGROUND);
1229 DisableTracing(); 1235 DisableTracing();
1230 } 1236 }
1231 1237
1232 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { 1238 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) {
1233 InitializeMemoryDumpManager(true /* is_coordinator */); 1239 InitializeMemoryDumpManager(true /* is_coordinator */);
1234 1240
1235 RunLoop run_loop; 1241 RunLoop run_loop;
1236 auto quit_closure = run_loop.QuitClosure(); 1242 auto quit_closure = run_loop.QuitClosure();
(...skipping 15 matching lines...) Expand all
1252 // Only background mode dumps should be allowed with the trace config. 1258 // Only background mode dumps should be allowed with the trace config.
1253 last_callback_success_ = false; 1259 last_callback_success_ = false;
1254 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 1260 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
1255 MemoryDumpLevelOfDetail::LIGHT); 1261 MemoryDumpLevelOfDetail::LIGHT);
1256 EXPECT_FALSE(last_callback_success_); 1262 EXPECT_FALSE(last_callback_success_);
1257 last_callback_success_ = false; 1263 last_callback_success_ = false;
1258 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 1264 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
1259 MemoryDumpLevelOfDetail::DETAILED); 1265 MemoryDumpLevelOfDetail::DETAILED);
1260 EXPECT_FALSE(last_callback_success_); 1266 EXPECT_FALSE(last_callback_success_);
1261 1267
1262 ASSERT_TRUE(IsPeriodicDumpingEnabled()); 1268 ASSERT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning());
1263 run_loop.Run(); 1269 run_loop.Run();
1264 DisableTracing(); 1270 DisableTracing();
1265 } 1271 }
1266 1272
1267 } // namespace trace_event 1273 } // namespace trace_event
1268 } // namespace base 1274 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698