From 42dcf802b14ff5b1aeda3c87eba9dd3426107b31 Mon Sep 17 00:00:00 2001 From: leibale Date: Thu, 23 Sep 2021 16:17:00 -0400 Subject: [PATCH] add CLUSTER_SLOTS, add some tests --- lib/client.spec.ts | 29 ++++++++++++ lib/commands/CLUSTER_SLOTS.spec.ts | 76 ++++++++++++++++++++++++++++++ lib/commands/CLUSTER_SLOTS.ts | 41 ++++++++++++++++ lib/commands/index.ts | 3 ++ 4 files changed, 149 insertions(+) create mode 100644 lib/commands/CLUSTER_SLOTS.spec.ts create mode 100644 lib/commands/CLUSTER_SLOTS.ts diff --git a/lib/client.spec.ts b/lib/client.spec.ts index 06f8d2bb10..9f600c7918 100644 --- a/lib/client.spec.ts +++ b/lib/client.spec.ts @@ -5,6 +5,7 @@ import RedisClient from './client'; import { AbortError, ClientClosedError, ConnectionTimeoutError, WatchError } from './errors'; import { defineScript } from './lua-script'; import { spy } from 'sinon'; +import { RedisNetSocketOptions } from './socket'; export const SQUARE_SCRIPT = defineScript({ NUMBER_OF_KEYS: 0, @@ -63,6 +64,34 @@ describe('Client', () => { TypeError ); }); + + it('redis://localhost', () => { + assert.deepEqual( + RedisClient.parseURL('redis://localhost'), + { + socket: { + host: 'localhost', + } + } + ); + }); + + it('createClient with url', async () => { + const client = RedisClient.create({ + url: `redis://localhost:${(TEST_REDIS_SERVERS[TestRedisServers.OPEN].socket as RedisNetSocketOptions)!.port!.toString()}/1` + }); + + await client.connect(); + + try { + assert.equal( + (await client.clientInfo()).db, + 1 + ); + } finally { + await client.disconnect(); + } + }); }); describe('authentication', () => { diff --git a/lib/commands/CLUSTER_SLOTS.spec.ts b/lib/commands/CLUSTER_SLOTS.spec.ts new file mode 100644 index 0000000000..ec6773bcdd --- /dev/null +++ b/lib/commands/CLUSTER_SLOTS.spec.ts @@ -0,0 +1,76 @@ +import { strict as assert } from 'assert'; +import { transformArguments, transformReply } from './CLUSTER_SLOTS'; + +describe('CLUSTER SLOTS', () => { + it('transformArguments', () => { + assert.deepEqual( + transformArguments(), + ['CLUSTER', 'SLOTS'] + ); + }); + + it('transformReply', () => { + assert.deepEqual( + transformReply([ + [ + 0, + 5460, + ['127.0.0.1', 30001, '09dbe9720cda62f7865eabc5fd8857c5d2678366'], + ['127.0.0.1', 30004, '821d8ca00d7ccf931ed3ffc7e3db0599d2271abf'] + ], + [ + 5461, + 10922, + ['127.0.0.1', 30002, 'c9d93d9f2c0c524ff34cc11838c2003d8c29e013'], + ['127.0.0.1', 30005, 'faadb3eb99009de4ab72ad6b6ed87634c7ee410f'] + ], + [ + 10923, + 16383, + ['127.0.0.1', 30003, '044ec91f325b7595e76dbcb18cc688b6a5b434a1'], + ['127.0.0.1', 30006, '58e6e48d41228013e5d9c1c37c5060693925e97e'] + ] + ]), + [{ + from: 0, + to: 5460, + master: { + ip: '127.0.0.1', + port: 30001, + id: '09dbe9720cda62f7865eabc5fd8857c5d2678366' + }, + replicas: [{ + ip: '127.0.0.1', + port: 30004, + id: '821d8ca00d7ccf931ed3ffc7e3db0599d2271abf' + }] + }, { + from: 5461, + to: 10922, + master: { + ip: '127.0.0.1', + port: 30002, + id: 'c9d93d9f2c0c524ff34cc11838c2003d8c29e013' + }, + replicas: [{ + ip: '127.0.0.1', + port: 30005, + id: 'faadb3eb99009de4ab72ad6b6ed87634c7ee410f' + }] + }, { + from: 10923, + to: 16383, + master: { + ip: '127.0.0.1', + port: 30003, + id: '044ec91f325b7595e76dbcb18cc688b6a5b434a1' + }, + replicas: [{ + ip: '127.0.0.1', + port: 30006, + id: '58e6e48d41228013e5d9c1c37c5060693925e97e' + }] + }] + ) + }); +}); diff --git a/lib/commands/CLUSTER_SLOTS.ts b/lib/commands/CLUSTER_SLOTS.ts new file mode 100644 index 0000000000..b4672e731a --- /dev/null +++ b/lib/commands/CLUSTER_SLOTS.ts @@ -0,0 +1,41 @@ +import { TransformArgumentsReply } from '.'; + +export function transformArguments(): TransformArgumentsReply { + return ['CLUSTER', 'SLOTS']; +} + +type ClusterSlotsRawNode = [ip: string, port: number, id: string]; + +type ClusterSlotsRawReply = Array<[from: number, to: number, master: ClusterSlotsRawNode, ...replicas: Array]>; + +type ClusterSlotsNode = { + ip: string; + port: number; + id: string; +}; + +export type ClusterSlotsReply = Array<{ + from: number; + to: number; + master: ClusterSlotsNode; + replicas: Array; +}>; + +export function transformReply(reply: ClusterSlotsRawReply): ClusterSlotsReply { + return reply.map(([from, to, master, ...replicas]) => { + return { + from, + to, + master: transformNode(master), + replicas: replicas.map(transformNode) + }; + }); +} + +function transformNode([ip, port, id]: ClusterSlotsRawNode): ClusterSlotsNode { + return { + ip, + port, + id + }; +} diff --git a/lib/commands/index.ts b/lib/commands/index.ts index 9322063098..89581090e5 100644 --- a/lib/commands/index.ts +++ b/lib/commands/index.ts @@ -34,6 +34,7 @@ import * as CLUSTER_NODES from './CLUSTER_NODES'; import * as CLUSTER_MEET from './CLUSTER_MEET'; import * as CLUSTER_RESET from './CLUSTER_RESET'; import * as CLUSTER_SETSLOT from './CLUSTER_SETSLOT'; +import * as CLUSTER_SLOTS from './CLUSTER_SLOTS'; import * as CONFIG_GET from './CONFIG_GET'; import * as CONFIG_RESETASTAT from './CONFIG_RESETSTAT'; import * as CONFIG_REWRITE from './CONFIG_REWRITE'; @@ -317,6 +318,8 @@ export default { clusterReset: CLUSTER_RESET, CLUSTER_SETSLOT, clusterSetSlot: CLUSTER_SETSLOT, + CLUSTER_SLOTS, + clusterSlots: CLUSTER_SLOTS, CONFIG_GET, configGet: CONFIG_GET, CONFIG_RESETASTAT,