From 33a3f3f6c6ae5e6a6877a8dbf3fd60878af687b3 Mon Sep 17 00:00:00 2001 From: Leibale Eidelman Date: Wed, 30 Mar 2022 08:12:21 -0400 Subject: [PATCH] run tests with redis 7 as well - copied from #2020 (#2062) * run tests on redis 7 as well - copied from #2020 * copy some changes from #2020 * clean BITCOUNT --- .github/workflows/tests.yml | 2 +- .../client/lib/commands/ACL_GETUSER.spec.ts | 36 ++++++++++++------ packages/client/lib/commands/ACL_GETUSER.ts | 30 ++++++++------- packages/client/lib/commands/BITCOUNT.ts | 2 +- .../client/lib/commands/COMMAND_INFO.spec.ts | 6 ++- packages/test-utils/lib/dockers.ts | 4 +- packages/test-utils/lib/index.ts | 38 ++++++++++++------- 7 files changed, 75 insertions(+), 43 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0ce929fbc5..a0c8223d66 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: node-version: ['12', '14', '16'] - redis-version: ['5', '6.0', '6.2'] + redis-version: ['5', '6.0', '6.2', '7.0-rc2'] steps: - uses: actions/checkout@v2.3.4 with: diff --git a/packages/client/lib/commands/ACL_GETUSER.spec.ts b/packages/client/lib/commands/ACL_GETUSER.spec.ts index fcc10768e6..f91f2ff9e5 100644 --- a/packages/client/lib/commands/ACL_GETUSER.spec.ts +++ b/packages/client/lib/commands/ACL_GETUSER.spec.ts @@ -13,20 +13,32 @@ describe('ACL GETUSER', () => { }); testUtils.testWithClient('client.aclGetUser', async client => { + const expectedReply: any = { + passwords: [], + commands: '+@all', + }; + + if (testUtils.isVersionGreaterThan([7])) { + expectedReply.flags = ['on', 'nopass']; + expectedReply.keys = '~*'; + expectedReply.channels = '&*'; + expectedReply.selectors = []; + } else { + expectedReply.keys = ['*']; + expectedReply.selectors = undefined; + + if (testUtils.isVersionGreaterThan([6, 2])) { + expectedReply.flags = ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass']; + expectedReply.channels = ['*']; + } else { + expectedReply.flags = ['on', 'allkeys', 'allcommands', 'nopass']; + expectedReply.channels = undefined; + } + } + assert.deepEqual( await client.aclGetUser('default'), - { - passwords: [], - commands: '+@all', - keys: ['*'], - ...(testUtils.isVersionGreaterThan([6, 2]) ? { - flags: ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'], - channels: ['*'] - } : { - flags: ['on', 'allkeys', 'allcommands', 'nopass'], - channels: undefined - }) - } + expectedReply ); }, GLOBAL.SERVERS.OPEN); }); diff --git a/packages/client/lib/commands/ACL_GETUSER.ts b/packages/client/lib/commands/ACL_GETUSER.ts index cdb9f3aa78..818a945bac 100644 --- a/packages/client/lib/commands/ACL_GETUSER.ts +++ b/packages/client/lib/commands/ACL_GETUSER.ts @@ -5,24 +5,27 @@ export function transformArguments(username: RedisCommandArgument): RedisCommand } type AclGetUserRawReply = [ - _: RedisCommandArgument, - flags: Array, - _: RedisCommandArgument, - passwords: Array, - _: RedisCommandArgument, - commands: RedisCommandArgument, - _: RedisCommandArgument, - keys: Array, - _: RedisCommandArgument, - channels: Array + 'flags', + Array, + 'passwords', + Array, + 'commands', + RedisCommandArgument, + 'keys', + Array | RedisCommandArgument, + 'channels', + Array | RedisCommandArgument, + 'selectors' | undefined, + Array> | undefined ]; interface AclUser { flags: Array; passwords: Array; commands: RedisCommandArgument; - keys: Array; - channels: Array + keys: Array | RedisCommandArgument; + channels: Array | RedisCommandArgument; + selectors?: Array>; } export function transformReply(reply: AclGetUserRawReply): AclUser { @@ -31,6 +34,7 @@ export function transformReply(reply: AclGetUserRawReply): AclUser { passwords: reply[3], commands: reply[5], keys: reply[7], - channels: reply[9] + channels: reply[9], + selectors: reply[11] }; } diff --git a/packages/client/lib/commands/BITCOUNT.ts b/packages/client/lib/commands/BITCOUNT.ts index d937af2b5d..4bbd4f0091 100644 --- a/packages/client/lib/commands/BITCOUNT.ts +++ b/packages/client/lib/commands/BITCOUNT.ts @@ -22,7 +22,7 @@ export function transformArguments( range.end.toString() ); - if (range?.mode) { + if (range.mode) { args.push(range.mode); } } diff --git a/packages/client/lib/commands/COMMAND_INFO.spec.ts b/packages/client/lib/commands/COMMAND_INFO.spec.ts index d648846048..c54a5d0aeb 100644 --- a/packages/client/lib/commands/COMMAND_INFO.spec.ts +++ b/packages/client/lib/commands/COMMAND_INFO.spec.ts @@ -9,7 +9,11 @@ export function assertPingCommand(commandInfo: CommandReply | null | undefined): { name: 'ping', arity: -1, - flags: new Set([CommandFlags.STALE, CommandFlags.FAST]), + flags: new Set( + testUtils.isVersionGreaterThan([7]) ? + [CommandFlags.FAST] : + [CommandFlags.STALE, CommandFlags.FAST] + ), firstKeyIndex: 0, lastKeyIndex: 0, step: 0, diff --git a/packages/test-utils/lib/dockers.ts b/packages/test-utils/lib/dockers.ts index 3dd6dcf3eb..0bf4f034bf 100644 --- a/packages/test-utils/lib/dockers.ts +++ b/packages/test-utils/lib/dockers.ts @@ -38,7 +38,7 @@ const portIterator = (async function*(): AsyncIterableIterator { export interface RedisServerDockerConfig { image: string; - version: Array; + version: string; } export interface RedisServerDocker { @@ -54,7 +54,7 @@ async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfi { stdout, stderr } = await execAsync( 'docker run -d --network host $(' + `docker build ${DOCKER_FODLER_PATH} -q ` + - `--build-arg IMAGE=${image}:${version.join('.')} ` + + `--build-arg IMAGE=${image}:${version} ` + `--build-arg REDIS_ARGUMENTS="--save --port ${port.toString()} ${serverArguments.join(' ')}"` + ')' ); diff --git a/packages/test-utils/lib/index.ts b/packages/test-utils/lib/index.ts index 56847ce84d..9eaed1f8d3 100644 --- a/packages/test-utils/lib/index.ts +++ b/packages/test-utils/lib/index.ts @@ -27,49 +27,61 @@ interface ClusterTestOptions ext numberOfNodes?: number; } +interface Version { + string: string; + numbers: Array; +} + export default class TestUtils { - static #getVersion(argumentName: string, defaultVersion: string): Array { + static #getVersion(argumentName: string, defaultVersion: string): Version { return yargs(hideBin(process.argv)) .option(argumentName, { type: 'string', default: defaultVersion }) .coerce(argumentName, (arg: string) => { - return arg.split('.').map(x => { - const value = Number(x); - if (Number.isNaN(value)) { - throw new TypeError(`${arg} is not a valid redis version`); - } + const indexOfDash = arg.indexOf('-'); + return { + string: arg, + numbers: (indexOfDash === -1 ? arg : arg.substring(0, indexOfDash)).split('.').map(x => { + const value = Number(x); + if (Number.isNaN(value)) { + throw new TypeError(`${arg} is not a valid redis version`); + } - return value; - }); + return value; + }) + }; }) .demandOption(argumentName) .parseSync()[argumentName]; } + readonly #VERSION_NUMBERS: Array; readonly #DOCKER_IMAGE: RedisServerDockerConfig; constructor(config: TestUtilsConfig) { + const { string, numbers } = TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion); + this.#VERSION_NUMBERS = numbers; this.#DOCKER_IMAGE = { image: config.dockerImageName, - version: TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion) + version: string }; } isVersionGreaterThan(minimumVersion: Array | undefined): boolean { if (minimumVersion === undefined) return true; - const lastIndex = Math.min(this.#DOCKER_IMAGE.version.length, minimumVersion.length) - 1; + const lastIndex = Math.min(this.#VERSION_NUMBERS.length, minimumVersion.length) - 1; for (let i = 0; i < lastIndex; i++) { - if (this.#DOCKER_IMAGE.version[i] > minimumVersion[i]) { + if (this.#VERSION_NUMBERS[i] > minimumVersion[i]) { return true; - } else if (minimumVersion[i] > this.#DOCKER_IMAGE.version[i]) { + } else if (minimumVersion[i] > this.#VERSION_NUMBERS[i]) { return false; } } - return this.#DOCKER_IMAGE.version[lastIndex] >= minimumVersion[lastIndex]; + return this.#VERSION_NUMBERS[lastIndex] >= minimumVersion[lastIndex]; } isVersionGreaterThanHook(minimumVersion: Array | undefined): void {