Index: third_party/WebKit/LayoutTests/mojo/validation.html |
diff --git a/third_party/WebKit/LayoutTests/mojo/validation.html b/third_party/WebKit/LayoutTests/mojo/validation.html |
index 1faec5d57ac3a2739fe346eb038f0ab34191c495..1bd32b881174162f7433818097f9fc862b848ebd 100644 |
--- a/third_party/WebKit/LayoutTests/mojo/validation.html |
+++ b/third_party/WebKit/LayoutTests/mojo/validation.html |
@@ -1,298 +1,297 @@ |
<!DOCTYPE html> |
<script src="../resources/testharness.js"></script> |
<script src="../resources/testharnessreport.js"></script> |
-<script src="../resources/mojo-helpers.js"></script> |
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> |
+<script src="file:///gen/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.js"></script> |
<script src="resources/validation_test_input_parser.js"></script> |
<script> |
'use strict'; |
-setup({ explicit_done: true }); |
- |
-define([ |
- 'mojo/public/js/bindings', |
- 'mojo/public/js/buffer', |
- 'mojo/public/js/codec', |
- 'mojo/public/js/core', |
- 'mojo/resources/validation_test_input_parser', |
- 'mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom', |
- 'mojo/public/js/validator', |
-], function(bindings, |
- buffer, |
- codec, |
- core, |
- parser, |
- testInterface, |
- validator) { |
- |
- var noError = validator.validationError.NONE; |
- |
- function checkData(data, expectedData, input) { |
- assert_equals(data.byteLength, expectedData.byteLength, |
- 'message length (' + data.byteLength + ') doesn\'t match ' + |
- 'expected length: ' + expectedData.byteLength + ' for ' + input); |
- |
- for (var i = 0; i < data.byteLength; i++) { |
- assert_equals(data.getUint8(i), expectedData.getUint8(i), |
- 'message data mismatch at byte offset ' + i + 'for' + input); |
- } |
- } |
+var noError = mojo.internal.validationError.NONE; |
- test(() => { |
- var input = '[f]+.3e9 [d]-10.03'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(12); |
- expectedData.setFloat32(0, +.3e9); |
- expectedData.setFloat64(4, -10.03); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: float items'); |
- |
- test(() => { |
- var input = '[u1]0x10// hello world !! \n\r \t [u2]65535 \n' + |
- '[u4]65536 [u8]0xFFFFFFFFFFFFF 0 0Xff'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(17); |
- expectedData.setUint8(0, 0x10); |
- expectedData.setUint16(1, 65535); |
- expectedData.setUint32(3, 65536); |
- expectedData.setUint64(7, 0xFFFFFFFFFFFFF); |
- expectedData.setUint8(15, 0); |
- expectedData.setUint8(16, 0xff); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: unsigned integer items'); |
- |
- test(() => { |
- var input = '[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(15); |
- expectedData.setInt64(0, -0x800); |
- expectedData.setInt8(8, -128); |
- expectedData.setInt16(9, 0); |
- expectedData.setInt32(11, -40); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: signed integer items'); |
- |
- test(() => { |
- var input = '[b]00001011 [b]10000000 // hello world\n [b]00000000'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(3); |
- expectedData.setUint8(0, 11); |
- expectedData.setUint8(1, 128); |
- expectedData.setUint8(2, 0); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: byte items'); |
- |
- test(() => { |
- var input = '[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(14); |
- expectedData.setUint32(0, 14); |
- expectedData.setUint8(4, 0); |
- expectedData.setUint64(5, 9); |
- expectedData.setUint8(13, 0); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: anchors'); |
- |
- test(() => { |
- var input = '// This message has handles! \n[handles]50 [u8]2'; |
- var msg = parser.parseTestMessage(input); |
- var expectedData = new buffer.Buffer(8); |
- expectedData.setUint64(0, 2); |
- |
- assert_equals(msg.handleCount, 50, |
- 'wrong handle count (' + msg.handleConut + ') for ' + input); |
- checkData(msg.buffer, expectedData, input); |
- }, 'message parser: handles'); |
- |
- test(() => { |
- var msg = parser.parseTestMessage(''); |
- assert_equals(msg.buffer.byteLength, 0, 'expected empty message for '); |
- }, 'message parser: empty input'); |
- |
- test(() => { |
- var input = ' \t // hello world \n\r \t// the answer is 42 '; |
- var msg = parser.parseTestMessage(input); |
- assert_equals(msg.buffer.byteLength, 0, |
- 'expected empty message for ' + input); |
- }, 'message parser: blank input'); |
- |
- test(() => { |
- function parserShouldFail(input) { |
- assert_throws(new parser.InputError(), function() { |
- parser.parseTestMessage(input); |
- }); |
- } |
+function checkData(data, expectedData, input) { |
+ assert_equals(data.byteLength, expectedData.byteLength, |
+ 'message length (' + data.byteLength + ') doesn\'t match ' + |
+ 'expected length: ' + expectedData.byteLength + ' for ' + input); |
- ['/ hello world', |
- '[u1]x', |
- '[u2]-1000', |
- '[u1]0x100', |
- '[s2]-0x8001', |
- '[b]1', |
- '[b]1111111k', |
- '[dist4]unmatched', |
- '[anchr]hello [dist8]hello', |
- '[dist4]a [dist4]a [anchr]a', |
- // '[dist4]a [anchr]a [dist4]a [anchr]a', |
- '0 [handles]50' |
- ].forEach(parserShouldFail); |
- }, 'message parser: invalid input'); |
- |
- function fetchLite(url) { |
- return new Promise((resolve, reject) => { |
- var xhr = new XMLHttpRequest(); |
- xhr.open('GET', url); |
- xhr.onreadystatechange = () => { |
- if (xhr.readyState != 4) return; |
- resolve(xhr.responseText); |
- }; |
- xhr.send(); |
- }); |
+ for (var i = 0; i < data.byteLength; i++) { |
+ assert_equals(data.getUint8(i), expectedData.getUint8(i), |
+ 'message data mismatch at byte offset ' + i + 'for' + input); |
} |
- |
- function getMessageTestFiles(prefix) { |
- let dataDirectory = 'file:///gen/layout_test_data/mojo/public/interfaces/bindings/tests/data/validation'; |
- return fetchLite(dataDirectory + '_index.txt').then((response) => { |
- assert_not_equals(response, null); |
- var testFiles = response.split(/\s+/); |
- assert_greater_than(testFiles.length, 0); |
- return testFiles.filter(function(s) { |
- return s.substr(-5) == '.data' && s.indexOf(prefix) == 0; |
- }).map(function(s) { |
- return dataDirectory + '/' + s.slice(0, -5); |
- }); |
+} |
+ |
+test(() => { |
+ var input = '[f]+.3e9 [d]-10.03'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(12); |
+ expectedData.setFloat32(0, +.3e9); |
+ expectedData.setFloat64(4, -10.03); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: float items'); |
+ |
+test(() => { |
+ var input = '[u1]0x10// hello world !! \n\r \t [u2]65535 \n' + |
+ '[u4]65536 [u8]0xFFFFFFFFFFFFF 0 0Xff'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(17); |
+ expectedData.setUint8(0, 0x10); |
+ expectedData.setUint16(1, 65535); |
+ expectedData.setUint32(3, 65536); |
+ expectedData.setUint64(7, 0xFFFFFFFFFFFFF); |
+ expectedData.setUint8(15, 0); |
+ expectedData.setUint8(16, 0xff); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: unsigned integer items'); |
+ |
+test(() => { |
+ var input = '[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(15); |
+ expectedData.setInt64(0, -0x800); |
+ expectedData.setInt8(8, -128); |
+ expectedData.setInt16(9, 0); |
+ expectedData.setInt32(11, -40); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: signed integer items'); |
+ |
+test(() => { |
+ var input = '[b]00001011 [b]10000000 // hello world\n [b]00000000'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(3); |
+ expectedData.setUint8(0, 11); |
+ expectedData.setUint8(1, 128); |
+ expectedData.setUint8(2, 0); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: byte items'); |
+ |
+test(() => { |
+ var input = '[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(14); |
+ expectedData.setUint32(0, 14); |
+ expectedData.setUint8(4, 0); |
+ expectedData.setUint64(5, 9); |
+ expectedData.setUint8(13, 0); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: anchors'); |
+ |
+test(() => { |
+ var input = '// This message has handles! \n[handles]50 [u8]2'; |
+ var msg = mojo.test.parseTestMessage(input); |
+ var expectedData = new mojo.internal.Buffer(8); |
+ expectedData.setUint64(0, 2); |
+ |
+ assert_equals(msg.handleCount, 50, |
+ 'wrong handle count (' + msg.handleConut + ') for ' + input); |
+ checkData(msg.buffer, expectedData, input); |
+}, 'message parser: handles'); |
+ |
+test(() => { |
+ var msg = mojo.test.parseTestMessage(''); |
+ assert_equals(msg.buffer.byteLength, 0, 'expected empty message for '); |
+}, 'message parser: empty input'); |
+ |
+test(() => { |
+ var input = ' \t // hello world \n\r \t// the answer is 42 '; |
+ var msg = mojo.test.parseTestMessage(input); |
+ assert_equals(msg.buffer.byteLength, 0, |
+ 'expected empty message for ' + input); |
+}, 'message parser: blank input'); |
+ |
+test(() => { |
+ function parserShouldFail(input) { |
+ assert_throws(new mojo.test.InputError(), function() { |
+ mojo.test.parseTestMessage(input); |
}); |
} |
- function readTestMessage(filename) { |
- return fetchLite(filename + '.data').then((response) => { |
- assert_not_equals(response, null); |
- return parser.parseTestMessage(response); |
+ ['/ hello world', |
+ '[u1]x', |
+ '[u2]-1000', |
+ '[u1]0x100', |
+ '[s2]-0x8001', |
+ '[b]1', |
+ '[b]1111111k', |
+ '[dist4]unmatched', |
+ '[anchr]hello [dist8]hello', |
+ '[dist4]a [dist4]a [anchr]a', |
+ // '[dist4]a [anchr]a [dist4]a [anchr]a', |
+ '0 [handles]50' |
+ ].forEach(parserShouldFail); |
+}, 'message parser: invalid input'); |
+ |
+function fetchLite(url) { |
+ return new Promise((resolve, reject) => { |
+ var xhr = new XMLHttpRequest(); |
+ xhr.open('GET', url); |
+ xhr.onreadystatechange = () => { |
+ if (xhr.readyState != 4) return; |
+ resolve(xhr.responseText); |
+ }; |
+ xhr.send(); |
+ }); |
+} |
+ |
+function getMessageTestFiles(prefix) { |
+ let dataDirectory = |
+ 'file:///gen/layout_test_data/mojo/public/interfaces/bindings/tests/data/validation'; |
+ return fetchLite(dataDirectory + '_index.txt').then((response) => { |
+ assert_not_equals(response, null); |
+ var testFiles = response.split(/\s+/); |
+ assert_greater_than(testFiles.length, 0); |
+ return testFiles.filter(function(s) { |
+ return s.substr(-5) == '.data' && s.indexOf(prefix) == 0; |
+ }).map(function(s) { |
+ return dataDirectory + '/' + s.slice(0, -5); |
}); |
- } |
+ }); |
+} |
+ |
+function readTestMessage(filename) { |
+ return fetchLite(filename + '.data').then((response) => { |
+ assert_not_equals(response, null); |
+ return mojo.test.parseTestMessage(response); |
+ }); |
+} |
+ |
+function readTestExpected(filename) { |
+ return fetchLite(filename + '.expected').then((response) => { |
+ assert_not_equals(response, null); |
+ return response.trim(); |
+ }); |
+} |
+ |
+async function checkValidationResult(testFile, err) { |
+ var actualResult = (err === noError) ? 'PASS' : err; |
+ var expectedResult = await readTestExpected(testFile); |
+ assert_equals(actualResult, expectedResult, |
+ '[Test message validation failed: ' + testFile + ' ]'); |
+} |
+ |
+async function testMessageValidation(prefix, filters) { |
+ var testFiles = await getMessageTestFiles(prefix); |
+ assert_greater_than(testFiles.length, 0); |
+ |
+ for (var i = 0; i < testFiles.length; i++) { |
+ // TODO(hansmuller) Temporarily skipping array pointer overflow tests |
+ // because JS numbers are limited to 53 bits. |
+ // TODO(rudominer): Temporarily skipping 'no-such-method', |
+ // 'invalid_request_flags', and 'invalid_response_flags' until additional |
+ // logic in *RequestValidator and *ResponseValidator is ported from |
+ // cpp to js. |
+ // TODO(crbug/640298): Implement max recursion depth for JS. |
+ // TODO(crbug/628104): Support struct map keys for JS. |
+ if (testFiles[i].indexOf('overflow') != -1 || |
+ testFiles[i].indexOf('conformance_mthd19') != -1 || |
+ testFiles[i].indexOf('conformance_mthd20') != -1 || |
+ testFiles[i].indexOf('no_such_method') != -1 || |
+ testFiles[i].indexOf('invalid_request_flags') != -1 || |
+ testFiles[i].indexOf('invalid_response_flags') != -1) { |
+ console.log('[Skipping ' + testFiles[i] + ']'); |
+ continue; |
+ } |
- function readTestExpected(filename) { |
- return fetchLite(filename + '.expected').then((response) => { |
- assert_not_equals(response, null); |
- return response.trim(); |
- }); |
- } |
+ var testMessage = await readTestMessage(testFiles[i]); |
+ var handles = new Array(testMessage.handleCount); |
+ var message = new mojo.internal.Message(testMessage.buffer, handles); |
+ var messageValidator = new mojo.internal.Validator(message); |
- async function checkValidationResult(testFile, err) { |
- var actualResult = (err === noError) ? 'PASS' : err; |
- var expectedResult = await readTestExpected(testFile); |
- assert_equals(actualResult, expectedResult, |
- '[Test message validation failed: ' + testFile + ' ]'); |
- } |
+ var err = messageValidator.validateMessageHeader(); |
+ for (var j = 0; err === noError && j < filters.length; ++j) |
+ err = filters[j](messageValidator); |
- async function testMessageValidation(prefix, filters) { |
- var testFiles = await getMessageTestFiles(prefix); |
- assert_greater_than(testFiles.length, 0); |
+ await checkValidationResult(testFiles[i], err); |
+ } |
+} |
+ |
+promise_test(() => { |
+ return testMessageValidation('conformance_', [ |
+ mojo.test.ConformanceTestInterface.validateRequest]); |
+}, 'conformance message validation'); |
+ |
+promise_test(() => { |
+ return testMessageValidation('boundscheck_', [ |
+ mojo.test.BoundsCheckTestInterface.validateRequest]); |
+}, 'bounds check message validation'); |
+ |
+promise_test(() => { |
+ return testMessageValidation('resp_conformance_', [ |
+ mojo.test.ConformanceTestInterface.validateResponse]); |
+}, 'response conformance message validation'); |
+ |
+promise_test(() => { |
+ return testMessageValidation('resp_boundscheck_', [ |
+ mojo.test.BoundsCheckTestInterface.validateResponse]); |
+}, 'response bounds check message validation'); |
+ |
+async function testIntegratedMessageValidation(testFilesPattern, endpoint) { |
+ var testFiles = await getMessageTestFiles(testFilesPattern); |
+ assert_greater_than(testFiles.length, 0); |
+ |
+ var testMessagePipe = Mojo.createMessagePipe(); |
+ assert_equals(testMessagePipe.result, Mojo.RESULT_OK); |
+ |
+ endpoint.bind(testMessagePipe.handle1); |
+ if (endpoint instanceof mojo.InterfacePtrController) { |
+ // Make sure the router and connector are initialized. |
+ endpoint.getProxy(); |
+ } |
- for (var i = 0; i < testFiles.length; i++) { |
- // TODO(hansmuller) Temporarily skipping array pointer overflow tests |
- // because JS numbers are limited to 53 bits. |
- // TODO(rudominer): Temporarily skipping 'no-such-method', |
- // 'invalid_request_flags', and 'invalid_response_flags' until additional |
- // logic in *RequestValidator and *ResponseValidator is ported from |
- // cpp to js. |
- // TODO(crbug/640298): Implement max recursion depth for JS. |
- // TODO(crbug/628104): Support struct map keys for JS. |
- if (testFiles[i].indexOf('overflow') != -1 || |
- testFiles[i].indexOf('conformance_mthd19') != -1 || |
- testFiles[i].indexOf('conformance_mthd20') != -1 || |
- testFiles[i].indexOf('no_such_method') != -1 || |
- testFiles[i].indexOf('invalid_request_flags') != -1 || |
- testFiles[i].indexOf('invalid_response_flags') != -1) { |
- console.log('[Skipping ' + testFiles[i] + ']'); |
- continue; |
- } |
- |
- var testMessage = await readTestMessage(testFiles[i]); |
- var handles = new Array(testMessage.handleCount); |
- var message = new codec.Message(testMessage.buffer, handles); |
- var messageValidator = new validator.Validator(message); |
- |
- var err = messageValidator.validateMessageHeader(); |
- for (var j = 0; err === noError && j < filters.length; ++j) |
- err = filters[j](messageValidator); |
- |
- await checkValidationResult(testFiles[i], err); |
+ var originalReceiver = endpoint.router_.connector_.incomingReceiver_.accept; |
+ var nextMessageCallback = null; |
+ endpoint.router_.connector_.incomingReceiver_.accept = function(message) { |
+ var result = originalReceiver(message); |
+ if (nextMessageCallback) { |
+ setTimeout(() => { |
+ nextMessageCallback(); |
+ nextMessageCallback = null; |
+ }, 0); |
} |
+ return result; |
} |
- promise_test(() => { |
- return testMessageValidation('conformance_', [ |
- testInterface.ConformanceTestInterface.validateRequest]); |
- }, 'conformance message validation'); |
- |
- promise_test(() => { |
- return testMessageValidation('boundscheck_', [ |
- testInterface.BoundsCheckTestInterface.validateRequest]); |
- }, 'bounds check message validation'); |
- |
- promise_test(() => { |
- return testMessageValidation('resp_conformance_', [ |
- testInterface.ConformanceTestInterface.validateResponse]); |
- }, 'response conformance message validation'); |
- |
- promise_test(() => { |
- return testMessageValidation('resp_boundscheck_', [ |
- testInterface.BoundsCheckTestInterface.validateResponse]); |
- }, 'response bounds check message validation'); |
- |
- async function testIntegratedMessageValidation(testFilesPattern, endpoint) { |
- var testFiles = await getMessageTestFiles(testFilesPattern); |
- assert_greater_than(testFiles.length, 0); |
- |
- var testMessagePipe = core.createMessagePipe(); |
- assert_equals(testMessagePipe.result, core.RESULT_OK); |
+ var observer = mojo.internal.ValidationErrorObserverForTesting.getInstance(); |
- endpoint.bind(testMessagePipe.handle1); |
- var observer = validator.ValidationErrorObserverForTesting.getInstance(); |
+ for (var i = 0; i < testFiles.length; i++) { |
+ var testMessage = await readTestMessage(testFiles[i]); |
+ var handles = new Array(testMessage.handleCount); |
- for (var i = 0; i < testFiles.length; i++) { |
- var testMessage = await readTestMessage(testFiles[i]); |
- var handles = new Array(testMessage.handleCount); |
+ await new Promise((resolve, reject) => { |
+ nextMessageCallback = resolve; |
- var writeMessageValue = core.writeMessage( |
- testMessagePipe.handle0, |
+ var writeMessageValue = testMessagePipe.handle0.writeMessage( |
new Uint8Array(testMessage.buffer.arrayBuffer), |
- new Array(testMessage.handleCount), |
- core.WRITE_MESSAGE_FLAG_NONE); |
- assert_equals(writeMessageValue, core.RESULT_OK); |
- |
- endpoint.waitForNextMessageForTesting(); |
- await checkValidationResult(testFiles[i], observer.lastError); |
- observer.reset(); |
- } |
- |
- assert_equals(core.close(testMessagePipe.handle0), core.RESULT_OK); |
+ new Array(testMessage.handleCount)); |
+ assert_equals(writeMessageValue, Mojo.RESULT_OK); |
+ }); |
+ await checkValidationResult(testFiles[i], observer.lastError); |
+ observer.reset(); |
} |
- promise_test(() => { |
- return testIntegratedMessageValidation( |
- 'integration_msghdr', |
- new bindings.Binding(testInterface.IntegrationTestInterface, {})) |
- .then(() => { |
- return testIntegratedMessageValidation( |
- 'integration_msghdr', |
- new testInterface.IntegrationTestInterfacePtr().ptr); |
- }); |
- }, 'integrated message header validation'); |
- |
- promise_test(() => { |
- return testIntegratedMessageValidation( |
- 'integration_intf_rqst', |
- new bindings.Binding(testInterface.IntegrationTestInterface, {})); |
- }, 'integrated request message validation'); |
- |
- promise_test(() => { |
- return testIntegratedMessageValidation( |
- 'integration_intf_resp', |
- new testInterface.IntegrationTestInterfacePtr().ptr); |
- }, 'integrated response message validation'); |
- |
- done(); |
-}); |
+ testMessagePipe.handle0.close(); |
+} |
+ |
+promise_test(() => { |
+ return testIntegratedMessageValidation( |
+ 'integration_msghdr', |
+ new mojo.Binding(mojo.test.IntegrationTestInterface, {})) |
+ .then(() => { |
+ return testIntegratedMessageValidation( |
+ 'integration_msghdr', |
+ new mojo.test.IntegrationTestInterfacePtr().ptr); |
+ }); |
+}, 'integrated message header validation'); |
+ |
+promise_test(() => { |
+ return testIntegratedMessageValidation( |
+ 'integration_intf_rqst', |
+ new mojo.Binding(mojo.test.IntegrationTestInterface, {})); |
+}, 'integrated request message validation'); |
+ |
+promise_test(() => { |
+ return testIntegratedMessageValidation( |
+ 'integration_intf_resp', |
+ new mojo.test.IntegrationTestInterfacePtr().ptr); |
+}, 'integrated response message validation'); |
</script> |