OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 // TODO(vardhan): There is some duplicate code here borrowed from | |
6 // mojo/public/cpp/bindings/tests/validation_unittest.cc; extract it into a | |
7 // library, and share? | |
8 | |
9 #include <mojo/bindings/internal/util.h> | |
10 #include <mojo/bindings/message.h> | |
11 #include <mojo/bindings/struct.h> | |
12 #include <stdio.h> | |
13 | |
14 #include <functional> | |
15 #include <string> | |
16 | |
17 #include "mojo/public/cpp/bindings/tests/validation_util.h" | |
18 #include "mojo/public/cpp/system/macros.h" | |
19 #include "mojo/public/cpp/test_support/test_support.h" | |
20 #include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
-c.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 using mojo::test::EnumerateSourceRootRelativeDirectory; | |
24 | |
25 namespace mojo { | |
26 namespace test { | |
27 namespace { | |
28 | |
29 const char* MojomValidationResultToString(MojomValidationResult error) { | |
30 switch (error) { | |
31 case MOJOM_VALIDATION_ERROR_NONE: | |
32 return "PASS"; | |
33 case MOJOM_VALIDATION_MISALIGNED_OBJECT: | |
34 return "VALIDATION_ERROR_MISALIGNED_OBJECT"; | |
35 case MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE: | |
36 return "VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE"; | |
37 case MOJOM_VALIDATION_UNEXPECTED_STRUCT_HEADER: | |
38 return "VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER"; | |
39 case MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER: | |
40 return "VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER"; | |
41 case MOJOM_VALIDATION_ILLEGAL_HANDLE: | |
42 return "VALIDATION_ERROR_ILLEGAL_HANDLE"; | |
43 case MOJOM_VALIDATION_UNEXPECTED_INVALID_HANDLE: | |
44 return "VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE"; | |
45 case MOJOM_VALIDATION_ILLEGAL_POINTER: | |
46 return "VALIDATION_ERROR_ILLEGAL_POINTER"; | |
47 case MOJOM_VALIDATION_UNEXPECTED_NULL_POINTER: | |
48 return "VALIDATION_ERROR_UNEXPECTED_NULL_POINTER"; | |
49 case MOJOM_VALIDATION_MESSAGE_HEADER_INVALID_FLAGS: | |
50 return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS"; | |
51 case MOJOM_VALIDATION_MESSAGE_HEADER_MISSING_REQUEST_ID: | |
52 return "VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID"; | |
53 case MOJOM_VALIDATION_MESSAGE_HEADER_UNKNOWN_METHOD: | |
54 return "VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD"; | |
55 case MOJOM_VALIDATION_DIFFERENT_SIZED_ARRAYS_IN_MAP: | |
56 return "VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP"; | |
57 case MOJOM_VALIDATION_UNEXPECTED_NULL_UNION: | |
58 return "VALIDATION_ERROR_UNEXPECTED_NULL_UNION"; | |
59 } | |
60 | |
61 return "Unknown error"; | |
62 } | |
63 | |
64 void RunValidationTests( | |
65 const std::string& prefix, | |
66 std::function<MojomValidationResult(const std::vector<uint8_t>&, size_t)> | |
67 validate_fn) { | |
68 std::vector<std::string> tests = validation_util::GetMatchingTests(prefix); | |
69 for (size_t i = 0; i < tests.size(); ++i) { | |
70 std::vector<uint8_t> message_data; | |
71 size_t num_handles; | |
72 std::string expected; | |
73 ASSERT_TRUE(validation_util::ReadTestCase(tests[i], &message_data, | |
74 &num_handles, &expected)); | |
75 // Validate this message. Should be PASS or ValidationErrorToString() | |
76 MojomValidationResult result = validate_fn(message_data, num_handles); | |
77 EXPECT_EQ(expected, MojomValidationResultToString(result)) << tests[i]; | |
78 } | |
79 } | |
80 | |
81 // Emits a case (as part of a switch{} block) for validating a request for the | |
82 // given method, and sets the |result|. | |
83 // TODO(vardhan): Should this be code generated? Seems like everyone will have | |
84 // to do this. | |
85 #define CASE_INTERFACE_METHOD_REQUEST(method_struct, data, data_size, \ | |
86 num_handles, result, expects_response) \ | |
87 case method_struct##__Ordinal: { \ | |
88 (result) = expects_response \ | |
89 ? MojomMessage_ValidateRequestExpectingResponse(data) \ | |
90 : MojomMessage_ValidateRequestWithoutResponse(data); \ | |
91 if ((result) == MOJOM_VALIDATION_ERROR_NONE) { \ | |
92 const struct MojomMessage* msg = (const struct MojomMessage*)(data); \ | |
93 (result) = method_struct##_Request_Validate( \ | |
94 (const struct method_struct##_Request*)((char*)data + \ | |
95 msg->header.num_bytes), \ | |
96 data_size - msg->header.num_bytes, (num_handles)); \ | |
97 } \ | |
98 break; \ | |
99 } | |
100 | |
101 #define CASE_INTERFACE_METHOD_RESPONSE(method_struct, data, data_size, \ | |
102 num_handles, result) \ | |
103 case method_struct##__Ordinal: { \ | |
104 (result) = MojomMessage_ValidateResponse(data); \ | |
105 if ((result) == MOJOM_VALIDATION_ERROR_NONE) { \ | |
106 const struct MojomMessage* msg = (const struct MojomMessage*)(data); \ | |
107 (result) = method_struct##_Response_Validate( \ | |
108 (const struct method_struct##_Response*)((char*)data + \ | |
109 msg->header.num_bytes), \ | |
110 data_size - msg->header.num_bytes, (num_handles)); \ | |
111 } \ | |
112 break; \ | |
113 } | |
114 MojomValidationResult DispatchConformanceTestInterface_Request_Validate( | |
115 const std::vector<uint8_t>& data, | |
116 size_t num_handles) { | |
117 const struct MojomMessage* msg = (const struct MojomMessage*)data.data(); | |
118 const char* msg_data = (const char*)data.data(); | |
119 uint32_t msg_size = data.size(); | |
120 | |
121 MojomValidationResult result = | |
122 MojomMessage_ValidateHeader(msg_data, msg_size); | |
123 if (result != MOJOM_VALIDATION_ERROR_NONE) | |
124 return result; | |
125 switch (msg->ordinal) { | |
126 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method0, | |
127 msg_data, msg_size, num_handles, result, | |
128 false) | |
129 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method1, | |
130 msg_data, msg_size, num_handles, result, | |
131 false) | |
132 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method2, | |
133 msg_data, msg_size, num_handles, result, | |
134 false) | |
135 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method3, | |
136 msg_data, msg_size, num_handles, result, | |
137 false) | |
138 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method4, | |
139 msg_data, msg_size, num_handles, result, | |
140 false) | |
141 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method5, | |
142 msg_data, msg_size, num_handles, result, | |
143 false) | |
144 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method6, | |
145 msg_data, msg_size, num_handles, result, | |
146 false) | |
147 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method7, | |
148 msg_data, msg_size, num_handles, result, | |
149 false) | |
150 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method8, | |
151 msg_data, msg_size, num_handles, result, | |
152 false) | |
153 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method9, | |
154 msg_data, msg_size, num_handles, result, | |
155 false) | |
156 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method10, | |
157 msg_data, msg_size, num_handles, result, | |
158 false) | |
159 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method11, | |
160 msg_data, msg_size, num_handles, result, | |
161 false) | |
162 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method12, | |
163 msg_data, msg_size, num_handles, result, true) | |
164 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method13, | |
165 msg_data, msg_size, num_handles, result, | |
166 false) | |
167 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method14, | |
168 msg_data, msg_size, num_handles, result, | |
169 false) | |
170 CASE_INTERFACE_METHOD_REQUEST(mojo_test_ConformanceTestInterface_Method15, | |
171 msg_data, msg_size, num_handles, result, | |
172 false) | |
173 default: | |
174 result = MOJOM_VALIDATION_MESSAGE_HEADER_UNKNOWN_METHOD; | |
175 break; | |
176 } | |
177 return result; | |
178 } | |
179 | |
180 MojomValidationResult DispatchConformanceTestInterface_Response_Validate( | |
181 const std::vector<uint8_t>& data, | |
182 size_t num_handles) { | |
183 const struct MojomMessage* msg = (const struct MojomMessage*)data.data(); | |
184 const char* msg_data = (const char*)data.data(); | |
185 uint32_t msg_size = data.size(); | |
186 | |
187 MojomValidationResult result = | |
188 MojomMessage_ValidateHeader(msg_data, msg_size); | |
189 if (result != MOJOM_VALIDATION_ERROR_NONE) | |
190 return result; | |
191 switch (msg->ordinal) { | |
192 CASE_INTERFACE_METHOD_RESPONSE(mojo_test_ConformanceTestInterface_Method12, | |
193 msg_data, msg_size, num_handles, result) | |
194 default: | |
195 result = MOJOM_VALIDATION_MESSAGE_HEADER_UNKNOWN_METHOD; | |
196 break; | |
197 } | |
198 return result; | |
199 } | |
200 | |
201 MojomValidationResult DispatchBoundsCheckTestInterface_Request_Validate( | |
202 const std::vector<uint8_t>& data, | |
203 size_t num_handles) { | |
204 const struct MojomMessage* msg = (const struct MojomMessage*)data.data(); | |
205 const char* msg_data = (const char*)data.data(); | |
206 uint32_t msg_size = data.size(); | |
207 | |
208 MojomValidationResult result = | |
209 MojomMessage_ValidateHeader(msg_data, msg_size); | |
210 if (result != MOJOM_VALIDATION_ERROR_NONE) | |
211 return result; | |
212 switch (msg->ordinal) { | |
213 CASE_INTERFACE_METHOD_REQUEST(mojo_test_BoundsCheckTestInterface_Method0, | |
214 msg_data, msg_size, num_handles, result, true) | |
215 CASE_INTERFACE_METHOD_REQUEST(mojo_test_BoundsCheckTestInterface_Method1, | |
216 msg_data, msg_size, num_handles, result, | |
217 false) | |
218 default: | |
219 result = MOJOM_VALIDATION_MESSAGE_HEADER_UNKNOWN_METHOD; | |
220 break; | |
221 } | |
222 return result; | |
223 } | |
224 | |
225 MojomValidationResult DispatchBoundsCheckTestInterface_Response_Validate( | |
226 const std::vector<uint8_t>& data, | |
227 size_t num_handles) { | |
228 const struct MojomMessage* msg = (const struct MojomMessage*)data.data(); | |
229 const char* msg_data = (const char*)data.data(); | |
230 uint32_t msg_size = data.size(); | |
231 | |
232 MojomValidationResult result = | |
233 MojomMessage_ValidateHeader(msg_data, msg_size); | |
234 if (result != MOJOM_VALIDATION_ERROR_NONE) | |
235 return result; | |
236 switch (msg->ordinal) { | |
237 CASE_INTERFACE_METHOD_RESPONSE(mojo_test_BoundsCheckTestInterface_Method0, | |
238 msg_data, msg_size, num_handles, result) | |
239 default: | |
240 result = MOJOM_VALIDATION_MESSAGE_HEADER_UNKNOWN_METHOD; | |
241 break; | |
242 } | |
243 return result; | |
244 } | |
245 | |
246 TEST(ValidationTest, Conformance) { | |
247 RunValidationTests("conformance_", | |
248 DispatchConformanceTestInterface_Request_Validate); | |
249 } | |
250 | |
251 TEST(ValidationTest, ResponseConformance) { | |
252 RunValidationTests("resp_conformance_", | |
253 DispatchConformanceTestInterface_Response_Validate); | |
254 } | |
255 | |
256 TEST(ValidationTest, BoundsCheck) { | |
257 RunValidationTests("boundscheck_", | |
258 DispatchBoundsCheckTestInterface_Request_Validate); | |
259 } | |
260 | |
261 TEST(ValidationTest, ResponseBoundsCheck) { | |
262 RunValidationTests("resp_boundscheck_", | |
263 DispatchBoundsCheckTestInterface_Response_Validate); | |
264 } | |
265 | |
266 // TODO(vardhan): Tests for "integration_" files. | |
267 | |
268 } // namespace | |
269 } // namespace test | |
270 } // namespace mojo | |
OLD | NEW |