Skip to content

Commit

Permalink
Get valkey/redis version using client's info command (#2276)
Browse files Browse the repository at this point in the history
* Get valkey/redis version using info command

Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: prateek-kumar-improving <prateek.kumar@improving.com>
  • Loading branch information
prateek-kumar-improving authored Sep 13, 2024
1 parent 0d6a44f commit f9cfe77
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 44 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions node/tests/GlideClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
flushAndCloseClient,
generateLuaLibCode,
getClientConfigurationOption,
getServerVersion,
parseCommandLineArgs,
parseEndpoints,
transactionTest,
Expand All @@ -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 () => {
Expand Down
5 changes: 4 additions & 1 deletion node/tests/GlideClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
generateLuaLibCode,
getClientConfigurationOption,
getFirstResult,
getServerVersion,
intoArray,
intoString,
parseCommandLineArgs,
Expand All @@ -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 () => {
Expand Down
9 changes: 7 additions & 2 deletions node/tests/PubSub.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import ValkeyCluster from "../../utils/TestUtils";
import {
flushAndCloseClient,
getServerVersion,
parseCommandLineArgs,
parseEndpoints,
} from "./TestUtilities";
Expand Down Expand Up @@ -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());
Expand Down
9 changes: 7 additions & 2 deletions node/tests/ScanTest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ValkeyCluster } from "../../utils/TestUtils.js";
import {
flushAndCloseClient,
getClientConfigurationOption,
getServerVersion,
parseCommandLineArgs,
parseEndpoints,
} from "./TestUtilities";
Expand All @@ -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 () => {
Expand Down Expand Up @@ -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 () => {
Expand Down
44 changes: 43 additions & 1 deletion node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import {
GeospatialData,
GlideClient,
GlideClusterClient,
GlideReturnType,
GlideString,
InfBoundary,
InfoOptions,
InsertPosition,
ListDirection,
ProtocolVersion,
GlideReturnType,
ReturnTypeMap,
ScoreFilter,
SignedEncoding,
Expand Down Expand Up @@ -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<string> {
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;
}
47 changes: 12 additions & 35 deletions utils/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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}`);
Expand All @@ -50,33 +50,11 @@ export class ValkeyCluster {
this.version = version;
}

private static async detectVersion(): Promise<string> {
return new Promise<string>((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<string>,
loadModule?: string[]
): Promise<ValkeyCluster> {
return new Promise<ValkeyCluster>((resolve, reject) => {
Expand All @@ -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)
)
);
}
Expand All @@ -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<string>
): Promise<ValkeyCluster> {
return ValkeyCluster.detectVersion().then(
return getVersionCallback(addresses, cluster_mode).then(
(ver) => new ValkeyCluster(ver, addresses, "")
);
}
Expand Down

0 comments on commit f9cfe77

Please sign in to comment.