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