// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/memory_peak_detector.h"

#include <memory>

#include "base/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/memory_dump_provider_info.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

namespace base {
namespace trace_event {

namespace {

const TimeDelta kMs = TimeDelta::FromMilliseconds(1);
const MemoryPeakDetector::Config kConfigNoCallbacks(
    1 /* polling_interval_ms */,
    60000 /* min_time_between_peaks_ms */,
    false /* enable_verbose_poll_tracing */
    );

class MockMemoryDumpProvider : public MemoryDumpProvider {
 public:
  bool OnMemoryDump(const MemoryDumpArgs&, ProcessMemoryDump*) override {
    NOTREACHED();
    return true;
  }

  MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t*));
};

// Wrapper to use gmock on a callback.
struct OnPeakDetectedWrapper {
  MOCK_METHOD0(OnPeak, void());
};

}  // namespace

class MemoryPeakDetectorTest : public testing::Test {
 public:
  struct FriendDeleter {
    void operator()(MemoryPeakDetector* inst) { delete inst; }
  };

  MemoryPeakDetectorTest() : testing::Test() {}
  static const uint64_t kSlidingWindowNumSamples =
      MemoryPeakDetector::kSlidingWindowNumSamples;

  std::unique_ptr<MemoryPeakDetector, FriendDeleter> NewInstance() {
    return std::unique_ptr<MemoryPeakDetector, FriendDeleter>(
        new MemoryPeakDetector());
  }

  void RestartThreadAndReinitializePeakDetector() {
    bg_thread_.reset(new Thread("Peak Detector Test Thread"));
    bg_thread_->Start();
    peak_detector_ = NewInstance();
    peak_detector_->Setup(
        Bind(&MemoryPeakDetectorTest::MockGetDumpProviders, Unretained(this)),
        bg_thread_->task_runner(),
        Bind(&OnPeakDetectedWrapper::OnPeak, Unretained(&on_peak_callback_)));
  }

  void SetUp() override {
    get_mdp_call_count_ = 0;
    RestartThreadAndReinitializePeakDetector();
  }

  void TearDown() override {
    peak_detector_->TearDown();
    bg_thread_->FlushForTesting();
    EXPECT_EQ(MemoryPeakDetector::NOT_INITIALIZED, GetPeakDetectorState());
    bg_thread_.reset();
    dump_providers_.clear();
  }

  // Calls MemoryPeakDetector::state_for_testing() on the bg thread and returns
  // the result on the current thread.
  MemoryPeakDetector::State GetPeakDetectorState() {
    WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                      WaitableEvent::InitialState::NOT_SIGNALED);
    MemoryPeakDetector::State res = MemoryPeakDetector::NOT_INITIALIZED;
    auto get_fn = [](MemoryPeakDetector* peak_detector, WaitableEvent* evt,
                     MemoryPeakDetector::State* res) {
      *res = peak_detector->state_for_testing();
      evt->Signal();
    };
    bg_thread_->task_runner()->PostTask(
        FROM_HERE, BindOnce(get_fn, Unretained(&*peak_detector_),
                            Unretained(&evt), Unretained(&res)));
    evt.Wait();
    return res;
  }

  // Calls MemoryPeakDetector::poll_tasks_count_for_testing() on the bg thread
  // and returns the result on the current thread.
  uint32_t GetNumPollingTasksRan() {
    uint32_t res = 0;
    auto get_fn = [](MemoryPeakDetector* peak_detector, WaitableEvent* evt,
                     uint32_t* res) {
      *res = peak_detector->poll_tasks_count_for_testing();
      evt->Signal();
    };

    WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                      WaitableEvent::InitialState::NOT_SIGNALED);
    bg_thread_->task_runner()->PostTask(
        FROM_HERE, BindOnce(get_fn, Unretained(&*peak_detector_),
                            Unretained(&evt), Unretained(&res)));
    evt.Wait();
    return res;
  }

  // Runs the peak detector with a mock MDP with the given
  // |config|. The mock MDP will invoke the |poll_function| on any call to
  // PollFastMemoryTotal(), until |num_samples| have been polled.
  // It returns the number of peaks detected.
  uint32_t RunWithCustomPollFunction(
      MemoryPeakDetector::Config config,
      uint32_t num_samples,
      RepeatingCallback<uint64_t(uint32_t)> poll_function) {
    WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                      WaitableEvent::InitialState::NOT_SIGNALED);
    scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
    dump_providers_.push_back(mdp);
    uint32_t cur_sample_idx = 0;
    EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
        .WillRepeatedly(Invoke(
            [&cur_sample_idx, &evt, poll_function, num_samples](uint64_t* mem) {
              if (cur_sample_idx >= num_samples) {
                *mem = 1;
                evt.Signal();
              } else {
                *mem = poll_function.Run(cur_sample_idx++);
              }
            }));

    uint32_t num_peaks = 0;
    EXPECT_CALL(on_peak_callback_, OnPeak())
        .WillRepeatedly(Invoke([&num_peaks] { num_peaks++; }));
    peak_detector_->Start(config);
    evt.Wait();  // Wait for |num_samples| invocations of PollFastMemoryTotal().
    peak_detector_->Stop();
    EXPECT_EQ(num_samples, cur_sample_idx);
    EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
    return num_peaks;
  }

  // Called on the |bg_thread_|.
  void MockGetDumpProviders(MemoryPeakDetector::DumpProvidersList* mdps) {
    get_mdp_call_count_++;
    *mdps = dump_providers_;
  }

  uint32_t GetNumGetDumpProvidersCalls() {
    bg_thread_->FlushForTesting();
    return get_mdp_call_count_;
  }

  scoped_refptr<MemoryDumpProviderInfo> CreateMockDumpProvider() {
    std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider());
    MemoryDumpProvider::Options opt;
    opt.is_fast_polling_supported = true;
    scoped_refptr<MemoryDumpProviderInfo> mdp_info(
        new MemoryDumpProviderInfo(mdp.get(), "Mock MDP", nullptr, opt,
                                   false /* whitelisted_for_background_mode */,
                                   false /* whitelisted_for_summary_mode */));

    // The |mdp| instance will be destroyed together with the |mdp_info|.
    mdp_info->owned_dump_provider = std::move(mdp);
    return mdp_info;
  }

  static MockMemoryDumpProvider& GetMockMDP(
      const scoped_refptr<MemoryDumpProviderInfo>& mdp_info) {
    return *static_cast<MockMemoryDumpProvider*>(mdp_info->dump_provider);
  }

  static uint64_t PollFunctionThatCausesPeakViaStdDev(uint32_t sample_idx) {
    // Start with a baseline of 50 MB.
    if (sample_idx < kSlidingWindowNumSamples)
      return 50000 + (sample_idx % 3) * 100;

    // Then 10 samples around 80 MB
    if (sample_idx < 10 + kSlidingWindowNumSamples)
      return 80000 + (sample_idx % 3) * 200;

    // Than back to 60 MB.
    if (sample_idx < 2 * kSlidingWindowNumSamples)
      return 60000 + (sample_idx % 3) * 100;

    // Then 20 samples around 120 MB.
    if (sample_idx < 20 + 2 * kSlidingWindowNumSamples)
      return 120000 + (sample_idx % 3) * 200;

    // Then back to idle to around 50 MB until the end.
    return 50000 + (sample_idx % 3) * 100;
  }

 protected:
  MemoryPeakDetector::DumpProvidersList dump_providers_;
  uint32_t get_mdp_call_count_;
  std::unique_ptr<MemoryPeakDetector, FriendDeleter> peak_detector_;
  std::unique_ptr<Thread> bg_thread_;
  OnPeakDetectedWrapper on_peak_callback_;
};

const uint64_t MemoryPeakDetectorTest::kSlidingWindowNumSamples;

TEST_F(MemoryPeakDetectorTest, GetDumpProvidersFunctionCalled) {
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(1u, GetNumGetDumpProvidersCalls());
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  EXPECT_EQ(0u, GetNumPollingTasksRan());
}

TEST_F(MemoryPeakDetectorTest, ThrottleAndNotifyBeforeInitialize) {
  peak_detector_->TearDown();

  WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                    WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
  EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt](uint64_t*) { evt.Signal(); }));
  dump_providers_.push_back(mdp);
  peak_detector_->Throttle();
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  EXPECT_EQ(MemoryPeakDetector::NOT_INITIALIZED, GetPeakDetectorState());
  RestartThreadAndReinitializePeakDetector();

  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());
  evt.Wait();  // Wait for a PollFastMemoryTotal() call.

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  EXPECT_EQ(1u, GetNumGetDumpProvidersCalls());
  EXPECT_GE(GetNumPollingTasksRan(), 1u);
}

TEST_F(MemoryPeakDetectorTest, DoubleStop) {
  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());

  EXPECT_EQ(1u, GetNumGetDumpProvidersCalls());
  EXPECT_EQ(0u, GetNumPollingTasksRan());
}

TEST_F(MemoryPeakDetectorTest, OneDumpProviderRegisteredBeforeStart) {
  WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                    WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
  EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt](uint64_t*) { evt.Signal(); }));
  dump_providers_.push_back(mdp);

  peak_detector_->Start(kConfigNoCallbacks);
  evt.Wait();  // Signaled when PollFastMemoryTotal() is called on the MockMDP.
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  EXPECT_EQ(1u, GetNumGetDumpProvidersCalls());
  EXPECT_GT(GetNumPollingTasksRan(), 0u);
}

TEST_F(MemoryPeakDetectorTest, ReInitializeAndRebindToNewThread) {
  WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                    WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
  EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt](uint64_t*) { evt.Signal(); }));
  dump_providers_.push_back(mdp);

  for (int i = 0; i < 5; ++i) {
    evt.Reset();
    peak_detector_->Start(kConfigNoCallbacks);
    evt.Wait();  // Wait for a PollFastMemoryTotal() call.
    // Check that calling TearDown implicitly does a Stop().
    peak_detector_->TearDown();

    // Reinitialize and re-bind to a new task runner.
    RestartThreadAndReinitializePeakDetector();
  }
}

TEST_F(MemoryPeakDetectorTest, OneDumpProviderRegisteredOutOfBand) {
  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());
  EXPECT_EQ(1u, GetNumGetDumpProvidersCalls());

  // Check that no poll tasks are posted before any dump provider is registered.
  PlatformThread::Sleep(5 * kConfigNoCallbacks.polling_interval_ms * kMs);
  EXPECT_EQ(0u, GetNumPollingTasksRan());

  // Registed the MDP After Start() has been issued and expect that the
  // PeakDetector transitions ENABLED -> RUNNING on the next
  // NotifyMemoryDumpProvidersChanged() call.
  WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                    WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
  EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt](uint64_t*) { evt.Signal(); }));
  dump_providers_.push_back(mdp);
  peak_detector_->NotifyMemoryDumpProvidersChanged();

  evt.Wait();  // Signaled when PollFastMemoryTotal() is called on the MockMDP.
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());
  EXPECT_EQ(2u, GetNumGetDumpProvidersCalls());

  // Now simulate the unregisration and expect that the PeakDetector transitions
  // back to ENABLED.
  dump_providers_.clear();
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());
  EXPECT_EQ(3u, GetNumGetDumpProvidersCalls());
  uint32_t num_poll_tasks = GetNumPollingTasksRan();
  EXPECT_GT(num_poll_tasks, 0u);

  // At this point, no more polling tasks should be posted.
  PlatformThread::Sleep(5 * kConfigNoCallbacks.polling_interval_ms * kMs);
  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  EXPECT_EQ(num_poll_tasks, GetNumPollingTasksRan());
}

// Test that a sequence of Start()/Stop() back-to-back doesn't end up creating
// several outstanding timer tasks and instead respects the polling_interval_ms.
TEST_F(MemoryPeakDetectorTest, StartStopQuickly) {
  WaitableEvent evt(WaitableEvent::ResetPolicy::MANUAL,
                    WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp = CreateMockDumpProvider();
  dump_providers_.push_back(mdp);
  const uint32_t kNumPolls = 20;
  uint32_t polls_done = 0;
  EXPECT_CALL(GetMockMDP(mdp), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&polls_done, &evt, kNumPolls](uint64_t*) {
        if (++polls_done == kNumPolls)
          evt.Signal();
      }));

  const TimeTicks tstart = TimeTicks::Now();
  for (int i = 0; i < 5; i++) {
    peak_detector_->Start(kConfigNoCallbacks);
    peak_detector_->Stop();
  }

  bg_thread_->task_runner()->PostTask(
      FROM_HERE, base::BindOnce([](uint32_t* polls_done) { *polls_done = 0; },
                                &polls_done));

  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());
  evt.Wait();  // Wait for kNumPolls.
  const double time_ms = (TimeTicks::Now() - tstart).InMillisecondsF();

  EXPECT_GE(time_ms, (kNumPolls - 1) * kConfigNoCallbacks.polling_interval_ms);
  peak_detector_->Stop();
}

TEST_F(MemoryPeakDetectorTest, RegisterAndUnregisterTwoDumpProviders) {
  WaitableEvent evt1(WaitableEvent::ResetPolicy::MANUAL,
                     WaitableEvent::InitialState::NOT_SIGNALED);
  WaitableEvent evt2(WaitableEvent::ResetPolicy::MANUAL,
                     WaitableEvent::InitialState::NOT_SIGNALED);
  scoped_refptr<MemoryDumpProviderInfo> mdp1 = CreateMockDumpProvider();
  scoped_refptr<MemoryDumpProviderInfo> mdp2 = CreateMockDumpProvider();
  EXPECT_CALL(GetMockMDP(mdp1), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt1](uint64_t*) { evt1.Signal(); }));
  EXPECT_CALL(GetMockMDP(mdp2), PollFastMemoryTotal(_))
      .WillRepeatedly(Invoke([&evt2](uint64_t*) { evt2.Signal(); }));

  // Register only one MDP and start the detector.
  dump_providers_.push_back(mdp1);
  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());

  // Wait for one poll task and then register also the other one.
  evt1.Wait();
  dump_providers_.push_back(mdp2);
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  evt2.Wait();
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());

  // Now unregister the first MDP and check that everything is still running.
  dump_providers_.erase(dump_providers_.begin());
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());

  // Now unregister both and check that the detector goes to idle.
  dump_providers_.clear();
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());

  // Now re-register both and check that the detector re-activates posting
  // new polling tasks.
  uint32_t num_poll_tasks = GetNumPollingTasksRan();
  evt1.Reset();
  evt2.Reset();
  dump_providers_.push_back(mdp1);
  dump_providers_.push_back(mdp2);
  peak_detector_->NotifyMemoryDumpProvidersChanged();
  evt1.Wait();
  evt2.Wait();
  EXPECT_EQ(MemoryPeakDetector::RUNNING, GetPeakDetectorState());
  EXPECT_GT(GetNumPollingTasksRan(), num_poll_tasks);

  // Stop everything, tear down the MDPs, restart the detector and check that
  // it detector doesn't accidentally try to re-access them.
  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  dump_providers_.clear();
  mdp1 = nullptr;
  mdp2 = nullptr;

  num_poll_tasks = GetNumPollingTasksRan();
  peak_detector_->Start(kConfigNoCallbacks);
  EXPECT_EQ(MemoryPeakDetector::ENABLED, GetPeakDetectorState());
  PlatformThread::Sleep(5 * kConfigNoCallbacks.polling_interval_ms * kMs);

  peak_detector_->Stop();
  EXPECT_EQ(MemoryPeakDetector::DISABLED, GetPeakDetectorState());
  EXPECT_EQ(num_poll_tasks, GetNumPollingTasksRan());

  EXPECT_EQ(6u, GetNumGetDumpProvidersCalls());
}

// Tests the behavior of the static threshold detector, which is supposed to
// detect a peak whenever an increase >= threshold is detected.
TEST_F(MemoryPeakDetectorTest, StaticThreshold) {
  const uint32_t kNumSamples = 2 * kSlidingWindowNumSamples;
  constexpr uint32_t kNumSamplesPerStep = 10;
  constexpr uint64_t kThreshold = 1000000;
  peak_detector_->SetStaticThresholdForTesting(kThreshold);
  const MemoryPeakDetector::Config kConfig(
      1 /* polling_interval_ms */, 0 /* min_time_between_peaks_ms */,
      false /* enable_verbose_poll_tracing */
      );

  // The mocked PollFastMemoryTotal() will return a step function,
  // e.g. (1, 1, 1, 5, 5, 5, ...) where the steps are 2x threshold, in order to
  // trigger only the static threshold logic.
  auto poll_fn = Bind(
      [](const uint32_t kNumSamplesPerStep, const uint64_t kThreshold,
         uint32_t sample_idx) -> uint64_t {
        return (1 + sample_idx / kNumSamplesPerStep) * 2 * kThreshold;
      },
      kNumSamplesPerStep, kThreshold);
  uint32_t num_peaks = RunWithCustomPollFunction(kConfig, kNumSamples, poll_fn);
  EXPECT_EQ(kNumSamples / kNumSamplesPerStep - 1, num_peaks);
}

// Checks the throttling logic of Config's |min_time_between_peaks_ms|.
TEST_F(MemoryPeakDetectorTest, PeakCallbackThrottling) {
  const size_t kNumSamples = 2 * kSlidingWindowNumSamples;
  constexpr uint64_t kThreshold = 1000000;
  peak_detector_->SetStaticThresholdForTesting(kThreshold);
  const MemoryPeakDetector::Config kConfig(
      1 /* polling_interval_ms */, 4 /* min_time_between_peaks_ms */,
      false /* enable_verbose_poll_tracing */
      );

  // Each mock value returned is N * 2 * threshold, so all of them would be
  // eligible to be a peak if throttling wasn't enabled.
  auto poll_fn = Bind(
      [](uint64_t kThreshold, uint32_t sample_idx) -> uint64_t {
        return (sample_idx + 1) * 2 * kThreshold;
      },
      kThreshold);
  uint32_t num_peaks = RunWithCustomPollFunction(kConfig, kNumSamples, poll_fn);
  const uint32_t kExpectedThrottlingRate =
      kConfig.min_time_between_peaks_ms / kConfig.polling_interval_ms;
  EXPECT_LT(num_peaks, kNumSamples / kExpectedThrottlingRate);
}

TEST_F(MemoryPeakDetectorTest, StdDev) {
  // Set the threshold to some arbitrarily high value, so that the static
  // threshold logic is not hit in this test.
  constexpr uint64_t kThreshold = 1024 * 1024 * 1024;
  peak_detector_->SetStaticThresholdForTesting(kThreshold);
  const size_t kNumSamples = 3 * kSlidingWindowNumSamples;
  const MemoryPeakDetector::Config kConfig(
      1 /* polling_interval_ms */, 0 /* min_time_between_peaks_ms */,
      false /* enable_verbose_poll_tracing */
      );

  auto poll_fn = Bind(&PollFunctionThatCausesPeakViaStdDev);
  uint32_t num_peaks = RunWithCustomPollFunction(kConfig, kNumSamples, poll_fn);
  EXPECT_EQ(2u, num_peaks);  // 80 MB, 120 MB.
}

// Tests that Throttle() actually holds back peak notifications.
TEST_F(MemoryPeakDetectorTest, Throttle) {
  constexpr uint64_t kThreshold = 1024 * 1024 * 1024;
  const uint32_t kNumSamples = 3 * kSlidingWindowNumSamples;
  peak_detector_->SetStaticThresholdForTesting(kThreshold);
  const MemoryPeakDetector::Config kConfig(
      1 /* polling_interval_ms */, 0 /* min_time_between_peaks_ms */,
      false /* enable_verbose_poll_tracing */
      );

  auto poll_fn = Bind(
      [](MemoryPeakDetector* peak_detector, uint32_t sample_idx) -> uint64_t {
        if (sample_idx % 20 == 20 - 1)
          peak_detector->Throttle();
        return PollFunctionThatCausesPeakViaStdDev(sample_idx);
      },
      Unretained(&*peak_detector_));
  uint32_t num_peaks = RunWithCustomPollFunction(kConfig, kNumSamples, poll_fn);
  EXPECT_EQ(0u, num_peaks);
}

// Tests that the windows stddev state is not carried over through
// Stop() -> Start() sequences.
TEST_F(MemoryPeakDetectorTest, RestartClearsState) {
  constexpr uint64_t kThreshold = 1024 * 1024 * 1024;
  peak_detector_->SetStaticThresholdForTesting(kThreshold);
  const size_t kNumSamples = 3 * kSlidingWindowNumSamples;
  const MemoryPeakDetector::Config kConfig(
      1 /* polling_interval_ms */, 0 /* min_time_between_peaks_ms */,
      false /* enable_verbose_poll_tracing */
      );
  auto poll_fn = Bind(
      [](MemoryPeakDetector* peak_detector,
         const uint32_t kSlidingWindowNumSamples,
         MemoryPeakDetector::Config kConfig, uint32_t sample_idx) -> uint64_t {
        if (sample_idx % kSlidingWindowNumSamples ==
            kSlidingWindowNumSamples - 1) {
          peak_detector->Stop();
          peak_detector->Start(kConfig);
        }
        return PollFunctionThatCausesPeakViaStdDev(sample_idx);
      },
      Unretained(&*peak_detector_), kSlidingWindowNumSamples, kConfig);
  uint32_t num_peaks = RunWithCustomPollFunction(kConfig, kNumSamples, poll_fn);
  EXPECT_EQ(0u, num_peaks);
}

}  // namespace trace_event
}  // namespace base
