You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
fix(sentinel): Migrated to the new testing framework, fixed issues that were discovered during transition
* [CAE-342] Fix a couple of bugs * Fixed issue with nodes masterauth persistency, changed docker container * [CAE-342] Fixed a couple of sentinel issues, enabled most tests * [CAE-342] Added comment * [CAE-342] Migrate majority of tests to testUtils * [CAE-342] Minor refactor * . * [CAE-342] Using cae containers for sentinel * [CAE-342] Improved resiliency of the legacy tests, added TSdoc comment * [CAE-342] Some extra logging, removed unneeded changes * [CAE-342] Moved docker env as optional part of redisserverdockerconfig * [CAE-342] Move password to serverArguments * [CAE-342] Moved ts-node to devDependencies * [CAE-342] Reverted legacy testing framework improvements
This commit is contained in:
203
package-lock.json
generated
203
package-lock.json
generated
@@ -8,6 +8,9 @@
|
|||||||
"workspaces": [
|
"workspaces": [
|
||||||
"./packages/*"
|
"./packages/*"
|
||||||
],
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"ts-node": "^10.9.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@types/mocha": "^10.0.6",
|
"@types/mocha": "^10.0.6",
|
||||||
@@ -664,6 +667,28 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@cspotcode/source-map-support": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/trace-mapping": "0.3.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
|
||||||
|
"version": "0.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||||
|
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/resolve-uri": "^3.0.3",
|
||||||
|
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@esbuild/linux-x64": {
|
"node_modules/@esbuild/linux-x64": {
|
||||||
"version": "0.19.12",
|
"version": "0.19.12",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
@@ -804,7 +829,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/resolve-uri": {
|
"node_modules/@jridgewell/resolve-uri": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
@@ -820,7 +844,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.4.15",
|
"version": "1.4.15",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
@@ -1067,10 +1090,6 @@
|
|||||||
"resolved": "packages/entraid",
|
"resolved": "packages/entraid",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@redis/graph": {
|
|
||||||
"resolved": "packages/graph",
|
|
||||||
"link": true
|
|
||||||
},
|
|
||||||
"node_modules/@redis/json": {
|
"node_modules/@redis/json": {
|
||||||
"resolved": "packages/json",
|
"resolved": "packages/json",
|
||||||
"link": true
|
"link": true
|
||||||
@@ -1164,6 +1183,30 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@tsconfig/node10": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node12": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node14": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@tsconfig/node16": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/body-parser": {
|
"node_modules/@types/body-parser": {
|
||||||
"version": "1.19.5",
|
"version": "1.19.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||||
@@ -1247,7 +1290,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.11.16",
|
"version": "20.11.16",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
@@ -1330,6 +1372,30 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn": {
|
||||||
|
"version": "8.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||||
|
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"acorn": "bin/acorn"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn-walk": {
|
||||||
|
"version": "8.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||||
|
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.11.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "7.1.0",
|
"version": "7.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -1448,6 +1514,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/arg": {
|
||||||
|
"version": "4.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -2315,6 +2387,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/create-require": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -5088,6 +5166,12 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/make-error": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -7576,6 +7660,58 @@
|
|||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-node": {
|
||||||
|
"version": "10.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||||
|
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@cspotcode/source-map-support": "^0.8.0",
|
||||||
|
"@tsconfig/node10": "^1.0.7",
|
||||||
|
"@tsconfig/node12": "^1.0.7",
|
||||||
|
"@tsconfig/node14": "^1.0.0",
|
||||||
|
"@tsconfig/node16": "^1.0.2",
|
||||||
|
"acorn": "^8.4.1",
|
||||||
|
"acorn-walk": "^8.1.1",
|
||||||
|
"arg": "^4.1.0",
|
||||||
|
"create-require": "^1.1.0",
|
||||||
|
"diff": "^4.0.1",
|
||||||
|
"make-error": "^1.1.1",
|
||||||
|
"v8-compile-cache-lib": "^3.0.1",
|
||||||
|
"yn": "3.1.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"ts-node": "dist/bin.js",
|
||||||
|
"ts-node-cwd": "dist/bin-cwd.js",
|
||||||
|
"ts-node-esm": "dist/bin-esm.js",
|
||||||
|
"ts-node-script": "dist/bin-script.js",
|
||||||
|
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||||
|
"ts-script": "dist/bin-script-deprecated.js"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@swc/core": ">=1.2.50",
|
||||||
|
"@swc/wasm": ">=1.2.50",
|
||||||
|
"@types/node": "*",
|
||||||
|
"typescript": ">=2.7"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@swc/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@swc/wasm": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-node/node_modules/diff": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
@@ -7741,7 +7877,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.3.3",
|
"version": "5.3.3",
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
@@ -7780,7 +7915,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unicorn-magic": {
|
"node_modules/unicorn-magic": {
|
||||||
@@ -7956,6 +8090,12 @@
|
|||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/v8-compile-cache-lib": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
@@ -8324,6 +8464,15 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yn": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -8353,7 +8502,7 @@
|
|||||||
},
|
},
|
||||||
"packages/bloom": {
|
"packages/bloom": {
|
||||||
"name": "@redis/bloom",
|
"name": "@redis/bloom",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redis/test-utils": "*"
|
"@redis/test-utils": "*"
|
||||||
@@ -8362,12 +8511,12 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "^5.0.0-next.6"
|
"@redis/client": "^5.0.0-next.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/client": {
|
"packages/client": {
|
||||||
"name": "@redis/client",
|
"name": "@redis/client",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cluster-key-slot": "1.1.2"
|
"cluster-key-slot": "1.1.2"
|
||||||
@@ -8383,7 +8532,7 @@
|
|||||||
},
|
},
|
||||||
"packages/entraid": {
|
"packages/entraid": {
|
||||||
"name": "@redis/entraid",
|
"name": "@redis/entraid",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/identity": "4.7.0",
|
"@azure/identity": "4.7.0",
|
||||||
@@ -8402,7 +8551,7 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "^5.0.0-next.6"
|
"@redis/client": "^5.0.0-next.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/entraid/node_modules/@types/node": {
|
"packages/entraid/node_modules/@types/node": {
|
||||||
@@ -8425,6 +8574,7 @@
|
|||||||
"packages/graph": {
|
"packages/graph": {
|
||||||
"name": "@redis/graph",
|
"name": "@redis/graph",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.6",
|
||||||
|
"extraneous": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redis/test-utils": "*"
|
"@redis/test-utils": "*"
|
||||||
@@ -8438,7 +8588,7 @@
|
|||||||
},
|
},
|
||||||
"packages/json": {
|
"packages/json": {
|
||||||
"name": "@redis/json",
|
"name": "@redis/json",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redis/test-utils": "*"
|
"@redis/test-utils": "*"
|
||||||
@@ -8447,19 +8597,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "^5.0.0-next.6"
|
"@redis/client": "^5.0.0-next.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/redis": {
|
"packages/redis": {
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redis/bloom": "5.0.0-next.6",
|
"@redis/bloom": "5.0.0-next.7",
|
||||||
"@redis/client": "5.0.0-next.6",
|
"@redis/client": "5.0.0-next.7",
|
||||||
"@redis/graph": "5.0.0-next.6",
|
"@redis/json": "5.0.0-next.7",
|
||||||
"@redis/json": "5.0.0-next.6",
|
"@redis/search": "5.0.0-next.7",
|
||||||
"@redis/search": "5.0.0-next.6",
|
"@redis/time-series": "5.0.0-next.7"
|
||||||
"@redis/time-series": "5.0.0-next.6"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
@@ -8467,7 +8616,7 @@
|
|||||||
},
|
},
|
||||||
"packages/search": {
|
"packages/search": {
|
||||||
"name": "@redis/search",
|
"name": "@redis/search",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redis/test-utils": "*"
|
"@redis/test-utils": "*"
|
||||||
@@ -8476,7 +8625,7 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "^5.0.0-next.6"
|
"@redis/client": "^5.0.0-next.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/test-utils": {
|
"packages/test-utils": {
|
||||||
@@ -8545,7 +8694,7 @@
|
|||||||
},
|
},
|
||||||
"packages/time-series": {
|
"packages/time-series": {
|
||||||
"name": "@redis/time-series",
|
"name": "@redis/time-series",
|
||||||
"version": "5.0.0-next.6",
|
"version": "5.0.0-next.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redis/test-utils": "*"
|
"@redis/test-utils": "*"
|
||||||
@@ -8554,7 +8703,7 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@redis/client": "^5.0.0-next.6"
|
"@redis/client": "^5.0.0-next.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
"release-it": "^17.0.3",
|
"release-it": "^17.0.3",
|
||||||
"tsx": "^4.7.0",
|
"tsx": "^4.7.0",
|
||||||
"typedoc": "^0.25.7",
|
"typedoc": "^0.25.7",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3",
|
||||||
|
"ts-node": "^10.9.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -299,6 +299,9 @@ export default class RedisClient<
|
|||||||
#monitorCallback?: MonitorCallback<TYPE_MAPPING>;
|
#monitorCallback?: MonitorCallback<TYPE_MAPPING>;
|
||||||
private _self = this;
|
private _self = this;
|
||||||
private _commandOptions?: CommandOptions<TYPE_MAPPING>;
|
private _commandOptions?: CommandOptions<TYPE_MAPPING>;
|
||||||
|
// flag used to annotate that the client
|
||||||
|
// was in a watch transaction when
|
||||||
|
// a topology change occured
|
||||||
#dirtyWatch?: string;
|
#dirtyWatch?: string;
|
||||||
#epoch: number;
|
#epoch: number;
|
||||||
#watchEpoch?: number;
|
#watchEpoch?: number;
|
||||||
@@ -325,6 +328,20 @@ export default class RedisClient<
|
|||||||
return this._self.#watchEpoch !== undefined;
|
return this._self.#watchEpoch !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the client's WATCH command has been invalidated by a topology change.
|
||||||
|
* When this returns true, any transaction using WATCH will fail with a WatchError.
|
||||||
|
* @returns true if the watched keys have been modified, false otherwise
|
||||||
|
*/
|
||||||
|
get isDirtyWatch(): boolean {
|
||||||
|
return this._self.#dirtyWatch !== undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the client's WATCH command as invalidated due to a topology change.
|
||||||
|
* This will cause any subsequent EXEC in a transaction to fail with a WatchError.
|
||||||
|
* @param msg - The error message explaining why the WATCH is dirty
|
||||||
|
*/
|
||||||
setDirtyWatch(msg: string) {
|
setDirtyWatch(msg: string) {
|
||||||
this._self.#dirtyWatch = msg;
|
this._self.#dirtyWatch = msg;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -345,9 +345,12 @@ export default class RedisSentinel<
|
|||||||
key: K,
|
key: K,
|
||||||
value: V
|
value: V
|
||||||
) {
|
) {
|
||||||
const proxy = Object.create(this._self);
|
const proxy = Object.create(this);
|
||||||
proxy._commandOptions = Object.create(this._self.#commandOptions ?? null);
|
// Create new commandOptions object with the inherited properties
|
||||||
proxy._commandOptions[key] = value;
|
proxy._self.#commandOptions = {
|
||||||
|
...(this._self.#commandOptions || {}),
|
||||||
|
[key]: value
|
||||||
|
};
|
||||||
return proxy as RedisSentinelType<
|
return proxy as RedisSentinelType<
|
||||||
M,
|
M,
|
||||||
F,
|
F,
|
||||||
@@ -682,9 +685,10 @@ class RedisSentinelInternal<
|
|||||||
|
|
||||||
async #connect() {
|
async #connect() {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
this.#trace("starting connect loop");
|
this.#trace("starting connect loop");
|
||||||
|
|
||||||
|
count+=1;
|
||||||
if (this.#destroy) {
|
if (this.#destroy) {
|
||||||
this.#trace("in #connect and want to destroy")
|
this.#trace("in #connect and want to destroy")
|
||||||
return;
|
return;
|
||||||
@@ -1109,7 +1113,7 @@ class RedisSentinelInternal<
|
|||||||
|
|
||||||
this.#trace(`transform: destroying old masters if open`);
|
this.#trace(`transform: destroying old masters if open`);
|
||||||
for (const client of this.#masterClients) {
|
for (const client of this.#masterClients) {
|
||||||
masterWatches.push(client.isWatching);
|
masterWatches.push(client.isWatching || client.isDirtyWatch);
|
||||||
|
|
||||||
if (client.isOpen) {
|
if (client.isOpen) {
|
||||||
client.destroy()
|
client.destroy()
|
||||||
@@ -1460,4 +1464,4 @@ export class RedisSentinelFactory extends EventEmitter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -602,4 +602,4 @@ export class SentinelFramework extends DockerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,9 +2,10 @@ import TestUtils from '@redis/test-utils';
|
|||||||
import { SinonSpy } from 'sinon';
|
import { SinonSpy } from 'sinon';
|
||||||
import { setTimeout } from 'node:timers/promises';
|
import { setTimeout } from 'node:timers/promises';
|
||||||
import { CredentialsProvider } from './authx';
|
import { CredentialsProvider } from './authx';
|
||||||
import { Command } from './RESP/types';
|
import { Command, NumberReply } from './RESP/types';
|
||||||
import { BasicCommandParser } from './client/parser';
|
import { BasicCommandParser, CommandParser } from './client/parser';
|
||||||
|
import { defineScript } from './lua-script';
|
||||||
|
import RedisBloomModules from '@redis/bloom';
|
||||||
const utils = TestUtils.createFromConfig({
|
const utils = TestUtils.createFromConfig({
|
||||||
dockerImageName: 'redislabs/client-libs-test',
|
dockerImageName: 'redislabs/client-libs-test',
|
||||||
dockerImageVersionArgument: 'redis-version',
|
dockerImageVersionArgument: 'redis-version',
|
||||||
@@ -42,6 +43,45 @@ const streamingCredentialsProvider: CredentialsProvider =
|
|||||||
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
const SQUARE_SCRIPT = defineScript({
|
||||||
|
SCRIPT:
|
||||||
|
`local number = redis.call('GET', KEYS[1])
|
||||||
|
return number * number`,
|
||||||
|
NUMBER_OF_KEYS: 1,
|
||||||
|
FIRST_KEY_INDEX: 0,
|
||||||
|
parseCommand(parser: CommandParser, key: string) {
|
||||||
|
parser.pushKey(key);
|
||||||
|
},
|
||||||
|
transformReply: undefined as unknown as () => NumberReply
|
||||||
|
});
|
||||||
|
|
||||||
|
export const MATH_FUNCTION = {
|
||||||
|
name: 'math',
|
||||||
|
engine: 'LUA',
|
||||||
|
code:
|
||||||
|
`#!LUA name=math
|
||||||
|
redis.register_function {
|
||||||
|
function_name = "square",
|
||||||
|
callback = function(keys, args)
|
||||||
|
local number = redis.call('GET', keys[1])
|
||||||
|
return number * number
|
||||||
|
end,
|
||||||
|
flags = { "no-writes" }
|
||||||
|
}`,
|
||||||
|
library: {
|
||||||
|
square: {
|
||||||
|
NAME: 'square',
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
NUMBER_OF_KEYS: 1,
|
||||||
|
FIRST_KEY_INDEX: 0,
|
||||||
|
parseCommand(parser: CommandParser, key: string) {
|
||||||
|
parser.pushKey(key);
|
||||||
|
},
|
||||||
|
transformReply: undefined as unknown as () => NumberReply
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const GLOBAL = {
|
export const GLOBAL = {
|
||||||
SERVERS: {
|
SERVERS: {
|
||||||
OPEN: {
|
OPEN: {
|
||||||
@@ -86,6 +126,43 @@ export const GLOBAL = {
|
|||||||
useReplicas: true
|
useReplicas: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
SENTINEL: {
|
||||||
|
OPEN: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
},
|
||||||
|
PASSWORD: {
|
||||||
|
serverArguments: ['--requirepass', 'test_password', ...DEBUG_MODE_ARGS],
|
||||||
|
},
|
||||||
|
WITH_SCRIPT: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
scripts: {
|
||||||
|
square: SQUARE_SCRIPT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
WITH_FUNCTION: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
functions: {
|
||||||
|
math: MATH_FUNCTION.library,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
WITH_MODULE: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
modules: RedisBloomModules,
|
||||||
|
},
|
||||||
|
WITH_REPLICA_POOL_SIZE_1: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
replicaPoolSize: 1,
|
||||||
|
},
|
||||||
|
WITH_RESERVE_CLIENT_MASTER_POOL_SIZE_2: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
masterPoolSize: 2,
|
||||||
|
reserveClient: true,
|
||||||
|
},
|
||||||
|
WITH_MASTER_POOL_SIZE_2: {
|
||||||
|
serverArguments: [...DEBUG_MODE_ARGS],
|
||||||
|
masterPoolSize: 2,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4,9 +4,11 @@ import { once } from 'node:events';
|
|||||||
import { createClient } from '@redis/client/index';
|
import { createClient } from '@redis/client/index';
|
||||||
import { setTimeout } from 'node:timers/promises';
|
import { setTimeout } from 'node:timers/promises';
|
||||||
// import { ClusterSlotsReply } from '@redis/client/dist/lib/commands/CLUSTER_SLOTS';
|
// import { ClusterSlotsReply } from '@redis/client/dist/lib/commands/CLUSTER_SLOTS';
|
||||||
|
|
||||||
import { execFile as execFileCallback } from 'node:child_process';
|
import { execFile as execFileCallback } from 'node:child_process';
|
||||||
import { promisify } from 'node:util';
|
import { promisify } from 'node:util';
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as os from 'node:os';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
|
||||||
const execAsync = promisify(execFileCallback);
|
const execAsync = promisify(execFileCallback);
|
||||||
|
|
||||||
@@ -38,37 +40,64 @@ const portIterator = (async function* (): AsyncIterableIterator<number> {
|
|||||||
throw new Error('All ports are in use');
|
throw new Error('All ports are in use');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export interface RedisServerDockerConfig {
|
interface RedisServerDockerConfig {
|
||||||
image: string;
|
image: string;
|
||||||
version: string;
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SentinelConfig {
|
||||||
|
mode: "sentinel";
|
||||||
|
mounts: Array<string>;
|
||||||
|
port: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ServerConfig {
|
||||||
|
mode: "server";
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RedisServerDockerOptions = RedisServerDockerConfig & (SentinelConfig | ServerConfig)
|
||||||
|
|
||||||
export interface RedisServerDocker {
|
export interface RedisServerDocker {
|
||||||
port: number;
|
port: number;
|
||||||
dockerId: string;
|
dockerId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function spawnRedisServerDocker({
|
async function spawnRedisServerDocker(
|
||||||
image,
|
options: RedisServerDockerOptions, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
||||||
version
|
let port;
|
||||||
}: RedisServerDockerConfig, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
if (options.mode == "sentinel") {
|
||||||
const port = (await portIterator.next()).value;
|
port = options.port;
|
||||||
|
} else {
|
||||||
|
port = (await portIterator.next()).value;
|
||||||
|
}
|
||||||
|
|
||||||
const portStr = port.toString();
|
const portStr = port.toString();
|
||||||
|
|
||||||
const dockerArgs = [
|
const dockerArgs = [
|
||||||
'run',
|
'run',
|
||||||
'-e', `PORT=${portStr}`,
|
'--init',
|
||||||
'-d',
|
'-e', `PORT=${portStr}`
|
||||||
'--network', 'host',
|
|
||||||
`${image}:${version}`,
|
|
||||||
'--port', portStr
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (serverArguments.length > 0) {
|
if (options.mode == "sentinel") {
|
||||||
dockerArgs.push(...serverArguments);
|
options.mounts.forEach(mount => {
|
||||||
|
dockerArgs.push('-v', mount);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[Docker] Spawning Redis container - Image: ${image}:${version}, Port: ${port}`);
|
dockerArgs.push(
|
||||||
|
'-d',
|
||||||
|
'--network', 'host',
|
||||||
|
`${options.image}:${options.version}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (serverArguments.length > 0) {
|
||||||
|
for (let i = 0; i < serverArguments.length; i++) {
|
||||||
|
dockerArgs.push(serverArguments[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[Docker] Spawning Redis container - Image: ${options.image}:${options.version}, Port: ${port}, Mode: ${options.mode}`);
|
||||||
|
|
||||||
const { stdout, stderr } = await execAsync('docker', dockerArgs);
|
const { stdout, stderr } = await execAsync('docker', dockerArgs);
|
||||||
|
|
||||||
@@ -87,7 +116,7 @@ async function spawnRedisServerDocker({
|
|||||||
}
|
}
|
||||||
const RUNNING_SERVERS = new Map<Array<string>, ReturnType<typeof spawnRedisServerDocker>>();
|
const RUNNING_SERVERS = new Map<Array<string>, ReturnType<typeof spawnRedisServerDocker>>();
|
||||||
|
|
||||||
export function spawnRedisServer(dockerConfig: RedisServerDockerConfig, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
export function spawnRedisServer(dockerConfig: RedisServerDockerOptions, serverArguments: Array<string>): Promise<RedisServerDocker> {
|
||||||
const runningServer = RUNNING_SERVERS.get(serverArguments);
|
const runningServer = RUNNING_SERVERS.get(serverArguments);
|
||||||
if (runningServer) {
|
if (runningServer) {
|
||||||
return runningServer;
|
return runningServer;
|
||||||
@@ -113,7 +142,7 @@ after(() => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface RedisClusterDockersConfig extends RedisServerDockerConfig {
|
export type RedisClusterDockersConfig = RedisServerDockerOptions & {
|
||||||
numberOfMasters?: number;
|
numberOfMasters?: number;
|
||||||
numberOfReplicas?: number;
|
numberOfReplicas?: number;
|
||||||
}
|
}
|
||||||
@@ -178,7 +207,7 @@ async function spawnRedisClusterNodeDockers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function spawnRedisClusterNodeDocker(
|
async function spawnRedisClusterNodeDocker(
|
||||||
dockersConfig: RedisClusterDockersConfig,
|
dockersConfig: RedisServerDockerOptions,
|
||||||
serverArguments: Array<string>,
|
serverArguments: Array<string>,
|
||||||
clientConfig?: Partial<RedisClusterClientOptions>
|
clientConfig?: Partial<RedisClusterClientOptions>
|
||||||
) {
|
) {
|
||||||
@@ -291,3 +320,107 @@ after(() => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const RUNNING_NODES = new Map<Array<string>, Array<RedisServerDocker>>();
|
||||||
|
const RUNNING_SENTINELS = new Map<Array<string>, Array<RedisServerDocker>>();
|
||||||
|
|
||||||
|
export async function spawnRedisSentinel(
|
||||||
|
dockerConfigs: RedisServerDockerOptions,
|
||||||
|
serverArguments: Array<string>,
|
||||||
|
): Promise<Array<RedisServerDocker>> {
|
||||||
|
const runningNodes = RUNNING_SENTINELS.get(serverArguments);
|
||||||
|
if (runningNodes) {
|
||||||
|
return runningNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const passIndex = serverArguments.indexOf('--requirepass')+1;
|
||||||
|
let password: string | undefined = undefined;
|
||||||
|
if (passIndex != 0) {
|
||||||
|
password = serverArguments[passIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
const master = await spawnRedisServerDocker(dockerConfigs, serverArguments);
|
||||||
|
const redisNodes: Array<RedisServerDocker> = [master];
|
||||||
|
const replicaPromises: Array<Promise<RedisServerDocker>> = [];
|
||||||
|
|
||||||
|
const replicasCount = 2;
|
||||||
|
for (let i = 0; i < replicasCount; i++) {
|
||||||
|
replicaPromises.push((async () => {
|
||||||
|
const replica = await spawnRedisServerDocker(dockerConfigs, serverArguments);
|
||||||
|
const client = createClient({
|
||||||
|
socket: {
|
||||||
|
port: replica.port
|
||||||
|
},
|
||||||
|
password: password
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.connect();
|
||||||
|
await client.replicaOf("127.0.0.1", master.port);
|
||||||
|
await client.close();
|
||||||
|
|
||||||
|
return replica;
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
|
||||||
|
const replicas = await Promise.all(replicaPromises);
|
||||||
|
redisNodes.push(...replicas);
|
||||||
|
RUNNING_NODES.set(serverArguments, redisNodes);
|
||||||
|
|
||||||
|
const sentinelPromises: Array<Promise<RedisServerDocker>> = [];
|
||||||
|
const sentinelCount = 3;
|
||||||
|
|
||||||
|
const appPrefix = 'sentinel-config-dir';
|
||||||
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), appPrefix));
|
||||||
|
|
||||||
|
for (let i = 0; i < sentinelCount; i++) {
|
||||||
|
sentinelPromises.push((async () => {
|
||||||
|
const port = (await portIterator.next()).value;
|
||||||
|
|
||||||
|
let sentinelConfig = `port ${port}
|
||||||
|
sentinel monitor mymaster 127.0.0.1 ${master.port} 2
|
||||||
|
sentinel down-after-milliseconds mymaster 5000
|
||||||
|
sentinel failover-timeout mymaster 6000
|
||||||
|
`;
|
||||||
|
if (password !== undefined) {
|
||||||
|
sentinelConfig += `requirepass ${password}\n`;
|
||||||
|
sentinelConfig += `sentinel auth-pass mymaster ${password}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dir = fs.mkdtempSync(path.join(tmpDir, i.toString()));
|
||||||
|
fs.writeFile(`${dir}/redis.conf`, sentinelConfig, err => {
|
||||||
|
if (err) {
|
||||||
|
console.error("failed to create temporary config file", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return await spawnRedisServerDocker(
|
||||||
|
{
|
||||||
|
image: dockerConfigs.image,
|
||||||
|
version: dockerConfigs.version,
|
||||||
|
mode: "sentinel",
|
||||||
|
mounts: [`${dir}/redis.conf:/redis/config/node-sentinel-1/redis.conf`],
|
||||||
|
port: port,
|
||||||
|
}, serverArguments);
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
|
||||||
|
const sentinelNodes = await Promise.all(sentinelPromises);
|
||||||
|
RUNNING_SENTINELS.set(serverArguments, sentinelNodes);
|
||||||
|
|
||||||
|
if (tmpDir) {
|
||||||
|
fs.rmSync(tmpDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return sentinelNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
return Promise.all(
|
||||||
|
[...RUNNING_NODES.values(), ...RUNNING_SENTINELS.values()].map(async dockersPromise => {
|
||||||
|
return Promise.all(
|
||||||
|
dockersPromise.map(({ dockerId }) => dockerRemove(dockerId))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@@ -6,8 +6,11 @@ import {
|
|||||||
TypeMapping,
|
TypeMapping,
|
||||||
// CommandPolicies,
|
// CommandPolicies,
|
||||||
createClient,
|
createClient,
|
||||||
|
createSentinel,
|
||||||
RedisClientOptions,
|
RedisClientOptions,
|
||||||
RedisClientType,
|
RedisClientType,
|
||||||
|
RedisSentinelOptions,
|
||||||
|
RedisSentinelType,
|
||||||
RedisPoolOptions,
|
RedisPoolOptions,
|
||||||
RedisClientPoolType,
|
RedisClientPoolType,
|
||||||
createClientPool,
|
createClientPool,
|
||||||
@@ -15,7 +18,8 @@ import {
|
|||||||
RedisClusterOptions,
|
RedisClusterOptions,
|
||||||
RedisClusterType
|
RedisClusterType
|
||||||
} from '@redis/client/index';
|
} from '@redis/client/index';
|
||||||
import { RedisServerDockerConfig, spawnRedisServer, spawnRedisCluster } from './dockers';
|
import { RedisNode } from '@redis/client/lib/sentinel/types'
|
||||||
|
import { spawnRedisServer, spawnRedisCluster, spawnRedisSentinel, RedisServerDockerOptions } from './dockers';
|
||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import { hideBin } from 'yargs/helpers';
|
import { hideBin } from 'yargs/helpers';
|
||||||
|
|
||||||
@@ -68,6 +72,24 @@ interface ClientTestOptions<
|
|||||||
disableClientSetup?: boolean;
|
disableClientSetup?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SentinelTestOptions<
|
||||||
|
M extends RedisModules,
|
||||||
|
F extends RedisFunctions,
|
||||||
|
S extends RedisScripts,
|
||||||
|
RESP extends RespVersions,
|
||||||
|
TYPE_MAPPING extends TypeMapping
|
||||||
|
> extends CommonTestOptions {
|
||||||
|
sentinelOptions?: Partial<RedisSentinelOptions<M, F, S, RESP, TYPE_MAPPING>>;
|
||||||
|
clientOptions?: Partial<RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>>;
|
||||||
|
scripts?: S;
|
||||||
|
functions?: F;
|
||||||
|
modules?: M;
|
||||||
|
disableClientSetup?: boolean;
|
||||||
|
replicaPoolSize?: number;
|
||||||
|
masterPoolSize?: number;
|
||||||
|
reserveClient?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface ClientPoolTestOptions<
|
interface ClientPoolTestOptions<
|
||||||
M extends RedisModules,
|
M extends RedisModules,
|
||||||
F extends RedisFunctions,
|
F extends RedisFunctions,
|
||||||
@@ -148,13 +170,14 @@ export default class TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly #VERSION_NUMBERS: Array<number>;
|
readonly #VERSION_NUMBERS: Array<number>;
|
||||||
readonly #DOCKER_IMAGE: RedisServerDockerConfig;
|
readonly #DOCKER_IMAGE: RedisServerDockerOptions;
|
||||||
|
|
||||||
constructor({ string, numbers }: Version, dockerImageName: string) {
|
constructor({ string, numbers }: Version, dockerImageName: string) {
|
||||||
this.#VERSION_NUMBERS = numbers;
|
this.#VERSION_NUMBERS = numbers;
|
||||||
this.#DOCKER_IMAGE = {
|
this.#DOCKER_IMAGE = {
|
||||||
image: dockerImageName,
|
image: dockerImageName,
|
||||||
version: string
|
version: string,
|
||||||
|
mode: "server"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +202,6 @@ export default class TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isVersionGreaterThanHook(minimumVersion: Array<number> | undefined): void {
|
isVersionGreaterThanHook(minimumVersion: Array<number> | undefined): void {
|
||||||
|
|
||||||
const isVersionGreaterThanHook = this.isVersionGreaterThan.bind(this);
|
const isVersionGreaterThanHook = this.isVersionGreaterThan.bind(this);
|
||||||
const versionNumber = this.#VERSION_NUMBERS.join('.');
|
const versionNumber = this.#VERSION_NUMBERS.join('.');
|
||||||
const minimumVersionString = minimumVersion?.join('.');
|
const minimumVersionString = minimumVersion?.join('.');
|
||||||
@@ -272,6 +294,81 @@ export default class TestUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testWithClientSentinel<
|
||||||
|
M extends RedisModules = {},
|
||||||
|
F extends RedisFunctions = {},
|
||||||
|
S extends RedisScripts = {},
|
||||||
|
RESP extends RespVersions = 2,
|
||||||
|
TYPE_MAPPING extends TypeMapping = {}
|
||||||
|
>(
|
||||||
|
title: string,
|
||||||
|
fn: (sentinel: RedisSentinelType<M, F, S, RESP, TYPE_MAPPING>) => unknown,
|
||||||
|
options: SentinelTestOptions<M, F, S, RESP, TYPE_MAPPING>
|
||||||
|
): void {
|
||||||
|
let dockerPromises: ReturnType<typeof spawnRedisSentinel>;
|
||||||
|
|
||||||
|
const passIndex = options.serverArguments.indexOf('--requirepass')+1;
|
||||||
|
let password: string | undefined = undefined;
|
||||||
|
if (passIndex != 0) {
|
||||||
|
password = options.serverArguments[passIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isVersionGreaterThan(options.minimumDockerVersion)) {
|
||||||
|
const dockerImage = this.#DOCKER_IMAGE;
|
||||||
|
before(function () {
|
||||||
|
this.timeout(30000);
|
||||||
|
dockerPromises = spawnRedisSentinel(dockerImage, options.serverArguments);
|
||||||
|
return dockerPromises;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it(title, async function () {
|
||||||
|
this.timeout(30000);
|
||||||
|
if (options.skipTest) return this.skip();
|
||||||
|
if (!dockerPromises) return this.skip();
|
||||||
|
|
||||||
|
|
||||||
|
const promises = await dockerPromises;
|
||||||
|
const rootNodes: Array<RedisNode> = promises.map(promise => ({
|
||||||
|
host: "127.0.0.1",
|
||||||
|
port: promise.port
|
||||||
|
}));
|
||||||
|
|
||||||
|
const sentinel = createSentinel({
|
||||||
|
name: 'mymaster',
|
||||||
|
sentinelRootNodes: rootNodes,
|
||||||
|
nodeClientOptions: {
|
||||||
|
password: password || undefined,
|
||||||
|
},
|
||||||
|
sentinelClientOptions: {
|
||||||
|
password: password || undefined,
|
||||||
|
},
|
||||||
|
replicaPoolSize: options?.replicaPoolSize || 0,
|
||||||
|
scripts: options?.scripts || {},
|
||||||
|
modules: options?.modules || {},
|
||||||
|
functions: options?.functions || {},
|
||||||
|
masterPoolSize: options?.masterPoolSize || undefined,
|
||||||
|
reserveClient: options?.reserveClient || false,
|
||||||
|
}) as RedisSentinelType<M, F, S, RESP, TYPE_MAPPING>;
|
||||||
|
|
||||||
|
if (options.disableClientSetup) {
|
||||||
|
return fn(sentinel);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sentinel.connect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sentinel.flushAll();
|
||||||
|
await fn(sentinel);
|
||||||
|
} finally {
|
||||||
|
if (sentinel.isOpen) {
|
||||||
|
await sentinel.flushAll();
|
||||||
|
sentinel.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
testWithClientIfVersionWithinRange<
|
testWithClientIfVersionWithinRange<
|
||||||
M extends RedisModules = {},
|
M extends RedisModules = {},
|
||||||
F extends RedisFunctions = {},
|
F extends RedisFunctions = {},
|
||||||
@@ -290,9 +387,28 @@ export default class TestUtils {
|
|||||||
} else {
|
} else {
|
||||||
console.warn(`Skipping test ${title} because server version ${this.#VERSION_NUMBERS.join('.')} is not within range ${range[0].join(".")} - ${range[1] !== 'LATEST' ? range[1].join(".") : 'LATEST'}`)
|
console.warn(`Skipping test ${title} because server version ${this.#VERSION_NUMBERS.join('.')} is not within range ${range[0].join(".")} - ${range[1] !== 'LATEST' ? range[1].join(".") : 'LATEST'}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testWithClienSentineltIfVersionWithinRange<
|
||||||
|
M extends RedisModules = {},
|
||||||
|
F extends RedisFunctions = {},
|
||||||
|
S extends RedisScripts = {},
|
||||||
|
RESP extends RespVersions = 2,
|
||||||
|
TYPE_MAPPING extends TypeMapping = {}
|
||||||
|
>(
|
||||||
|
range: ([minVersion: Array<number>, maxVersion: Array<number>] | [minVersion: Array<number>, 'LATEST']),
|
||||||
|
title: string,
|
||||||
|
fn: (sentinel: RedisSentinelType<M, F, S, RESP, TYPE_MAPPING>) => unknown,
|
||||||
|
options: SentinelTestOptions<M, F, S, RESP, TYPE_MAPPING>
|
||||||
|
): void {
|
||||||
|
|
||||||
|
if (this.isVersionInRange(range[0], range[1] === 'LATEST' ? [Infinity, Infinity, Infinity] : range[1])) {
|
||||||
|
return this.testWithClientSentinel(`${title} [${range[0].join('.')}] - [${(range[1] === 'LATEST') ? range[1] : range[1].join(".")}] `, fn, options)
|
||||||
|
} else {
|
||||||
|
console.warn(`Skipping test ${title} because server version ${this.#VERSION_NUMBERS.join('.')} is not within range ${range[0].join(".")} - ${range[1] !== 'LATEST' ? range[1].join(".") : 'LATEST'}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
testWithClientPool<
|
testWithClientPool<
|
||||||
M extends RedisModules = {},
|
M extends RedisModules = {},
|
||||||
F extends RedisFunctions = {},
|
F extends RedisFunctions = {},
|
||||||
|
Reference in New Issue
Block a user