1319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski// Copyright 2017 The Chromium Authors. All rights reserved.
2319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski// Use of this source code is governed by a BSD-style license that can be
3319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski// found in the LICENSE file.
4319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
5319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski#include "base/trace_event/memory_dump_scheduler.h"
6319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
7319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski#include <memory>
8319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
9319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski#include "base/single_thread_task_runner.h"
10319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski#include "testing/gtest/include/gtest/gtest.h"
11319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
12319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowskinamespace base {
13319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowskinamespace trace_event {
14319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
15319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowskiclass MemoryDumpSchedulerPollingTest : public testing::Test {
16319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski public:
17319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  static const uint32_t kMinPollsToDump = 5;
18319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
19319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  MemoryDumpSchedulerPollingTest()
20319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      : testing::Test(),
21319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski        num_samples_tracked_(
22319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski            MemoryDumpScheduler::PollingTriggerState::kMaxNumMemorySamples) {}
23319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
24319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  void SetUp() override {
25319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    MemoryDumpScheduler::SetPollingIntervalForTesting(1);
26319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    uint32_t kMinPollsToDump = 5;
27319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_ = MemoryDumpScheduler::GetInstance();
28319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_->Setup(nullptr, nullptr);
29319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_->AddTrigger(MemoryDumpType::PEAK_MEMORY_USAGE,
30319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski                     MemoryDumpLevelOfDetail::LIGHT, kMinPollsToDump);
31319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_->polling_state_->ResetTotals();
32319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_->polling_state_->current_state =
33319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski        MemoryDumpScheduler::PollingTriggerState::ENABLED;
34319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
35319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
36319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  void TearDown() override {
37319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    mds_->polling_state_->current_state =
38319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski        MemoryDumpScheduler::PollingTriggerState::DISABLED;
39319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
40319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
41319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski protected:
42319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  bool ShouldTriggerDump(uint64_t total) {
43319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    return mds_->ShouldTriggerDump(total);
44319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
45319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
46319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  uint32_t num_samples_tracked_;
47319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  MemoryDumpScheduler* mds_;
48319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski};
49319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
50319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub PawlowskiTEST_F(MemoryDumpSchedulerPollingTest, PeakDetection) {
51319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  for (uint32_t i = 0; i < num_samples_tracked_ * 6; ++i) {
52319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // Memory is increased in steps and dumps must be triggered at every step.
53319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    uint64_t total = (2 + (i / (2 * num_samples_tracked_))) * 1024 * 1204;
54319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    bool did_trigger = ShouldTriggerDump(total);
55319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // Dumps must be triggered only at specific iterations.
56319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    bool should_have_triggered = i == 0;
57319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    should_have_triggered |=
58319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski        (i > num_samples_tracked_) && (i % (2 * num_samples_tracked_) == 1);
59319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    if (should_have_triggered) {
60319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      ASSERT_TRUE(did_trigger) << "Dump wasn't triggered at " << i;
61319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    } else {
62319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      ASSERT_FALSE(did_trigger) << "Unexpected dump at " << i;
63319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    }
64319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
65319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski}
66319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
67319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub PawlowskiTEST_F(MemoryDumpSchedulerPollingTest, SlowGrowthDetection) {
68319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  for (uint32_t i = 0; i < 15; ++i) {
69319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // Record 1GiB of increase in each call. Dumps are triggered with 1% w.r.t
70319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // system's total memory.
71319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    uint64_t total = static_cast<uint64_t>(i + 1) * 1024 * 1024 * 1024;
72319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    bool did_trigger = ShouldTriggerDump(total);
73319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    bool should_have_triggered = i % kMinPollsToDump == 0;
74319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    if (should_have_triggered) {
75319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      ASSERT_TRUE(did_trigger) << "Dump wasn't triggered at " << i;
76319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    } else {
77319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      ASSERT_FALSE(did_trigger) << "Unexpected dump at " << i;
78319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    }
79319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
80319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski}
81319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
82319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub PawlowskiTEST_F(MemoryDumpSchedulerPollingTest, NotifyDumpTriggered) {
83319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  for (uint32_t i = 0; i < num_samples_tracked_ * 6; ++i) {
84319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    uint64_t total = (2 + (i / (2 * num_samples_tracked_))) * 1024 * 1204;
85319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    if (i % num_samples_tracked_ == 0)
86319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski      mds_->NotifyDumpTriggered();
87319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    bool did_trigger = ShouldTriggerDump(total);
88319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // Dumps should never be triggered since NotifyDumpTriggered() is called
89319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    // frequently.
90319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    EXPECT_NE(0u, mds_->polling_state_->last_dump_memory_total);
91319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    EXPECT_GT(num_samples_tracked_ - 1,
92319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski              mds_->polling_state_->last_memory_totals_kb_index);
93319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    EXPECT_LT(static_cast<int64_t>(
94319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski                  total - mds_->polling_state_->last_dump_memory_total),
95319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski              mds_->polling_state_->memory_increase_threshold);
96319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski    ASSERT_FALSE(did_trigger && i) << "Unexpected dump at " << i;
97319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski  }
98319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski}
99319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski
100319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski}  // namespace trace_event
101319afc59a539d6261307aadbdab4d4ee93eaf1ffJakub Pawlowski}  // namespace base
102