1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const assert = require('assert'); 25 26const http = require('http'); 27 28http.createServer(function(req, res) { 29 req.resume(); 30 req.on('end', function() { 31 write(res); 32 }); 33 this.close(); 34}).listen(0, function() { 35 const req = http.request({ 36 port: this.address().port, 37 method: 'PUT' 38 }); 39 write(req); 40 req.on('response', function(res) { 41 res.resume(); 42 }); 43}); 44 45const buf = Buffer.alloc(1024 * 16, 'x'); 46function write(out) { 47 const name = out.constructor.name; 48 let finishEvent = false; 49 let endCb = false; 50 51 // First, write until it gets some backpressure 52 while (out.write(buf, common.mustSucceed())); 53 54 // Now end, and make sure that we don't get the 'finish' event 55 // before the tick where the cb gets called. We give it until 56 // nextTick because this is added as a listener before the endcb 57 // is registered. The order is not what we're testing here, just 58 // that 'finish' isn't emitted until the stream is fully flushed. 59 out.on('finish', function() { 60 finishEvent = true; 61 console.error(`${name} finish event`); 62 process.nextTick(function() { 63 assert(endCb, `${name} got finish event before endcb!`); 64 console.log(`ok - ${name} finishEvent`); 65 }); 66 }); 67 68 out.end(buf, common.mustCall(function() { 69 endCb = true; 70 console.error(`${name} endCb`); 71 process.nextTick(function() { 72 assert(finishEvent, `${name} got endCb event before finishEvent!`); 73 console.log(`ok - ${name} endCb`); 74 }); 75 })); 76} 77