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