Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / mojo / system / memory_unittest.cc
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/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