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 |