Skip to content

Commit 737f3c2

Browse files
authored
Fix Redis container to accept command override (#1155)
1 parent bf41f91 commit 737f3c2

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

packages/modules/redis/src/redis-container.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,84 @@ describe("RedisContainer", { timeout: 240_000 }, () => {
119119
client.destroy();
120120
// }
121121
});
122+
123+
it("should start redis with custom command", async () => {
124+
const container = new RedisContainer(IMAGE).withCommand(["redis-server", "--loglevel", "verbose"]);
125+
await using startedContainer = await container.start();
126+
127+
// @ts-expect-error - accessing private property for testing
128+
expect(container.createOpts.Cmd).toEqual(["redis-server", "--loglevel", "verbose"]);
129+
130+
const client = createClient({ url: startedContainer.getConnectionUrl() });
131+
await client.connect();
132+
133+
await client.set("key", "val");
134+
expect(await client.get("key")).toBe("val");
135+
136+
client.destroy();
137+
});
138+
139+
it("should start redis-stack with custom env", async () => {
140+
const container = new RedisContainer(REDISSTACK_IMAGE).withEnvironment({ REDIS_ARGS: "--loglevel verbose" });
141+
await using startedContainer = await container.start();
142+
143+
// @ts-expect-error - accessing private property for testing
144+
expect(container.createOpts.Env).toEqual(["REDIS_ARGS=--loglevel verbose"]);
145+
146+
const client = createClient({ url: startedContainer.getConnectionUrl() });
147+
await client.connect();
148+
149+
await client.set("key", "val");
150+
expect(await client.get("key")).toBe("val");
151+
152+
client.destroy();
153+
});
154+
155+
it("should start redis with custom command and keeping default args", async () => {
156+
const sourcePath = fs.mkdtempSync("redis-");
157+
158+
const container = new RedisContainer(IMAGE)
159+
.withCommand(["redis-server", "--loglevel", "verbose"])
160+
.withPersistence(sourcePath);
161+
await using startedContainer = await container.start();
162+
163+
// @ts-expect-error - accessing private property for testing
164+
expect(container.createOpts.Cmd).toEqual([
165+
"redis-server",
166+
"--loglevel",
167+
"verbose",
168+
"--save 1 1 ",
169+
"--appendonly yes",
170+
]);
171+
172+
const client = createClient({ url: startedContainer.getConnectionUrl() });
173+
await client.connect();
174+
175+
await client.set("key", "val");
176+
expect(await client.get("key")).toBe("val");
177+
178+
client.destroy();
179+
fs.rmSync(sourcePath, { force: true, recursive: true });
180+
});
181+
182+
it("should start redis-stack with custom env and keeping default args", async () => {
183+
const sourcePath = fs.mkdtempSync("redis-");
184+
185+
const container = new RedisContainer(REDISSTACK_IMAGE)
186+
.withEnvironment({ REDIS_ARGS: "--loglevel verbose" })
187+
.withPersistence(sourcePath);
188+
await using startedContainer = await container.start();
189+
190+
// @ts-expect-error - accessing private property for testing
191+
expect(container.createOpts.Env).toEqual(["REDIS_ARGS=--loglevel verbose --save 1 1 --appendonly yes"]);
192+
193+
const client = createClient({ url: startedContainer.getConnectionUrl() });
194+
await client.connect();
195+
196+
await client.set("key", "val");
197+
expect(await client.get("key")).toBe("val");
198+
199+
client.destroy();
200+
fs.rmSync(sourcePath, { force: true, recursive: true });
201+
});
122202
});

packages/modules/redis/src/redis-container.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,21 @@ export class RedisContainer extends GenericContainer {
4444
...(this.persistenceVolume ? ["--save 1 1 ", "--appendonly yes"] : []),
4545
];
4646
if (this.imageName.image.includes("redis-stack")) {
47+
const existingRedisArgs = this.environment["REDIS_ARGS"] ?? "";
48+
49+
// merge with filter to remove empty items
50+
const mergedRedisArgs = [existingRedisArgs, ...redisArgs].filter(Boolean).join(" ");
51+
52+
// remove existing REDIS_ARGS to avoid duplicates
53+
this.createOpts.Env = (this.createOpts.Env || []).filter((e) => !e.startsWith("REDIS_ARGS="));
54+
4755
this.withEnvironment({
48-
REDIS_ARGS: redisArgs.join(" "),
56+
REDIS_ARGS: mergedRedisArgs,
4957
}).withEntrypoint(["/entrypoint.sh"]);
5058
} else {
51-
this.withCommand(["redis-server", ...redisArgs]);
59+
const existingCmd = this.createOpts.Cmd || [];
60+
const baseCmd = existingCmd.length ? existingCmd : ["redis-server"];
61+
this.withCommand([...baseCmd, ...redisArgs]);
5262
}
5363
if (this.persistenceVolume) {
5464
this.withBindMounts([{ mode: "rw", source: this.persistenceVolume, target: "/data" }]);

0 commit comments

Comments
 (0)