| 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 <stdio.h> | 5 #include <stdio.h> |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 template <typename T> | 31 template <typename T> |
| 32 void Append(std::vector<uint8_t>* data_vector, T data) { | 32 void Append(std::vector<uint8_t>* data_vector, T data) { |
| 33 size_t pos = data_vector->size(); | 33 size_t pos = data_vector->size(); |
| 34 data_vector->resize(pos + sizeof(T)); | 34 data_vector->resize(pos + sizeof(T)); |
| 35 memcpy(&(*data_vector)[pos], &data, sizeof(T)); | 35 memcpy(&(*data_vector)[pos], &data, sizeof(T)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 bool TestInputParser(const std::string& input, | 38 bool TestInputParser(const std::string& input, |
| 39 bool expected_result, | 39 bool expected_result, |
| 40 const std::vector<uint8_t>& expected_parsed_input) { | 40 const std::vector<uint8_t>& expected_data, |
| 41 std::vector<uint8_t> parsed_input; | 41 size_t expected_num_handles) { |
| 42 std::vector<uint8_t> data; |
| 43 size_t num_handles; |
| 42 std::string error_message; | 44 std::string error_message; |
| 43 | 45 |
| 44 bool result = ParseValidationTestInput(input, &parsed_input, &error_message); | 46 bool result = ParseValidationTestInput(input, &data, &num_handles, |
| 47 &error_message); |
| 45 if (expected_result) { | 48 if (expected_result) { |
| 46 if (result && error_message.empty() && | 49 if (result && error_message.empty() && |
| 47 expected_parsed_input == parsed_input) { | 50 expected_data == data && expected_num_handles == num_handles) { |
| 48 return true; | 51 return true; |
| 49 } | 52 } |
| 50 | 53 |
| 51 // Compare with an empty string instead of checking |error_message.empty()|, | 54 // Compare with an empty string instead of checking |error_message.empty()|, |
| 52 // so that the message will be printed out if the two are not equal. | 55 // so that the message will be printed out if the two are not equal. |
| 53 EXPECT_EQ(std::string(), error_message); | 56 EXPECT_EQ(std::string(), error_message); |
| 54 EXPECT_EQ(expected_parsed_input, parsed_input); | 57 EXPECT_EQ(expected_data, data); |
| 58 EXPECT_EQ(expected_num_handles, num_handles); |
| 55 return false; | 59 return false; |
| 56 } | 60 } |
| 57 | 61 |
| 58 EXPECT_FALSE(error_message.empty()); | 62 EXPECT_FALSE(error_message.empty()); |
| 59 return !result && !error_message.empty(); | 63 return !result && !error_message.empty(); |
| 60 } | 64 } |
| 61 | 65 |
| 62 std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names, | 66 std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names, |
| 63 const std::string& prefix) { | 67 const std::string& prefix) { |
| 64 const std::string suffix = ".data"; | 68 const std::string suffix = ".data"; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 85 fclose(fp); | 89 fclose(fp); |
| 86 return true; | 90 return true; |
| 87 } | 91 } |
| 88 fseek(fp, 0, SEEK_SET); | 92 fseek(fp, 0, SEEK_SET); |
| 89 result->resize(size); | 93 result->resize(size); |
| 90 size_t size_read = fread(&result->at(0), 1, size, fp); | 94 size_t size_read = fread(&result->at(0), 1, size, fp); |
| 91 fclose(fp); | 95 fclose(fp); |
| 92 return size == size_read; | 96 return size == size_read; |
| 93 } | 97 } |
| 94 | 98 |
| 95 bool ReadAndParseDataFile(const std::string& path, std::vector<uint8_t>* data) { | 99 bool ReadAndParseDataFile(const std::string& path, |
| 100 std::vector<uint8_t>* data, |
| 101 size_t* num_handles) { |
| 96 std::string input; | 102 std::string input; |
| 97 if (!ReadFile(path, &input)) | 103 if (!ReadFile(path, &input)) |
| 98 return false; | 104 return false; |
| 99 | 105 |
| 100 std::string error_message; | 106 std::string error_message; |
| 101 if (!ParseValidationTestInput(input, data, &error_message)) { | 107 if (!ParseValidationTestInput(input, data, num_handles, &error_message)) { |
| 102 ADD_FAILURE() << error_message; | 108 ADD_FAILURE() << error_message; |
| 103 return false; | 109 return false; |
| 104 } | 110 } |
| 105 | 111 |
| 106 return true; | 112 return true; |
| 107 } | 113 } |
| 108 | 114 |
| 109 bool ReadResultFile(const std::string& path, std::string* result) { | 115 bool ReadResultFile(const std::string& path, std::string* result) { |
| 110 if (!ReadFile(path, result)) | 116 if (!ReadFile(path, result)) |
| 111 return false; | 117 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 127 std::string GetPath(const std::string& root, const std::string& suffix) { | 133 std::string GetPath(const std::string& root, const std::string& suffix) { |
| 128 return "mojo/public/interfaces/bindings/tests/data/validation/" + | 134 return "mojo/public/interfaces/bindings/tests/data/validation/" + |
| 129 root + suffix; | 135 root + suffix; |
| 130 } | 136 } |
| 131 | 137 |
| 132 // |message| should be a newly created object. | 138 // |message| should be a newly created object. |
| 133 bool ReadTestCase(const std::string& test, | 139 bool ReadTestCase(const std::string& test, |
| 134 Message* message, | 140 Message* message, |
| 135 std::string* expected) { | 141 std::string* expected) { |
| 136 std::vector<uint8_t> data; | 142 std::vector<uint8_t> data; |
| 137 if (!ReadAndParseDataFile(GetPath(test, ".data"), &data) || | 143 size_t num_handles; |
| 144 if (!ReadAndParseDataFile(GetPath(test, ".data"), &data, &num_handles) || |
| 138 !ReadResultFile(GetPath(test, ".expected"), expected)) { | 145 !ReadResultFile(GetPath(test, ".expected"), expected)) { |
| 139 return false; | 146 return false; |
| 140 } | 147 } |
| 141 | 148 |
| 142 message->AllocUninitializedData(static_cast<uint32_t>(data.size())); | 149 message->AllocUninitializedData(static_cast<uint32_t>(data.size())); |
| 143 if (!data.empty()) | 150 if (!data.empty()) |
| 144 memcpy(message->mutable_data(), &data[0], data.size()); | 151 memcpy(message->mutable_data(), &data[0], data.size()); |
| 145 | 152 message->mutable_handles()->resize(num_handles); |
| 146 // TODO(yzshen): add support to specify the number of handles associated with | |
| 147 // the message. | |
| 148 | 153 |
| 149 return true; | 154 return true; |
| 150 } | 155 } |
| 151 | 156 |
| 152 void RunValidationTests(const std::string& prefix, | 157 void RunValidationTests(const std::string& prefix, |
| 153 MessageReceiver* test_message_receiver) { | 158 MessageReceiver* test_message_receiver) { |
| 154 std::vector<std::string> names = | 159 std::vector<std::string> names = |
| 155 EnumerateSourceRootRelativeDirectory(GetPath("", "")); | 160 EnumerateSourceRootRelativeDirectory(GetPath("", "")); |
| 156 std::vector<std::string> tests = GetMatchingTests(names, prefix); | 161 std::vector<std::string> tests = GetMatchingTests(names, prefix); |
| 157 | 162 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 // The parser, as well as Append() defined above, assumes that this code is | 278 // The parser, as well as Append() defined above, assumes that this code is |
| 274 // running on a little-endian platform. Test whether that is true. | 279 // running on a little-endian platform. Test whether that is true. |
| 275 uint16_t x = 1; | 280 uint16_t x = 1; |
| 276 ASSERT_EQ(1, *(reinterpret_cast<char*>(&x))); | 281 ASSERT_EQ(1, *(reinterpret_cast<char*>(&x))); |
| 277 } | 282 } |
| 278 { | 283 { |
| 279 // Test empty input. | 284 // Test empty input. |
| 280 std::string input; | 285 std::string input; |
| 281 std::vector<uint8_t> expected; | 286 std::vector<uint8_t> expected; |
| 282 | 287 |
| 283 EXPECT_TRUE(TestInputParser(input, true, expected)); | 288 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 284 } | 289 } |
| 285 { | 290 { |
| 286 // Test input that only consists of comments and whitespaces. | 291 // Test input that only consists of comments and whitespaces. |
| 287 std::string input = " \t // hello world \n\r \t// the answer is 42 "; | 292 std::string input = " \t // hello world \n\r \t// the answer is 42 "; |
| 288 std::vector<uint8_t> expected; | 293 std::vector<uint8_t> expected; |
| 289 | 294 |
| 290 EXPECT_TRUE(TestInputParser(input, true, expected)); | 295 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 291 } | 296 } |
| 292 { | 297 { |
| 293 std::string input = "[u1]0x10// hello world !! \n\r \t [u2]65535 \n" | 298 std::string input = "[u1]0x10// hello world !! \n\r \t [u2]65535 \n" |
| 294 "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff"; | 299 "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff"; |
| 295 std::vector<uint8_t> expected; | 300 std::vector<uint8_t> expected; |
| 296 Append(&expected, static_cast<uint8_t>(0x10)); | 301 Append(&expected, static_cast<uint8_t>(0x10)); |
| 297 Append(&expected, static_cast<uint16_t>(65535)); | 302 Append(&expected, static_cast<uint16_t>(65535)); |
| 298 Append(&expected, static_cast<uint32_t>(65536)); | 303 Append(&expected, static_cast<uint32_t>(65536)); |
| 299 Append(&expected, static_cast<uint64_t>(0xffffffffffffffff)); | 304 Append(&expected, static_cast<uint64_t>(0xffffffffffffffff)); |
| 300 Append(&expected, static_cast<uint8_t>(0)); | 305 Append(&expected, static_cast<uint8_t>(0)); |
| 301 Append(&expected, static_cast<uint8_t>(0xff)); | 306 Append(&expected, static_cast<uint8_t>(0xff)); |
| 302 | 307 |
| 303 EXPECT_TRUE(TestInputParser(input, true, expected)); | 308 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 304 } | 309 } |
| 305 { | 310 { |
| 306 std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40"; | 311 std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40"; |
| 307 std::vector<uint8_t> expected; | 312 std::vector<uint8_t> expected; |
| 308 Append(&expected, -static_cast<int64_t>(0x800)); | 313 Append(&expected, -static_cast<int64_t>(0x800)); |
| 309 Append(&expected, static_cast<int8_t>(-128)); | 314 Append(&expected, static_cast<int8_t>(-128)); |
| 310 Append(&expected, static_cast<int16_t>(0)); | 315 Append(&expected, static_cast<int16_t>(0)); |
| 311 Append(&expected, static_cast<int32_t>(-40)); | 316 Append(&expected, static_cast<int32_t>(-40)); |
| 312 | 317 |
| 313 EXPECT_TRUE(TestInputParser(input, true, expected)); | 318 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 314 } | 319 } |
| 315 { | 320 { |
| 316 std::string input = "[b]00001011 [b]10000000 // hello world\r [b]00000000"; | 321 std::string input = "[b]00001011 [b]10000000 // hello world\r [b]00000000"; |
| 317 std::vector<uint8_t> expected; | 322 std::vector<uint8_t> expected; |
| 318 Append(&expected, static_cast<uint8_t>(11)); | 323 Append(&expected, static_cast<uint8_t>(11)); |
| 319 Append(&expected, static_cast<uint8_t>(128)); | 324 Append(&expected, static_cast<uint8_t>(128)); |
| 320 Append(&expected, static_cast<uint8_t>(0)); | 325 Append(&expected, static_cast<uint8_t>(0)); |
| 321 | 326 |
| 322 EXPECT_TRUE(TestInputParser(input, true, expected)); | 327 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 323 } | 328 } |
| 324 { | 329 { |
| 325 std::string input = "[f]+.3e9 [d]-10.03"; | 330 std::string input = "[f]+.3e9 [d]-10.03"; |
| 326 std::vector<uint8_t> expected; | 331 std::vector<uint8_t> expected; |
| 327 Append(&expected, +.3e9f); | 332 Append(&expected, +.3e9f); |
| 328 Append(&expected, -10.03); | 333 Append(&expected, -10.03); |
| 329 | 334 |
| 330 EXPECT_TRUE(TestInputParser(input, true, expected)); | 335 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 331 } | 336 } |
| 332 { | 337 { |
| 333 std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar"; | 338 std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar"; |
| 334 std::vector<uint8_t> expected; | 339 std::vector<uint8_t> expected; |
| 335 Append(&expected, static_cast<uint32_t>(14)); | 340 Append(&expected, static_cast<uint32_t>(14)); |
| 336 Append(&expected, static_cast<uint8_t>(0)); | 341 Append(&expected, static_cast<uint8_t>(0)); |
| 337 Append(&expected, static_cast<uint64_t>(9)); | 342 Append(&expected, static_cast<uint64_t>(9)); |
| 338 Append(&expected, static_cast<uint8_t>(0)); | 343 Append(&expected, static_cast<uint8_t>(0)); |
| 339 | 344 |
| 340 EXPECT_TRUE(TestInputParser(input, true, expected)); | 345 EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
| 346 } |
| 347 { |
| 348 std::string input = "// This message has handles! \n[handles]50 [u8]2"; |
| 349 std::vector<uint8_t> expected; |
| 350 Append(&expected, static_cast<uint64_t>(2)); |
| 351 |
| 352 EXPECT_TRUE(TestInputParser(input, true, expected, 50)); |
| 341 } | 353 } |
| 342 | 354 |
| 343 // Test some failure cases. | 355 // Test some failure cases. |
| 344 { | 356 { |
| 345 const char* error_inputs[] = { | 357 const char* error_inputs[] = { |
| 346 "/ hello world", | 358 "/ hello world", |
| 347 "[u1]x", | 359 "[u1]x", |
| 360 "[u2]-1000", |
| 348 "[u1]0x100", | 361 "[u1]0x100", |
| 349 "[s2]-0x8001", | 362 "[s2]-0x8001", |
| 350 "[b]1", | 363 "[b]1", |
| 351 "[b]1111111k", | 364 "[b]1111111k", |
| 352 "[dist4]unmatched", | 365 "[dist4]unmatched", |
| 353 "[anchr]hello [dist8]hello", | 366 "[anchr]hello [dist8]hello", |
| 367 "0 [handles]50", |
| 354 NULL | 368 NULL |
| 355 }; | 369 }; |
| 356 | 370 |
| 357 for (size_t i = 0; error_inputs[i]; ++i) { | 371 for (size_t i = 0; error_inputs[i]; ++i) { |
| 358 std::vector<uint8_t> expected; | 372 std::vector<uint8_t> expected; |
| 359 if (!TestInputParser(error_inputs[i], false, expected)) | 373 if (!TestInputParser(error_inputs[i], false, expected, 0)) |
| 360 ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i]; | 374 ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i]; |
| 361 } | 375 } |
| 362 } | 376 } |
| 363 } | 377 } |
| 364 | 378 |
| 365 TEST(ValidationTest, Conformance) { | 379 TEST(ValidationTest, Conformance) { |
| 366 DummyMessageReceiver dummy_receiver; | 380 DummyMessageReceiver dummy_receiver; |
| 367 mojo::internal::FilterChain validators(&dummy_receiver); | 381 mojo::internal::FilterChain validators(&dummy_receiver); |
| 368 validators.Append<mojo::internal::MessageHeaderValidator>(); | 382 validators.Append<mojo::internal::MessageHeaderValidator>(); |
| 369 validators.Append<ConformanceTestInterface::RequestValidator_>(); | 383 validators.Append<ConformanceTestInterface::RequestValidator_>(); |
| 370 | 384 |
| 371 // TODO(yzshen): add more conformance tests. | |
| 372 RunValidationTests("conformance_", validators.GetHead()); | 385 RunValidationTests("conformance_", validators.GetHead()); |
| 373 } | 386 } |
| 374 | 387 |
| 375 TEST_F(ValidationIntegrationTest, InterfacePtr) { | 388 TEST_F(ValidationIntegrationTest, InterfacePtr) { |
| 376 // Test that InterfacePtr<X> applies the correct validators and they don't | 389 // Test that InterfacePtr<X> applies the correct validators and they don't |
| 377 // conflict with each other: | 390 // conflict with each other: |
| 378 // - MessageHeaderValidator | 391 // - MessageHeaderValidator |
| 379 // - X::Client::RequestValidator_ | 392 // - X::Client::RequestValidator_ |
| 380 // - X::ResponseValidator_ | 393 // - X::ResponseValidator_ |
| 381 | 394 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 399 IntegrationTestInterface1Impl* interface1_impl = | 412 IntegrationTestInterface1Impl* interface1_impl = |
| 400 BindToPipe(new IntegrationTestInterface1Impl(), testee_endpoint().Pass()); | 413 BindToPipe(new IntegrationTestInterface1Impl(), testee_endpoint().Pass()); |
| 401 interface1_impl->internal_state()->router()->EnableTestingMode(); | 414 interface1_impl->internal_state()->router()->EnableTestingMode(); |
| 402 | 415 |
| 403 RunValidationTests("integration_", test_message_receiver()); | 416 RunValidationTests("integration_", test_message_receiver()); |
| 404 } | 417 } |
| 405 | 418 |
| 406 } // namespace | 419 } // namespace |
| 407 } // namespace test | 420 } // namespace test |
| 408 } // namespace mojo | 421 } // namespace mojo |
| OLD | NEW |