diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c6e9023b1b..38cb8804a4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,7 +45,7 @@ jobs: version: "8.2" - tag: "8.4.0" version: "8.4" - - tag: "8.8-rc1" + - tag: "custom-26235535976-debian" version: "8.8" steps: - uses: actions/checkout@v4 diff --git a/packages/bloom/lib/test-utils.ts b/packages/bloom/lib/test-utils.ts index a2a88afcc3..08d6a7602c 100644 --- a/packages/bloom/lib/test-utils.ts +++ b/packages/bloom/lib/test-utils.ts @@ -5,7 +5,7 @@ export default TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); export const GLOBAL = { diff --git a/packages/client/lib/commands/INCREX.spec.ts b/packages/client/lib/commands/INCREX.spec.ts new file mode 100644 index 0000000000..510eff9787 --- /dev/null +++ b/packages/client/lib/commands/INCREX.spec.ts @@ -0,0 +1,270 @@ +import { strict as assert } from 'node:assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import INCREX from './INCREX'; +import { parseArgs } from './generic-transformers'; +import { RESP_TYPES } from '../RESP/decoder'; + +describe('INCREX', () => { + describe('transformArguments', () => { + it('no options', () => { + assert.deepEqual( + parseArgs(INCREX, 'key'), + ['INCREX', 'key'] + ); + }); + + it('BYINT positive', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { by: 5 }), + ['INCREX', 'key', 'BYINT', '5'] + ); + }); + + it('BYINT negative', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { by: -3 }), + ['INCREX', 'key', 'BYINT', '-3'] + ); + }); + + it('BYINT accepts string for values past MAX_SAFE_INTEGER', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { by: '9223372036854775000' }), + ['INCREX', 'key', 'BYINT', '9223372036854775000'] + ); + }); + + it('lowerBound and upperBound accept strings', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { + lowerBound: '-9223372036854775000', + upperBound: '9223372036854775000' + }), + ['INCREX', 'key', 'LBOUND', '-9223372036854775000', 'UBOUND', '9223372036854775000'] + ); + }); + + it('lowerBound', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { lowerBound: -10 }), + ['INCREX', 'key', 'LBOUND', '-10'] + ); + }); + + it('upperBound', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { upperBound: 100 }), + ['INCREX', 'key', 'UBOUND', '100'] + ); + }); + + it('lowerBound and upperBound', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { lowerBound: 0, upperBound: 100 }), + ['INCREX', 'key', 'LBOUND', '0', 'UBOUND', '100'] + ); + }); + + it('saturate true', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { saturate: true }), + ['INCREX', 'key', 'SATURATE'] + ); + }); + + it('saturate false omits flag', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { saturate: false }), + ['INCREX', 'key'] + ); + }); + + it('expiration EX', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'EX', value: 60 } }), + ['INCREX', 'key', 'EX', '60'] + ); + }); + + it('expiration PX', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'PX', value: 60000 } }), + ['INCREX', 'key', 'PX', '60000'] + ); + }); + + it('expiration EXAT', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'EXAT', value: 1700000000 } }), + ['INCREX', 'key', 'EXAT', '1700000000'] + ); + }); + + it('expiration PXAT', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'PXAT', value: 1700000000000 } }), + ['INCREX', 'key', 'PXAT', '1700000000000'] + ); + }); + + it('expiration PERSIST', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'PERSIST' } }), + ['INCREX', 'key', 'PERSIST'] + ); + }); + + it('expiration EX with ENX', () => { + assert.deepEqual( + parseArgs(INCREX, 'key', { expiration: { type: 'EX', value: 60, ENX: true } }), + ['INCREX', 'key', 'EX', '60', 'ENX'] + ); + }); + + it('all options together (rate-limiter pattern)', () => { + assert.deepEqual( + parseArgs(INCREX, 'ratelimit:user', { + by: 1, + upperBound: 100, + expiration: { type: 'EX', value: 60, ENX: true } + }), + ['INCREX', 'ratelimit:user', 'BYINT', '1', 'UBOUND', '100', 'EX', '60', 'ENX'] + ); + }); + }); + + testUtils.testAll('increx default increments by 1', async client => { + assert.deepEqual( + await client.increx('key'), + [1, 1] + ); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx BYINT positive', async client => { + await client.set('key', '100'); + assert.deepEqual( + await client.increx('key', { by: 5 }), + [105, 5] + ); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx BYINT negative', async client => { + await client.set('key', '100'); + assert.deepEqual( + await client.increx('key', { by: -10 }), + [90, -10] + ); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx SATURATE saturates at upper bound', async client => { + await client.set('key', '99'); + assert.deepEqual( + await client.increx('key', { + by: 5, + upperBound: 100, + saturate: true + }), + [100, 1] + ); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx default (no saturate) leaves value unchanged when out of bounds', async client => { + await client.set('key', '99'); + assert.deepEqual( + await client.increx('key', { + by: 5, + upperBound: 100 + }), + [99, 0] + ); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx EX sets TTL', async client => { + await client.increx('key', { + by: 1, + expiration: { type: 'EX', value: 100 } + }); + const ttl = await client.ttl('key'); + assert.ok(ttl > 0 && ttl <= 100); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx ENX does not overwrite existing TTL', async client => { + await client.set('key', '10', { expiration: { type: 'EX', value: 500 } }); + await client.increx('key', { + by: 1, + expiration: { type: 'EX', value: 10, ENX: true } + }); + const ttl = await client.ttl('key'); + assert.ok(ttl > 10, `expected TTL to remain near 500, got ${ttl}`); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('increx PERSIST removes TTL', async client => { + await client.set('key', '5', { expiration: { type: 'EX', value: 1000 } }); + await client.increx('key', { + by: 1, + expiration: { type: 'PERSIST' } + }); + assert.equal(await client.ttl('key'), -1); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + // The reply is always `[NumberReply, NumberReply]`. `NUMBER:String` opts the + // user into precision-safe string output via the decoder itself. + describe('type mappings', () => { + for (const resp of [2, 3] as const) { + testUtils.testWithClient(`RESP${resp} default returns JS numbers`, async client => { + await client.sendCommand(['DEL', 'k']); + await client.sendCommand(['SET', 'k', '100']); + const reply = await client.increx('k', { by: 5 }); + assert.equal(typeof reply[0], 'number'); + assert.equal(typeof reply[1], 'number'); + assert.deepEqual(reply, [105, 5]); + }, { + ...GLOBAL.SERVERS.OPEN, + minimumDockerVersion: [8, 8], + clientOptions: { RESP: resp } + }); + + testUtils.testWithClient(`RESP${resp} NUMBER:String returns precision-safe strings`, async client => { + const seed = '9223372036854775000'; + await client.sendCommand(['DEL', 'k']); + await client.sendCommand(['SET', 'k', seed]); + + const reply = await client + .withTypeMapping({ [RESP_TYPES.NUMBER]: String }) + .increx('k', { by: '100' }); + + assert.equal(typeof reply[0], 'string'); + assert.equal(reply[0], '9223372036854775100'); + assert.equal(reply[1], '100'); + }, { + ...GLOBAL.SERVERS.OPEN, + minimumDockerVersion: [8, 8], + clientOptions: { RESP: resp } + }); + } + }); +}); diff --git a/packages/client/lib/commands/INCREX.ts b/packages/client/lib/commands/INCREX.ts new file mode 100644 index 0000000000..7444b41076 --- /dev/null +++ b/packages/client/lib/commands/INCREX.ts @@ -0,0 +1,63 @@ +import { CommandParser } from '../client/parser'; +import { RedisArgument, TuplesReply, NumberReply, Command } from '../RESP/types'; +import { transformStringDoubleArgument } from './generic-transformers'; + +export interface IncrExOptions { + /** + * Optional explicit integer increment (default: 1). Pass as `string` to + * preserve precision past `Number.MAX_SAFE_INTEGER` (Redis integers are + * 64-bit), e.g. `{ by: '9223372036854775000' }`. + */ + by?: RedisArgument | number; + + lowerBound?: RedisArgument | number; + upperBound?: RedisArgument | number; + + /** + * Out-of-bounds policy. + * - `true` — clamp the result to `lowerBound`/`upperBound` (or to type limits if no explicit bound). + * - `false` or omitted (default) — the operation is rejected silently: the reply is + * `[currentValue, 0]` and the key's value and TTL are left unchanged. An + * `actualIncrement` of `0` always indicates a rejected out-of-bounds operation. + */ + saturate?: boolean; + + expiration?: + | { type: 'EX' | 'PX' | 'EXAT' | 'PXAT'; value: number; ENX?: boolean } + | { type: 'PERSIST' }; +} + +export default { + parseCommand(parser: CommandParser, key: RedisArgument, options?: IncrExOptions) { + parser.push('INCREX'); + parser.pushKey(key); + + if (options?.by !== undefined) { + parser.push('BYINT', transformStringDoubleArgument(options.by)); + } + + if (options?.lowerBound !== undefined) { + parser.push('LBOUND', transformStringDoubleArgument(options.lowerBound)); + } + + if (options?.upperBound !== undefined) { + parser.push('UBOUND', transformStringDoubleArgument(options.upperBound)); + } + + if (options?.saturate) { + parser.push('SATURATE'); + } + + if (options?.expiration) { + if (options.expiration.type === 'PERSIST') { + parser.push('PERSIST'); + } else { + parser.push(options.expiration.type, options.expiration.value.toString()); + if (options.expiration.ENX) { + parser.push('ENX'); + } + } + } + }, + transformReply: undefined as unknown as () => TuplesReply<[NumberReply, NumberReply]> +} as const satisfies Command; diff --git a/packages/client/lib/commands/INCREXBYFLOAT.spec.ts b/packages/client/lib/commands/INCREXBYFLOAT.spec.ts new file mode 100644 index 0000000000..3c48d33073 --- /dev/null +++ b/packages/client/lib/commands/INCREXBYFLOAT.spec.ts @@ -0,0 +1,97 @@ +import { strict as assert } from 'node:assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import INCREXBYFLOAT from './INCREXBYFLOAT'; +import { parseArgs } from './generic-transformers'; + +describe('INCREXBYFLOAT', () => { + describe('transformArguments', () => { + it('basic', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', 0.25), + ['INCREX', 'key', 'BYFLOAT', '0.25'] + ); + }); + + it('negative', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', -0.5), + ['INCREX', 'key', 'BYFLOAT', '-0.5'] + ); + }); + + it('accepts string for precision-safe big values', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', '1.234567890123456789'), + ['INCREX', 'key', 'BYFLOAT', '1.234567890123456789'] + ); + }); + + it('with bounds', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', 1.5, { lowerBound: 0, upperBound: 100 }), + ['INCREX', 'key', 'BYFLOAT', '1.5', 'LBOUND', '0', 'UBOUND', '100'] + ); + }); + + it('with SATURATE', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', 5, { upperBound: 2, saturate: true }), + ['INCREX', 'key', 'BYFLOAT', '5', 'UBOUND', '2', 'SATURATE'] + ); + }); + + it('expiration EX with ENX', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', 1.5, { expiration: { type: 'EX', value: 60, ENX: true } }), + ['INCREX', 'key', 'BYFLOAT', '1.5', 'EX', '60', 'ENX'] + ); + }); + + it('expiration PERSIST', () => { + assert.deepEqual( + parseArgs(INCREXBYFLOAT, 'key', 1.5, { expiration: { type: 'PERSIST' } }), + ['INCREX', 'key', 'BYFLOAT', '1.5', 'PERSIST'] + ); + }); + }); + + testUtils.testAll('incrExByFloat basic increment', async client => { + await client.set('key', '1.5'); + const reply = await client.incrExByFloat('key', 0.25); + assert.ok(Math.abs(Number(reply[0]) - 1.75) < 1e-9); + assert.ok(Math.abs(Number(reply[1]) - 0.25) < 1e-9); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('incrExByFloat negative', async client => { + await client.set('key', '1.5'); + const reply = await client.incrExByFloat('key', -0.5); + assert.ok(Math.abs(Number(reply[0]) - 1) < 1e-9); + assert.ok(Math.abs(Number(reply[1]) - -0.5) < 1e-9); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('incrExByFloat SATURATE clamps at upper bound', async client => { + await client.set('key', '1.5'); + const reply = await client.incrExByFloat('key', 5, { upperBound: 2, saturate: true }); + assert.ok(Math.abs(Number(reply[0]) - 2) < 1e-9); + assert.ok(Math.abs(Number(reply[1]) - 0.5) < 1e-9); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); + + testUtils.testAll('incrExByFloat out-of-bounds rejected (no SATURATE) returns 0 as actualIncrement', async client => { + await client.set('key', '1.5'); + const reply = await client.incrExByFloat('key', 5, { upperBound: 2 }); + assert.ok(Math.abs(Number(reply[0]) - 1.5) < 1e-9); + assert.equal(Number(reply[1]), 0); + }, { + client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 8] }, + cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 8] } + }); +}); diff --git a/packages/client/lib/commands/INCREXBYFLOAT.ts b/packages/client/lib/commands/INCREXBYFLOAT.ts new file mode 100644 index 0000000000..70c91b573c --- /dev/null +++ b/packages/client/lib/commands/INCREXBYFLOAT.ts @@ -0,0 +1,61 @@ +import { CommandParser } from '../client/parser'; +import { RedisArgument, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types'; +import { transformStringDoubleArgument } from './generic-transformers'; + +export interface IncrExByFloatOptions { + lowerBound?: RedisArgument | number; + upperBound?: RedisArgument | number; + + /** + * Out-of-bounds policy. + * - `true` — clamp the result to `lowerBound`/`upperBound` (or to type limits if no explicit bound). + * - `false` or omitted (default) — the operation is rejected silently: the reply is + * `[currentValue, 0]` and the key's value and TTL are left unchanged. An + * `actualIncrement` of `0` always indicates a rejected out-of-bounds operation. + */ + saturate?: boolean; + + expiration?: + | { type: 'EX' | 'PX' | 'EXAT' | 'PXAT'; value: number; ENX?: boolean } + | { type: 'PERSIST' }; +} + +export default { + parseCommand( + parser: CommandParser, + key: RedisArgument, + value: RedisArgument | number, + options?: IncrExByFloatOptions + ) { + parser.push('INCREX'); + parser.pushKey(key); + parser.push('BYFLOAT', transformStringDoubleArgument(value)); + + if (options?.lowerBound !== undefined) { + parser.push('LBOUND', transformStringDoubleArgument(options.lowerBound)); + } + + if (options?.upperBound !== undefined) { + parser.push('UBOUND', transformStringDoubleArgument(options.upperBound)); + } + + if (options?.saturate) { + parser.push('SATURATE'); + } + + if (options?.expiration) { + if (options.expiration.type === 'PERSIST') { + parser.push('PERSIST'); + } else { + parser.push(options.expiration.type, options.expiration.value.toString()); + if (options.expiration.ENX) { + parser.push('ENX'); + } + } + } + }, + transformReply: { + 2: undefined as unknown as () => TuplesReply<[BlobStringReply, BlobStringReply]>, + 3: undefined as unknown as () => TuplesReply<[DoubleReply, DoubleReply]> + } +} as const satisfies Command; diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index 5aee0ef7cc..6c7921bc5b 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -190,6 +190,8 @@ import HOTKEYS_STOP from './HOTKEYS_STOP'; import INCR from './INCR'; import INCRBY from './INCRBY'; import INCRBYFLOAT from './INCRBYFLOAT'; +import INCREX from './INCREX'; +import INCREXBYFLOAT from './INCREXBYFLOAT'; import INFO from './INFO'; import KEYS from './KEYS'; import LASTSAVE from './LASTSAVE'; @@ -2746,6 +2748,42 @@ export default { * @see https://redis.io/commands/incrbyfloat/ */ incrByFloat: INCRBYFLOAT, + /** + * Atomic integer increment with optional bounds, overflow policy, and TTL control. + * For float increments use `INCREXBYFLOAT`. + * + * @param key - The key to increment + * @param options - Increment, bounds, overflow, and expiration options + * @see https://redis.io/commands/increx/ + */ + INCREX, + /** + * Atomic integer increment with optional bounds, overflow policy, and TTL control. + * For float increments use `incrExByFloat`. + * + * @param key - The key to increment + * @param options - Increment, bounds, overflow, and expiration options + * @see https://redis.io/commands/increx/ + */ + increx: INCREX, + /** + * Atomic float increment with optional bounds, overflow policy, and TTL control. + * + * @param key - The key to increment + * @param value - The float increment to apply (BYFLOAT on the wire) + * @param options - Bounds, overflow, and expiration options + * @see https://redis.io/commands/increx/ + */ + INCREXBYFLOAT, + /** + * Atomic float increment with optional bounds, overflow policy, and TTL control. + * + * @param key - The key to increment + * @param value - The float increment to apply (BYFLOAT on the wire) + * @param options - Bounds, overflow, and expiration options + * @see https://redis.io/commands/increx/ + */ + incrExByFloat: INCREXBYFLOAT, /** * Constructs the INFO command * diff --git a/packages/client/lib/sentinel/test-util.ts b/packages/client/lib/sentinel/test-util.ts index 5328cf2abc..b20f4e1d54 100644 --- a/packages/client/lib/sentinel/test-util.ts +++ b/packages/client/lib/sentinel/test-util.ts @@ -175,7 +175,7 @@ export class SentinelFramework extends DockerBase { dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); this.#nodeMap = new Map>>>(); this.#sentinelMap = new Map>>>(); diff --git a/packages/client/lib/test-utils.ts b/packages/client/lib/test-utils.ts index c41b95ee43..605632ad6c 100644 --- a/packages/client/lib/test-utils.ts +++ b/packages/client/lib/test-utils.ts @@ -10,7 +10,7 @@ const utils = TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); export default utils; diff --git a/packages/entraid/lib/test-utils.ts b/packages/entraid/lib/test-utils.ts index 240e772c84..56df4410ee 100644 --- a/packages/entraid/lib/test-utils.ts +++ b/packages/entraid/lib/test-utils.ts @@ -7,7 +7,7 @@ export const testUtils = TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); const DEBUG_MODE_ARGS = testUtils.isVersionGreaterThan([7]) ? diff --git a/packages/json/lib/test-utils.ts b/packages/json/lib/test-utils.ts index 43a8c4247c..a58bf8823a 100644 --- a/packages/json/lib/test-utils.ts +++ b/packages/json/lib/test-utils.ts @@ -5,7 +5,7 @@ export default TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); export const GLOBAL = { diff --git a/packages/search/lib/test-utils.ts b/packages/search/lib/test-utils.ts index ef987c61ef..f9603b2c0d 100644 --- a/packages/search/lib/test-utils.ts +++ b/packages/search/lib/test-utils.ts @@ -6,7 +6,7 @@ export default TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); export const GLOBAL = { diff --git a/packages/test-utils/lib/test-utils.ts b/packages/test-utils/lib/test-utils.ts index a82fed2160..e14532ab35 100644 --- a/packages/test-utils/lib/test-utils.ts +++ b/packages/test-utils/lib/test-utils.ts @@ -4,7 +4,7 @@ export const testUtils = TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); diff --git a/packages/time-series/lib/test-utils.ts b/packages/time-series/lib/test-utils.ts index d3e74de20c..beec61a6a7 100644 --- a/packages/time-series/lib/test-utils.ts +++ b/packages/time-series/lib/test-utils.ts @@ -5,7 +5,7 @@ export default TestUtils.createFromConfig({ dockerImageName: 'redislabs/client-libs-test', dockerImageTagArgument: 'redis-tag', dockerImageVersionArgument: 'redis-version', - defaultDockerVersion: { tag: '8.8-rc1', version: '8.8' } + defaultDockerVersion: { tag: 'custom-26235535976-debian', version: '8.8' } }); export const GLOBAL = {