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

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

Issue 2799023002: memory-infra: Switch to MemoryPeakDetector and simplify MemoryDumpScheduler (Closed)
Patch Set: . Created 3 years, 8 months 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_scheduler.h" 5 #include "base/trace_event/memory_dump_scheduler.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h"
9 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
11 15
16 using ::testing::Invoke;
17 using ::testing::_;
18
12 namespace base { 19 namespace base {
13 namespace trace_event { 20 namespace trace_event {
14 21
15 class MemoryDumpSchedulerPollingTest : public testing::Test { 22 namespace {
23
24 // Wrapper to use gmock on a callback.
25 struct SchedulerCallbackWrapper {
26 MOCK_METHOD1(OnTick, void(MemoryDumpLevelOfDetail));
27 };
28
29 } // namespace
30
31 class MemoryDumpSchedulerTest : public testing::Test {
16 public: 32 public:
17 static const uint32_t kMinPollsToDump = 5; 33 struct FriendDeleter {
34 void operator()(MemoryDumpScheduler* inst) { delete inst; }
35 };
18 36
19 MemoryDumpSchedulerPollingTest() 37 MemoryDumpSchedulerTest() : testing::Test() {}
20 : testing::Test(),
21 num_samples_tracked_(
22 MemoryDumpScheduler::PollingTriggerState::kMaxNumMemorySamples) {}
23 38
24 void SetUp() override { 39 void SetUp() override {
25 MemoryDumpScheduler::SetPollingIntervalForTesting(1); 40 bg_thread_.reset(new Thread("MemoryDumpSchedulerTest Thread"));
26 uint32_t kMinPollsToDump = 5; 41 bg_thread_->Start();
27 mds_ = MemoryDumpScheduler::GetInstance(); 42 scheduler_.reset(new MemoryDumpScheduler());
28 mds_->Setup(nullptr, nullptr);
29 mds_->AddTrigger(MemoryDumpType::PEAK_MEMORY_USAGE,
30 MemoryDumpLevelOfDetail::LIGHT, kMinPollsToDump);
31 mds_->polling_state_->ResetTotals();
32 mds_->polling_state_->current_state =
33 MemoryDumpScheduler::PollingTriggerState::ENABLED;
34 } 43 }
35 44
36 void TearDown() override { 45 void TearDown() override {
37 mds_->polling_state_->current_state = 46 bg_thread_.reset();
38 MemoryDumpScheduler::PollingTriggerState::DISABLED; 47 scheduler_.reset();
39 } 48 }
40 49
41 protected: 50 protected:
42 bool ShouldTriggerDump(uint64_t total) { 51 std::unique_ptr<MemoryDumpScheduler, FriendDeleter> scheduler_;
43 return mds_->ShouldTriggerDump(total); 52 std::unique_ptr<Thread> bg_thread_;
44 } 53 SchedulerCallbackWrapper on_tick_callback_;
45
46 uint32_t num_samples_tracked_;
47 MemoryDumpScheduler* mds_;
48 }; 54 };
49 55
50 TEST_F(MemoryDumpSchedulerPollingTest, PeakDetection) { 56 TEST_F(MemoryDumpSchedulerTest, SingleTrigger) {
ssid 2017/04/05 22:04:22 We should remove some tests from MDM maybe, which
Primiano Tucci (use gerrit) 2017/04/10 19:16:41 I simplified a bit the TestPollingOnDumpThread lim
ssid 2017/04/10 21:35:51 You are right. They test trace config parsing.
51 for (uint32_t i = 0; i < num_samples_tracked_ * 6; ++i) { 57 const uint32_t kPeriodMs = 1;
52 // Memory is increased in steps and dumps must be triggered at every step. 58 const auto kLevelOfDetail = MemoryDumpLevelOfDetail::DETAILED;
53 uint64_t total = (2 + (i / (2 * num_samples_tracked_))) * 1024 * 1204; 59 const uint32_t kTicks = 10;
54 bool did_trigger = ShouldTriggerDump(total); 60 WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
55 // Dumps must be triggered only at specific iterations. 61 WaitableEvent::InitialState::NOT_SIGNALED);
56 bool should_have_triggered = i == 0; 62 MemoryDumpScheduler::Config config;
57 should_have_triggered |= 63 config.triggers.push_back({kLevelOfDetail, kPeriodMs});
58 (i > num_samples_tracked_) && (i % (2 * num_samples_tracked_) == 1); 64 config.callback =
59 if (should_have_triggered) { 65 Bind(&SchedulerCallbackWrapper::OnTick, Unretained(&on_tick_callback_));
60 ASSERT_TRUE(did_trigger) << "Dump wasn't triggered at " << i; 66
61 } else { 67 uint32_t num_ticks = 0;
62 ASSERT_FALSE(did_trigger) << "Unexpected dump at " << i; 68 EXPECT_CALL(on_tick_callback_, OnTick(_))
63 } 69 .WillRepeatedly(Invoke([&num_ticks, &evt, kTicks, kLevelOfDetail](
64 } 70 MemoryDumpLevelOfDetail level_of_detail) {
71 EXPECT_EQ(kLevelOfDetail, level_of_detail);
72 if (++num_ticks == kTicks)
73 evt.Signal();
74 }));
75 const TimeTicks tstart = TimeTicks::Now();
76
77 // Check that Stop() before Start() doesn't cause any error.
78 scheduler_->Stop();
79
80 scheduler_->Start(config, bg_thread_->task_runner());
81 evt.Wait();
82 const double time_ms = (TimeTicks::Now() - tstart).InMillisecondsF();
83 EXPECT_GE(time_ms, kPeriodMs * kTicks);
84
85 // Check that stopping twice doesn't cause any problems.
86 scheduler_->Stop();
87 scheduler_->Stop();
65 } 88 }
66 89
67 TEST_F(MemoryDumpSchedulerPollingTest, SlowGrowthDetection) { 90 // TODO add other tests to cover StartStopQuickly and multiple triggers.
68 for (uint32_t i = 0; i < 15; ++i) {
69 // Record 1GiB of increase in each call. Dumps are triggered with 1% w.r.t
70 // system's total memory.
71 uint64_t total = static_cast<uint64_t>(i + 1) * 1024 * 1024 * 1024;
72 bool did_trigger = ShouldTriggerDump(total);
73 bool should_have_triggered = i % kMinPollsToDump == 0;
74 if (should_have_triggered) {
75 ASSERT_TRUE(did_trigger) << "Dump wasn't triggered at " << i;
76 } else {
77 ASSERT_FALSE(did_trigger) << "Unexpected dump at " << i;
78 }
79 }
80 }
81
82 TEST_F(MemoryDumpSchedulerPollingTest, NotifyDumpTriggered) {
83 for (uint32_t i = 0; i < num_samples_tracked_ * 6; ++i) {
84 uint64_t total = (2 + (i / (2 * num_samples_tracked_))) * 1024 * 1204;
85 if (i % num_samples_tracked_ == 0)
86 mds_->NotifyDumpTriggered();
87 bool did_trigger = ShouldTriggerDump(total);
88 // Dumps should never be triggered since NotifyDumpTriggered() is called
89 // frequently.
90 EXPECT_NE(0u, mds_->polling_state_->last_dump_memory_total);
91 EXPECT_GT(num_samples_tracked_ - 1,
92 mds_->polling_state_->last_memory_totals_kb_index);
93 EXPECT_LT(static_cast<int64_t>(
94 total - mds_->polling_state_->last_dump_memory_total),
95 mds_->polling_state_->memory_increase_threshold);
96 ASSERT_FALSE(did_trigger && i) << "Unexpected dump at " << i;
97 }
98 }
99 91
100 } // namespace trace_event 92 } // namespace trace_event
101 } // namespace base 93 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698