• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4
5const assert = require('assert');
6const http = require('http');
7
8const durationBetweenIntervals = [];
9let timeoutTooShort = false;
10const TIMEOUT = common.platformTimeout(200);
11const INTERVAL = Math.floor(TIMEOUT / 8);
12
13runTest(TIMEOUT);
14
15function runTest(timeoutDuration) {
16  let intervalWasInvoked = false;
17  let newTimeoutDuration = 0;
18  const closeCallback = (err) => {
19    assert.ifError(err);
20    if (newTimeoutDuration) {
21      runTest(newTimeoutDuration);
22    }
23  };
24
25  const server = http.createServer((req, res) => {
26    server.close(common.mustCall(closeCallback));
27
28    res.writeHead(200);
29    res.flushHeaders();
30
31    req.setTimeout(timeoutDuration, () => {
32      if (!intervalWasInvoked) {
33        // Interval wasn't invoked, probably because the machine is busy with
34        // other things. Try again with a longer timeout.
35        newTimeoutDuration = timeoutDuration * 2;
36        console.error('The interval was not invoked.');
37        console.error(`Trying w/ timeout of ${newTimeoutDuration}.`);
38        return;
39      }
40
41      if (timeoutTooShort) {
42        intervalWasInvoked = false;
43        timeoutTooShort = false;
44        newTimeoutDuration =
45          Math.max(...durationBetweenIntervals, timeoutDuration) * 2;
46        console.error(`Time between intervals: ${durationBetweenIntervals}`);
47        console.error(`Trying w/ timeout of ${newTimeoutDuration}`);
48        return;
49      }
50
51      assert.fail('Request timeout should not fire');
52    });
53
54    req.resume();
55    req.once('end', () => {
56      res.end();
57    });
58  });
59
60  server.listen(0, common.mustCall(() => {
61    const req = http.request({
62      port: server.address().port,
63      method: 'POST'
64    }, () => {
65      let lastIntervalTimestamp = Date.now();
66      const interval = setInterval(() => {
67        const lastDuration = Date.now() - lastIntervalTimestamp;
68        durationBetweenIntervals.push(lastDuration);
69        lastIntervalTimestamp = Date.now();
70        if (lastDuration > timeoutDuration / 2) {
71          // The interval is supposed to be about 1/8 of the timeout duration.
72          // If it's running so infrequently that it's greater than 1/2 the
73          // timeout duration, then run the test again with a longer timeout.
74          timeoutTooShort = true;
75        }
76        intervalWasInvoked = true;
77        req.write('a');
78      }, INTERVAL);
79      setTimeout(() => {
80        clearInterval(interval);
81        req.end();
82      }, timeoutDuration);
83    });
84    req.write('.');
85  }));
86}
87