// Copyright 2015 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/memory/memory_pressure_monitor_win.h"

#include "base/macros.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace win {

namespace {

struct PressureSettings {
  int phys_left_mb;
  MemoryPressureListener::MemoryPressureLevel level;
};

}  // namespace

// This is outside of the anonymous namespace so that it can be seen as a friend
// to the monitor class.
class TestMemoryPressureMonitor : public MemoryPressureMonitor {
 public:
  using MemoryPressureMonitor::CalculateCurrentPressureLevel;
  using MemoryPressureMonitor::CheckMemoryPressure;

  static const DWORDLONG kMBBytes = 1024 * 1024;

  explicit TestMemoryPressureMonitor(bool large_memory)
      : mem_status_() {
    // Generate a plausible amount of memory.
    mem_status_.ullTotalPhys =
        static_cast<DWORDLONG>(GenerateTotalMemoryMb(large_memory)) * kMBBytes;

    // Rerun InferThresholds using the test fixture's GetSystemMemoryStatus.
    InferThresholds();
    // Stop the timer.
    StopObserving();
  }

  TestMemoryPressureMonitor(int system_memory_mb,
                            int moderate_threshold_mb,
                            int critical_threshold_mb)
      : MemoryPressureMonitor(moderate_threshold_mb, critical_threshold_mb),
        mem_status_() {
    // Set the amount of system memory.
    mem_status_.ullTotalPhys = static_cast<DWORDLONG>(
        system_memory_mb * kMBBytes);

    // Stop the timer.
    StopObserving();
  }

  virtual ~TestMemoryPressureMonitor() {}

  MOCK_METHOD1(OnMemoryPressure,
               void(MemoryPressureListener::MemoryPressureLevel level));

  // Generates an amount of total memory that is consistent with the requested
  // memory model.
  int GenerateTotalMemoryMb(bool large_memory) {
    int total_mb = 64;
    while (total_mb < MemoryPressureMonitor::kLargeMemoryThresholdMb)
      total_mb *= 2;
    if (large_memory)
      return total_mb * 2;
    return total_mb / 2;
  }

  // Sets up the memory status to reflect the provided absolute memory left.
  void SetMemoryFree(int phys_left_mb) {
    // ullTotalPhys is set in the constructor and not modified.

    // Set the amount of available memory.
    mem_status_.ullAvailPhys =
        static_cast<DWORDLONG>(phys_left_mb) * kMBBytes;
    DCHECK_LT(mem_status_.ullAvailPhys, mem_status_.ullTotalPhys);

    // These fields are unused.
    mem_status_.dwMemoryLoad = 0;
    mem_status_.ullTotalPageFile = 0;
    mem_status_.ullAvailPageFile = 0;
    mem_status_.ullTotalVirtual = 0;
    mem_status_.ullAvailVirtual = 0;
  }

  void SetNone() {
    SetMemoryFree(moderate_threshold_mb() + 1);
  }

  void SetModerate() {
    SetMemoryFree(moderate_threshold_mb() - 1);
  }

  void SetCritical() {
    SetMemoryFree(critical_threshold_mb() - 1);
  }

 private:
  bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status) override {
    // Simply copy the memory status set by the test fixture.
    *mem_status = mem_status_;
    return true;
  }

  MEMORYSTATUSEX mem_status_;

  DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
};

class WinMemoryPressureMonitorTest : public testing::Test {
 protected:
  void CalculateCurrentMemoryPressureLevelTest(
      TestMemoryPressureMonitor* monitor) {

    int mod = monitor->moderate_threshold_mb();
    monitor->SetMemoryFree(mod + 1);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
              monitor->CalculateCurrentPressureLevel());

    monitor->SetMemoryFree(mod);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
              monitor->CalculateCurrentPressureLevel());

    monitor->SetMemoryFree(mod - 1);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
              monitor->CalculateCurrentPressureLevel());

    int crit = monitor->critical_threshold_mb();
    monitor->SetMemoryFree(crit + 1);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
              monitor->CalculateCurrentPressureLevel());

    monitor->SetMemoryFree(crit);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
              monitor->CalculateCurrentPressureLevel());

    monitor->SetMemoryFree(crit - 1);
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
              monitor->CalculateCurrentPressureLevel());
  }

  base::MessageLoopForUI message_loop_;
};

// Tests the fundamental direct calculation of memory pressure with automatic
// small-memory thresholds.
TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelSmall) {
  static const int kModerateMb =
      MemoryPressureMonitor::kSmallMemoryDefaultModerateThresholdMb;
  static const int kCriticalMb =
      MemoryPressureMonitor::kSmallMemoryDefaultCriticalThresholdMb;

  TestMemoryPressureMonitor monitor(false);  // Small-memory model.

  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());

  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
}

// Tests the fundamental direct calculation of memory pressure with automatic
// large-memory thresholds.
TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelLarge) {
  static const int kModerateMb =
      MemoryPressureMonitor::kLargeMemoryDefaultModerateThresholdMb;
  static const int kCriticalMb =
      MemoryPressureMonitor::kLargeMemoryDefaultCriticalThresholdMb;

  TestMemoryPressureMonitor monitor(true);  // Large-memory model.

  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());

  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
}

// Tests the fundamental direct calculation of memory pressure with manually
// specified threshold levels.
TEST_F(WinMemoryPressureMonitorTest,
       CalculateCurrentMemoryPressureLevelCustom) {
  static const int kSystemMb = 512;
  static const int kModerateMb = 256;
  static const int kCriticalMb = 128;

  TestMemoryPressureMonitor monitor(kSystemMb, kModerateMb, kCriticalMb);

  EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
  EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());

  ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
}

// This test tests the various transition states from memory pressure, looking
// for the correct behavior on event reposting as well as state updates.
TEST_F(WinMemoryPressureMonitorTest, CheckMemoryPressure) {
  // Large-memory.
  testing::StrictMock<TestMemoryPressureMonitor> monitor(true);
  MemoryPressureListener listener(
      base::Bind(&TestMemoryPressureMonitor::OnMemoryPressure,
                 base::Unretained(&monitor)));

  // Checking the memory pressure at 0% load should not produce any
  // events.
  monitor.SetNone();
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
            monitor.GetCurrentPressureLevel());

  // Setting the memory level to 80% should produce a moderate pressure level.
  EXPECT_CALL(monitor,
              OnMemoryPressure(MemoryPressureListener::
                                   MEMORY_PRESSURE_LEVEL_MODERATE));
  monitor.SetModerate();
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
            monitor.GetCurrentPressureLevel());
  testing::Mock::VerifyAndClearExpectations(&monitor);

  // Check that the event gets reposted after a while.
  for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
    if (i + 1 == monitor.kModeratePressureCooldownCycles) {
      EXPECT_CALL(monitor,
                  OnMemoryPressure(MemoryPressureListener::
                                       MEMORY_PRESSURE_LEVEL_MODERATE));
    }
    monitor.CheckMemoryPressure();
    RunLoop().RunUntilIdle();
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
              monitor.GetCurrentPressureLevel());
    testing::Mock::VerifyAndClearExpectations(&monitor);
  }

  // Setting the memory usage to 99% should produce critical levels.
  EXPECT_CALL(monitor,
              OnMemoryPressure(MemoryPressureListener::
                                   MEMORY_PRESSURE_LEVEL_CRITICAL));
  monitor.SetCritical();
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
            monitor.GetCurrentPressureLevel());
  testing::Mock::VerifyAndClearExpectations(&monitor);

  // Calling it again should immediately produce a second call.
  EXPECT_CALL(monitor,
              OnMemoryPressure(MemoryPressureListener::
                                   MEMORY_PRESSURE_LEVEL_CRITICAL));
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
            monitor.GetCurrentPressureLevel());
  testing::Mock::VerifyAndClearExpectations(&monitor);

  // When lowering the pressure again there should be a notification and the
  // pressure should go back to moderate.
  EXPECT_CALL(monitor,
              OnMemoryPressure(MemoryPressureListener::
                                   MEMORY_PRESSURE_LEVEL_MODERATE));
  monitor.SetModerate();
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
            monitor.GetCurrentPressureLevel());
  testing::Mock::VerifyAndClearExpectations(&monitor);

  // Check that the event gets reposted after a while.
  for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
    if (i + 1 == monitor.kModeratePressureCooldownCycles) {
      EXPECT_CALL(monitor,
                  OnMemoryPressure(MemoryPressureListener::
                                       MEMORY_PRESSURE_LEVEL_MODERATE));
    }
    monitor.CheckMemoryPressure();
    RunLoop().RunUntilIdle();
    EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
              monitor.GetCurrentPressureLevel());
    testing::Mock::VerifyAndClearExpectations(&monitor);
  }

  // Going down to no pressure should not produce an notification.
  monitor.SetNone();
  monitor.CheckMemoryPressure();
  RunLoop().RunUntilIdle();
  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
            monitor.GetCurrentPressureLevel());
  testing::Mock::VerifyAndClearExpectations(&monitor);
}

}  // namespace win
}  // namespace base
