UNPKG

mqrpc

Version:

💫 Easy RPC over RabbitMQ

70 lines (69 loc) • 3.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ava_1 = require("ava"); const uuid = require("uuid/v4"); const amqp = require("amqplib"); const _config_1 = require("./_config"); const _utils_1 = require("./_utils"); const RpcServer_1 = require("../lib/RpcServer"); const RpcClient_1 = require("../lib/RpcClient"); const clientErrors = require("../lib/RpcClient/errors"); const Timer_1 = require("../lib/Timer"); let connection; ava_1.default.before(async () => { connection = await amqp.connect(_config_1.AMQP_URL); }); ava_1.default.after.always(async () => { await connection.close(); }); ava_1.default.beforeEach(async (t) => { const rpcExchangeName = `mqrpc.${uuid()}`; // make sure each call goes to the right server t.context.client = new RpcClient_1.default({ amqpClient: { connection }, rpcClient: { rpcExchangeName, idleTimeout: 50 } }); t.context.server = new RpcServer_1.default({ amqpClient: { connection }, rpcServer: { rpcExchangeName } }); await t.context.server.init(); await t.context.client.init(); t.context.server.registerDebugProcedures(); }); ava_1.default.afterEach(async (t) => { await Promise.all([ t.context.client.term(), t.context.server.term() ]); }); ava_1.default('[integration] an RPC call resolves to the returned value from the procedure', async (t) => { const res = await t.context.client.call('mqrpc.echo', 42); t.is(res, 42); }); ava_1.default('[integration] calling an unknown procedure raises', async (t) => { await t.throws(t.context.client.call('doesnt.exist'), clientErrors.ServerError, 'Server Error - NoSuchOperation: No operation named "doesnt.exist" has been registered'); }); ava_1.default('[integration] works nicely with no arguments and no returns', async (t) => { t.context.server.register('noop', () => { }); t.is(await t.context.client.call('noop'), undefined); }); ava_1.default.serial('[integration] clears call timeouts on resolution and rejection', async (t) => { const resolves = t.context.client.call('mqrpc.echo', 42); const rejects = t.context.client.call('doesnt.exist'); const errorMsg = 'Server Error - NoSuchOperation: No operation named "doesnt.exist" has been registered'; const unhandledListener = err => t.fail(`Uncaught Error: ${err.message}`); process.on('unhandledRejection', unhandledListener); await t.notThrows(resolves); await t.throws(rejects, clientErrors.ServerError, errorMsg); await _utils_1.delay(50); process.removeListener('unhandledRejection', unhandledListener); t.pass(); }); ava_1.default('[integration] a slow call still works with well configured timeouts', async (t) => { t.context.server.register('mqrpc.slow', () => _utils_1.delay(200).then(() => 42)); // works fine locally with smaller numbers, but not over the wire in CI t.context.client.idleTimeout = 150; t.context.client.ackTimeout = 250; t.context.client.callTimeout = 500; t.is(await t.context.client.call('mqrpc.slow'), 42); }); ava_1.default('[integration] a slow call fails with a short callTimeout', async (t) => { t.context.server.register('mqrpc.slow', () => _utils_1.delay(100).then(() => 42)); t.context.client.callTimeout = 50; await t.throws(t.context.client.call('mqrpc.slow'), Timer_1.TimeoutExpired, 'callTimeout expired after 50ms'); await _utils_1.delay(150); // dont close channel yet (server will still reply) });