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/interfaces/bindings/tests/validation_test_interfaces.mojom" , | |
yzshen1
2017/03/23 17:46:20
80 chars, please. (here and below)
| |
12 "mojo/public/js/bindings", | |
13 "mojo/public/js/buffer", | |
14 "mojo/public/js/codec", | |
15 "mojo/public/js/core", | |
16 "mojo/resources/validation_test_input_parser", | |
17 "mojo/public/js/validator", | |
yzshen1
2017/03/23 17:46:20
Please arrange them alphabetically.
| |
18 ], function(testInterface, | |
19 bindings, | |
20 buffer, | |
21 codec, | |
22 core, | |
23 parser, | |
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, 'expected empty message for ' + inpu t); | |
114 }, 'message parser: blank input'); | |
115 | |
116 test(() => { | |
117 function parserShouldFail(input) { | |
118 assert_throws(new parser.InputError(), function() { | |
119 parser.parseTestMessage(input); | |
120 }); | |
121 } | |
122 | |
123 ['/ hello world', | |
124 '[u1]x', | |
125 '[u2]-1000', | |
126 '[u1]0x100', | |
127 '[s2]-0x8001', | |
128 '[b]1', | |
129 '[b]1111111k', | |
130 '[dist4]unmatched', | |
131 '[anchr]hello [dist8]hello', | |
132 '[dist4]a [dist4]a [anchr]a', | |
133 // '[dist4]a [anchr]a [dist4]a [anchr]a', | |
134 '0 [handles]50' | |
135 ].forEach(parserShouldFail); | |
136 }, 'message parser: invalid input'); | |
137 | |
138 function fetchLite(url) { | |
139 return new Promise((resolve, reject) => { | |
140 var xhr = new XMLHttpRequest(); | |
141 xhr.open('GET', url); | |
142 xhr.onreadystatechange = () => { | |
143 if (xhr.readyState != 4) return; | |
144 resolve(xhr.responseText); | |
145 }; | |
146 xhr.send(); | |
147 }); | |
148 } | |
149 | |
150 function getMessageTestFiles(prefix) { | |
151 let genDirectory = '/gen/mojo/public/interfaces/bindings/tests/'; | |
152 return fetchLite(genDirectory + 'data_files.txt').then((response) => { | |
153 assert_not_equals(response, null); | |
154 var testFiles = response.split('\n'); | |
155 assert_greater_than(testFiles.length, 0); | |
156 return testFiles.filter(function(s) { | |
157 return s.indexOf(prefix) == 0; | |
158 }).map(function(s) { | |
159 return genDirectory + 'data/' + s; | |
160 }); | |
161 }); | |
162 } | |
163 | |
164 function readTestMessage(filename) { | |
165 return fetchLite(filename + '.data').then((response) => { | |
166 assert_not_equals(response, null); | |
167 return parser.parseTestMessage(response); | |
168 }); | |
169 } | |
170 | |
171 function readTestExpected(filename) { | |
172 return fetchLite(filename + '.expected').then((response) => { | |
173 assert_not_equals(response, null); | |
174 return response.trim(); | |
175 }); | |
176 } | |
177 | |
178 async function checkValidationResult(testFile, err) { | |
179 var actualResult = (err === noError) ? "PASS" : err; | |
180 var expectedResult = await readTestExpected(testFile); | |
181 assert_equals(actualResult, expectedResult, | |
182 "[Test message validation failed: " + testFile + " ]"); | |
183 } | |
184 | |
185 async function testMessageValidation(prefix, filters) { | |
186 var testFiles = await getMessageTestFiles(prefix); | |
187 assert_greater_than(testFiles.length, 0); | |
188 | |
189 for (var i = 0; i < testFiles.length; i++) { | |
190 // TODO(hansmuller) Temporarily skipping array pointer overflow tests | |
191 // because JS numbers are limited to 53 bits. | |
192 // TODO(rudominer): Temporarily skipping 'no-such-method', | |
193 // 'invalid_request_flags', and 'invalid_response_flags' until additional | |
194 // logic in *RequestValidator and *ResponseValidator is ported from | |
195 // cpp to js. | |
196 // TODO(crbug/640298): Implement max recursion depth for JS. | |
197 // TODO(crbug/628104): Support struct map keys for JS. | |
198 if (testFiles[i].indexOf("overflow") != -1 || | |
199 testFiles[i].indexOf("conformance_mthd19") != -1 || | |
200 testFiles[i].indexOf("conformance_mthd20") != -1 || | |
201 testFiles[i].indexOf("no_such_method") != -1 || | |
202 testFiles[i].indexOf("invalid_request_flags") != -1 || | |
203 testFiles[i].indexOf("invalid_response_flags") != -1) { | |
204 console.log("[Skipping " + testFiles[i] + "]"); | |
205 continue; | |
206 } | |
207 | |
208 var testMessage = await readTestMessage(testFiles[i]); | |
209 var handles = new Array(testMessage.handleCount); | |
210 var message = new codec.Message(testMessage.buffer, handles); | |
211 var messageValidator = new validator.Validator(message); | |
212 | |
213 var err = messageValidator.validateMessageHeader(); | |
214 for (var j = 0; err === noError && j < filters.length; ++j) | |
215 err = filters[j](messageValidator); | |
216 | |
217 await checkValidationResult(testFiles[i], err); | |
218 } | |
219 } | |
220 | |
221 promise_test(() => { | |
222 return testMessageValidation("conformance_", [ | |
223 testInterface.ConformanceTestInterface.validateRequest]); | |
224 }, 'conformance message validation'); | |
225 | |
226 promise_test(() => { | |
227 return testMessageValidation("boundscheck_", [ | |
228 testInterface.BoundsCheckTestInterface.validateRequest]); | |
229 }, 'bounds check message validation'); | |
230 | |
231 promise_test(() => { | |
232 return testMessageValidation("resp_conformance_", [ | |
233 testInterface.ConformanceTestInterface.validateResponse]); | |
234 }, 'response conformance message validation'); | |
235 | |
236 promise_test(() => { | |
237 return testMessageValidation("resp_boundscheck_", [ | |
238 testInterface.BoundsCheckTestInterface.validateResponse]); | |
239 }, 'response bounds check message validation'); | |
240 | |
241 async function testIntegratedMessageValidation(testFilesPattern, endpoint) { | |
242 var testFiles = await getMessageTestFiles(testFilesPattern); | |
243 assert_greater_than(testFiles.length, 0); | |
244 | |
245 var testMessagePipe = core.createMessagePipe(); | |
246 assert_equals(testMessagePipe.result, core.RESULT_OK); | |
247 | |
248 endpoint.bind(testMessagePipe.handle1); | |
249 var testingController = endpoint.enableTestingMode(); | |
250 | |
251 var validationError; | |
252 testingController.setInvalidIncomingMessageHandler(function(error) { | |
253 validationError = error; | |
254 }); | |
255 | |
256 for (var i = 0; i < testFiles.length; i++) { | |
257 validationError = noError; | |
258 var testMessage = await readTestMessage(testFiles[i]); | |
259 var handles = new Array(testMessage.handleCount); | |
260 | |
261 var writeMessageValue = core.writeMessage( | |
262 testMessagePipe.handle0, | |
263 new Uint8Array(testMessage.buffer.arrayBuffer), | |
264 new Array(testMessage.handleCount), | |
265 core.WRITE_MESSAGE_FLAG_NONE); | |
266 assert_equals(writeMessageValue, core.RESULT_OK); | |
267 | |
268 testingController.waitForNextMessage(); | |
269 await checkValidationResult(testFiles[i], validationError); | |
270 } | |
271 | |
272 assert_equals(core.close(testMessagePipe.handle0), core.RESULT_OK); | |
273 } | |
274 | |
275 promise_test(() => { | |
276 return testIntegratedMessageValidation( | |
277 "integration_msghdr", | |
278 new bindings.Binding(testInterface.IntegrationTestInterface, {})).then(( ) => { | |
279 return testIntegratedMessageValidation( | |
280 "integration_msghdr", | |
281 new testInterface.IntegrationTestInterfacePtr().ptr); | |
282 }); | |
283 }, 'integrated message header validation'); | |
284 | |
285 promise_test(() => { | |
286 return testIntegratedMessageValidation( | |
287 "integration_intf_rqst", | |
288 new bindings.Binding(testInterface.IntegrationTestInterface, {})); | |
289 }, 'integrated request message validation'); | |
290 | |
291 promise_test(() => { | |
292 return testIntegratedMessageValidation( | |
293 "integration_intf_resp", | |
294 new testInterface.IntegrationTestInterfacePtr().ptr); | |
295 }, 'integrated response message validation'); | |
296 | |
297 done(); | |
298 }); | |
299 | |
300 </script> | |
OLD | NEW |