'use strict'; // helper to start and stop the redis process. var config = require('./config'); var fs = require('fs'); var path = require('path'); var spawn = require('cross-spawn'); var tcpPortUsed = require('tcp-port-used'); var bluebird = require('bluebird'); // wait for redis to be listening in // all three modes (ipv4, ipv6, socket). function waitForRedis (available, cb, port) { var time = Date.now(); var running = false; var socket = '/tmp/redis.sock'; if (port) { // We have to distinguishe the redis sockets if we have more than a single redis instance running socket = '/tmp/redis' + port + '.sock'; } port = port || config.PORT; var id = setInterval(function () { if (running) return; running = true; bluebird.join( tcpPortUsed.check(port, '127.0.0.1'), tcpPortUsed.check(port, '::1'), function (ipV4, ipV6) { if (ipV6 === available && ipV4 === available) { if (fs.existsSync(socket) === available || process.platform === 'win32') { clearInterval(id); return cb(); } // The same message applies for can't stop but we ignore that case throw new Error('Port ' + port + ' is already in use. Tests can\'t start.\n'); } if (Date.now() - time > 24000) { throw new Error('Redis could not start on port ' + (port || config.PORT) + '\n'); } running = false; }).catch(function (err) { console.error('\x1b[31m' + err.stack + '\x1b[0m\n'); process.exit(1); }); }, 100); } module.exports = { start: function (done, conf, port) { // spawn redis with our testing configuration. var confFile = conf || path.resolve(__dirname, '../conf/redis.conf'); var redis = 'redis-server'; if (process.platform === 'win32') { confFile = confFile.replace('.conf', '.win32.conf'); redis = 'redis-64\\tools\\redis-server.exe'; } var rp = spawn(redis, [confFile], { stdio: 'inherit' }); waitForRedis(true, function () { done(null, { spawnFailed: function () { return false; // Remove if as soon as it's not necessary anymore }, stop: function (done) { rp.once('exit', function (code) { var error = null; if (code !== null && code !== 0) { error = new Error('Redis shutdown failed with code ' + code); } waitForRedis(false, function () { return done(error); }, port); }); rp.kill('SIGTERM'); } }); }, port); } };