OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "mojo/edk/system/memory.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include <limits> | |
11 | |
12 #include "mojo/public/c/system/macros.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace mojo { | |
16 namespace system { | |
17 namespace { | |
18 | |
19 TEST(MemoryTest, Valid) { | |
20 char my_char; | |
21 int32_t my_int32; | |
22 int64_t my_int64_array[5] = {}; // Zero initialize. | |
23 | |
24 UserPointer<char> my_char_ptr(&my_char); | |
25 UserPointer<int32_t> my_int32_ptr(&my_int32); | |
26 UserPointer<int64_t> my_int64_array_ptr(my_int64_array); | |
27 | |
28 // |UserPointer<>::IsNull()|: | |
29 EXPECT_FALSE(my_char_ptr.IsNull()); | |
30 EXPECT_FALSE(my_int32_ptr.IsNull()); | |
31 EXPECT_FALSE(my_int64_array_ptr.IsNull()); | |
32 | |
33 // |UserPointer<>::Put()| and |UserPointer<>::Get()|: | |
34 my_char_ptr.Put('x'); | |
35 EXPECT_EQ('x', my_char); | |
36 EXPECT_EQ('x', my_char_ptr.Get()); | |
37 my_int32_ptr.Put(123); | |
38 EXPECT_EQ(123, my_int32); | |
39 EXPECT_EQ(123, my_int32_ptr.Get()); | |
40 my_int64_array_ptr.Put(456); | |
41 EXPECT_EQ(456, my_int64_array[0]); | |
42 EXPECT_EQ(456, my_int64_array_ptr.Get()); | |
43 | |
44 // |UserPointer<>::At()|, etc.: | |
45 my_int64_array_ptr.At(3).Put(789); | |
46 EXPECT_EQ(789, my_int64_array[3]); | |
47 { | |
48 // Copy construction: | |
49 UserPointer<int64_t> other(my_int64_array_ptr.At(3)); | |
50 EXPECT_FALSE(other.IsNull()); | |
51 EXPECT_EQ(789, other.Get()); | |
52 | |
53 // Assignment: | |
54 other = my_int64_array_ptr; | |
55 EXPECT_FALSE(other.IsNull()); | |
56 EXPECT_EQ(456, other.Get()); | |
57 | |
58 // Assignment to |NullUserPointer()|: | |
59 other = NullUserPointer(); | |
60 EXPECT_TRUE(other.IsNull()); | |
61 | |
62 // |MakeUserPointer()|: | |
63 other = MakeUserPointer(&my_int64_array[1]); | |
64 other.Put(-123); | |
65 EXPECT_EQ(-123, my_int64_array_ptr.At(1).Get()); | |
66 } | |
67 | |
68 // "const" |UserPointer<>|: | |
69 { | |
70 // Explicit constructor from |NullUserPointer()|: | |
71 UserPointer<const char> other((NullUserPointer())); | |
72 EXPECT_TRUE(other.IsNull()); | |
73 | |
74 // Conversion to "const": | |
75 other = my_char_ptr; | |
76 EXPECT_EQ('x', other.Get()); | |
77 } | |
78 | |
79 // Default constructor: | |
80 { | |
81 UserPointer<int32_t> other; | |
82 EXPECT_TRUE(other.IsNull()); | |
83 | |
84 other = my_int32_ptr; | |
85 other.Put(-456); | |
86 EXPECT_EQ(-456, my_int32_ptr.Get()); | |
87 } | |
88 | |
89 // |UserPointer<>::CheckArray()|: | |
90 my_int64_array_ptr.CheckArray(5); | |
91 | |
92 // |UserPointer<>::GetArray()|: | |
93 { | |
94 // From a "const" |UserPointer<>| (why not?): | |
95 UserPointer<const int64_t> other(my_int64_array_ptr); | |
96 int64_t array[3] = {1, 2, 3}; | |
97 other.At(1).GetArray(array, 3); | |
98 EXPECT_EQ(-123, array[0]); | |
99 EXPECT_EQ(0, array[1]); | |
100 EXPECT_EQ(789, array[2]); | |
101 } | |
102 | |
103 // |UserPointer<>::PutArray()|: | |
104 { | |
105 const int64_t array[2] = {654, 321}; | |
106 my_int64_array_ptr.At(3).PutArray(array, 2); | |
107 EXPECT_EQ(0, my_int64_array[2]); | |
108 EXPECT_EQ(654, my_int64_array[3]); | |
109 EXPECT_EQ(321, my_int64_array[4]); | |
110 } | |
111 | |
112 // |UserPointer<>::Reader|: | |
113 { | |
114 UserPointer<int64_t>::Reader reader(my_int64_array_ptr, 5); | |
115 EXPECT_EQ(456, reader.GetPointer()[0]); | |
116 EXPECT_EQ(321, reader.GetPointer()[4]); | |
117 } | |
118 | |
119 // Non-const to const: | |
120 { | |
121 UserPointer<const int64_t>::Reader reader(my_int64_array_ptr.At(3), 1); | |
122 const int64_t* ptr = reader.GetPointer(); | |
123 EXPECT_EQ(654, *ptr); | |
124 } | |
125 | |
126 // |UserPointer<>::Writer|: | |
127 { | |
128 UserPointer<int64_t>::Writer writer(my_int64_array_ptr.At(2), 1); | |
129 int64_t* ptr = writer.GetPointer(); | |
130 *ptr = 1234567890123LL; | |
131 writer.Commit(); | |
132 EXPECT_EQ(1234567890123LL, my_int64_array[2]); | |
133 } | |
134 | |
135 // |UserPointer<>::ReaderWriter|: | |
136 { | |
137 UserPointer<int32_t>::ReaderWriter reader_writer(my_int32_ptr, 1); | |
138 int32_t* ptr = reader_writer.GetPointer(); | |
139 EXPECT_EQ(-456, *ptr); | |
140 *ptr = 42; | |
141 reader_writer.Commit(); | |
142 EXPECT_EQ(42, my_int32); | |
143 } | |
144 | |
145 // |UserPointer<>::ReinterpretCast<>|: | |
146 // (This assumes little-endian, etc.) | |
147 { | |
148 UserPointer<const char> other(my_int32_ptr.ReinterpretCast<char>()); | |
149 EXPECT_EQ(42, other.Get()); | |
150 EXPECT_EQ(0, other.At(1).Get()); | |
151 EXPECT_EQ(0, other.At(2).Get()); | |
152 EXPECT_EQ(0, other.At(3).Get()); | |
153 } | |
154 | |
155 // |UserPointer<>::GetPointerValue()|: | |
156 { | |
157 UserPointer<int32_t> other; | |
158 EXPECT_EQ(0u, other.GetPointerValue()); | |
159 other = my_int32_ptr; | |
160 EXPECT_EQ(reinterpret_cast<uintptr_t>(&my_int32), other.GetPointerValue()); | |
161 } | |
162 } | |
163 | |
164 TEST(MemoryTest, InvalidDeath) { | |
165 const char kMemoryCheckFailedRegex[] = "Check failed"; | |
166 | |
167 // Note: |Check...()| are defined to be "best effort" checks (and may always | |
168 // return true). Thus these tests of invalid cases only reflect the current | |
169 // implementation. | |
170 | |
171 // These tests depend on |int32_t| and |int64_t| having nontrivial alignment. | |
172 static_assert(MOJO_ALIGNOF(int32_t) != 1, | |
173 "int32_t does not require nontrivial alignment"); | |
174 static_assert(MOJO_ALIGNOF(int64_t) != 1, | |
175 "int64_t does not require nontrivial alignment"); | |
176 | |
177 // Null: | |
178 { | |
179 UserPointer<char> ptr(nullptr); | |
180 char array[5] = {}; | |
181 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
182 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
183 EXPECT_DEATH_IF_SUPPORTED(ptr.Put('x'), kMemoryCheckFailedRegex); | |
184 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
185 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
186 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex); | |
187 } | |
188 { | |
189 UserPointer<int32_t> ptr(nullptr); | |
190 int32_t array[5] = {}; | |
191 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
192 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
193 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex); | |
194 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
195 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
196 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex); | |
197 } | |
198 { | |
199 UserPointer<int64_t> ptr(nullptr); | |
200 int64_t array[5] = {}; | |
201 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
202 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
203 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex); | |
204 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
205 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
206 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex); | |
207 } | |
208 // Also check a const pointer: | |
209 { | |
210 UserPointer<const int32_t> ptr(nullptr); | |
211 int32_t array[5] = {}; | |
212 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
213 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
214 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
215 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
216 } | |
217 | |
218 // Unaligned: | |
219 { | |
220 int32_t x[10]; | |
221 UserPointer<int32_t> ptr( | |
222 reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(x) + 1)); | |
223 int32_t array[5] = {}; | |
224 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
225 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
226 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex); | |
227 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
228 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
229 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex); | |
230 } | |
231 { | |
232 int64_t x[10]; | |
233 UserPointer<int64_t> ptr( | |
234 reinterpret_cast<int64_t*>(reinterpret_cast<uintptr_t>(x) + 1)); | |
235 int64_t array[5] = {}; | |
236 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
237 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
238 EXPECT_DEATH_IF_SUPPORTED(ptr.Put(123), kMemoryCheckFailedRegex); | |
239 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
240 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
241 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(array, 5), kMemoryCheckFailedRegex); | |
242 } | |
243 // Also check a const pointer: | |
244 { | |
245 int32_t x[10]; | |
246 UserPointer<const int32_t> ptr( | |
247 reinterpret_cast<const int32_t*>(reinterpret_cast<uintptr_t>(x) + 1)); | |
248 int32_t array[5] = {}; | |
249 EXPECT_DEATH_IF_SUPPORTED(ptr.Check(), kMemoryCheckFailedRegex); | |
250 EXPECT_DEATH_IF_SUPPORTED(ptr.Get(), kMemoryCheckFailedRegex); | |
251 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(5), kMemoryCheckFailedRegex); | |
252 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(array, 5), kMemoryCheckFailedRegex); | |
253 } | |
254 | |
255 // Count too big: | |
256 { | |
257 const size_t kTooBig = | |
258 std::numeric_limits<size_t>::max() / sizeof(int32_t) + 1; | |
259 int32_t x = 0; | |
260 UserPointer<int32_t> ptr(&x); | |
261 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex); | |
262 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig), | |
263 kMemoryCheckFailedRegex); | |
264 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(&x, kTooBig), | |
265 kMemoryCheckFailedRegex); | |
266 } | |
267 { | |
268 const size_t kTooBig = | |
269 std::numeric_limits<size_t>::max() / sizeof(int64_t) + 1; | |
270 int64_t x = 0; | |
271 UserPointer<int64_t> ptr(&x); | |
272 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex); | |
273 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig), | |
274 kMemoryCheckFailedRegex); | |
275 EXPECT_DEATH_IF_SUPPORTED(ptr.PutArray(&x, kTooBig), | |
276 kMemoryCheckFailedRegex); | |
277 } | |
278 // Also check a const pointer: | |
279 { | |
280 const size_t kTooBig = | |
281 std::numeric_limits<size_t>::max() / sizeof(int32_t) + 1; | |
282 int32_t x = 0; | |
283 UserPointer<const int32_t> ptr(&x); | |
284 EXPECT_DEATH_IF_SUPPORTED(ptr.CheckArray(kTooBig), kMemoryCheckFailedRegex); | |
285 EXPECT_DEATH_IF_SUPPORTED(ptr.GetArray(&x, kTooBig), | |
286 kMemoryCheckFailedRegex); | |
287 } | |
288 | |
289 // TODO(vtl): Tests for |UserPointer{Reader,Writer,ReaderWriter}|. | |
290 } | |
291 | |
292 } // namespace | |
293 } // namespace system | |
294 } // namespace mojo | |
OLD | NEW |