text: '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('win-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) {
      if (process.platform === 'win32') return cb();
  
      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) {
                          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 > 6000) {
                      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) {
          var spawnFailed = false;
          // spawn redis with our testing configuration.
          var confFile = conf || path.resolve(__dirname, '../conf/redis.conf');
          var rp = spawn('redis-server', [confFile], {});
  
          // capture a failure booting redis, and give
          // the user running the test some directions.
          rp.once('exit', function (code) {
              if (code !== 0) spawnFailed = true;
          });
  
          // wait for redis to become available, by
          // checking the port we bind on.
          waitForRedis(true, function () {
              // return an object that can be used in
              // an after() block to shutdown redis.
              return done(null, {
                  spawnFailed: function () {
                      return spawnFailed;
                  },
                  stop: function (done) {
                      if (spawnFailed) return 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);
      }
  };
  