From d16c002083ba0c37759798b43fa5b0f5c139cfba Mon Sep 17 00:00:00 2001 From: Nick Muerdter Date: Tue, 24 Feb 2015 00:30:48 -0700 Subject: [PATCH] Add a test to try to identify file descriptor leaks across nginx reloads See: https://github.com/18F/api.data.gov/issues/188 --- test/integration/processes.js | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 test/integration/processes.js diff --git a/test/integration/processes.js b/test/integration/processes.js new file mode 100644 index 0000000..dac40e1 --- /dev/null +++ b/test/integration/processes.js @@ -0,0 +1,67 @@ +'use strict'; + +require('../test_helper'); + +var _ = require('lodash'), + apiUmbrellaConfig = require('api-umbrella-config'), + async = require('async'), + execFile = require('child_process').execFile, + Factory = require('factory-lady'), + fs = require('fs'), + ipaddr = require('ipaddr.js'), + mongoose = require('mongoose'), + path = require('path'), + processEnv = require('../../lib/process_env'), + request = require('request'), + Tail = require('tail').Tail; + +var config = apiUmbrellaConfig.load(path.resolve(__dirname, '../config/test.yml')); + +describe('server processes', function() { + describe('nginx', function() { + it('does not leak file descriptors across reloads', function(done) { + this.timeout(30000); + + var configPath = processEnv.supervisordConfigPath(); + var execOpts = { env: processEnv.env() }; + execFile('supervisorctl', ['-c', configPath, 'pid', 'router-nginx'], execOpts, function(error, stdout, stderr) { + if(error) { + return done('Error fetching nginx pid: ' + error.message + '\n\nSTDOUT: ' + stdout + '\n\nSTDERR:' + stderr); + } + + var parentPid = stdout.trim(); + + async.timesSeries(10, function(index, next) { + execFile('supervisorctl', ['-c', configPath, 'kill', 'HUP', 'router-nginx'], execOpts, function(error, stdout, stderr) { + if(error) { + return next('Error reloading nginx: ' + error.message + '\n\nSTDOUT: ' + stdout + '\n\nSTDERR:' + stderr); + } + + setTimeout(function() { + execFile('lsof', ['-R', '-c', 'nginx'], execOpts, function(error, stdout, stderr) { + if(error) { + return next('Error gathering lsof details: ' + error.message + '\n\nSTDOUT: ' + stdout + '\n\nSTDERR:' + stderr); + } + + var lines = _.filter(stdout.split('\n'), function(line) { + var columns = line.split(/\s+/); + return columns[2] == parentPid; + }); + setTimeout(function() { + next(null, lines.length); + }, 500); + }); + }, 500); + }); + }, function(error, descriptorCounts) { + if(error) { + return done(error); + } + + _.uniq(descriptorCounts).length.should.eql(1); + done(); + }); + }); + }); + }); +});