diff --git a/CHANGELOG.md b/CHANGELOG.md index a82ea59b12..f51fc1c58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ * Python: Replace instances of Redis with Valkey ([#2266](https://github.com/valkey-io/valkey-glide/pull/2266)) * Java: Replace instances of Redis with Valkey ([#2268](https://github.com/valkey-io/valkey-glide/pull/2268)) * Node: Replace instances of Redis with Valkey ([#2260](https://github.com/valkey-io/valkey-glide/pull/2260)) -* Java: Fetch server version using info command ([#2258](https://github.com/valkey-io/valkey-glide/pull/2258)) * Node: Added binary variant for commands which have `Record` as input or output ([#2207](https://github.com/valkey-io/valkey-glide/pull/2207)) * Node: Renamed `ReturnType` to `GlideReturnType` ([#2241](https://github.com/valkey-io/valkey-glide/pull/2241)) * Node, Python: Rename `stop` to `end` in sorted set queries ([#2214](https://github.com/valkey-io/valkey-glide/pull/2214)) @@ -138,6 +137,8 @@ * Python: Fix `XClaim` return type to `List[bytes]` instead of `List[TEncodable]` ([#2075](https://github.com/valkey-io/valkey-glide/pull/2075)) ### Operational Enhancements +* Node: Get valkey/redis version using client's info command ([#2276]https://github.com/valkey-io/valkey-glide/pull/2276) +* Java: Fetch server version using client's info command ([#2258](https://github.com/valkey-io/valkey-glide/pull/2258)) * CI/CD: Add workflow for automating Maven release ([#2128](https://github.com/valkey-io/valkey-glide/pull/2128)) ## 1.0.0 (2024-07-09) diff --git a/node/tests/GlideClient.test.ts b/node/tests/GlideClient.test.ts index 19b0d7b431..4e3a31d195 100644 --- a/node/tests/GlideClient.test.ts +++ b/node/tests/GlideClient.test.ts @@ -40,6 +40,7 @@ import { flushAndCloseClient, generateLuaLibCode, getClientConfigurationOption, + getServerVersion, parseCommandLineArgs, parseEndpoints, transactionTest, @@ -57,12 +58,13 @@ describe("GlideClient", () => { beforeAll(async () => { const standaloneAddresses = parseCommandLineArgs()["standalone-endpoints"]; - // Connect to cluster or create a new one based on the parsed addresses cluster = standaloneAddresses ? await ValkeyCluster.initFromExistingCluster( + false, parseEndpoints(standaloneAddresses), + getServerVersion, ) - : await ValkeyCluster.createCluster(false, 1, 1); + : await ValkeyCluster.createCluster(false, 1, 1, getServerVersion); }, 20000); afterEach(async () => { diff --git a/node/tests/GlideClusterClient.test.ts b/node/tests/GlideClusterClient.test.ts index 6603aa4308..c474031ba4 100644 --- a/node/tests/GlideClusterClient.test.ts +++ b/node/tests/GlideClusterClient.test.ts @@ -46,6 +46,7 @@ import { generateLuaLibCode, getClientConfigurationOption, getFirstResult, + getServerVersion, intoArray, intoString, parseCommandLineArgs, @@ -67,10 +68,12 @@ describe("GlideClusterClient", () => { // Connect to cluster or create a new one based on the parsed addresses cluster = clusterAddresses ? await ValkeyCluster.initFromExistingCluster( + true, parseEndpoints(clusterAddresses), + getServerVersion, ) : // setting replicaCount to 1 to facilitate tests routed to replicas - await ValkeyCluster.createCluster(true, 3, 1); + await ValkeyCluster.createCluster(true, 3, 1, getServerVersion); }, 20000); afterEach(async () => { diff --git a/node/tests/PubSub.test.ts b/node/tests/PubSub.test.ts index 5e031cbbd6..82aec7f826 100644 --- a/node/tests/PubSub.test.ts +++ b/node/tests/PubSub.test.ts @@ -27,6 +27,7 @@ import { import ValkeyCluster from "../../utils/TestUtils"; import { flushAndCloseClient, + getServerVersion, parseCommandLineArgs, parseEndpoints, } from "./TestUtilities"; @@ -65,14 +66,18 @@ describe("PubSub", () => { // Connect to cluster or create a new one based on the parsed addresses cmdCluster = standaloneAddresses ? await ValkeyCluster.initFromExistingCluster( + false, parseEndpoints(standaloneAddresses), + getServerVersion, ) - : await ValkeyCluster.createCluster(false, 1, 1); + : await ValkeyCluster.createCluster(false, 1, 1, getServerVersion); cmeCluster = clusterAddresses ? await ValkeyCluster.initFromExistingCluster( + true, parseEndpoints(clusterAddresses), + getServerVersion, ) - : await ValkeyCluster.createCluster(true, 3, 1); + : await ValkeyCluster.createCluster(true, 3, 1, getServerVersion); }, 40000); afterEach(async () => { await flushAndCloseClient(false, cmdCluster.getAddresses()); diff --git a/node/tests/ScanTest.test.ts b/node/tests/ScanTest.test.ts index 7e62665bf9..eaec19e640 100644 --- a/node/tests/ScanTest.test.ts +++ b/node/tests/ScanTest.test.ts @@ -17,6 +17,7 @@ import { ValkeyCluster } from "../../utils/TestUtils.js"; import { flushAndCloseClient, getClientConfigurationOption, + getServerVersion, parseCommandLineArgs, parseEndpoints, } from "./TestUtilities"; @@ -33,10 +34,12 @@ describe("Scan GlideClusterClient", () => { // Connect to cluster or create a new one based on the parsed addresses cluster = clusterAddresses ? await ValkeyCluster.initFromExistingCluster( + true, parseEndpoints(clusterAddresses), + getServerVersion, ) : // setting replicaCount to 1 to facilitate tests routed to replicas - await ValkeyCluster.createCluster(true, 3, 1); + await ValkeyCluster.createCluster(true, 3, 1, getServerVersion); }, 20000); afterEach(async () => { @@ -387,10 +390,12 @@ describe("Scan GlideClient", () => { // Connect to cluster or create a new one based on the parsed addresses cluster = clusterAddresses ? await ValkeyCluster.initFromExistingCluster( + true, parseEndpoints(clusterAddresses), + getServerVersion, ) : // setting replicaCount to 1 to facilitate tests routed to replicas - await ValkeyCluster.createCluster(false, 3, 1); + await ValkeyCluster.createCluster(false, 3, 1, getServerVersion); }, 20000); afterEach(async () => { diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index 38454809be..6975c0894a 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -24,12 +24,13 @@ import { GeospatialData, GlideClient, GlideClusterClient, + GlideReturnType, GlideString, InfBoundary, + InfoOptions, InsertPosition, ListDirection, ProtocolVersion, - GlideReturnType, ReturnTypeMap, ScoreFilter, SignedEncoding, @@ -1756,3 +1757,44 @@ export async function transactionTest( responseData.push(["wait(1, 200)", 1]); return responseData; } + +/** + * This function gets server version using info command in glide client. + * + * @param addresses - Addresses containing host and port for the valkey server. + * @returns Server version for valkey server + */ +export async function getServerVersion( + addresses: [string, number][], + clusterMode = false, +): Promise { + let info = ""; + + if (clusterMode) { + const glideClusterClient = await GlideClusterClient.createClient( + getClientConfigurationOption(addresses, ProtocolVersion.RESP2), + ); + info = getFirstResult( + await glideClusterClient.info({ sections: [InfoOptions.Server] }), + ).toString(); + await flushAndCloseClient(clusterMode, addresses, glideClusterClient); + } else { + const glideClient = await GlideClient.createClient( + getClientConfigurationOption(addresses, ProtocolVersion.RESP2), + ); + info = await glideClient.info([InfoOptions.Server]); + await flushAndCloseClient(clusterMode, addresses, glideClient); + } + + let version = ""; + const redisVersionKey = "redis_version:"; + const valkeyVersionKey = "valkey_version:"; + + if (info.includes(valkeyVersionKey)) { + version = info.split(valkeyVersionKey)[1].split("\n")[0]; + } else if (info.includes(redisVersionKey)) { + version = info.split(redisVersionKey)[1].split("\n")[0]; + } + + return version; +} diff --git a/utils/TestUtils.ts b/utils/TestUtils.ts index 1af27364ee..53ad2098c2 100644 --- a/utils/TestUtils.ts +++ b/utils/TestUtils.ts @@ -2,7 +2,7 @@ * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ -import { exec, execFile } from "child_process"; +import { execFile } from "child_process"; import { lt } from "semver"; const PY_SCRIPT_PATH = __dirname + "/cluster_manager.py"; @@ -21,9 +21,9 @@ function parseOutput(input: string): { .split(",") .map((address) => address.split(":")) .map((address) => [address[0], Number(address[1])]) as [ - string, - number - ][]; + string, + number + ][]; if (clusterFolder === undefined || ports === undefined) { throw new Error(`Insufficient data in input: ${input}`); @@ -50,33 +50,11 @@ export class ValkeyCluster { this.version = version; } - private static async detectVersion(): Promise { - return new Promise((resolve, reject) => { - const extractVersion = (stdout: string): string => - stdout.split("v=")[1].split(" ")[0]; - - // First, try with `valkey-server -v` - exec("valkey-server -v", (error, stdout) => { - if (error) { - // If `valkey-server` fails, try `redis-server -v` - exec("redis-server -v", (error, stdout) => { - if (error) { - reject(error); - } else { - resolve(extractVersion(stdout)); - } - }); - } else { - resolve(extractVersion(stdout)); - } - }); - }); - } - public static createCluster( cluster_mode: boolean, shardCount: number, replicaCount: number, + getVersionCallback: (addresses: [string, number][], clusterMode: boolean) => Promise, loadModule?: string[] ): Promise { return new Promise((resolve, reject) => { @@ -98,22 +76,19 @@ export class ValkeyCluster { } } - console.log(command); execFile( "python3", [PY_SCRIPT_PATH, ...command.split(" ")], (error, stdout, stderr) => { if (error) { - console.error(stderr); reject(error); } else { - const { clusterFolder, addresses: ports } = + const { clusterFolder, addresses } = parseOutput(stdout); - resolve( - ValkeyCluster.detectVersion().then( + getVersionCallback(addresses, cluster_mode).then( (ver) => - new ValkeyCluster(ver, ports, clusterFolder) + new ValkeyCluster(ver, addresses, clusterFolder) ) ); } @@ -123,9 +98,11 @@ export class ValkeyCluster { } public static async initFromExistingCluster( - addresses: [string, number][] + cluster_mode: boolean, + addresses: [string, number][], + getVersionCallback: (addresses: [string, number][], clusterMode: boolean) => Promise ): Promise { - return ValkeyCluster.detectVersion().then( + return getVersionCallback(addresses, cluster_mode).then( (ver) => new ValkeyCluster(ver, addresses, "") ); }