iamqp
Version:
RabbitMQ wrapper for NodeJS with several produce(reply)/consume scenarios
529 lines (442 loc) • 17.1 kB
JavaScript
const iamqp = require('../../../index')
const assert = require('chai').assert
const lodash = require('lodash')
/**
* RemoteProcedureCall testing.
*/
function rpcTest () {
const amqpURL = 'amqp://localhost'
describe('RPC tests', () => {
/**
* One client is sending multiple messages to one server.
* The server changes the message each time.
*/
it('one server, one client', (pDone) => {
let isTestOn = false
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_A')
const rpcClient = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_A')
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClient.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClient ${err.message}`)
})
rpcServer.getEventer().on('call', (pMessage) => {
if (isTestOn) {
assert.strictEqual(lodash.has(pMessage, 'a'), true, 'rpcServer missing key "a"')
assert.strictEqual(lodash.isSafeInteger(lodash.get(pMessage, 'a')), true)
assert.strictEqual((lodash.get(pMessage, 'a') % 5), 0)
pMessage.a += 5
assert.strictEqual(rpcServer.respond(pMessage), true)
}
})
let count = 0
const expected = {
a: 5
}
rpcClient.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
count++
expected.a += 5
assert.strictEqual(pReplay.a, expected.a)
if (count < 5) {
setTimeout(() => {
assert.strictEqual(lodash.isString(rpcClient.callRemote(pReplay)), true)
}, 100)
} else {
assert.strictEqual(pReplay.a, 5 + (count * 5))
assert.strictEqual(rpcServer.closeConnection(), true)
assert.strictEqual(rpcClient.closeConnection(), true)
setTimeout(() => {
pDone()
}, 200)
}
}
})
rpcClient.openConnection()
rpcServer.openConnection()
setTimeout(() => {
isTestOn = true
assert.strictEqual(lodash.isString(rpcClient.callRemote({ a: 5 })), true)
}, 200)
}).timeout(1200)
/**
* Three clients are calling the same server in succession.
* The server keeps its own data, increments and replies.
*/
it('three clients one server', (pDone) => {
let isTestOn = false
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_B')
const rpcClientA = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_B')
const rpcClientB = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_B')
const rpcClientC = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_B')
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClientA.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientA ${err.message}`)
})
rpcClientB.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientB ${err.message}`)
})
rpcClientC.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientC ${err.message}`)
})
let serverData = 5
rpcServer.getEventer().on('call', (pMessage) => {
if (isTestOn) {
assert.strictEqual(lodash.isSafeInteger(pMessage), true)
serverData += pMessage
assert.strictEqual(rpcServer.respond(serverData), true)
}
})
rpcClientA.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay, 10)
}
})
rpcClientB.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay, 16)
}
})
rpcClientC.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay, 23)
}
})
rpcServer.openConnection()
rpcClientA.openConnection()
rpcClientB.openConnection()
rpcClientC.openConnection()
setTimeout(() => {
isTestOn = true
assert.strictEqual(lodash.isString(rpcClientA.callRemote(5)), true)
}, 200)
setTimeout(() => {
assert.strictEqual(lodash.isString(rpcClientB.callRemote(6)), true)
}, 400)
setTimeout(() => {
assert.strictEqual(lodash.isString(rpcClientC.callRemote(7)), true)
}, 600)
setTimeout(() => {
assert.strictEqual(serverData, 23)
assert.strictEqual(rpcServer.closeConnection(), true)
assert.strictEqual(rpcClientA.closeConnection(), true)
assert.strictEqual(rpcClientB.closeConnection(), true)
assert.strictEqual(rpcClientC.closeConnection(), true)
setTimeout(() => {
pDone()
}, 200)
}, 800)
}).timeout(1100)
/**
* Three clients are calling the same server.
*/
it('testing types - number, string, boolean, array', (pDone) => {
let isTestOn = false
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_C')
const rpcClient = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_C')
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClient.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClient ${err.message}`)
})
let lodashCheckFunction = null
rpcServer.getEventer().on('call', (pMessage) => {
if (isTestOn) {
assert.strictEqual(lodashCheckFunction(pMessage), true)
assert.strictEqual(rpcServer.respond(pMessage), true)
}
})
rpcClient.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(lodashCheckFunction(pReplay), true)
}
})
rpcServer.openConnection()
rpcClient.openConnection()
setTimeout(() => {
isTestOn = true
lodashCheckFunction = lodash.isNumber
assert.strictEqual(lodash.isString(rpcClient.callRemote(Math.random())), true)
}, 200)
setTimeout(() => {
lodashCheckFunction = lodash.isString
assert.strictEqual(lodash.isString(rpcClient.callRemote('test-string')), true)
}, 400)
setTimeout(() => {
lodashCheckFunction = lodash.isBoolean
assert.strictEqual(lodash.isString(rpcClient.callRemote(true)), true)
}, 600)
setTimeout(() => {
lodashCheckFunction = lodash.isArray
assert.strictEqual(lodash.isString(rpcClient.callRemote([
Math.random(),
'test-string'
])), true)
}, 800)
setTimeout(() => {
assert.strictEqual(rpcServer.closeConnection(), true)
assert.strictEqual(rpcClient.closeConnection(), true)
setTimeout(() => {
pDone()
}, 200)
}, 1000)
}).timeout(1300)
/**
* Multiple clients are calling the same server at the same time (with one call each).
* The server is tested as to respond to the correct client.
*/
it('multiple clients are sending one call to a single server', (pDone) => {
let isTestOn = false
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_D')
const rpcClientA = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_D')
const rpcClientB = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_D')
const rpcClientC = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_D')
const rpcClientD = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_D')
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClientA.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientA ${err.message}`)
})
rpcClientB.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientB ${err.message}`)
})
rpcClientC.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientC ${err.message}`)
})
rpcClientD.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientD ${err.message}`)
})
let serverCalls = 0
const serverCounts = []
rpcServer.getEventer().on('call', (pMessage, pCorrelationId) => {
if (isTestOn) {
serverCalls++
pMessage.count += 1
setTimeout(() => {
serverCounts.push(pMessage.count)
assert.strictEqual(rpcServer.respond(pMessage, pCorrelationId), true)
}, pMessage.timeout)
}
})
rpcClientA.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay.count, 11)
}
})
rpcClientB.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay.count, 21)
}
})
rpcClientC.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay.count, 31)
}
})
rpcClientD.getEventer().on('reply', (pReplay) => {
if (isTestOn) {
assert.strictEqual(pReplay.count, 41)
}
})
rpcServer.openConnection()
rpcClientA.openConnection()
rpcClientB.openConnection()
rpcClientC.openConnection()
rpcClientD.openConnection()
setTimeout(() => {
isTestOn = true
assert.strictEqual(lodash.isString(rpcClientA.callRemote({
count: 10,
timeout: 500
})), true)
assert.strictEqual(lodash.isString(rpcClientB.callRemote({
count: 20,
timeout: 250
})), true)
assert.strictEqual(lodash.isString(rpcClientC.callRemote({
count: 30,
timeout: 1000
})), true)
assert.strictEqual(lodash.isString(rpcClientD.callRemote({
count: 40,
timeout: 1500
})), true)
}, 200)
setTimeout(() => {
assert.strictEqual(rpcServer.closeConnection(), true)
assert.strictEqual(rpcClientA.closeConnection(), true)
assert.strictEqual(rpcClientB.closeConnection(), true)
assert.strictEqual(rpcClientC.closeConnection(), true)
assert.strictEqual(rpcClientD.closeConnection(), true)
assert.deepEqual(serverCounts, [21, 11, 31, 41])
assert.strictEqual(serverCalls, 4)
setTimeout(() => {
pDone()
}, 200)
}, 2000)
}).timeout(2300)
/**
* Multiple clients are calling the same server at the same time.
* The server is tested as to respond to the correct client.
*/
it('multiple clients are sending multiple calls to a single server', (pDone) => {
let isTestOn = false
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_E')
const rpcClientA = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_E')
const rpcClientB = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_E')
const rpcClientC = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_E')
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClientA.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientA ${err.message}`)
})
rpcClientB.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientB ${err.message}`)
})
rpcClientC.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClientC ${err.message}`)
})
let serverCalls = 0
rpcServer.getEventer().on('call', (pMessage, pCorrelationId) => {
if (isTestOn) {
serverCalls++
pMessage.count += 1
setTimeout(() => {
assert.strictEqual(rpcServer.respond(pMessage.count, pCorrelationId), true)
}, pMessage.timeout)
}
})
const clientsData = {
clientA: {
counts: [10, 20, 30],
correlationIds: {}
},
clientB: {
counts: [40, 50, 60],
correlationIds: {}
},
clientC: {
counts: [70, 80, 90],
correlationIds: {}
}
}
rpcClientA.getEventer().on('reply', (pReplay, pCorrelationId) => {
if (isTestOn) {
clientsData.clientA.correlationIds[pCorrelationId].got = pReplay
}
})
rpcClientB.getEventer().on('reply', (pReplay, pCorrelationId) => {
if (isTestOn) {
clientsData.clientB.correlationIds[pCorrelationId].got = pReplay
}
})
rpcClientC.getEventer().on('reply', (pReplay, pCorrelationId) => {
if (isTestOn) {
clientsData.clientC.correlationIds[pCorrelationId].got = pReplay
}
})
rpcServer.openConnection()
rpcClientA.openConnection()
rpcClientB.openConnection()
rpcClientC.openConnection()
setTimeout(() => {
isTestOn = true
for (let i = 0; i < clientsData.clientA.counts.length; i++) {
const correlationId = rpcClientA.callRemote({
count: clientsData.clientA.counts[i],
timeout: 200
})
assert.strictEqual(lodash.isString(correlationId), true)
clientsData.clientA.correlationIds[correlationId] = {
got: null,
expected: clientsData.clientA.counts[i] + 1
}
}
for (let i = 0; i < clientsData.clientB.counts.length; i++) {
const correlationId = rpcClientB.callRemote({
count: clientsData.clientB.counts[i],
timeout: 200
})
assert.strictEqual(lodash.isString(correlationId), true)
clientsData.clientB.correlationIds[correlationId] = {
got: null,
expected: clientsData.clientB.counts[i] + 1
}
}
for (let i = 0; i < clientsData.clientC.counts.length; i++) {
const correlationId = rpcClientC.callRemote({
count: clientsData.clientC.counts[i],
timeout: 200
})
assert.strictEqual(lodash.isString(correlationId), true)
clientsData.clientC.correlationIds[correlationId] = {
got: null,
expected: clientsData.clientC.counts[i] + 1
}
}
}, 200)
setTimeout(() => {
assert.strictEqual(rpcServer.closeConnection(), true)
assert.strictEqual(rpcClientA.closeConnection(), true)
assert.strictEqual(rpcClientB.closeConnection(), true)
assert.strictEqual(rpcClientC.closeConnection(), true)
assert.strictEqual(serverCalls, 9)
for (const client in clientsData) {
for (const corrId in clientsData[client].correlationIds) {
const got = clientsData[client].correlationIds[corrId].got
const expected = clientsData[client].correlationIds[corrId].expected
assert.strictEqual(got, expected, `${client} ${corrId}: ${got} != ${expected}`)
}
}
setTimeout(() => {
pDone()
}, 200)
}, 2000)
}).timeout(2400)
it('one server, one client test message TTL', (pDone) => {
const rpcServer = new iamqp.RPCServer(amqpURL, 'rpc_test_channel_F', {
queueArguments: {
messageTtl: 1000
}
})
const rpcClient = new iamqp.RPCClient(amqpURL, 'rpc_test_channel_F', {
queueArguments: {
messageTtl: 1000
}
})
rpcServer.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcServer ${err.message}`)
})
rpcClient.getEventer().on('error', (err) => {
assert.strictEqual(err, null, `rpcClient ${err.message}`)
})
let serverCallCount = 0
rpcServer.getEventer().on('call', (pMessage) => {
serverCallCount += 1
})
let clientReplyCount = 0
rpcClient.getEventer().on('reply', (pReplay) => {
clientReplyCount += 1
})
rpcClient.openConnection()
setTimeout(() => {
assert.strictEqual(lodash.isString(rpcClient.callRemote({ a: 5 })), true)
}, 200)
setTimeout(() => {
rpcServer.openConnection()
}, 1300)
setTimeout(() => {
assert.strictEqual(serverCallCount, 0)
assert.strictEqual(clientReplyCount, 0)
pDone()
}, 1500)
}).timeout(1600)
})
}
module.exports.run = rpcTest