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