Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/discardable_memory.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/run_loop.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 #if defined(OS_ANDROID)
     13 #include <limits>
     14 #endif
     15 
     16 namespace base {
     17 namespace {
     18 
     19 class DiscardableMemoryTest
     20     : public testing::TestWithParam<DiscardableMemoryType> {
     21  public:
     22   DiscardableMemoryTest() : message_loop_(MessageLoop::TYPE_IO) {
     23     // Register memory pressure listeners now that we have a message loop.
     24     DiscardableMemory::RegisterMemoryPressureListeners();
     25   }
     26   virtual ~DiscardableMemoryTest() {
     27     DiscardableMemory::UnregisterMemoryPressureListeners();
     28   }
     29 
     30  protected:
     31   scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) {
     32     return DiscardableMemory::CreateLockedMemoryWithType(
     33         GetParam(), size).Pass();
     34   }
     35 
     36  private:
     37   MessageLoop message_loop_;
     38 };
     39 
     40 const size_t kSize = 1024;
     41 
     42 TEST_P(DiscardableMemoryTest, IsNamed) {
     43   std::string type_name(DiscardableMemory::GetTypeName(GetParam()));
     44   EXPECT_NE("unknown", type_name);
     45   EXPECT_EQ(GetParam(), DiscardableMemory::GetNamedType(type_name));
     46 }
     47 
     48 bool IsNativeType(DiscardableMemoryType type) {
     49   return
     50       type == DISCARDABLE_MEMORY_TYPE_ASHMEM ||
     51       type == DISCARDABLE_MEMORY_TYPE_MAC;
     52 }
     53 
     54 TEST_P(DiscardableMemoryTest, SupportedNatively) {
     55   std::vector<DiscardableMemoryType> supported_types;
     56   DiscardableMemory::GetSupportedTypes(&supported_types);
     57 #if defined(DISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY)
     58   EXPECT_NE(0, std::count_if(supported_types.begin(),
     59                              supported_types.end(),
     60                              IsNativeType));
     61 #else
     62   // If we ever have a platform that decides at runtime if it can support
     63   // discardable memory natively, then we'll have to add a 'never supported
     64   // natively' define for this case. At present, if it's not always supported
     65   // natively, it's never supported.
     66   EXPECT_EQ(0, std::count_if(supported_types.begin(),
     67                              supported_types.end(),
     68                              IsNativeType));
     69 #endif
     70 }
     71 
     72 // Test Lock() and Unlock() functionalities.
     73 TEST_P(DiscardableMemoryTest, LockAndUnLock) {
     74   const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
     75   ASSERT_TRUE(memory);
     76   void* addr = memory->Memory();
     77   ASSERT_NE(static_cast<void*>(NULL), addr);
     78 
     79   memory->Unlock();
     80 
     81   EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, memory->Lock());
     82   addr = memory->Memory();
     83   ASSERT_NE(static_cast<void*>(NULL), addr);
     84 
     85   memory->Unlock();
     86 }
     87 
     88 // Test delete a discardable memory while it is locked.
     89 TEST_P(DiscardableMemoryTest, DeleteWhileLocked) {
     90   const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
     91   ASSERT_TRUE(memory);
     92 }
     93 
     94 // Test forced purging.
     95 TEST_P(DiscardableMemoryTest, Purge) {
     96   const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
     97   ASSERT_TRUE(memory);
     98   memory->Unlock();
     99 
    100   DiscardableMemory::PurgeForTesting();
    101   EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, memory->Lock());
    102 }
    103 
    104 #if !defined(NDEBUG) && !defined(OS_ANDROID)
    105 // Death tests are not supported with Android APKs.
    106 TEST_P(DiscardableMemoryTest, UnlockedMemoryAccessCrashesInDebugMode) {
    107   const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
    108   ASSERT_TRUE(memory);
    109   memory->Unlock();
    110   ASSERT_DEATH_IF_SUPPORTED(
    111       { *static_cast<int*>(memory->Memory()) = 0xdeadbeef; }, ".*");
    112 }
    113 #endif
    114 
    115 std::vector<DiscardableMemoryType> GetSupportedDiscardableMemoryTypes() {
    116   std::vector<DiscardableMemoryType> supported_types;
    117   DiscardableMemory::GetSupportedTypes(&supported_types);
    118   return supported_types;
    119 }
    120 
    121 INSTANTIATE_TEST_CASE_P(
    122     DiscardableMemoryTests,
    123     DiscardableMemoryTest,
    124     ::testing::ValuesIn(GetSupportedDiscardableMemoryTypes()));
    125 
    126 }  // namespace
    127 }  // namespace base
    128