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