OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/allocation_scope.h" | |
6 #include "mojo/public/cpp/bindings/array.h" | 5 #include "mojo/public/cpp/bindings/array.h" |
| 6 #include "mojo/public/cpp/bindings/lib/array_serialization.h" |
7 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" | 7 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" |
8 #include "mojo/public/cpp/bindings/lib/scratch_buffer.h" | |
9 #include "mojo/public/cpp/environment/environment.h" | 8 #include "mojo/public/cpp/environment/environment.h" |
10 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 9 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
12 | 11 |
13 namespace mojo { | 12 namespace mojo { |
14 namespace test { | 13 namespace test { |
15 namespace { | 14 namespace { |
16 | 15 |
17 // Tests that basic Array operations work. | 16 // Tests that basic Array operations work. |
18 TEST(ArrayTest, Basic) { | 17 TEST(ArrayTest, Basic) { |
19 Environment env; | 18 Array<char> array(8); |
20 | 19 for (size_t i = 0; i < array.size(); ++i) { |
21 // 8 bytes for the array, with 8 bytes left over for elements. | |
22 internal::FixedBuffer buf(8 + 8*sizeof(char)); | |
23 EXPECT_EQ(16u, buf.size()); | |
24 | |
25 Array<char>::Builder builder(8); | |
26 EXPECT_EQ(8u, builder.size()); | |
27 for (size_t i = 0; i < builder.size(); ++i) { | |
28 char val = static_cast<char>(i*2); | 20 char val = static_cast<char>(i*2); |
29 builder[i] = val; | 21 array[i] = val; |
30 EXPECT_EQ(val, builder.at(i)); | 22 EXPECT_EQ(val, array.at(i)); |
31 } | |
32 Array<char> array = builder.Finish(); | |
33 for (size_t i = 0; i < array.size(); ++i) { | |
34 char val = static_cast<char>(i) * 2; | |
35 EXPECT_EQ(val, array[i]); | |
36 } | 23 } |
37 } | 24 } |
38 | 25 |
39 // Tests that basic Array<bool> operations work, and that it's packed into 1 | 26 // Tests that basic Array<bool> operations work. |
40 // bit per element. | |
41 TEST(ArrayTest, Bool) { | 27 TEST(ArrayTest, Bool) { |
42 Environment env; | 28 Array<bool> array(64); |
43 | |
44 // 8 bytes for the array header, with 8 bytes left over for elements. | |
45 internal::FixedBuffer buf(8 + 3); | |
46 EXPECT_EQ(16u, buf.size()); | |
47 | |
48 // An array of 64 bools can fit into 8 bytes. | |
49 Array<bool>::Builder builder(64); | |
50 EXPECT_EQ(64u, builder.size()); | |
51 for (size_t i = 0; i < builder.size(); ++i) { | |
52 bool val = i % 3 == 0; | |
53 builder[i] = val; | |
54 EXPECT_EQ(val, builder.at(i)); | |
55 } | |
56 Array<bool> array = builder.Finish(); | |
57 for (size_t i = 0; i < array.size(); ++i) { | 29 for (size_t i = 0; i < array.size(); ++i) { |
58 bool val = i % 3 == 0; | 30 bool val = i % 3 == 0; |
59 EXPECT_EQ(val, array[i]); | 31 array[i] = val; |
| 32 EXPECT_EQ(val, array.at(i)); |
60 } | 33 } |
61 } | 34 } |
62 | 35 |
63 // Tests that Array<Handle> supports transferring handles. | 36 // Tests that Array<ScopedMessagePipeHandle> supports transferring handles. |
64 TEST(ArrayTest, Handle) { | 37 TEST(ArrayTest, Handle) { |
65 Environment env; | |
66 | |
67 AllocationScope scope; | |
68 | |
69 ScopedMessagePipeHandle pipe0, pipe1; | 38 ScopedMessagePipeHandle pipe0, pipe1; |
70 CreateMessagePipe(&pipe0, &pipe1); | 39 CreateMessagePipe(&pipe0, &pipe1); |
71 | 40 |
72 Array<MessagePipeHandle>::Builder handles_builder(2); | 41 Array<ScopedMessagePipeHandle> handles(2); |
73 handles_builder[0] = pipe0.Pass(); | 42 handles[0] = pipe0.Pass(); |
74 handles_builder[1].reset(pipe1.release()); | 43 handles[1].reset(pipe1.release()); |
75 | 44 |
76 EXPECT_FALSE(pipe0.is_valid()); | 45 EXPECT_FALSE(pipe0.is_valid()); |
77 EXPECT_FALSE(pipe1.is_valid()); | 46 EXPECT_FALSE(pipe1.is_valid()); |
78 | 47 |
79 Array<MessagePipeHandle> handles = handles_builder.Finish(); | 48 Array<ScopedMessagePipeHandle> handles2 = handles.Pass(); |
80 EXPECT_TRUE(handles[0].is_valid()); | 49 EXPECT_TRUE(handles2[0].is_valid()); |
81 EXPECT_TRUE(handles[1].is_valid()); | 50 EXPECT_TRUE(handles2[1].is_valid()); |
82 | 51 |
83 pipe0 = handles[0].Pass(); | 52 pipe0 = handles2[0].Pass(); |
84 EXPECT_TRUE(pipe0.is_valid()); | 53 EXPECT_TRUE(pipe0.is_valid()); |
85 EXPECT_FALSE(handles[0].is_valid()); | 54 EXPECT_FALSE(handles2[0].is_valid()); |
86 } | 55 } |
87 | 56 |
88 // Tests that Array<Handle> supports closing handles. | 57 // Tests that Array<ScopedMessagePipeHandle> supports closing handles. |
89 TEST(ArrayTest, HandlesAreClosed) { | 58 TEST(ArrayTest, HandlesAreClosed) { |
90 Environment env; | 59 ScopedMessagePipeHandle pipe0, pipe1; |
91 | 60 CreateMessagePipe(&pipe0, &pipe1); |
92 ScopedMessagePipeHandle msg_pipe0, msg_pipe1; | |
93 CreateMessagePipe(&msg_pipe0, &msg_pipe1); | |
94 | |
95 ScopedHandle pipe0 = ScopedHandle::From(msg_pipe0.Pass()); | |
96 ScopedHandle pipe1 = ScopedHandle::From(msg_pipe1.Pass()); | |
97 | 61 |
98 MojoHandle pipe0_value = pipe0.get().value(); | 62 MojoHandle pipe0_value = pipe0.get().value(); |
99 MojoHandle pipe1_value = pipe1.get().value(); | 63 MojoHandle pipe1_value = pipe1.get().value(); |
100 | 64 |
101 { | 65 { |
102 AllocationScope scope; | 66 Array<ScopedMessagePipeHandle> handles(2); |
103 | 67 handles[0] = pipe0.Pass(); |
104 Array<Handle>::Builder handles_builder(2); | 68 handles[1].reset(pipe1.release()); |
105 handles_builder[0] = pipe0.Pass(); | |
106 handles_builder[1].reset(pipe1.release()); | |
107 | |
108 MOJO_ALLOW_UNUSED Array<Handle> handles = | |
109 handles_builder.Finish(); | |
110 } | 69 } |
111 | 70 |
112 // We expect the pipes to have been closed. | 71 // We expect the pipes to have been closed. |
113 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value)); | 72 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value)); |
114 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value)); | 73 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value)); |
115 } | 74 } |
116 | 75 |
117 // Tests that Array<MessagePipeHandle> supports closing handles. | 76 TEST(ArrayTest, Serialization_ArrayOfPOD) { |
118 TEST(ArrayTest, MessagePipeHandlesAreClosed) { | 77 Array<int32_t> array(4); |
119 Environment env; | 78 for (size_t i = 0; i < array.size(); ++i) |
| 79 array[i] = static_cast<int32_t>(i); |
120 | 80 |
121 ScopedMessagePipeHandle pipe0, pipe1; | 81 size_t size = GetSerializedSize_(array); |
122 CreateMessagePipe(&pipe0, &pipe1); | 82 EXPECT_EQ(8U + 4*4U, size); |
123 | 83 |
124 MojoHandle pipe0_value = pipe0.get().value(); | 84 internal::FixedBuffer buf(size); |
125 MojoHandle pipe1_value = pipe1.get().value(); | 85 internal::Array_Data<int32_t>* data; |
| 86 Serialize_(array.Pass(), &buf, &data); |
126 | 87 |
127 { | 88 Array<int32_t> array2; |
128 AllocationScope scope; | 89 Deserialize_(data, &array2); |
129 | 90 |
130 Array<MessagePipeHandle>::Builder handles_builder(2); | 91 EXPECT_EQ(4U, array2.size()); |
131 handles_builder[0] = pipe0.Pass(); | 92 for (size_t i = 0; i < array2.size(); ++i) |
132 handles_builder[1].reset(pipe1.release()); | 93 EXPECT_EQ(static_cast<int32_t>(i), array2[i]); |
| 94 } |
133 | 95 |
134 MOJO_ALLOW_UNUSED Array<MessagePipeHandle> handles = | 96 TEST(ArrayTest, Serialization_ArrayOfArrayOfPOD) { |
135 handles_builder.Finish(); | 97 Array<Array<int32_t> > array(2); |
| 98 for (size_t j = 0; j < array.size(); ++j) { |
| 99 Array<int32_t> inner(4); |
| 100 for (size_t i = 0; i < inner.size(); ++i) |
| 101 inner[i] = static_cast<int32_t>(i + (j * 10)); |
| 102 array[j] = inner.Pass(); |
136 } | 103 } |
137 | 104 |
138 // We expect the pipes to have been closed. | 105 size_t size = GetSerializedSize_(array); |
139 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value)); | 106 EXPECT_EQ(8U + 2*8U + 2*(8U + 4*4U), size); |
140 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value)); | 107 |
| 108 internal::FixedBuffer buf(size); |
| 109 internal::Array_Data<internal::Array_Data<int32_t>*>* data; |
| 110 Serialize_(array.Pass(), &buf, &data); |
| 111 |
| 112 Array<Array<int32_t> > array2; |
| 113 Deserialize_(data, &array2); |
| 114 |
| 115 EXPECT_EQ(2U, array2.size()); |
| 116 for (size_t j = 0; j < array2.size(); ++j) { |
| 117 const Array<int32_t>& inner = array2[j]; |
| 118 EXPECT_EQ(4U, inner.size()); |
| 119 for (size_t i = 0; i < inner.size(); ++i) |
| 120 EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]); |
| 121 } |
| 122 } |
| 123 |
| 124 TEST(ArrayTest, Serialization_ArrayOfBool) { |
| 125 Array<bool> array(10); |
| 126 for (size_t i = 0; i < array.size(); ++i) |
| 127 array[i] = i % 2 ? true : false; |
| 128 |
| 129 size_t size = GetSerializedSize_(array); |
| 130 EXPECT_EQ(8U + 8U, size); |
| 131 |
| 132 internal::FixedBuffer buf(size); |
| 133 internal::Array_Data<bool>* data; |
| 134 Serialize_(array.Pass(), &buf, &data); |
| 135 |
| 136 Array<bool> array2; |
| 137 Deserialize_(data, &array2); |
| 138 |
| 139 EXPECT_EQ(10U, array2.size()); |
| 140 for (size_t i = 0; i < array2.size(); ++i) |
| 141 EXPECT_EQ(i % 2 ? true : false, array2[i]); |
| 142 } |
| 143 |
| 144 TEST(ArrayTest, Serialization_ArrayOfString) { |
| 145 Array<String> array(10); |
| 146 for (size_t i = 0; i < array.size(); ++i) { |
| 147 char c = 'A' + 1; |
| 148 array[i] = String(&c, 1); |
| 149 } |
| 150 |
| 151 size_t size = GetSerializedSize_(array); |
| 152 EXPECT_EQ(8U + // array header |
| 153 10*8U + // array payload (10 pointers) |
| 154 10*(8U + // string header |
| 155 8U), // string length of 1 padded to 8 |
| 156 size); |
| 157 |
| 158 internal::FixedBuffer buf(size); |
| 159 internal::Array_Data<internal::String_Data*>* data; |
| 160 Serialize_(array.Pass(), &buf, &data); |
| 161 |
| 162 Array<String> array2; |
| 163 Deserialize_(data, &array2); |
| 164 |
| 165 EXPECT_EQ(10U, array2.size()); |
| 166 for (size_t i = 0; i < array2.size(); ++i) { |
| 167 char c = 'A' + 1; |
| 168 EXPECT_EQ(String(&c, 1), array2[i]); |
| 169 } |
141 } | 170 } |
142 | 171 |
143 } // namespace | 172 } // namespace |
144 } // namespace test | 173 } // namespace test |
145 } // namespace mojo | 174 } // namespace mojo |
OLD | NEW |