| 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 "gtest/gtest.h" | |
| 18 #include "mojo/public/cpp/bindings/tests/validation_util.h" | |
| 19 #include "mojo/public/cpp/system/macros.h" | |
| 20 #include "mojo/public/cpp/test_support/test_support.h" | |
| 21 #include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
-c.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 |