Skip to content

Commit

Permalink
Merge pull request #415 from shachlanAmazon/client-setinfo
Browse files Browse the repository at this point in the history
Write CLIENT SETINFO data for each client.
  • Loading branch information
shachlanAmazon authored Sep 7, 2023
2 parents 76b2d7b + 4ca1033 commit fc21cc8
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 14 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/lint-rust/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ runs:
sudo apt install protobuf-compiler
shell: bash
- run: cargo fmt --manifest-path ${{ inputs.cargo-toml-folder }}/Cargo.toml --all -- --check
- run: cargo fmt --all -- --check
working-directory: ${{ inputs.cargo-toml-folder }}
shell: bash

- run: cargo clippy --manifest-path ${{ inputs.cargo-toml-folder }}/Cargo.toml --all-features --all-targets -- -D warnings
- run: cargo clippy --all-features --all-targets -- -D warnings
working-directory: ${{ inputs.cargo-toml-folder }}
shell: bash

- run: |
cd ${{ inputs.cargo-toml-folder }}
cargo update
cargo install cargo-deny
cargo deny check licenses --config ${GITHUB_WORKSPACE}/deny.toml
working-directory: ${{ inputs.cargo-toml-folder }}
shell: bash
- name: doc
Expand Down
3 changes: 3 additions & 0 deletions babushka-core/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
BABUSHKA_NAME = "Babushka" # This should be overwritten by each wrapper library.
BABUSHKA_VERSION = "0.1.0"
9 changes: 9 additions & 0 deletions babushka-core/tests/utilities/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ async fn receive_and_respond_to_next_message(
};

let message = from_utf8(&buffer[..size]).unwrap().to_string();
let setinfo_count = message.matches("SETINFO").count();
if setinfo_count > 0 {
let mut buffer = Vec::new();
for _ in 0..setinfo_count {
super::encode_value(&Value::Okay, &mut buffer).unwrap();
}
socket.write_all(&buffer).await.unwrap();
return true;
}

if let Some(response) = constant_responses.get(&message) {
let mut buffer = Vec::new();
Expand Down
3 changes: 3 additions & 0 deletions benchmarks/rust/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
BABUSHKA_NAME = "Babushka" # This should be overwritten by each wrapper library.
BABUSHKA_VERSION = "0.1.0"
3 changes: 3 additions & 0 deletions csharp/lib/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
BABUSHKA_NAME = { value = "BabushkaC#", force = true }
BABUSHKA_VERSION = "0.1.0"
3 changes: 3 additions & 0 deletions node/rust-client/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
BABUSHKA_NAME = { value = "BabushkaJS", force = true }
BABUSHKA_VERSION = "0.1.0"
73 changes: 64 additions & 9 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect, it } from "@jest/globals";
import { exec } from "child_process";
import { v4 as uuidv4 } from "uuid";
import { InfoOptions, ReturnType, SetOptions, parseInfoResponse } from "../";
import { Client, GetAndSetRandomValue, getFirstResult } from "./TestUtilities";
Expand All @@ -19,6 +20,24 @@ type BaseClient = {
customCommand: (commandName: string, args: string[]) => Promise<ReturnType>;
};

async function getVersion(): Promise<[number, number, number]> {
const versioString = await new Promise<string>((resolve, reject) => {
exec(`redis-server -v`, (error, stdout) => {
if (error) {
reject(error);
} else {
resolve(stdout);
}
});
});
const version = versioString.split("v=")[1].split(" ")[0];
const numbers = version?.split(".");
if (numbers.length != 3) {
return [0, 0, 0];
}
return [parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2])];
}

export function runBaseTests<Context>(config: {
init: () => Promise<{ context: Context; client: BaseClient }>;
close: (context: Context, testSucceeded: boolean) => void;
Expand All @@ -37,6 +56,24 @@ export function runBaseTests<Context>(config: {
}
};

it(
"should register client name and version",
async () => {
await runTest(async (client: BaseClient) => {
const version = await getVersion();
if (version[0] < 7 || (version[0] === 7 && version[1] < 2)) {
return;
}

const result = await client.customCommand("CLIENT", ["INFO"]);

expect(result).toContain("lib-name=BabushkaJS");
expect(result).toContain("lib-ver=0.1.0");
});
},
config.timeout
);

it(
"set with return of old value works",
async () => {
Expand Down Expand Up @@ -172,15 +209,19 @@ export function runBaseTests<Context>(config: {
async () => {
await runTest(async (client: BaseClient) => {
const serverInfo = await client.info([InfoOptions.Server]);
const conf_file = parseInfoResponse(getFirstResult(serverInfo))["config_file"];
const conf_file = parseInfoResponse(getFirstResult(serverInfo))[
"config_file"
];
if (conf_file.length > 0) {
expect(await client.configRewrite()).toEqual("OK");
} else {
try{
try {
/// We expect Redis to return an error since the test cluster doesn't use redis.conf file
expect(await client.configRewrite()).toThrow();
} catch(e){
expect((e as Error).message).toMatch('The server is running without a config file');
} catch (e) {
expect((e as Error).message).toMatch(
"The server is running without a config file"
);
}
}
});
Expand All @@ -196,10 +237,20 @@ export function runBaseTests<Context>(config: {
/// after the configResetStat call we initiate an info command and the the total_commands_processed will be 1.
await client.set("foo", "bar");
const OldResult = await client.info([InfoOptions.Stats]);
expect(Number(parseInfoResponse(getFirstResult(OldResult))["total_commands_processed"])).toBeGreaterThan(1);
expect(
Number(
parseInfoResponse(getFirstResult(OldResult))[
"total_commands_processed"
]
)
).toBeGreaterThan(1);
expect(await client.configResetStat()).toEqual("OK");
const result = await client.info([InfoOptions.Stats]);
expect(parseInfoResponse(getFirstResult(result))["total_commands_processed"]).toEqual("1");
expect(
parseInfoResponse(getFirstResult(result))[
"total_commands_processed"
]
).toEqual("1");
});
},
config.timeout
Expand All @@ -226,7 +277,7 @@ export function runBaseTests<Context>(config: {
await runTest(async (client: BaseClient) => {
const key1 = uuidv4();
const key2 = uuidv4();
/// key1 and key2 does not exist, so it set to 0 before performing the operation.
/// key1 and key2 does not exist, so it set to 0 before performing the operation.
expect(await client.incr(key1)).toEqual(1);
expect(await client.get(key1)).toEqual("1");
expect(await client.incrBy(key2, 2)).toEqual(2);
Expand All @@ -245,13 +296,17 @@ export function runBaseTests<Context>(config: {
try {
expect(await client.incr(key)).toThrow();
} catch (e) {
expect((e as Error).message).toMatch("value is not an integer");
expect((e as Error).message).toMatch(
"value is not an integer"
);
}

try {
expect(await client.incrBy(key, 1)).toThrow();
} catch (e) {
expect((e as Error).message).toMatch("value is not an integer");
expect((e as Error).message).toMatch(
"value is not an integer"
);
}
});
},
Expand Down
3 changes: 3 additions & 0 deletions python/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
BABUSHKA_NAME = { value = "BabushkaPy", force = true }
BABUSHKA_VERSION = "0.1.0"
14 changes: 13 additions & 1 deletion python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,26 @@ async def check_if_server_version_lt(client: BaseRedisClient, min_version: str)


@pytest.mark.asyncio
class TestSocketClient:
class TestRedisClients:
@pytest.mark.parametrize("cluster_mode", [True, False])
async def test_socket_set_get(self, redis_client: BaseRedisClient):
key = get_random_string(10)
value = datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
assert await redis_client.set(key, value) == OK
assert await redis_client.get(key) == value

@pytest.mark.parametrize("cluster_mode", [True, False])
async def test_register_client_name_and_version(
self, redis_client: BaseRedisClient
):
min_version = "7.2.0"
if await check_if_server_version_lt(redis_client, min_version):
# TODO: change it to pytest fixture after we'll implement a sync client
return pytest.mark.skip(reason=f"Redis version required >= {min_version}")
info = await redis_client.custom_command(["CLIENT", "INFO"])
assert "lib-name=BabushkaPy" in info
assert "lib-ver=0.1.0" in info

@pytest.mark.parametrize("cluster_mode", [True, False])
async def test_large_values(self, redis_client: BaseRedisClient):
length = 2**16
Expand Down

0 comments on commit fc21cc8

Please sign in to comment.