1 // Copyright (c) 2011, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // memory_range_unittest.cc: Unit tests for google_breakpad::MemoryRange. 31 32 #include "breakpad_googletest_includes.h" 33 #include "common/memory_range.h" 34 35 using google_breakpad::MemoryRange; 36 using testing::Message; 37 38 namespace { 39 40 const uint32_t kBuffer[10] = { 0 }; 41 const size_t kBufferSize = sizeof(kBuffer); 42 const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer); 43 44 // Test vectors for verifying Covers, GetData, and Subrange. 45 const struct { 46 bool valid; 47 size_t offset; 48 size_t length; 49 } kSubranges[] = { 50 { true, 0, 0 }, 51 { true, 0, 2 }, 52 { true, 0, kBufferSize }, 53 { true, 2, 0 }, 54 { true, 2, 4 }, 55 { true, 2, kBufferSize - 2 }, 56 { true, kBufferSize - 1, 1 }, 57 { false, kBufferSize, 0 }, 58 { false, kBufferSize, static_cast<size_t>(-1) }, 59 { false, kBufferSize + 1, 0 }, 60 { false, static_cast<size_t>(-1), 2 }, 61 { false, 1, kBufferSize }, 62 { false, kBufferSize - 1, 2 }, 63 { false, 0, static_cast<size_t>(-1) }, 64 { false, 1, static_cast<size_t>(-1) }, 65 }; 66 const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]); 67 68 // Test vectors for verifying GetArrayElement. 69 const struct { 70 size_t offset; 71 size_t size; 72 size_t index; 73 const void* const pointer; 74 } kElements[] = { 75 // Valid array elemenets 76 { 0, 1, 0, kBufferPointer }, 77 { 0, 1, 1, kBufferPointer + 1 }, 78 { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 }, 79 { 0, 2, 1, kBufferPointer + 2 }, 80 { 0, 4, 2, kBufferPointer + 8 }, 81 { 0, 4, 9, kBufferPointer + 36 }, 82 { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, 83 // Invalid array elemenets 84 { 0, 1, kBufferSize, NULL }, 85 { 0, 4, 10, NULL }, 86 { kBufferSize - 1, 1, 1, NULL }, 87 { kBufferSize - 1, 2, 0, NULL }, 88 { kBufferSize, 1, 0, NULL }, 89 }; 90 const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); 91 92 } // namespace 93 94 TEST(MemoryRangeTest, DefaultConstructor) { 95 MemoryRange range; 96 EXPECT_EQ(NULL, range.data()); 97 EXPECT_EQ(0U, range.length()); 98 } 99 100 TEST(MemoryRangeTest, ConstructorWithDataAndLength) { 101 MemoryRange range(kBuffer, kBufferSize); 102 EXPECT_EQ(kBufferPointer, range.data()); 103 EXPECT_EQ(kBufferSize, range.length()); 104 } 105 106 TEST(MemoryRangeTest, Reset) { 107 MemoryRange range; 108 range.Reset(); 109 EXPECT_EQ(NULL, range.data()); 110 EXPECT_EQ(0U, range.length()); 111 112 range.Set(kBuffer, kBufferSize); 113 EXPECT_EQ(kBufferPointer, range.data()); 114 EXPECT_EQ(kBufferSize, range.length()); 115 116 range.Reset(); 117 EXPECT_EQ(NULL, range.data()); 118 EXPECT_EQ(0U, range.length()); 119 } 120 121 TEST(MemoryRangeTest, Set) { 122 MemoryRange range; 123 range.Set(kBuffer, kBufferSize); 124 EXPECT_EQ(kBufferPointer, range.data()); 125 EXPECT_EQ(kBufferSize, range.length()); 126 127 range.Set(NULL, 0); 128 EXPECT_EQ(NULL, range.data()); 129 EXPECT_EQ(0U, range.length()); 130 } 131 132 TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) { 133 MemoryRange range; 134 MemoryRange subrange = range.Subrange(0, 10); 135 EXPECT_EQ(NULL, subrange.data()); 136 EXPECT_EQ(0U, subrange.length()); 137 } 138 139 TEST(MemoryRangeTest, SubrangeAndGetData) { 140 MemoryRange range(kBuffer, kBufferSize); 141 for (size_t i = 0; i < kNumSubranges; ++i) { 142 bool valid = kSubranges[i].valid; 143 size_t sub_offset = kSubranges[i].offset; 144 size_t sub_length = kSubranges[i].length; 145 SCOPED_TRACE(Message() << "offset=" << sub_offset 146 << ", length=" << sub_length); 147 148 MemoryRange subrange = range.Subrange(sub_offset, sub_length); 149 if (valid) { 150 EXPECT_TRUE(range.Covers(sub_offset, sub_length)); 151 EXPECT_EQ(kBufferPointer + sub_offset, 152 range.GetData(sub_offset, sub_length)); 153 EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); 154 EXPECT_EQ(sub_length, subrange.length()); 155 } else { 156 EXPECT_FALSE(range.Covers(sub_offset, sub_length)); 157 EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); 158 EXPECT_EQ(NULL, subrange.data()); 159 EXPECT_EQ(0U, subrange.length()); 160 } 161 } 162 } 163 164 TEST(MemoryRangeTest, GetDataWithTemplateType) { 165 MemoryRange range(kBuffer, kBufferSize); 166 const char* char_pointer = range.GetData<char>(0); 167 EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer); 168 const int* int_pointer = range.GetData<int>(0); 169 EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer); 170 } 171 172 TEST(MemoryRangeTest, GetArrayElement) { 173 MemoryRange range(kBuffer, kBufferSize); 174 for (size_t i = 0; i < kNumElements; ++i) { 175 size_t element_offset = kElements[i].offset; 176 size_t element_size = kElements[i].size; 177 unsigned element_index = kElements[i].index; 178 const void* const element_pointer = kElements[i].pointer; 179 SCOPED_TRACE(Message() << "offset=" << element_offset 180 << ", size=" << element_size 181 << ", index=" << element_index); 182 EXPECT_EQ(element_pointer, range.GetArrayElement( 183 element_offset, element_size, element_index)); 184 } 185 } 186 187 TEST(MemoryRangeTest, GetArrayElmentWithTemplateType) { 188 MemoryRange range(kBuffer, kBufferSize); 189 const char* char_pointer = range.GetArrayElement<char>(0, 0); 190 EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer); 191 const int* int_pointer = range.GetArrayElement<int>(0, 0); 192 EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer); 193 } 194