You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-04 15:02:09 +03:00
chore: use standard
This commit is contained in:
@@ -1,347 +1,351 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
var assert = require('assert');
|
||||
var config = require('./lib/config');
|
||||
var helper = require('./helper');
|
||||
var redis = config.redis;
|
||||
var assert = require('assert')
|
||||
var config = require('./lib/config')
|
||||
var helper = require('./helper')
|
||||
var redis = config.redis
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// TODO: Fix redis process spawn on windows
|
||||
return;
|
||||
}
|
||||
|
||||
describe('client authentication', function () {
|
||||
// TODO: Fix redis process spawn on windows
|
||||
if (process.platform !== 'win32') {
|
||||
describe('client authentication', function () {
|
||||
before(function (done) {
|
||||
helper.stopRedis(function () {
|
||||
helper.startRedis('./conf/password.conf', done);
|
||||
});
|
||||
});
|
||||
helper.stopRedis(function () {
|
||||
helper.startRedis('./conf/password.conf', done)
|
||||
})
|
||||
})
|
||||
|
||||
helper.allTests({
|
||||
allConnections: true
|
||||
allConnections: true
|
||||
}, function (ip, args) {
|
||||
describe('using ' + ip, function () {
|
||||
var auth = 'porkchopsandwiches'
|
||||
var client = null
|
||||
|
||||
describe('using ' + ip, function () {
|
||||
var auth = 'porkchopsandwiches';
|
||||
var client = null;
|
||||
beforeEach(function () {
|
||||
client = null
|
||||
})
|
||||
afterEach(function () {
|
||||
// Explicitly ignore still running commands
|
||||
// The ready command could still be running
|
||||
client.end(false)
|
||||
})
|
||||
|
||||
beforeEach(function () {
|
||||
client = null;
|
||||
});
|
||||
afterEach(function () {
|
||||
// Explicitly ignore still running commands
|
||||
// The ready command could still be running
|
||||
client.end(false);
|
||||
});
|
||||
it('allows auth to be provided with \'auth\' method', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it("allows auth to be provided with 'auth' method", function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.auth(auth, function (err, res) {
|
||||
assert.strictEqual(null, err)
|
||||
assert.strictEqual('OK', res.toString())
|
||||
return done(err)
|
||||
})
|
||||
})
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.auth(auth, function (err, res) {
|
||||
assert.strictEqual(null, err);
|
||||
assert.strictEqual('OK', res.toString());
|
||||
return done(err);
|
||||
});
|
||||
});
|
||||
it('support redis 2.4 with retrying auth commands if still loading', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('support redis 2.4 with retrying auth commands if still loading', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
var time = Date.now();
|
||||
client.auth(auth, function (err, res) {
|
||||
assert.strictEqual('retry worked', res);
|
||||
var now = Date.now();
|
||||
// Hint: setTimeout sometimes triggers early and therefore the value can be like one or two ms to early
|
||||
assert(now - time >= 98, 'Time should be above 100 ms (the reconnect time) and is ' + (now - time));
|
||||
assert(now - time < 225, 'Time should be below 255 ms (the reconnect should only take a bit above 100 ms) and is ' + (now - time));
|
||||
done();
|
||||
});
|
||||
var tmp = client.commandQueue.get(0).callback;
|
||||
client.commandQueue.get(0).callback = function (err, res) {
|
||||
client.auth = function (pass, callback) {
|
||||
callback(null, 'retry worked');
|
||||
};
|
||||
tmp(new Error('ERR redis is still LOADING'));
|
||||
};
|
||||
});
|
||||
|
||||
it('emits error when auth is bad without callback', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
|
||||
client.once('error', function (err) {
|
||||
assert.strictEqual(err.command, 'AUTH');
|
||||
assert.ok(/ERR invalid password/.test(err.message));
|
||||
return done();
|
||||
});
|
||||
|
||||
client.auth(auth + 'bad');
|
||||
});
|
||||
|
||||
it('returns an error when auth is bad (empty string) with a callback', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
|
||||
client.auth('', function (err, res) {
|
||||
assert.strictEqual(err.command, 'AUTH');
|
||||
assert.ok(/ERR invalid password/.test(err.message));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
if (ip === 'IPv4') {
|
||||
it('allows auth to be provided as part of redis url and do not fire commands before auth is done', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
var end = helper.callFuncAfter(done, 2);
|
||||
client = redis.createClient('redis://:' + auth + '@' + config.HOST[ip] + ':' + config.PORT);
|
||||
client.on('ready', function () {
|
||||
end();
|
||||
});
|
||||
// The info command may be used while loading but not if not yet authenticated
|
||||
client.info(function (err, res) {
|
||||
assert(!err);
|
||||
end();
|
||||
});
|
||||
});
|
||||
|
||||
it('allows auth and database to be provided as part of redis url query parameter', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT + '?db=2&password=' + auth);
|
||||
assert.strictEqual(client.options.db, '2');
|
||||
assert.strictEqual(client.options.password, auth);
|
||||
assert.strictEqual(client.authPass, auth);
|
||||
client.on('ready', function () {
|
||||
// Set a key so the used database is returned in the info command
|
||||
client.set('foo', 'bar');
|
||||
client.get('foo');
|
||||
assert.strictEqual(client.serverInfo.db2, undefined);
|
||||
// Using the info command should update the serverInfo
|
||||
client.info(function (err, res) {
|
||||
assert(typeof client.serverInfo.db2 === 'object');
|
||||
});
|
||||
client.flushdb(done);
|
||||
});
|
||||
});
|
||||
client = redis.createClient.apply(null, args)
|
||||
var time = Date.now()
|
||||
client.auth(auth, function (err, res) {
|
||||
assert.strictEqual(err, null)
|
||||
assert.strictEqual('retry worked', res)
|
||||
var now = Date.now()
|
||||
// Hint: setTimeout sometimes triggers early and therefore the value can be like one or two ms to early
|
||||
assert(now - time >= 98, 'Time should be above 100 ms (the reconnect time) and is ' + (now - time))
|
||||
assert(now - time < 225, 'Time should be below 255 ms (the reconnect should only take a bit above 100 ms) and is ' + (now - time))
|
||||
done()
|
||||
})
|
||||
var tmp = client.commandQueue.get(0).callback
|
||||
client.commandQueue.get(0).callback = function (err) {
|
||||
assert.strictEqual(err, null)
|
||||
client.auth = function (pass, callback) {
|
||||
callback(null, 'retry worked')
|
||||
}
|
||||
tmp(new Error('ERR redis is still LOADING'))
|
||||
}
|
||||
})
|
||||
|
||||
it('allows auth to be provided as config option for client', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
it('emits error when auth is bad without callback', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
authPass: auth
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', done);
|
||||
});
|
||||
client = redis.createClient.apply(null, args)
|
||||
|
||||
it('allows auth and noReadyCheck to be provided as config option for client', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client.once('error', function (err) {
|
||||
assert.strictEqual(err.command, 'AUTH')
|
||||
assert.ok(/ERR invalid password/.test(err.message))
|
||||
return done()
|
||||
})
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
password: auth,
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', done);
|
||||
});
|
||||
client.auth(auth + 'bad')
|
||||
})
|
||||
|
||||
it('allows auth to be provided post-hoc with auth method', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
it('returns an error when auth is bad (empty string) with a callback', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
var args = config.configureClient(ip);
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.auth(auth);
|
||||
client.on('ready', done);
|
||||
});
|
||||
client = redis.createClient.apply(null, args)
|
||||
|
||||
it('reconnects with appropriate authentication while offline commands are present', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client.auth('', function (err) {
|
||||
assert.strictEqual(err.command, 'AUTH')
|
||||
assert.ok(/ERR invalid password/.test(err.message))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.auth(auth);
|
||||
client.on('ready', function () {
|
||||
if (this.timesConnected < 3) {
|
||||
var interval = setInterval(function () {
|
||||
if (client.commandQueue.length !== 0) {
|
||||
return;
|
||||
}
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
client.stream.destroy();
|
||||
client.set('foo', 'bar');
|
||||
client.get('foo'); // Errors would bubble
|
||||
assert.strictEqual(client.offlineQueue.length, 2);
|
||||
}, 1);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
client.on('reconnecting', function (params) {
|
||||
assert.strictEqual(params.error, null);
|
||||
});
|
||||
});
|
||||
if (ip === 'IPv4') {
|
||||
it('allows auth to be provided as part of redis url and do not fire commands before auth is done', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('should return an error if the password is not correct and a callback has been provided', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
var end = helper.callFuncAfter(done, 2)
|
||||
client = redis.createClient('redis://:' + auth + '@' + config.HOST[ip] + ':' + config.PORT)
|
||||
client.on('ready', function () {
|
||||
end()
|
||||
})
|
||||
// The info command may be used while loading but not if not yet authenticated
|
||||
client.info(function (err) {
|
||||
assert.strictEqual(err, null)
|
||||
end(err)
|
||||
})
|
||||
})
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
var async = true;
|
||||
client.auth(undefined, function (err, res) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password');
|
||||
assert.strictEqual(err.command, 'AUTH');
|
||||
assert.strictEqual(res, undefined);
|
||||
async = false;
|
||||
done();
|
||||
});
|
||||
assert(async);
|
||||
});
|
||||
it('allows auth and database to be provided as part of redis url query parameter', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('should emit an error if the password is not correct and no callback has been provided', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT + '?db=2&password=' + auth)
|
||||
assert.strictEqual(client.options.db, '2')
|
||||
assert.strictEqual(client.options.password, auth)
|
||||
assert.strictEqual(client.authPass, auth)
|
||||
client.on('ready', function () {
|
||||
// Set a key so the used database is returned in the info command
|
||||
client.set('foo', 'bar')
|
||||
client.get('foo')
|
||||
assert.strictEqual(client.serverInfo.db2, undefined)
|
||||
// Using the info command should update the serverInfo
|
||||
client.info(function (err) {
|
||||
assert.strictEqual(err, null)
|
||||
assert(typeof client.serverInfo.db2 === 'object')
|
||||
})
|
||||
client.flushdb(done)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('error', function (err) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password');
|
||||
assert.strictEqual(err.command, 'AUTH');
|
||||
done();
|
||||
});
|
||||
client.auth(234567);
|
||||
});
|
||||
it('allows auth to be provided as config option for client', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('allows auth to be provided post-hoc with auth method again', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
var args = config.configureClient(ip, {
|
||||
authPass: auth
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('ready', done)
|
||||
})
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
authPass: auth
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', function () {
|
||||
client.auth(auth, helper.isString('OK', done));
|
||||
});
|
||||
});
|
||||
it('allows auth and noReadyCheck to be provided as config option for client', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('does not allow any commands to be processed if not authenticated using noReadyCheck true', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
var args = config.configureClient(ip, {
|
||||
password: auth,
|
||||
noReadyCheck: true
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('ready', done)
|
||||
})
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', function () {
|
||||
client.set('foo', 'bar', function (err, res) {
|
||||
assert.equal(err.message, 'NOAUTH Authentication required.');
|
||||
assert.equal(err.code, 'NOAUTH');
|
||||
assert.equal(err.command, 'SET');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
it('allows auth to be provided post-hoc with auth method', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('does not allow auth to be provided post-hoc with auth method if not authenticated before', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('error', function (err) {
|
||||
assert.equal(err.code, 'NOAUTH');
|
||||
assert.equal(err.message, 'Ready check failed: NOAUTH Authentication required.');
|
||||
assert.equal(err.command, 'INFO');
|
||||
done();
|
||||
});
|
||||
});
|
||||
var args = config.configureClient(ip)
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.auth(auth)
|
||||
client.on('ready', done)
|
||||
})
|
||||
|
||||
it('should emit an error if the provided password is faulty', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient({
|
||||
password: 'wrongPassword'
|
||||
});
|
||||
client.once('error', function (err) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('reconnects with appropriate authentication while offline commands are present', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('pubsub working with auth', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.auth(auth)
|
||||
client.on('ready', function () {
|
||||
if (this.timesConnected < 3) {
|
||||
var interval = setInterval(function () {
|
||||
if (client.commandQueue.length !== 0) {
|
||||
return
|
||||
}
|
||||
clearInterval(interval)
|
||||
interval = null
|
||||
client.stream.destroy()
|
||||
client.set('foo', 'bar')
|
||||
client.get('foo') // Errors would bubble
|
||||
assert.strictEqual(client.offlineQueue.length, 2)
|
||||
}, 1)
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
})
|
||||
client.on('reconnecting', function (params) {
|
||||
assert.strictEqual(params.error, null)
|
||||
})
|
||||
})
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
password: auth
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.set('foo', 'bar');
|
||||
client.subscribe('somechannel', 'another channel', function (err, res) {
|
||||
client.once('ready', function () {
|
||||
assert.strictEqual(client.pubSubMode, 1);
|
||||
client.get('foo', function (err, res) {
|
||||
assert(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/.test(err.message));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
client.once('ready', function () {
|
||||
// Coherent behavior with all other offline commands fires commands before emitting but does not wait till they return
|
||||
assert.strictEqual(client.pubSubMode, 2);
|
||||
client.ping(function () { // Make sure all commands were properly processed already
|
||||
client.stream.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should return an error if the password is not correct and a callback has been provided', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
it('individual commands work properly with batch', function (done) {
|
||||
// quit => might return an error instead of "OK" in the exec callback... (if not connected)
|
||||
// auth => might return an error instead of "OK" in the exec callback... (if no password is required / still loading on Redis <= 2.4)
|
||||
// This could be fixed by checking the return value of the callback in the exec callback and
|
||||
// returning the manipulated [error, result] from the callback.
|
||||
// There should be a better solution though
|
||||
client = redis.createClient.apply(null, args)
|
||||
var async = true
|
||||
client.auth(undefined, function (err, res) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password')
|
||||
assert.strictEqual(err.command, 'AUTH')
|
||||
assert.strictEqual(res, undefined)
|
||||
async = false
|
||||
done()
|
||||
})
|
||||
assert(async)
|
||||
})
|
||||
|
||||
var args = config.configureClient('localhost', {
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
assert.strictEqual(client.selectedDb, undefined);
|
||||
var end = helper.callFuncAfter(done, 8);
|
||||
client.on('monitor', function () {
|
||||
end(); // Should be called for each command after monitor
|
||||
});
|
||||
client.batch()
|
||||
.auth(auth)
|
||||
.select(5, function (err, res) {
|
||||
assert.strictEqual(client.selectedDb, 5);
|
||||
assert.strictEqual(res, 'OK');
|
||||
assert.notDeepEqual(client.serverInfo.db5, { avgTtl: 0, expires: 0, keys: 1 });
|
||||
})
|
||||
.monitor()
|
||||
.set('foo', 'bar', helper.isString('OK'))
|
||||
.info('stats', function (err, res) {
|
||||
assert.strictEqual(res.indexOf('# Stats\r\n'), 0);
|
||||
assert.strictEqual(client.serverInfo.sync_full, '0');
|
||||
})
|
||||
.get('foo', helper.isString('bar'))
|
||||
.subscribe(['foo', 'bar', 'foo'], helper.isUnSubscribe(2, ['foo', 'bar', 'foo']))
|
||||
.unsubscribe('foo')
|
||||
.subscribe('/foo', helper.isUnSubscribe(2, '/foo'))
|
||||
.psubscribe('*')
|
||||
.quit(helper.isString('OK'))
|
||||
.exec(function (err, res) {
|
||||
res[4] = res[4].substr(0, 9);
|
||||
assert.deepStrictEqual(
|
||||
res,
|
||||
['OK', 'OK', 'OK', 'OK', '# Stats\r\n', 'bar', [2, ['foo', 'bar', 'foo']], [1, ['foo']], [2, ['/foo']], [3, ['*']], 'OK']
|
||||
);
|
||||
end();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should emit an error if the password is not correct and no callback has been provided', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('error', function (err) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password')
|
||||
assert.strictEqual(err.command, 'AUTH')
|
||||
done()
|
||||
})
|
||||
client.auth(234567)
|
||||
})
|
||||
|
||||
it('allows auth to be provided post-hoc with auth method again', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
authPass: auth
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('ready', function () {
|
||||
client.auth(auth, helper.isString('OK', done))
|
||||
})
|
||||
})
|
||||
|
||||
it('does not allow any commands to be processed if not authenticated using noReadyCheck true', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
noReadyCheck: true
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('ready', function () {
|
||||
client.set('foo', 'bar', function (err) {
|
||||
assert.strictEqual(err.message, 'NOAUTH Authentication required.')
|
||||
assert.strictEqual(err.code, 'NOAUTH')
|
||||
assert.strictEqual(err.command, 'SET')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('does not allow auth to be provided post-hoc with auth method if not authenticated before', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.on('error', function (err) {
|
||||
assert.strictEqual(err.code, 'NOAUTH')
|
||||
assert.strictEqual(err.message, 'Ready check failed: NOAUTH Authentication required.')
|
||||
assert.strictEqual(err.command, 'INFO')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should emit an error if the provided password is faulty', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
client = redis.createClient({
|
||||
password: 'wrongPassword'
|
||||
})
|
||||
client.once('error', function (err) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('pubsub working with auth', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip()
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
password: auth
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
client.set('foo', 'bar')
|
||||
client.subscribe('somechannel', 'another channel', function (err) {
|
||||
assert.strictEqual(err, null)
|
||||
client.once('ready', function () {
|
||||
assert.strictEqual(client.pubSubMode, 1)
|
||||
client.get('foo', function (err) {
|
||||
assert(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/.test(err.message))
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
client.once('ready', function () {
|
||||
// Coherent behavior with all other offline commands fires commands before emitting but does not wait till they return
|
||||
assert.strictEqual(client.pubSubMode, 2)
|
||||
client.ping(function () { // Make sure all commands were properly processed already
|
||||
client.stream.destroy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('individual commands work properly with batch', function (done) {
|
||||
// quit => might return an error instead of "OK" in the exec callback... (if not connected)
|
||||
// auth => might return an error instead of "OK" in the exec callback... (if no password is required / still loading on Redis <= 2.4)
|
||||
// This could be fixed by checking the return value of the callback in the exec callback and
|
||||
// returning the manipulated [error, result] from the callback.
|
||||
// There should be a better solution though
|
||||
|
||||
var args = config.configureClient('localhost', {
|
||||
noReadyCheck: true
|
||||
})
|
||||
client = redis.createClient.apply(null, args)
|
||||
assert.strictEqual(client.selectedDb, undefined)
|
||||
var end = helper.callFuncAfter(done, 8)
|
||||
client.on('monitor', function () {
|
||||
end() // Should be called for each command after monitor
|
||||
})
|
||||
client.batch()
|
||||
.auth(auth)
|
||||
.select(5, function (err, res) {
|
||||
assert.strictEqual(err, null)
|
||||
assert.strictEqual(client.selectedDb, 5)
|
||||
assert.strictEqual(res, 'OK')
|
||||
assert.notDeepEqual(client.serverInfo.db5, { avgTtl: 0, expires: 0, keys: 1 })
|
||||
})
|
||||
.monitor()
|
||||
.set('foo', 'bar', helper.isString('OK'))
|
||||
.info('stats', function (err, res) {
|
||||
assert.strictEqual(err, null)
|
||||
assert.strictEqual(res.indexOf('# Stats\r\n'), 0)
|
||||
assert.strictEqual(client.serverInfo.sync_full, '0')
|
||||
})
|
||||
.get('foo', helper.isString('bar'))
|
||||
.subscribe(['foo', 'bar', 'foo'], helper.isDeepEqual([2, ['foo', 'bar', 'foo']]))
|
||||
.unsubscribe('foo')
|
||||
.subscribe('/foo', helper.isDeepEqual([2, ['/foo']]))
|
||||
.psubscribe('*')
|
||||
.quit(helper.isString('OK'))
|
||||
.exec(function (err, res) {
|
||||
assert.strictEqual(err, null)
|
||||
res[4] = res[4].substr(0, 9)
|
||||
assert.deepStrictEqual(
|
||||
res,
|
||||
['OK', 'OK', 'OK', 'OK', '# Stats\r\n', 'bar', [2, ['foo', 'bar', 'foo']], [1, ['foo']], [2, ['/foo']], [3, ['*']], 'OK']
|
||||
)
|
||||
end()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
after(function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) return done();
|
||||
helper.stopRedis(function () {
|
||||
helper.startRedis('./conf/redis.conf', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (helper.redisProcess().spawnFailed()) return done()
|
||||
helper.stopRedis(function () {
|
||||
helper.startRedis('./conf/redis.conf', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user