Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 51 additions & 49 deletions packages/modules/redis/src/redis-container.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { createClient } from "redis";
import { getImage } from "../../../testcontainers/src/utils/test-helper";
import { RedisContainer } from "./redis-container";

const IMAGE = getImage(__dirname);
const IMAGES = ["redis:6.2.24", "redis:7.4.11", getImage(__dirname)];
const REDISSTACK_IMAGE = getImage(__dirname, 1);

describe("RedisContainer", { timeout: 240_000 }, () => {
it("should connect and execute set-get", async () => {
describe.each(IMAGES)("RedisContainer (%s)", { concurrent: false, timeout: 240_000 }, (image) => {
it.concurrent("should connect and execute set-get", async () => {
// redisStartContainer {
await using container = await new RedisContainer(IMAGE).start();
await using container = await new RedisContainer(image).start();

const client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -22,8 +22,8 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
// }
});

it("should connect with password and execute set-get", async () => {
await using container = await new RedisContainer(IMAGE).withPassword("test").start();
it.concurrent("should connect with password and execute set-get", async () => {
await using container = await new RedisContainer(image).withPassword("test").start();

const client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -34,11 +34,11 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should reconnect with volume and persistence data", async () => {
it.concurrent("should reconnect with volume and persistence data", async () => {
// persistentData {
const sourcePath = fs.mkdtempSync("redis-");

await using container = await new RedisContainer(IMAGE).withPassword("test").withPersistence(sourcePath).start();
await using container = await new RedisContainer(image).withPassword("test").withPersistence(sourcePath).start();

let client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -56,9 +56,9 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
// }
});

it("should load initial data and can read it", async () => {
it.concurrent("should load initial data and can read it", async () => {
// withPredefinedData {
await using container = await new RedisContainer(IMAGE)
await using container = await new RedisContainer(image)
.withPassword("test")
.withInitialData(path.join(__dirname, "initData.redis"))
.start();
Expand All @@ -77,8 +77,8 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
// }
});

it("should load initial data once", async () => {
await using container = await new RedisContainer(IMAGE)
it.concurrent("should load initial data once", async () => {
await using container = await new RedisContainer(image)
.withInitialData(path.join(__dirname, "initCount.redis"))
.start();

Expand All @@ -90,11 +90,11 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should start with credentials and login", async () => {
it.concurrent("should start with credentials and login", async () => {
// redisStartWithCredentials {
const password = "testPassword";

await using container = await new RedisContainer(IMAGE).withPassword(password).start();
await using container = await new RedisContainer(image).withPassword(password).start();

expect(container.getConnectionUrl()).toEqual(`redis://:${password}@${container.getHost()}:${container.getPort()}`);
// }
Expand All @@ -108,33 +108,18 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should execute container cmd and return the result", async () => {
it.concurrent("should execute container cmd and return the result", async () => {
// executeCommand {
await using container = await new RedisContainer(IMAGE).start();
await using container = await new RedisContainer(image).start();

const queryResult = await container.executeCliCmd("info", ["clients"]);

expect(queryResult).toEqual(expect.stringContaining("connected_clients:1"));
// }
});

it("should start with redis-stack-server and json module", async () => {
// startWithRedisStack {
await using container = await new RedisContainer(REDISSTACK_IMAGE).withPassword("testPassword").start();

const client = createClient({ url: container.getConnectionUrl() });
await client.connect();

await client.json.set("key", "$", { name: "test" });
const result = await client.json.get("key");
expect(result).toEqual({ name: "test" });

client.destroy();
// }
});

it("should start redis with custom command", async () => {
const container = new RedisContainer(IMAGE).withCommand(["redis-server", "--loglevel", "verbose"]);
it.concurrent("should start redis with custom command", async () => {
const container = new RedisContainer(image).withCommand(["redis-server", "--loglevel", "verbose"]);
await using startedContainer = await container.start();

// @ts-expect-error - accessing private property for testing
Expand All @@ -149,12 +134,22 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should start redis-stack with custom env", async () => {
const container = new RedisContainer(REDISSTACK_IMAGE).withEnvironment({ REDIS_ARGS: "--loglevel verbose" });
it.concurrent("should start redis with custom command and keeping default args", async () => {
const sourcePath = fs.mkdtempSync("redis-");

const container = new RedisContainer(image)
.withCommand(["redis-server", "--loglevel", "verbose"])
.withPersistence(sourcePath);
await using startedContainer = await container.start();

// @ts-expect-error - accessing private property for testing
expect(container.createOpts.Env).toEqual(["REDIS_ARGS=--loglevel verbose"]);
expect(container.createOpts.Cmd).toEqual([
"redis-server",
"--loglevel",
"verbose",
"--save 1 1 ",
"--appendonly yes",
]);

const client = createClient({ url: startedContainer.getConnectionUrl() });
await client.connect();
Expand All @@ -163,24 +158,32 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
expect(await client.get("key")).toBe("val");

client.destroy();
fs.rmSync(sourcePath, { force: true, recursive: true });
});
});

it("should start redis with custom command and keeping default args", async () => {
const sourcePath = fs.mkdtempSync("redis-");
describe(`RedisContainer (${REDISSTACK_IMAGE})`, { timeout: 240_000 }, () => {
it("should start with redis-stack-server and json module", async () => {
// startWithRedisStack {
await using container = await new RedisContainer(REDISSTACK_IMAGE).withPassword("testPassword").start();

const container = new RedisContainer(IMAGE)
.withCommand(["redis-server", "--loglevel", "verbose"])
.withPersistence(sourcePath);
const client = createClient({ url: container.getConnectionUrl() });
await client.connect();

await client.json.set("key", "$", { name: "test" });
const result = await client.json.get("key");
expect(result).toEqual({ name: "test" });

client.destroy();
// }
});

it("should start redis-stack with custom env", async () => {
const container = new RedisContainer(REDISSTACK_IMAGE).withEnvironment({ REDIS_ARGS: "--loglevel verbose" });
await using startedContainer = await container.start();

// @ts-expect-error - accessing private property for testing
expect(container.createOpts.Cmd).toEqual([
"redis-server",
"--loglevel",
"verbose",
"--save 1 1 ",
"--appendonly yes",
]);
expect(container.createOpts.Env).toEqual(["REDIS_ARGS=--loglevel verbose"]);

const client = createClient({ url: startedContainer.getConnectionUrl() });
await client.connect();
Expand All @@ -189,7 +192,6 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
expect(await client.get("key")).toBe("val");

client.destroy();
fs.rmSync(sourcePath, { force: true, recursive: true });
});

it("should start redis-stack with custom env and keeping default args", async () => {
Expand Down
32 changes: 16 additions & 16 deletions packages/modules/valkey/src/valkey-container.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { createClient } from "redis";
import { getImage } from "../../../testcontainers/src/utils/test-helper";
import { ValkeyContainer } from "./valkey-container";

const IMAGE = getImage(__dirname);
const IMAGES = ["valkey/valkey:7.2.14", "valkey/valkey:8.1.10", getImage(__dirname)];

describe("ValkeyContainer", { timeout: 240_000 }, () => {
it("should connect and execute set-get", async () => {
describe.each(IMAGES)("ValkeyContainer (%s)", { concurrent: false, timeout: 240_000 }, (image) => {
it.concurrent("should connect and execute set-get", async () => {
// valkeyStartContainer {
await using container = await new ValkeyContainer(IMAGE).start();
await using container = await new ValkeyContainer(image).start();

const client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -21,8 +21,8 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
// }
});

it("should connect with password and execute set-get", async () => {
await using container = await new ValkeyContainer(IMAGE).withPassword("test").start();
it.concurrent("should connect with password and execute set-get", async () => {
await using container = await new ValkeyContainer(image).withPassword("test").start();

const client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -33,11 +33,11 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should reconnect with volume and persistence data", async () => {
it.concurrent("should reconnect with volume and persistence data", async () => {
// valkeyWithPersistentData {
const sourcePath = fs.mkdtempSync("valkey-");

await using container = await new ValkeyContainer(IMAGE).withPassword("test").withPersistence(sourcePath).start();
await using container = await new ValkeyContainer(image).withPassword("test").withPersistence(sourcePath).start();

let client = createClient({ url: container.getConnectionUrl() });
await client.connect();
Expand All @@ -56,9 +56,9 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
// }
});

it("should load initial data and can read it", async () => {
it.concurrent("should load initial data and can read it", async () => {
// valkeyWithPredefinedData {
await using container = await new ValkeyContainer(IMAGE)
await using container = await new ValkeyContainer(image)
.withPassword("test")
.withInitialData(path.join(__dirname, "initData.valkey"))
.start();
Expand All @@ -77,12 +77,12 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
// }
});

it("should start with username and password", async () => {
it.concurrent("should start with username and password", async () => {
// valkeyWithUsernameAndPassword {
const username = "testUser";
const password = "testPassword";

await using container = await new ValkeyContainer(IMAGE).withUsername(username).withPassword(password).start();
await using container = await new ValkeyContainer(image).withUsername(username).withPassword(password).start();

expect(container.getConnectionUrl()).toEqual(
`redis://${username}:${password}@${container.getHost()}:${container.getPort()}`
Expand All @@ -98,11 +98,11 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should start with password only", async () => {
it.concurrent("should start with password only", async () => {
// valkeyWithPassword {
const password = "testPassword";

await using container = await new ValkeyContainer(IMAGE).withPassword(password).start();
await using container = await new ValkeyContainer(image).withPassword(password).start();

expect(container.getConnectionUrl()).toEqual(`redis://:${password}@${container.getHost()}:${container.getPort()}`);
// }
Expand All @@ -116,9 +116,9 @@ describe("ValkeyContainer", { timeout: 240_000 }, () => {
client.destroy();
});

it("should execute container cmd and return the result", async () => {
it.concurrent("should execute container cmd and return the result", async () => {
// valkeyExecuteCommand {
await using container = await new ValkeyContainer(IMAGE).start();
await using container = await new ValkeyContainer(image).start();

const queryResult = await container.executeCliCmd("info", ["clients"]);

Expand Down
Loading