You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-04 15:02:09 +03:00
Standard is not as up to date and still uses a old eslint version. Instead, use the airbnb default with a couple of modifications. All required changes are included.
208 lines
7.0 KiB
JavaScript
208 lines
7.0 KiB
JavaScript
'use strict'
|
|
|
|
const { Buffer } = require('buffer')
|
|
const assert = require('assert')
|
|
const config = require('../lib/config')
|
|
const helper = require('../helper')
|
|
const utils = require('../../lib/utils')
|
|
|
|
const { redis } = config
|
|
|
|
describe('The \'monitor\' method', () => {
|
|
helper.allTests((parser, ip, args) => {
|
|
let client
|
|
|
|
afterEach(() => {
|
|
client.end(true)
|
|
})
|
|
|
|
beforeEach(() => {
|
|
client = redis.createClient.apply(null, args)
|
|
return client.flushdb()
|
|
})
|
|
|
|
it('monitors commands on all redis clients and works in the correct order', (done) => {
|
|
const monitorClient = redis.createClient.apply(null, args)
|
|
const responses = [
|
|
['mget', 'some', 'keys', 'foo', 'bar'],
|
|
['set', 'json', '{"foo":"123","bar":"sdflkdfsjk","another":false}'],
|
|
['eval', 'return redis.call(\'set\', \'sha\', \'test\')', '0'],
|
|
['set', 'sha', 'test'],
|
|
['get', 'baz'],
|
|
['set', 'foo', 'bar" "s are " " good!"'],
|
|
['mget', 'foo', 'baz'],
|
|
['subscribe', 'foo', 'baz']
|
|
]
|
|
const end = helper.callFuncAfter(done, 5)
|
|
|
|
monitorClient.set('foo', 'bar')
|
|
monitorClient.flushdb()
|
|
monitorClient.monitor().then((res) => {
|
|
assert.strictEqual(res, 'OK')
|
|
client.mget('some', 'keys', 'foo', 'bar')
|
|
client.set('json', JSON.stringify({
|
|
foo: '123',
|
|
bar: 'sdflkdfsjk',
|
|
another: false
|
|
}))
|
|
client.eval('return redis.call(\'set\', \'sha\', \'test\')', 0)
|
|
monitorClient.get('baz').then((res) => {
|
|
assert.strictEqual(res, null)
|
|
end()
|
|
})
|
|
monitorClient.set('foo', 'bar" "s are " " good!"').then((res) => {
|
|
assert.strictEqual(res, 'OK')
|
|
end()
|
|
})
|
|
monitorClient.mget('foo', 'baz').then((res) => {
|
|
assert.strictEqual(res[0], 'bar" "s are " " good!"')
|
|
assert.strictEqual(res[1], null)
|
|
end()
|
|
})
|
|
monitorClient.subscribe('foo', 'baz').then(() => end())
|
|
})
|
|
|
|
monitorClient.on('monitor', (time, args, rawOutput) => {
|
|
assert.strictEqual(monitorClient._monitoring, true)
|
|
assert.deepStrictEqual(args, responses.shift())
|
|
assert(utils.monitorRegex.test(rawOutput), rawOutput)
|
|
if (responses.length === 0) {
|
|
monitorClient.quit().then(() => end())
|
|
}
|
|
})
|
|
})
|
|
|
|
it('monitors returns strings in the rawOutput even with returnBuffers activated', function (done) {
|
|
if (process.platform === 'win32') {
|
|
this.skip()
|
|
}
|
|
const monitorClient = redis.createClient({
|
|
returnBuffers: true,
|
|
path: '/tmp/redis.sock'
|
|
})
|
|
|
|
monitorClient.monitor().then((res) => {
|
|
assert.strictEqual(monitorClient._monitoring, true)
|
|
assert.strictEqual(res.inspect(), Buffer.from('OK').inspect())
|
|
monitorClient.mget('hello', Buffer.from('world'))
|
|
})
|
|
|
|
monitorClient.on('monitor', (time, args, rawOutput) => {
|
|
assert.strictEqual(typeof rawOutput, 'string')
|
|
assert(utils.monitorRegex.test(rawOutput), rawOutput)
|
|
assert.deepStrictEqual(args, ['mget', 'hello', 'world'])
|
|
// Quit immediately ends monitoring mode and therefore does not stream back the quit command
|
|
monitorClient.quit().then(() => done())
|
|
})
|
|
})
|
|
|
|
it('monitors reconnects properly and works with the offline queue', (done) => {
|
|
let called = false
|
|
client.monitor().then(helper.isString('OK'))
|
|
client.mget('hello', 'world')
|
|
client.on('monitor', (time, args, rawOutput) => {
|
|
assert.strictEqual(client._monitoring, true)
|
|
assert(utils.monitorRegex.test(rawOutput), rawOutput)
|
|
assert.deepStrictEqual(args, ['mget', 'hello', 'world'])
|
|
if (called) {
|
|
// End after a reconnect
|
|
return done()
|
|
}
|
|
client._stream.destroy()
|
|
client.mget('hello', 'world')
|
|
called = true
|
|
})
|
|
})
|
|
|
|
it('monitors reconnects properly and works with the offline queue in a batch statement', (done) => {
|
|
let called = false
|
|
const multi = client.batch()
|
|
multi.monitor()
|
|
multi.mget('hello', 'world')
|
|
multi.exec().then(helper.isDeepEqual(['OK', [null, null]]))
|
|
client.on('monitor', (time, args, rawOutput) => {
|
|
assert.strictEqual(client._monitoring, true)
|
|
assert(utils.monitorRegex.test(rawOutput), rawOutput)
|
|
assert.deepStrictEqual(args, ['mget', 'hello', 'world'])
|
|
if (called) {
|
|
// End after a reconnect
|
|
return done()
|
|
}
|
|
client._stream.destroy()
|
|
client.mget('hello', 'world')
|
|
called = true
|
|
})
|
|
})
|
|
|
|
it('monitor activates even if the command could not be processed properly after a reconnect', (done) => {
|
|
client.monitor().then(assert, (err) => {
|
|
assert.strictEqual(err.code, 'UNCERTAIN_STATE')
|
|
})
|
|
client.on('error', () => {}) // Ignore error here
|
|
client._stream.destroy()
|
|
const end = helper.callFuncAfter(done, 2)
|
|
client.on('monitor', (time, args, rawOutput) => {
|
|
assert.strictEqual(client._monitoring, true)
|
|
end()
|
|
})
|
|
client.on('reconnecting', () => {
|
|
client.get('foo').then((res) => {
|
|
assert.strictEqual(client._monitoring, true)
|
|
end()
|
|
})
|
|
})
|
|
})
|
|
|
|
it('monitors works in combination with the pub sub mode and the offline queue', (done) => {
|
|
const responses = [
|
|
['subscribe', '/foo', '/bar'],
|
|
['unsubscribe', '/bar'],
|
|
['get', 'foo'],
|
|
['subscribe', '/foo'],
|
|
['subscribe', 'baz'],
|
|
['unsubscribe', 'baz'],
|
|
['publish', '/foo', 'hello world']
|
|
]
|
|
const pub = redis.createClient()
|
|
pub.on('ready', () => {
|
|
client.monitor().then((res) => {
|
|
assert.strictEqual(res, 'OK')
|
|
pub.get('foo').then(helper.isNull())
|
|
})
|
|
client.subscribe('/foo', '/bar')
|
|
client.unsubscribe('/bar')
|
|
setTimeout(() => {
|
|
client._stream.destroy()
|
|
client.once('ready', () => {
|
|
pub.publish('/foo', 'hello world')
|
|
})
|
|
client.set('foo', 'bar')
|
|
.then(assert, helper.isError(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/))
|
|
client.subscribe('baz')
|
|
client.unsubscribe('baz')
|
|
}, 150)
|
|
let called = false
|
|
client.on('monitor', (time, args, rawOutput) => {
|
|
assert.deepStrictEqual(args, responses.shift())
|
|
assert(utils.monitorRegex.test(rawOutput), rawOutput)
|
|
if (responses.length === 0) {
|
|
// The publish is called right after the reconnect and the monitor
|
|
// is called before the message is emitted. Therefore we have to
|
|
// wait till the next tick
|
|
process.nextTick(() => {
|
|
assert(called)
|
|
pub.end(false)
|
|
client.quit().then(() => done())
|
|
})
|
|
}
|
|
})
|
|
client.on('message', (channel, msg) => {
|
|
assert.strictEqual(channel, '/foo')
|
|
assert.strictEqual(msg, 'hello world')
|
|
called = true
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|