| 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 |