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