You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
* run tests on redis 7 as well - copied from #2020 * copy some changes from #2020 * clean BITCOUNT
This commit is contained in:
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -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:
|
||||
|
@@ -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);
|
||||
});
|
||||
|
@@ -5,24 +5,27 @@ export function transformArguments(username: RedisCommandArgument): RedisCommand
|
||||
}
|
||||
|
||||
type AclGetUserRawReply = [
|
||||
_: RedisCommandArgument,
|
||||
flags: Array<RedisCommandArgument>,
|
||||
_: RedisCommandArgument,
|
||||
passwords: Array<RedisCommandArgument>,
|
||||
_: RedisCommandArgument,
|
||||
commands: RedisCommandArgument,
|
||||
_: RedisCommandArgument,
|
||||
keys: Array<RedisCommandArgument>,
|
||||
_: RedisCommandArgument,
|
||||
channels: Array<RedisCommandArgument>
|
||||
'flags',
|
||||
Array<RedisCommandArgument>,
|
||||
'passwords',
|
||||
Array<RedisCommandArgument>,
|
||||
'commands',
|
||||
RedisCommandArgument,
|
||||
'keys',
|
||||
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||
'channels',
|
||||
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||
'selectors' | undefined,
|
||||
Array<Array<string>> | undefined
|
||||
];
|
||||
|
||||
interface AclUser {
|
||||
flags: Array<RedisCommandArgument>;
|
||||
passwords: Array<RedisCommandArgument>;
|
||||
commands: RedisCommandArgument;
|
||||
keys: Array<RedisCommandArgument>;
|
||||
channels: Array<RedisCommandArgument>
|
||||
keys: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||
channels: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||
selectors?: Array<Array<string>>;
|
||||
}
|
||||
|
||||
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]
|
||||
};
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ export function transformArguments(
|
||||
range.end.toString()
|
||||
);
|
||||
|
||||
if (range?.mode) {
|
||||
if (range.mode) {
|
||||
args.push(range.mode);
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -38,7 +38,7 @@ const portIterator = (async function*(): AsyncIterableIterator<number> {
|
||||
|
||||
export interface RedisServerDockerConfig {
|
||||
image: string;
|
||||
version: Array<number>;
|
||||
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(' ')}"` +
|
||||
')'
|
||||
);
|
||||
|
@@ -27,49 +27,61 @@ interface ClusterTestOptions<M extends RedisModules, S extends RedisScripts> ext
|
||||
numberOfNodes?: number;
|
||||
}
|
||||
|
||||
interface Version {
|
||||
string: string;
|
||||
numbers: Array<number>;
|
||||
}
|
||||
|
||||
export default class TestUtils {
|
||||
static #getVersion(argumentName: string, defaultVersion: string): Array<number> {
|
||||
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<number>;
|
||||
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<number> | 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<number> | undefined): void {
|
||||
|
Reference in New Issue
Block a user