// Copyright 2014 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/discardable_memory_manager.h"

#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

class TestAllocationImpl : public internal::DiscardableMemoryManagerAllocation {
 public:
  TestAllocationImpl() : is_allocated_(false), is_locked_(false) {}
  ~TestAllocationImpl() override { DCHECK(!is_locked_); }

  // Overridden from internal::DiscardableMemoryManagerAllocation:
  bool AllocateAndAcquireLock() override {
    bool was_allocated = is_allocated_;
    is_allocated_ = true;
    DCHECK(!is_locked_);
    is_locked_ = true;
    return was_allocated;
  }
  void ReleaseLock() override {
    DCHECK(is_locked_);
    is_locked_ = false;
  }
  void Purge() override {
    DCHECK(is_allocated_);
    is_allocated_ = false;
  }
  virtual bool IsMemoryResident() const override {
    DCHECK(is_allocated_);
    return true;
  }

  bool is_locked() const { return is_locked_; }

 private:
  bool is_allocated_;
  bool is_locked_;
};

// Tests can assume that the default limit is at least 1024. Tests that rely on
// something else needs to explicit set the limit.
const size_t kDefaultMemoryLimit = 1024;
const size_t kDefaultSoftMemoryLimit = kDefaultMemoryLimit;

class TestDiscardableMemoryManagerImpl
    : public internal::DiscardableMemoryManager {
 public:
  TestDiscardableMemoryManagerImpl()
      : DiscardableMemoryManager(kDefaultMemoryLimit,
                                 kDefaultSoftMemoryLimit,
                                 TimeDelta::Max()) {}

  void SetNow(TimeTicks now) { now_ = now; }

 private:
  // Overriden from internal::DiscardableMemoryManager:
  TimeTicks Now() const override { return now_; }

  TimeTicks now_;
};

class DiscardableMemoryManagerTestBase {
 public:
  DiscardableMemoryManagerTestBase() {}

 protected:
  enum LockStatus {
    LOCK_STATUS_FAILED,
    LOCK_STATUS_PURGED,
    LOCK_STATUS_SUCCESS
  };

  size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); }

  void SetMemoryLimit(size_t bytes) { manager_.SetMemoryLimit(bytes); }

  void SetSoftMemoryLimit(size_t bytes) { manager_.SetSoftMemoryLimit(bytes); }

  void SetHardMemoryLimitExpirationTime(TimeDelta time) {
    manager_.SetHardMemoryLimitExpirationTime(time);
  }

  void Register(TestAllocationImpl* allocation, size_t bytes) {
    manager_.Register(allocation, bytes);
  }

  void Unregister(TestAllocationImpl* allocation) {
    manager_.Unregister(allocation);
  }

  bool IsRegistered(TestAllocationImpl* allocation) const {
    return manager_.IsRegisteredForTest(allocation);
  }

  LockStatus Lock(TestAllocationImpl* allocation) {
    bool purged;
    if (!manager_.AcquireLock(allocation, &purged))
      return LOCK_STATUS_FAILED;
    return purged ? LOCK_STATUS_PURGED : LOCK_STATUS_SUCCESS;
  }

  void Unlock(TestAllocationImpl* allocation) {
    manager_.ReleaseLock(allocation);
  }

  LockStatus RegisterAndLock(TestAllocationImpl* allocation, size_t bytes) {
    manager_.Register(allocation, bytes);
    return Lock(allocation);
  }

  bool CanBePurged(TestAllocationImpl* allocation) const {
    return manager_.CanBePurgedForTest(allocation);
  }

  void SetNow(TimeTicks now) { manager_.SetNow(now); }

  void PurgeAll() { return manager_.PurgeAll(); }

  bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); }

  void ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
    manager_.ReduceMemoryUsageUntilWithinLimit(bytes);
  }

 private:
  TestDiscardableMemoryManagerImpl manager_;
};

class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase,
                                     public testing::Test {
 public:
  DiscardableMemoryManagerTest() {}
};

TEST_F(DiscardableMemoryManagerTest, CreateAndLock) {
  size_t size = 1024;
  TestAllocationImpl allocation;
  Register(&allocation, size);
  EXPECT_TRUE(IsRegistered(&allocation));
  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
  EXPECT_TRUE(allocation.is_locked());
  EXPECT_EQ(1024u, BytesAllocated());
  EXPECT_FALSE(CanBePurged(&allocation));
  Unlock(&allocation);
  Unregister(&allocation);
}

TEST_F(DiscardableMemoryManagerTest, CreateZeroSize) {
  size_t size = 0;
  TestAllocationImpl allocation;
  Register(&allocation, size);
  EXPECT_TRUE(IsRegistered(&allocation));
  EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&allocation));
  EXPECT_EQ(0u, BytesAllocated());
  Unregister(&allocation);
}

TEST_F(DiscardableMemoryManagerTest, LockAfterUnlock) {
  size_t size = 1024;
  TestAllocationImpl allocation;
  RegisterAndLock(&allocation, size);
  EXPECT_EQ(1024u, BytesAllocated());
  EXPECT_FALSE(CanBePurged(&allocation));

  // Now unlock so we can lock later.
  Unlock(&allocation);
  EXPECT_TRUE(CanBePurged(&allocation));

  EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(&allocation));
  EXPECT_FALSE(CanBePurged(&allocation));
  Unlock(&allocation);
  Unregister(&allocation);
}

TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) {
  size_t size = 1024;
  TestAllocationImpl allocation;
  RegisterAndLock(&allocation, size);
  EXPECT_EQ(1024u, BytesAllocated());
  EXPECT_FALSE(CanBePurged(&allocation));

  // Now unlock so we can lock later.
  Unlock(&allocation);
  EXPECT_TRUE(CanBePurged(&allocation));

  // Force the system to purge.
  PurgeAll();

  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
  EXPECT_FALSE(CanBePurged(&allocation));

  Unlock(&allocation);
  Unregister(&allocation);
}

TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) {
  size_t size = 1024;
  TestAllocationImpl allocation;
  RegisterAndLock(&allocation, size);
  EXPECT_EQ(1024u, BytesAllocated());
  EXPECT_FALSE(CanBePurged(&allocation));

  // Now unlock so we can lock later.
  Unlock(&allocation);
  EXPECT_TRUE(CanBePurged(&allocation));

  // Set max allowed allocation to 1 byte. This will cause the memory to be
  // purged.
  SetMemoryLimit(1);

  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
  EXPECT_FALSE(CanBePurged(&allocation));

  Unlock(&allocation);
  Unregister(&allocation);
}

TEST_F(DiscardableMemoryManagerTest, Overflow) {
  size_t size = 1024;
  {
    TestAllocationImpl allocation;
    RegisterAndLock(&allocation, size);
    EXPECT_EQ(1024u, BytesAllocated());

    size_t massive_size = std::numeric_limits<size_t>::max();
    TestAllocationImpl massive_allocation;
    Register(&massive_allocation, massive_size);
    EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&massive_allocation));
    EXPECT_EQ(1024u, BytesAllocated());

    Unlock(&allocation);
    EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&massive_allocation));
    Unlock(&massive_allocation);
    Unregister(&massive_allocation);
    Unregister(&allocation);
  }
  EXPECT_EQ(0u, BytesAllocated());
}

class PermutationTestData {
 public:
  PermutationTestData(unsigned d0, unsigned d1, unsigned d2) {
    ordering_[0] = d0;
    ordering_[1] = d1;
    ordering_[2] = d2;
  }

  const unsigned* ordering() const { return ordering_; }

 private:
  unsigned ordering_[3];
};

class DiscardableMemoryManagerPermutationTest
    : public DiscardableMemoryManagerTestBase,
      public testing::TestWithParam<PermutationTestData> {
 public:
  DiscardableMemoryManagerPermutationTest() {}

 protected:
  // Use memory in order specified by ordering parameter.
  void RegisterAndUseAllocations() {
    for (int i = 0; i < 3; ++i) {
      RegisterAndLock(&allocation_[i], 1024);
      Unlock(&allocation_[i]);
    }
    for (int i = 0; i < 3; ++i) {
      int index = GetParam().ordering()[i];
      EXPECT_NE(LOCK_STATUS_FAILED, Lock(&allocation_[index]));
      // Leave i == 0 locked.
      if (i > 0)
        Unlock(&allocation_[index]);
    }
  }

  TestAllocationImpl* allocation(unsigned position) {
    return &allocation_[GetParam().ordering()[position]];
  }

  void UnlockAndUnregisterAllocations() {
    for (int i = 0; i < 3; ++i) {
      if (allocation_[i].is_locked())
        Unlock(&allocation_[i]);
      Unregister(&allocation_[i]);
    }
  }

 private:
  TestAllocationImpl allocation_[3];
};

// Verify that memory was discarded in the correct order after reducing usage to
// limit.
TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscarded) {
  RegisterAndUseAllocations();

  SetMemoryLimit(2048);

  ReduceMemoryUsageUntilWithinLimit(1024);

  EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
  // 0 should still be locked.
  EXPECT_TRUE(allocation(0)->is_locked());

  UnlockAndUnregisterAllocations();
}

// Verify that memory was discarded in the correct order after changing
// memory limit.
TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) {
  RegisterAndUseAllocations();

  SetMemoryLimit(2048);

  EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
  // 0 should still be locked.
  EXPECT_TRUE(allocation(0)->is_locked());

  UnlockAndUnregisterAllocations();
}

// Verify that no more memory than necessary was discarded after changing
// memory limit.
TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) {
  SetMemoryLimit(4096);

  RegisterAndUseAllocations();

  SetMemoryLimit(2048);

  EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(allocation(2)));
  EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
  // 0 should still be locked.
  EXPECT_TRUE(allocation(0)->is_locked());

  UnlockAndUnregisterAllocations();
}

TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) {
  RegisterAndUseAllocations();

  PurgeAll();

  for (int i = 0; i < 3; ++i) {
    if (i == 0)
      EXPECT_TRUE(allocation(i)->is_locked());
    else
      EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i)));
  }

  UnlockAndUnregisterAllocations();
}

INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests,
                        DiscardableMemoryManagerPermutationTest,
                        ::testing::Values(PermutationTestData(0, 1, 2),
                                          PermutationTestData(0, 2, 1),
                                          PermutationTestData(1, 0, 2),
                                          PermutationTestData(1, 2, 0),
                                          PermutationTestData(2, 0, 1),
                                          PermutationTestData(2, 1, 0)));

TEST_F(DiscardableMemoryManagerTest, NormalDestruction) {
  {
    size_t size = 1024;
    TestAllocationImpl allocation;
    Register(&allocation, size);
    Unregister(&allocation);
  }
  EXPECT_EQ(0u, BytesAllocated());
}

TEST_F(DiscardableMemoryManagerTest, DestructionAfterLocked) {
  {
    size_t size = 1024;
    TestAllocationImpl allocation;
    RegisterAndLock(&allocation, size);
    EXPECT_EQ(1024u, BytesAllocated());
    EXPECT_FALSE(CanBePurged(&allocation));
    Unlock(&allocation);
    Unregister(&allocation);
  }
  EXPECT_EQ(0u, BytesAllocated());
}

TEST_F(DiscardableMemoryManagerTest, DestructionAfterPurged) {
  {
    size_t size = 1024;
    TestAllocationImpl allocation;
    RegisterAndLock(&allocation, size);
    EXPECT_EQ(1024u, BytesAllocated());
    Unlock(&allocation);
    EXPECT_TRUE(CanBePurged(&allocation));
    SetMemoryLimit(0);
    EXPECT_EQ(0u, BytesAllocated());
    Unregister(&allocation);
  }
  EXPECT_EQ(0u, BytesAllocated());
}

TEST_F(DiscardableMemoryManagerTest, ReduceMemoryUsage) {
  SetMemoryLimit(3072);
  SetSoftMemoryLimit(1024);
  SetHardMemoryLimitExpirationTime(TimeDelta::FromInternalValue(1));

  size_t size = 1024;
  TestAllocationImpl allocation[3];
  RegisterAndLock(&allocation[0], size);
  RegisterAndLock(&allocation[1], size);
  RegisterAndLock(&allocation[2], size);
  EXPECT_EQ(3072u, BytesAllocated());

  // Above soft limit but nothing that can be purged.
  EXPECT_FALSE(ReduceMemoryUsage());

  SetNow(TimeTicks::FromInternalValue(0));
  Unlock(&allocation[0]);

  // Above soft limit but still nothing that can be purged as all unlocked
  // allocations are within the hard limit cutoff time.
  EXPECT_FALSE(ReduceMemoryUsage());

  SetNow(TimeTicks::FromInternalValue(1));
  Unlock(&allocation[1]);

  // One unlocked allocation is no longer within the hard limit cutoff time. It
  // should be purged and ReduceMemoryUsage() should return false as we're not
  // yet within the soft memory limit.
  EXPECT_FALSE(ReduceMemoryUsage());
  EXPECT_EQ(2048u, BytesAllocated());

  // One more unlocked allocation is no longer within the hard limit cutoff
  // time. It should be purged and ReduceMemoryUsage() should return true as
  // we're now within the soft memory limit.
  SetNow(TimeTicks::FromInternalValue(2));
  EXPECT_TRUE(ReduceMemoryUsage());
  EXPECT_EQ(1024u, BytesAllocated());

  Unlock(&allocation[2]);

  Unregister(&allocation[0]);
  Unregister(&allocation[1]);
  Unregister(&allocation[2]);
}

class ThreadedDiscardableMemoryManagerTest
    : public DiscardableMemoryManagerTest {
 public:
  ThreadedDiscardableMemoryManagerTest()
      : memory_usage_thread_("memory_usage_thread"),
        thread_sync_(true, false) {}

  virtual void SetUp() override { memory_usage_thread_.Start(); }

  virtual void TearDown() override { memory_usage_thread_.Stop(); }

  void UseMemoryHelper() {
    size_t size = 1024;
    TestAllocationImpl allocation;
    RegisterAndLock(&allocation, size);
    Unlock(&allocation);
    Unregister(&allocation);
  }

  void SignalHelper() { thread_sync_.Signal(); }

  Thread memory_usage_thread_;
  WaitableEvent thread_sync_;
};

TEST_F(ThreadedDiscardableMemoryManagerTest, UseMemoryOnThread) {
  memory_usage_thread_.message_loop()->PostTask(
      FROM_HERE,
      Bind(&ThreadedDiscardableMemoryManagerTest::UseMemoryHelper,
           Unretained(this)));
  memory_usage_thread_.message_loop()->PostTask(
      FROM_HERE,
      Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper,
           Unretained(this)));
  thread_sync_.Wait();
}

}  // namespace
}  // namespace base
