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 /** | 5 /** |
6 * Unit tests for the JS serial service client. | 6 * Unit tests for the JS serial service client. |
7 * | 7 * |
8 * These test that configuration and data are correctly transmitted between the | 8 * These test that configuration and data are correctly transmitted between the |
9 * client and the service. | 9 * client and the service. They are launched by |
10 * extensions/renderer/api/serial/serial_api_unittest.cc. | |
10 */ | 11 */ |
11 | 12 |
12 var test = require('test').binding; | 13 var test = require('test').binding; |
13 var serial = require('serial').binding; | 14 var serial = require('serial').binding; |
14 var unittestBindings = require('test_environment_specific_bindings'); | 15 var unittestBindings = require('test_environment_specific_bindings'); |
16 var utils = require('utils'); | |
17 | |
18 var timeoutManager = new unittestBindings.TimeoutManager(); | |
19 timeoutManager.installGlobals(); | |
20 | |
21 var BUFFER_SIZE = 10; | |
15 | 22 |
16 var connectionId = null; | 23 var connectionId = null; |
17 | 24 |
18 function connect(callback, options) { | 25 function connect(callback, options) { |
19 options = options || { | 26 options = options || { |
20 name: 'test connection', | 27 name: 'test connection', |
21 bufferSize: 8192, | 28 bufferSize: BUFFER_SIZE, |
22 receiveTimeout: 12345, | 29 receiveTimeout: 12345, |
23 sendTimeout: 6789, | 30 sendTimeout: 6789, |
24 persistent: true, | 31 persistent: true, |
25 } | 32 }; |
26 serial.connect('device', options, test.callbackPass(function(connectionInfo) { | 33 serial.connect('device', options, test.callbackPass(function(connectionInfo) { |
27 connectionId = connectionInfo.connectionId; | 34 connectionId = connectionInfo.connectionId; |
28 callback(connectionInfo); | 35 if (callback) |
36 callback(connectionInfo); | |
29 })); | 37 })); |
30 } | 38 } |
31 | 39 |
40 // Sets a function to be called once when data is received. Returns a promise | |
41 // that will resolve once the hook is installed. | |
42 function addReceiveHook(callback) { | |
43 return requireAsync('serial_service').then(function(serialService) { | |
44 var called = false; | |
45 var dataReceived = serialService.Connection.prototype.onDataReceived_; | |
46 serialService.Connection.prototype.onDataReceived_ = function() { | |
47 var result = $Function.apply(dataReceived, this, arguments); | |
48 if (!called) | |
49 callback(); | |
50 called = true; | |
51 return result; | |
52 }; | |
53 }); | |
54 } | |
55 | |
56 // Sets a function to be called once when a receive error is received. Returns a | |
57 // promise that will resolve once the hook is installed. | |
58 function addReceiveErrorHook(callback) { | |
59 return requireAsync('serial_service').then(function(serialService) { | |
60 var called = false; | |
61 var receiveError = serialService.Connection.prototype.onReceiveError_; | |
62 serialService.Connection.prototype.onReceiveError_ = function() { | |
63 var result = $Function.apply(receiveError, this, arguments); | |
64 if (!called) | |
65 callback(); | |
66 called = true; | |
67 return result; | |
68 }; | |
69 }); | |
70 } | |
71 | |
32 function disconnect() { | 72 function disconnect() { |
33 serial.disconnect(connectionId, test.callbackPass(function(success) { | 73 serial.disconnect(connectionId, test.callbackPass(function(success) { |
34 test.assertTrue(success); | 74 test.assertTrue(success); |
35 connectionId = null; | 75 connectionId = null; |
36 })); | 76 })); |
37 } | 77 } |
38 | 78 |
39 function checkClientConnectionInfo(connectionInfo) { | 79 function checkClientConnectionInfo(connectionInfo) { |
40 test.assertFalse(connectionInfo.persistent); | 80 test.assertFalse(connectionInfo.persistent); |
41 test.assertEq('test connection', connectionInfo.name); | 81 test.assertEq('test connection', connectionInfo.name); |
42 test.assertEq(12345, connectionInfo.receiveTimeout); | 82 test.assertEq(12345, connectionInfo.receiveTimeout); |
43 test.assertEq(6789, connectionInfo.sendTimeout); | 83 test.assertEq(6789, connectionInfo.sendTimeout); |
44 test.assertEq(8192, connectionInfo.bufferSize); | 84 test.assertEq(BUFFER_SIZE, connectionInfo.bufferSize); |
45 test.assertFalse(connectionInfo.paused); | 85 test.assertFalse(connectionInfo.paused); |
46 } | 86 } |
47 | 87 |
48 function checkServiceConnectionInfo(connectionInfo) { | 88 function checkServiceConnectionInfo(connectionInfo) { |
49 test.assertEq(9600, connectionInfo.bitrate); | 89 test.assertEq(9600, connectionInfo.bitrate); |
50 test.assertEq('eight', connectionInfo.dataBits); | 90 test.assertEq('eight', connectionInfo.dataBits); |
51 test.assertEq('no', connectionInfo.parityBit); | 91 test.assertEq('no', connectionInfo.parityBit); |
52 test.assertEq('one', connectionInfo.stopBits); | 92 test.assertEq('one', connectionInfo.stopBits); |
53 test.assertFalse(connectionInfo.ctsFlowControl); | 93 test.assertFalse(connectionInfo.ctsFlowControl); |
54 } | 94 } |
55 | 95 |
56 function checkConnectionInfo(connectionInfo) { | 96 function checkConnectionInfo(connectionInfo) { |
57 checkClientConnectionInfo(connectionInfo); | 97 checkClientConnectionInfo(connectionInfo); |
58 checkServiceConnectionInfo(connectionInfo); | 98 checkServiceConnectionInfo(connectionInfo); |
59 } | 99 } |
60 | 100 |
101 function runReceiveErrorTest(expectedError) { | |
102 connect(); | |
103 test.listenOnce(serial.onReceiveError, function(result) { | |
104 serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) { | |
105 disconnect(); | |
106 test.assertTrue(connectionInfo.paused); | |
107 })); | |
108 test.assertEq(connectionId, result.connectionId); | |
109 test.assertEq(expectedError, result.error); | |
110 }); | |
111 } | |
112 | |
113 function runSendErrorTest(expectedError) { | |
114 connect(function() { | |
115 var buffer = new ArrayBuffer(1); | |
116 serial.send(connectionId, buffer, test.callbackPass(function(sendInfo) { | |
117 disconnect(); | |
118 test.assertEq(0, sendInfo.bytesSent); | |
119 test.assertEq(expectedError, sendInfo.error); | |
120 })); | |
121 }); | |
122 } | |
123 | |
124 function sendData() { | |
125 var data = 'data'; | |
126 var buffer = new ArrayBuffer(data.length); | |
127 var byteBuffer = new Int8Array(buffer); | |
128 for (var i = 0; i < data.length; i++) { | |
129 byteBuffer[i] = data.charCodeAt(i); | |
130 } | |
131 return utils.promise(serial.send, connectionId, buffer); | |
132 } | |
133 | |
134 function checkReceivedData(result) { | |
135 var data = 'data'; | |
136 test.assertEq(connectionId, result.connectionId); | |
137 test.assertEq(data.length, result.data.byteLength); | |
138 var resultByteBuffer = new Int8Array(result.data); | |
139 for (var i = 0; i < data.length; i++) { | |
140 test.assertEq(data.charCodeAt(i), resultByteBuffer[i]); | |
141 } | |
142 } | |
143 | |
61 unittestBindings.exportTests([ | 144 unittestBindings.exportTests([ |
62 function testGetDevices() { | 145 function testGetDevices() { |
63 serial.getDevices(test.callbackPass(function(devices) { | 146 serial.getDevices(test.callbackPass(function(devices) { |
64 test.assertEq(3, devices.length); | 147 test.assertEq(3, devices.length); |
65 test.assertEq(4, $Object.keys(devices[0]).length); | 148 test.assertEq(4, $Object.keys(devices[0]).length); |
66 test.assertEq('device', devices[0].path); | 149 test.assertEq('device', devices[0].path); |
67 test.assertEq(1234, devices[0].vendorId); | 150 test.assertEq(1234, devices[0].vendorId); |
68 test.assertEq(5678, devices[0].productId); | 151 test.assertEq(5678, devices[0].productId); |
69 test.assertEq('foo', devices[0].displayName); | 152 test.assertEq('foo', devices[0].displayName); |
70 test.assertEq(1, $Object.keys(devices[1]).length); | 153 test.assertEq(1, $Object.keys(devices[1]).length); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 test.assertFalse(info.paused); | 353 test.assertFalse(info.paused); |
271 disconnect(); | 354 disconnect(); |
272 })); | 355 })); |
273 })); | 356 })); |
274 test.assertTrue(info.paused); | 357 test.assertTrue(info.paused); |
275 })); | 358 })); |
276 })); | 359 })); |
277 }); | 360 }); |
278 }, | 361 }, |
279 | 362 |
363 function testEcho() { | |
364 connect(function() { | |
365 sendData().then(test.callbackPass(function(sendInfo) { | |
366 test.assertEq(4, sendInfo.bytesSent); | |
367 test.assertEq(undefined, sendInfo.error); | |
368 })); | |
369 test.listenOnce(serial.onReceive, function(result) { | |
370 checkReceivedData(result); | |
371 disconnect(); | |
372 }); | |
373 }); | |
374 }, | |
375 | |
376 function testSendDuringExistingSend() { | |
377 connect(function() { | |
378 sendData().then(test.callbackPass(function(sendInfo) { | |
379 test.assertEq(4, sendInfo.bytesSent); | |
380 test.assertEq(undefined, sendInfo.error); | |
381 disconnect(); | |
382 })); | |
383 sendData().then(test.callbackPass(function(sendInfo) { | |
384 test.assertEq(0, sendInfo.bytesSent); | |
385 test.assertEq('pending', sendInfo.error); | |
386 })); | |
387 }); | |
388 }, | |
389 | |
390 function testSendAfterSuccessfulSend() { | |
391 connect(function() { | |
392 sendData().then(test.callbackPass(function(sendInfo) { | |
393 test.assertEq(4, sendInfo.bytesSent); | |
394 test.assertEq(undefined, sendInfo.error); | |
395 // Test that a second send started after the first completes succeeds. | |
396 return sendData(); | |
397 })).then(test.callbackPass(function(sendInfo) { | |
398 test.assertEq(4, sendInfo.bytesSent); | |
399 test.assertEq(undefined, sendInfo.error); | |
400 })); | |
401 // Check that the correct data is echoed twice. | |
402 test.listenOnce(serial.onReceive, function(result) { | |
403 checkReceivedData(result); | |
404 test.listenOnce(serial.onReceive, function(result) { | |
405 checkReceivedData(result); | |
406 disconnect(); | |
407 }); | |
408 }); | |
409 }); | |
410 }, | |
411 | |
412 function testSendPartialSuccessWithError() { | |
413 connect(function() { | |
414 sendData().then(test.callbackPass(function(sendInfo) { | |
415 test.assertEq(2, sendInfo.bytesSent); | |
416 test.assertEq('system_error', sendInfo.error); | |
417 return sendData(); | |
418 })).then(test.callbackPass(function(sendInfo) { | |
419 test.assertEq(4, sendInfo.bytesSent); | |
420 test.assertEq(undefined, sendInfo.error); | |
421 disconnect(); | |
422 })); | |
423 }); | |
424 }, | |
425 | |
426 function testSendTimeout() { | |
427 connect(function() { | |
428 sendData().then(test.callbackPass(function(sendInfo) { | |
429 test.assertEq(0, sendInfo.bytesSent); | |
430 test.assertEq('timeout', sendInfo.error); | |
431 test.assertEq(5, timeoutManager.currentTime); | |
432 disconnect(); | |
433 timeoutManager.disableAutorun(); | |
434 })); | |
435 // Changing the timeout does not effect a send in progress. | |
436 serial.update(connectionId, {sendTimeout: 10}, test.callbackPass( | |
437 timeoutManager.enableAutorun.bind(timeoutManager))); | |
raymes
2014/09/02 04:59:32
What about calling these timeoutManager.pause() an
Sam McNally
2014/09/02 07:41:13
Done. For testReceiveTimeout, leaving it running c
raymes
2014/09/03 01:28:32
Hmm do you know why that is the case? This seems s
Sam McNally
2014/09/03 01:56:13
Removed the need to pause as discussed.
| |
438 }, {sendTimeout: 5}); | |
439 }, | |
440 | |
441 function testDisableSendTimeout() { | |
442 connect(function() { | |
443 sendData().then(test.callbackPass(function(sendInfo) { | |
444 test.assertEq(0, sendInfo.bytesSent); | |
445 test.assertEq('timeout', sendInfo.error); | |
446 test.assertEq(6, timeoutManager.currentTime); | |
447 disconnect(); | |
448 timeoutManager.disableAutorun(); | |
449 })); | |
450 // Disabling the timeout does not effect a send in progress. | |
451 serial.update(connectionId, {sendTimeout: 0}, test.callbackPass( | |
452 timeoutManager.enableAutorun.bind(timeoutManager))); | |
453 }, {sendTimeout: 6}); | |
454 }, | |
455 | |
456 function testPausedReceive() { | |
457 // Wait until the receive hook is installed, then start the test. | |
458 addReceiveHook(function() { | |
459 // Unpause the connection after the connection has queued the received | |
460 // data to ensure the queued data is dispatched when the connection is | |
461 // unpaused. | |
462 serial.setPaused(connectionId, false, test.callbackPass()); | |
463 // Check that setPaused(false) is idempotent. | |
464 serial.setPaused(connectionId, false, test.callbackPass()); | |
465 }).then(function() { | |
466 connect(function() { | |
467 // Check that setPaused(true) is idempotent. | |
468 serial.setPaused(connectionId, true, test.callbackPass()); | |
469 serial.setPaused(connectionId, true, test.callbackPass()); | |
470 }); | |
471 }); | |
472 test.listenOnce(serial.onReceive, function(result) { | |
473 checkReceivedData(result); | |
474 disconnect(); | |
475 }); | |
476 }, | |
477 | |
478 function testPausedReceiveError() { | |
479 addReceiveErrorHook(function() { | |
480 // Unpause the connection after the connection has queued the receive | |
481 // error to ensure the queued error is dispatched when the connection is | |
482 // unpaused. | |
483 serial.setPaused(connectionId, false, test.callbackPass()); | |
484 }).then(test.callbackPass(function() { | |
485 connect(function() { | |
486 serial.setPaused(connectionId, true, test.callbackPass()); | |
487 }); | |
488 })); | |
489 | |
490 test.listenOnce(serial.onReceiveError, function(result) { | |
491 serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) { | |
492 disconnect(); | |
493 test.assertTrue(connectionInfo.paused); | |
494 })); | |
495 test.assertEq(connectionId, result.connectionId); | |
496 test.assertEq('device_lost', result.error); | |
497 }); | |
498 serial.onReceive.addListener(function() { | |
499 test.fail('unexpected onReceive event'); | |
500 }); | |
501 }, | |
502 | |
503 function testReceiveTimeout() { | |
504 connect(function() { | |
505 test.listenOnce(serial.onReceiveError, function(result) { | |
506 test.assertEq(connectionId, result.connectionId); | |
507 test.assertEq('timeout', result.error); | |
508 test.assertEq(20, timeoutManager.currentTime); | |
509 serial.getInfo(connectionId, test.callbackPass( | |
510 function(connectionInfo) { | |
511 test.assertFalse(connectionInfo.paused); | |
512 disconnect(); | |
513 })); | |
514 timeoutManager.disableAutorun(); | |
515 }); | |
516 // Changing the timeout does not take effect until the current timeout | |
517 // expires or a receive completes. | |
518 serial.update(connectionId, {receiveTimeout: 10}, test.callbackPass( | |
519 timeoutManager.enableAutorun.bind(timeoutManager))); | |
520 }, {receiveTimeout: 20}); | |
521 }, | |
522 | |
523 function testDisableReceiveTimeout() { | |
524 connect(function() { | |
525 test.listenOnce(serial.onReceiveError, function(result) { | |
526 test.assertEq(connectionId, result.connectionId); | |
527 test.assertEq('timeout', result.error); | |
528 test.assertEq(30, timeoutManager.currentTime); | |
529 serial.getInfo(connectionId, test.callbackPass( | |
530 function(connectionInfo) { | |
531 disconnect(); | |
532 test.assertFalse(connectionInfo.paused); | |
533 })); | |
534 timeoutManager.disableAutorun(); | |
535 }); | |
536 // Disabling the timeout does not take effect until the current timeout | |
537 // expires or a receive completes. | |
538 serial.update(connectionId, {receiveTimeout: 0}, test.callbackPass( | |
539 timeoutManager.enableAutorun.bind(timeoutManager))); | |
540 }, {receiveTimeout: 30}); | |
541 }, | |
542 | |
543 function testReceiveErrorDisconnected() { | |
544 runReceiveErrorTest('disconnected'); | |
545 }, | |
546 | |
547 function testReceiveErrorTimeout() { | |
548 // Note: this tests that a timeout error from the service pauses the | |
549 // connection, but in production, the service never sends a timeout error - | |
550 // the timeout error is generated internally by the connection and in that | |
551 // case doesn't trigger a pause. | |
raymes
2014/09/02 04:59:32
Should this comment also be on testSendErrorTimeou
Sam McNally
2014/09/02 07:41:13
Removed these tests.
| |
552 runReceiveErrorTest('timeout'); | |
553 }, | |
554 | |
555 function testReceiveErrorDeviceLost() { | |
556 runReceiveErrorTest('device_lost'); | |
557 }, | |
558 | |
559 function testReceiveErrorSystemError() { | |
560 runReceiveErrorTest('system_error'); | |
561 }, | |
562 | |
563 function testSendErrorDisconnected() { | |
564 runSendErrorTest('disconnected'); | |
565 }, | |
566 | |
567 function testSendErrorTimeout() { | |
568 runSendErrorTest('timeout'); | |
569 }, | |
570 | |
571 function testSendErrorSystemError() { | |
572 runSendErrorTest('system_error'); | |
573 }, | |
574 | |
280 function testDisconnectUnknownConnectionId() { | 575 function testDisconnectUnknownConnectionId() { |
281 serial.disconnect(-1, test.callbackFail('Serial connection not found.')); | 576 serial.disconnect(-1, test.callbackFail('Serial connection not found.')); |
282 }, | 577 }, |
283 | 578 |
284 function testGetInfoUnknownConnectionId() { | 579 function testGetInfoUnknownConnectionId() { |
285 serial.getInfo(-1, test.callbackFail('Serial connection not found.')); | 580 serial.getInfo(-1, test.callbackFail('Serial connection not found.')); |
286 }, | 581 }, |
287 | 582 |
288 function testUpdateUnknownConnectionId() { | 583 function testUpdateUnknownConnectionId() { |
289 serial.update(-1, {}, test.callbackFail('Serial connection not found.')); | 584 serial.update(-1, {}, test.callbackFail('Serial connection not found.')); |
(...skipping 12 matching lines...) Expand all Loading... | |
302 function testFlushUnknownConnectionId() { | 597 function testFlushUnknownConnectionId() { |
303 serial.flush(-1, test.callbackFail('Serial connection not found.')); | 598 serial.flush(-1, test.callbackFail('Serial connection not found.')); |
304 }, | 599 }, |
305 | 600 |
306 function testSetPausedUnknownConnectionId() { | 601 function testSetPausedUnknownConnectionId() { |
307 serial.setPaused( | 602 serial.setPaused( |
308 -1, true, test.callbackFail('Serial connection not found.')); | 603 -1, true, test.callbackFail('Serial connection not found.')); |
309 serial.setPaused( | 604 serial.setPaused( |
310 -1, false, test.callbackFail('Serial connection not found.')); | 605 -1, false, test.callbackFail('Serial connection not found.')); |
311 }, | 606 }, |
607 | |
608 function testSendUnknownConnectionId() { | |
609 var buffer = new ArrayBuffer(1); | |
610 serial.send(-1, buffer, test.callbackFail('Serial connection not found.')); | |
611 }, | |
312 ], test.runTests, exports); | 612 ], test.runTests, exports); |
OLD | NEW |