1// Test for "overlapped" stdio option. This test uses the "overlapped-checker" 2// helper program which basically a specialized echo program. 3// 4// The test has two goals: 5// 6// - Verify that overlapped I/O works on windows. The test program will deadlock 7// if stdin doesn't have the FILE_FLAG_OVERLAPPED flag set on startup (see 8// test/overlapped-checker/main_win.c for more details). 9// - Verify that "overlapped" stdio option works transparently as a pipe (on 10// unix/windows) 11// 12// This is how the test works: 13// 14// - This script assumes only numeric strings are written to the test program 15// stdout. 16// - The test program will be spawned with "overlapped" set on stdin and "pipe" 17// set on stdout/stderr and at startup writes a number to its stdout 18// - When this script receives some data, it will parse the number, add 50 and 19// write to the test program's stdin. 20// - The test program will then echo the number back to us which will repeat the 21// cycle until the number reaches 200, at which point we send the "exit" 22// string, which causes the test program to exit. 23// - Extra assertion: Every time the test program writes a string to its stdout, 24// it will write the number of bytes written to stderr. 25// - If overlapped I/O is not setup correctly, this test is going to hang. 26'use strict'; 27const common = require('../common'); 28const assert = require('assert'); 29const path = require('path'); 30const child_process = require('child_process'); 31 32const exeExtension = process.platform === 'win32' ? '.exe' : ''; 33const exe = 'overlapped-checker' + exeExtension; 34const exePath = path.join(path.dirname(process.execPath), exe); 35 36if (!require('fs').existsSync(exePath)) { 37 common.skip(exe + ' binary is not available'); 38} 39 40const child = child_process.spawn(exePath, [], { 41 stdio: ['overlapped', 'pipe', 'pipe'] 42}); 43 44child.stdin.setEncoding('utf8'); 45child.stdout.setEncoding('utf8'); 46child.stderr.setEncoding('utf8'); 47 48function writeNext(n) { 49 child.stdin.write((n + 50).toString()); 50} 51 52child.stdout.on('data', (s) => { 53 const n = Number(s); 54 if (n >= 200) { 55 child.stdin.write('exit'); 56 return; 57 } 58 writeNext(n); 59}); 60 61let stderr = ''; 62child.stderr.on('data', (s) => { 63 stderr += s; 64}); 65 66child.stderr.on('end', common.mustCall(() => { 67 // This is the sequence of numbers sent to us: 68 // - 0 (1 byte written) 69 // - 50 (2 bytes written) 70 // - 100 (3 bytes written) 71 // - 150 (3 bytes written) 72 // - 200 (3 bytes written) 73 assert.strictEqual(stderr, '12333'); 74})); 75 76child.on('exit', common.mustCall((status) => { 77 // The test program will return the number of writes as status code. 78 assert.strictEqual(status, 0); 79})); 80