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

Side by Side Diff: extensions/test/data/serial_unittest.js

Issue 509813002: Implement the client side of Serial I/O on data pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@serial-io
Patch Set: address comments Created 6 years, 3 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 // 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
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
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);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698