Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 <!DOCTYPE html> | |
| 2 <script src="../resources/testharness.js"></script> | |
| 3 <script src="../resources/testharnessreport.js"></script> | |
| 4 <script src="../resources/mojo-helpers.js"></script> | |
| 5 <script src="resources/validation_test_input_parser.js"></script> | |
| 6 <script> | |
| 7 'use strict'; | |
| 8 | |
| 9 setup({ explicit_done: true }); | |
| 10 | |
| 11 define(["mojo/public/js/bindings", | |
|
alokp
2017/03/27 01:50:09
nit: formatting?
| |
| 12 "mojo/public/js/buffer", | |
| 13 "mojo/public/js/codec", | |
| 14 "mojo/public/js/core", | |
| 15 "mojo/resources/validation_test_input_parser", | |
| 16 "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom", | |
| 17 "mojo/public/js/validator", | |
| 18 ], function(bindings, | |
| 19 buffer, | |
| 20 codec, | |
| 21 core, | |
| 22 parser, | |
| 23 testInterface, | |
| 24 validator) { | |
| 25 | |
| 26 var noError = validator.validationError.NONE; | |
| 27 | |
| 28 function checkData(data, expectedData, input) { | |
| 29 assert_equals(data.byteLength, expectedData.byteLength, | |
| 30 "message length (" + data.byteLength + ") doesn't match " + | |
| 31 "expected length: " + expectedData.byteLength + " for " + input); | |
| 32 | |
| 33 for (var i = 0; i < data.byteLength; i++) { | |
| 34 assert_equals(data.getUint8(i), expectedData.getUint8(i), | |
| 35 'message data mismatch at byte offset ' + i + "for" + input); | |
| 36 } | |
| 37 } | |
| 38 | |
| 39 test(() => { | |
| 40 var input = '[f]+.3e9 [d]-10.03'; | |
| 41 var msg = parser.parseTestMessage(input); | |
| 42 var expectedData = new buffer.Buffer(12); | |
| 43 expectedData.setFloat32(0, +.3e9); | |
| 44 expectedData.setFloat64(4, -10.03); | |
| 45 checkData(msg.buffer, expectedData, input); | |
| 46 }, 'message parser: float items'); | |
| 47 | |
| 48 test(() => { | |
| 49 var input = '[u1]0x10// hello world !! \n\r \t [u2]65535 \n' + | |
| 50 '[u4]65536 [u8]0xFFFFFFFFFFFFF 0 0Xff'; | |
| 51 var msg = parser.parseTestMessage(input); | |
| 52 var expectedData = new buffer.Buffer(17); | |
| 53 expectedData.setUint8(0, 0x10); | |
| 54 expectedData.setUint16(1, 65535); | |
| 55 expectedData.setUint32(3, 65536); | |
| 56 expectedData.setUint64(7, 0xFFFFFFFFFFFFF); | |
| 57 expectedData.setUint8(15, 0); | |
| 58 expectedData.setUint8(16, 0xff); | |
| 59 checkData(msg.buffer, expectedData, input); | |
| 60 }, 'message parser: unsigned integer items'); | |
| 61 | |
| 62 test(() => { | |
| 63 var input = '[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40'; | |
| 64 var msg = parser.parseTestMessage(input); | |
| 65 var expectedData = new buffer.Buffer(15); | |
| 66 expectedData.setInt64(0, -0x800); | |
| 67 expectedData.setInt8(8, -128); | |
| 68 expectedData.setInt16(9, 0); | |
| 69 expectedData.setInt32(11, -40); | |
| 70 checkData(msg.buffer, expectedData, input); | |
| 71 }, 'message parser: signed integer items'); | |
| 72 | |
| 73 test(() => { | |
| 74 var input = '[b]00001011 [b]10000000 // hello world\n [b]00000000'; | |
| 75 var msg = parser.parseTestMessage(input); | |
| 76 var expectedData = new buffer.Buffer(3); | |
| 77 expectedData.setUint8(0, 11); | |
| 78 expectedData.setUint8(1, 128); | |
| 79 expectedData.setUint8(2, 0); | |
| 80 checkData(msg.buffer, expectedData, input); | |
| 81 }, 'message parser: byte items'); | |
| 82 | |
| 83 test(() => { | |
| 84 var input = '[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar'; | |
| 85 var msg = parser.parseTestMessage(input); | |
| 86 var expectedData = new buffer.Buffer(14); | |
| 87 expectedData.setUint32(0, 14); | |
| 88 expectedData.setUint8(4, 0); | |
| 89 expectedData.setUint64(5, 9); | |
| 90 expectedData.setUint8(13, 0); | |
| 91 checkData(msg.buffer, expectedData, input); | |
| 92 }, 'message parser: anchors'); | |
| 93 | |
| 94 test(() => { | |
| 95 var input = '// This message has handles! \n[handles]50 [u8]2'; | |
| 96 var msg = parser.parseTestMessage(input); | |
| 97 var expectedData = new buffer.Buffer(8); | |
| 98 expectedData.setUint64(0, 2); | |
| 99 | |
| 100 assert_equals(msg.handleCount, 50, | |
| 101 'wrong handle count (' + msg.handleConut + ') for ' + input); | |
| 102 checkData(msg.buffer, expectedData, input); | |
| 103 }, 'message parser: handles'); | |
| 104 | |
| 105 test(() => { | |
| 106 var msg = parser.parseTestMessage(''); | |
| 107 assert_equals(msg.buffer.byteLength, 0, 'expected empty message for '); | |
| 108 }, 'message parser: empty input'); | |
| 109 | |
| 110 test(() => { | |
| 111 var input = ' \t // hello world \n\r \t// the answer is 42 '; | |
| 112 var msg = parser.parseTestMessage(input); | |
| 113 assert_equals(msg.buffer.byteLength, 0, | |
| 114 'expected empty message for ' + input); | |
| 115 }, 'message parser: blank input'); | |
| 116 | |
| 117 test(() => { | |
| 118 function parserShouldFail(input) { | |
| 119 assert_throws(new parser.InputError(), function() { | |
| 120 parser.parseTestMessage(input); | |
| 121 }); | |
| 122 } | |
| 123 | |
| 124 ['/ hello world', | |
| 125 '[u1]x', | |
| 126 '[u2]-1000', | |
| 127 '[u1]0x100', | |
| 128 '[s2]-0x8001', | |
| 129 '[b]1', | |
| 130 '[b]1111111k', | |
| 131 '[dist4]unmatched', | |
| 132 '[anchr]hello [dist8]hello', | |
| 133 '[dist4]a [dist4]a [anchr]a', | |
| 134 // '[dist4]a [anchr]a [dist4]a [anchr]a', | |
| 135 '0 [handles]50' | |
| 136 ].forEach(parserShouldFail); | |
| 137 }, 'message parser: invalid input'); | |
| 138 | |
| 139 function fetchLite(url) { | |
| 140 return new Promise((resolve, reject) => { | |
| 141 var xhr = new XMLHttpRequest(); | |
| 142 xhr.open('GET', url); | |
| 143 xhr.onreadystatechange = () => { | |
| 144 if (xhr.readyState != 4) return; | |
| 145 resolve(xhr.responseText); | |
| 146 }; | |
| 147 xhr.send(); | |
| 148 }); | |
| 149 } | |
| 150 | |
| 151 function getMessageTestFiles(prefix) { | |
| 152 let genDirectory = "/gen/mojo/public/interfaces/bindings/tests/"; | |
|
yzshen1
2017/03/27 00:29:17
style nit: please use single quotes in JavaScript.
| |
| 153 return fetchLite(genDirectory + "validation_files.txt").then((response) => { | |
| 154 assert_not_equals(response, null); | |
| 155 var testFiles = response.split('\n'); | |
| 156 assert_greater_than(testFiles.length, 0); | |
| 157 return testFiles.filter(function(s) { | |
| 158 return s.substr(-5) == ".data" && s.indexOf(prefix) == 0; | |
| 159 }).map(function(s) { | |
| 160 return genDirectory + "data/validation/" + s.slice(0, -5); | |
| 161 }); | |
| 162 }); | |
| 163 } | |
| 164 | |
| 165 function readTestMessage(filename) { | |
| 166 return fetchLite(filename + ".data").then((response) => { | |
| 167 assert_not_equals(response, null); | |
| 168 return parser.parseTestMessage(response); | |
| 169 }); | |
| 170 } | |
| 171 | |
| 172 function readTestExpected(filename) { | |
| 173 return fetchLite(filename + ".expected").then((response) => { | |
| 174 assert_not_equals(response, null); | |
| 175 return response.trim(); | |
| 176 }); | |
| 177 } | |
| 178 | |
| 179 async function checkValidationResult(testFile, err) { | |
| 180 var actualResult = (err === noError) ? "PASS" : err; | |
| 181 var expectedResult = await readTestExpected(testFile); | |
| 182 assert_equals(actualResult, expectedResult, | |
| 183 "[Test message validation failed: " + testFile + " ]"); | |
| 184 } | |
| 185 | |
| 186 async function testMessageValidation(prefix, filters) { | |
| 187 var testFiles = await getMessageTestFiles(prefix); | |
| 188 assert_greater_than(testFiles.length, 0); | |
| 189 | |
| 190 for (var i = 0; i < testFiles.length; i++) { | |
| 191 // TODO(hansmuller) Temporarily skipping array pointer overflow tests | |
| 192 // because JS numbers are limited to 53 bits. | |
| 193 // TODO(rudominer): Temporarily skipping 'no-such-method', | |
| 194 // 'invalid_request_flags', and 'invalid_response_flags' until additional | |
| 195 // logic in *RequestValidator and *ResponseValidator is ported from | |
| 196 // cpp to js. | |
| 197 // TODO(crbug/640298): Implement max recursion depth for JS. | |
| 198 // TODO(crbug/628104): Support struct map keys for JS. | |
| 199 if (testFiles[i].indexOf("overflow") != -1 || | |
| 200 testFiles[i].indexOf("conformance_mthd19") != -1 || | |
| 201 testFiles[i].indexOf("conformance_mthd20") != -1 || | |
| 202 testFiles[i].indexOf("no_such_method") != -1 || | |
| 203 testFiles[i].indexOf("invalid_request_flags") != -1 || | |
| 204 testFiles[i].indexOf("invalid_response_flags") != -1) { | |
| 205 console.log("[Skipping " + testFiles[i] + "]"); | |
| 206 continue; | |
| 207 } | |
| 208 | |
| 209 var testMessage = await readTestMessage(testFiles[i]); | |
| 210 var handles = new Array(testMessage.handleCount); | |
| 211 var message = new codec.Message(testMessage.buffer, handles); | |
| 212 var messageValidator = new validator.Validator(message); | |
| 213 | |
| 214 var err = messageValidator.validateMessageHeader(); | |
| 215 for (var j = 0; err === noError && j < filters.length; ++j) | |
| 216 err = filters[j](messageValidator); | |
| 217 | |
| 218 await checkValidationResult(testFiles[i], err); | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 promise_test(() => { | |
| 223 return testMessageValidation("conformance_", [ | |
| 224 testInterface.ConformanceTestInterface.validateRequest]); | |
| 225 }, 'conformance message validation'); | |
| 226 | |
| 227 promise_test(() => { | |
| 228 return testMessageValidation("boundscheck_", [ | |
| 229 testInterface.BoundsCheckTestInterface.validateRequest]); | |
| 230 }, 'bounds check message validation'); | |
| 231 | |
| 232 promise_test(() => { | |
| 233 return testMessageValidation("resp_conformance_", [ | |
| 234 testInterface.ConformanceTestInterface.validateResponse]); | |
| 235 }, 'response conformance message validation'); | |
| 236 | |
| 237 promise_test(() => { | |
| 238 return testMessageValidation("resp_boundscheck_", [ | |
| 239 testInterface.BoundsCheckTestInterface.validateResponse]); | |
| 240 }, 'response bounds check message validation'); | |
| 241 | |
| 242 async function testIntegratedMessageValidation(testFilesPattern, endpoint) { | |
| 243 var testFiles = await getMessageTestFiles(testFilesPattern); | |
| 244 assert_greater_than(testFiles.length, 0); | |
| 245 | |
| 246 var testMessagePipe = core.createMessagePipe(); | |
| 247 assert_equals(testMessagePipe.result, core.RESULT_OK); | |
| 248 | |
| 249 endpoint.bind(testMessagePipe.handle1); | |
| 250 var testingController = endpoint.enableTestingMode(); | |
| 251 | |
| 252 var validationError; | |
| 253 testingController.setInvalidIncomingMessageHandler(function(error) { | |
| 254 validationError = error; | |
| 255 }); | |
| 256 | |
| 257 for (var i = 0; i < testFiles.length; i++) { | |
| 258 validationError = noError; | |
| 259 var testMessage = await readTestMessage(testFiles[i]); | |
| 260 var handles = new Array(testMessage.handleCount); | |
| 261 | |
| 262 var writeMessageValue = core.writeMessage( | |
| 263 testMessagePipe.handle0, | |
| 264 new Uint8Array(testMessage.buffer.arrayBuffer), | |
| 265 new Array(testMessage.handleCount), | |
| 266 core.WRITE_MESSAGE_FLAG_NONE); | |
| 267 assert_equals(writeMessageValue, core.RESULT_OK); | |
| 268 | |
| 269 testingController.waitForNextMessage(); | |
| 270 await checkValidationResult(testFiles[i], validationError); | |
| 271 } | |
| 272 | |
| 273 assert_equals(core.close(testMessagePipe.handle0), core.RESULT_OK); | |
| 274 } | |
| 275 | |
| 276 promise_test(() => { | |
| 277 return testIntegratedMessageValidation( | |
| 278 "integration_msghdr", | |
| 279 new bindings.Binding(testInterface.IntegrationTestInterface, {})) | |
| 280 .then(() => { | |
| 281 return testIntegratedMessageValidation( | |
| 282 "integration_msghdr", | |
| 283 new testInterface.IntegrationTestInterfacePtr().ptr); | |
| 284 }); | |
| 285 }, 'integrated message header validation'); | |
| 286 | |
| 287 promise_test(() => { | |
| 288 return testIntegratedMessageValidation( | |
| 289 "integration_intf_rqst", | |
| 290 new bindings.Binding(testInterface.IntegrationTestInterface, {})); | |
| 291 }, 'integrated request message validation'); | |
| 292 | |
| 293 promise_test(() => { | |
| 294 return testIntegratedMessageValidation( | |
| 295 "integration_intf_resp", | |
| 296 new testInterface.IntegrationTestInterfacePtr().ptr); | |
| 297 }, 'integrated response message validation'); | |
| 298 | |
| 299 done(); | |
| 300 }); | |
| 301 | |
| 302 </script> | |
| OLD | NEW |