1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-01 16:46:54 +03:00
Files
node-redis/packages/client/lib/test-utils.ts
Bobby I. 69d507a572 refactor!: redis 8 compatibility improvements and test infrastructure updates (#2893)
* churn(test): use redislabs/client-libs-test for testing

This  switches our testing infrastructure from redis/redis-stack to
redislabs/client-libs-test Docker image across all packages. This change
also updates the default Docker version from 7.4.0-v1 to 8.0-M04-pre.

* churn(test): verify CONFIG SET / GET compatibility with Redis 8

- Add tests for Redis 8 search configuration settings
- Deprecate Redis Search CONFIG commands in favor of standard CONFIG
- Test read-only config restrictions for Redis 8

* churn(test): handle Redis 8 coordinate precision in GEOPOS

- Update GEOPOS tests to handle increased precision in Redis 8 (17 decimal places vs 14)
- Add precision-aware coordinate comparison helper
- Add comprehensive test suite for coordinate comparison function

* test(search): adapt SUGGET tests for Redis 8 empty results

- Update tests to expect empty array ([]) instead of null for SUGGET variants
- Affects sugGet, sugGetWithPayloads, sugGetWithScores, and sugGetWithScoresWithPayloads

* test(search): support Redis 8 INFO indexes_all field

- Add indexes_all field introduced in Redis 8 to index definition test

* refactor!(search): simplify PROFILE commands to return raw response

- BREAKING CHANGE: FT.PROFILE now returns raw response, letting users implement their own parsing

* test: improve version-specific test coverage

- Add `testWithClientIfVersionWithinRange` method to run tests for specific Redis versions
- Refactor TestUtils to handle version comparisons more accurately
- Update test utilities across Redis modules to run tests against multiple versions, and not against latest only
2025-02-27 10:56:58 +02:00

116 lines
2.9 KiB
TypeScript

import TestUtils from '@redis/test-utils';
import { SinonSpy } from 'sinon';
import { setTimeout } from 'node:timers/promises';
import { CredentialsProvider } from './authx';
import { Command } from './RESP/types';
import { BasicCommandParser } from './client/parser';
const utils = TestUtils.createFromConfig({
dockerImageName: 'redislabs/client-libs-test',
dockerImageVersionArgument: 'redis-version',
defaultDockerVersion: '8.0-M04-pre'
});
export default utils;
const DEBUG_MODE_ARGS = utils.isVersionGreaterThan([7]) ?
['--enable-debug-command', 'yes'] :
[];
const asyncBasicAuthCredentialsProvider: CredentialsProvider =
{
type: 'async-credentials-provider',
credentials: async () => ({ password: 'password' })
} as const;
const streamingCredentialsProvider: CredentialsProvider =
{
type: 'streaming-credentials-provider',
subscribe : (observable) => ( Promise.resolve([
{ password: 'password' },
{
dispose: () => {
console.log('disposing credentials provider subscription');
}
}
])),
onReAuthenticationError: (error) => {
console.error('re-authentication error', error);
}
} as const;
export const GLOBAL = {
SERVERS: {
OPEN: {
serverArguments: [...DEBUG_MODE_ARGS]
},
PASSWORD: {
serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS],
clientOptions: {
password: 'password'
}
},
ASYNC_BASIC_AUTH: {
serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS],
clientOptions: {
credentialsProvider: asyncBasicAuthCredentialsProvider
}
},
STREAMING_AUTH: {
serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS],
clientOptions: {
credentialsProvider: streamingCredentialsProvider
}
}
},
CLUSTERS: {
OPEN: {
serverArguments: [...DEBUG_MODE_ARGS]
},
PASSWORD: {
serverArguments: ['--requirepass', 'password', ...DEBUG_MODE_ARGS],
clusterConfiguration: {
defaults: {
password: 'password'
}
}
},
WITH_REPLICAS: {
serverArguments: [...DEBUG_MODE_ARGS],
numberOfMasters: 2,
numberOfReplicas: 1,
clusterConfiguration: {
useReplicas: true
}
}
}
};
export async function waitTillBeenCalled(spy: SinonSpy): Promise<void> {
const start = process.hrtime.bigint(),
calls = spy.callCount;
do {
if (process.hrtime.bigint() - start > 1_000_000_000) {
throw new Error('Waiting for more than 1 second');
}
await setTimeout(50);
} while (spy.callCount === calls);
}
export const BLOCKING_MIN_VALUE = (
utils.isVersionGreaterThan([7]) ? Number.MIN_VALUE :
utils.isVersionGreaterThan([6]) ? 0.01 :
1
);
export function parseFirstKey(command: Command, ...args: Array<any>) {
const parser = new BasicCommandParser();
command.parseCommand!(parser, ...args);
return parser.firstKey;
}