Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: third_party/WebKit/LayoutTests/mojo/validation.html

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

Powered by Google App Engine
This is Rietveld 408576698