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
TEST(MemoryRangeTest,DefaultConstructor)94 TEST(MemoryRangeTest, DefaultConstructor) {
95 MemoryRange range;
96 EXPECT_EQ(NULL, range.data());
97 EXPECT_EQ(0U, range.length());
98 }
99
TEST(MemoryRangeTest,ConstructorWithDataAndLength)100 TEST(MemoryRangeTest, ConstructorWithDataAndLength) {
101 MemoryRange range(kBuffer, kBufferSize);
102 EXPECT_EQ(kBufferPointer, range.data());
103 EXPECT_EQ(kBufferSize, range.length());
104 }
105
TEST(MemoryRangeTest,Reset)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
TEST(MemoryRangeTest,Set)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
TEST(MemoryRangeTest,SubrangeOfEmptyMemoryRange)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
TEST(MemoryRangeTest,SubrangeAndGetData)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
TEST(MemoryRangeTest,GetDataWithTemplateType)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
TEST(MemoryRangeTest,GetArrayElement)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
TEST(MemoryRangeTest,GetArrayElmentWithTemplateType)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