memory_range_unittest.cc revision 8365e1d569a51487dcdcbde27c4563b6cae6e1d0
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
35using google_breakpad::MemoryRange;
36using testing::Message;
37
38namespace {
39
40const u_int32_t kBuffer[10] = { 0 };
41const size_t kBufferSize = sizeof(kBuffer);
42const u_int8_t* kBufferPointer = reinterpret_cast<const u_int8_t*>(kBuffer);
43
44// Test vectors for verifying Covers, GetData, and Subrange.
45const 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};
66const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]);
67
68// Test vectors for verifying GetArrayElement.
69const 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};
90const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]);
91
92}  // namespace
93
94TEST(MemoryRangeTest, DefaultConstructor) {
95  MemoryRange range;
96  EXPECT_EQ(NULL, range.data());
97  EXPECT_EQ(0, range.length());
98}
99
100TEST(MemoryRangeTest, ConstructorWithDataAndLength) {
101  MemoryRange range(kBuffer, kBufferSize);
102  EXPECT_EQ(kBufferPointer, range.data());
103  EXPECT_EQ(kBufferSize, range.length());
104}
105
106TEST(MemoryRangeTest, Reset) {
107  MemoryRange range;
108  range.Reset();
109  EXPECT_EQ(NULL, range.data());
110  EXPECT_EQ(0, 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(0, range.length());
119}
120
121TEST(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(0, range.length());
130}
131
132TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) {
133  MemoryRange range;
134  MemoryRange subrange = range.Subrange(0, 10);
135  EXPECT_EQ(NULL, subrange.data());
136  EXPECT_EQ(0, subrange.length());
137}
138
139TEST(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(0, subrange.length());
160    }
161  }
162}
163
164TEST(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
172TEST(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
187TEST(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