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
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node-version: ['12', '14', '16']
|
node-version: ['12', '14', '16']
|
||||||
redis-version: ['5', '6.0', '6.2']
|
redis-version: ['5', '6.0', '6.2', '7.0-rc2']
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
|
@@ -13,20 +13,32 @@ describe('ACL GETUSER', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.aclGetUser', async client => {
|
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(
|
assert.deepEqual(
|
||||||
await client.aclGetUser('default'),
|
await client.aclGetUser('default'),
|
||||||
{
|
expectedReply
|
||||||
passwords: [],
|
|
||||||
commands: '+@all',
|
|
||||||
keys: ['*'],
|
|
||||||
...(testUtils.isVersionGreaterThan([6, 2]) ? {
|
|
||||||
flags: ['on', 'allkeys', 'allchannels', 'allcommands', 'nopass'],
|
|
||||||
channels: ['*']
|
|
||||||
} : {
|
|
||||||
flags: ['on', 'allkeys', 'allcommands', 'nopass'],
|
|
||||||
channels: undefined
|
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -5,24 +5,27 @@ export function transformArguments(username: RedisCommandArgument): RedisCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AclGetUserRawReply = [
|
type AclGetUserRawReply = [
|
||||||
_: RedisCommandArgument,
|
'flags',
|
||||||
flags: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument>,
|
||||||
_: RedisCommandArgument,
|
'passwords',
|
||||||
passwords: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument>,
|
||||||
_: RedisCommandArgument,
|
'commands',
|
||||||
commands: RedisCommandArgument,
|
RedisCommandArgument,
|
||||||
_: RedisCommandArgument,
|
'keys',
|
||||||
keys: Array<RedisCommandArgument>,
|
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
_: RedisCommandArgument,
|
'channels',
|
||||||
channels: Array<RedisCommandArgument>
|
Array<RedisCommandArgument> | RedisCommandArgument,
|
||||||
|
'selectors' | undefined,
|
||||||
|
Array<Array<string>> | undefined
|
||||||
];
|
];
|
||||||
|
|
||||||
interface AclUser {
|
interface AclUser {
|
||||||
flags: Array<RedisCommandArgument>;
|
flags: Array<RedisCommandArgument>;
|
||||||
passwords: Array<RedisCommandArgument>;
|
passwords: Array<RedisCommandArgument>;
|
||||||
commands: RedisCommandArgument;
|
commands: RedisCommandArgument;
|
||||||
keys: Array<RedisCommandArgument>;
|
keys: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||||
channels: Array<RedisCommandArgument>
|
channels: Array<RedisCommandArgument> | RedisCommandArgument;
|
||||||
|
selectors?: Array<Array<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformReply(reply: AclGetUserRawReply): AclUser {
|
export function transformReply(reply: AclGetUserRawReply): AclUser {
|
||||||
@@ -31,6 +34,7 @@ export function transformReply(reply: AclGetUserRawReply): AclUser {
|
|||||||
passwords: reply[3],
|
passwords: reply[3],
|
||||||
commands: reply[5],
|
commands: reply[5],
|
||||||
keys: reply[7],
|
keys: reply[7],
|
||||||
channels: reply[9]
|
channels: reply[9],
|
||||||
|
selectors: reply[11]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ export function transformArguments(
|
|||||||
range.end.toString()
|
range.end.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (range?.mode) {
|
if (range.mode) {
|
||||||
args.push(range.mode);
|
args.push(range.mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,11 @@ export function assertPingCommand(commandInfo: CommandReply | null | undefined):
|
|||||||
{
|
{
|
||||||
name: 'ping',
|
name: 'ping',
|
||||||
arity: -1,
|
arity: -1,
|
||||||
flags: new Set([CommandFlags.STALE, CommandFlags.FAST]),
|
flags: new Set(
|
||||||
|
testUtils.isVersionGreaterThan([7]) ?
|
||||||
|
[CommandFlags.FAST] :
|
||||||
|
[CommandFlags.STALE, CommandFlags.FAST]
|
||||||
|
),
|
||||||
firstKeyIndex: 0,
|
firstKeyIndex: 0,
|
||||||
lastKeyIndex: 0,
|
lastKeyIndex: 0,
|
||||||
step: 0,
|
step: 0,
|
||||||
|
@@ -38,7 +38,7 @@ const portIterator = (async function*(): AsyncIterableIterator<number> {
|
|||||||
|
|
||||||
export interface RedisServerDockerConfig {
|
export interface RedisServerDockerConfig {
|
||||||
image: string;
|
image: string;
|
||||||
version: Array<number>;
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RedisServerDocker {
|
export interface RedisServerDocker {
|
||||||
@@ -54,7 +54,7 @@ async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfi
|
|||||||
{ stdout, stderr } = await execAsync(
|
{ stdout, stderr } = await execAsync(
|
||||||
'docker run -d --network host $(' +
|
'docker run -d --network host $(' +
|
||||||
`docker build ${DOCKER_FODLER_PATH} -q ` +
|
`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(' ')}"` +
|
`--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;
|
numberOfNodes?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Version {
|
||||||
|
string: string;
|
||||||
|
numbers: Array<number>;
|
||||||
|
}
|
||||||
|
|
||||||
export default class TestUtils {
|
export default class TestUtils {
|
||||||
static #getVersion(argumentName: string, defaultVersion: string): Array<number> {
|
static #getVersion(argumentName: string, defaultVersion: string): Version {
|
||||||
return yargs(hideBin(process.argv))
|
return yargs(hideBin(process.argv))
|
||||||
.option(argumentName, {
|
.option(argumentName, {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: defaultVersion
|
default: defaultVersion
|
||||||
})
|
})
|
||||||
.coerce(argumentName, (arg: string) => {
|
.coerce(argumentName, (arg: string) => {
|
||||||
return arg.split('.').map(x => {
|
const indexOfDash = arg.indexOf('-');
|
||||||
const value = Number(x);
|
return {
|
||||||
if (Number.isNaN(value)) {
|
string: arg,
|
||||||
throw new TypeError(`${arg} is not a valid redis version`);
|
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)
|
.demandOption(argumentName)
|
||||||
.parseSync()[argumentName];
|
.parseSync()[argumentName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly #VERSION_NUMBERS: Array<number>;
|
||||||
readonly #DOCKER_IMAGE: RedisServerDockerConfig;
|
readonly #DOCKER_IMAGE: RedisServerDockerConfig;
|
||||||
|
|
||||||
constructor(config: TestUtilsConfig) {
|
constructor(config: TestUtilsConfig) {
|
||||||
|
const { string, numbers } = TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion);
|
||||||
|
this.#VERSION_NUMBERS = numbers;
|
||||||
this.#DOCKER_IMAGE = {
|
this.#DOCKER_IMAGE = {
|
||||||
image: config.dockerImageName,
|
image: config.dockerImageName,
|
||||||
version: TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion)
|
version: string
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
isVersionGreaterThan(minimumVersion: Array<number> | undefined): boolean {
|
isVersionGreaterThan(minimumVersion: Array<number> | undefined): boolean {
|
||||||
if (minimumVersion === undefined) return true;
|
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++) {
|
for (let i = 0; i < lastIndex; i++) {
|
||||||
if (this.#DOCKER_IMAGE.version[i] > minimumVersion[i]) {
|
if (this.#VERSION_NUMBERS[i] > minimumVersion[i]) {
|
||||||
return true;
|
return true;
|
||||||
} else if (minimumVersion[i] > this.#DOCKER_IMAGE.version[i]) {
|
} else if (minimumVersion[i] > this.#VERSION_NUMBERS[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.#DOCKER_IMAGE.version[lastIndex] >= minimumVersion[lastIndex];
|
return this.#VERSION_NUMBERS[lastIndex] >= minimumVersion[lastIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
isVersionGreaterThanHook(minimumVersion: Array<number> | undefined): void {
|
isVersionGreaterThanHook(minimumVersion: Array<number> | undefined): void {
|
||||||
|
Reference in New Issue
Block a user