Skip to content

Commit dc96299

Browse files
authored
Add TESTCONTAINERS_RYUK_VERBOSE setting (#941)
1 parent e7c499e commit dc96299

File tree

4 files changed

+63
-19
lines changed

4 files changed

+63
-19
lines changed

docs/configuration.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ Configuration of the Docker daemon:
3232

3333
Configuration of Testcontainers and its behaviours:
3434

35-
| Variable | Example | Description |
36-
| ------------------------------------- | -------------------------- | ---------------------------------------- |
37-
| TESTCONTAINERS_HOST_OVERRIDE | tcp://docker:2375 | Docker's host on which ports are exposed |
38-
| TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE | /var/run/docker.sock | Path to Docker's socket used by ryuk |
39-
| TESTCONTAINERS_RYUK_PRIVILEGED | true | Run ryuk as a privileged container |
40-
| TESTCONTAINERS_RYUK_DISABLED | true | Disable ryuk |
41-
| TESTCONTAINERS_RYUK_PORT | 65515 | Set ryuk host port (not recommended) |
42-
| TESTCONTAINERS_SSHD_PORT | 65515 | Set SSHd host port (not recommended) |
43-
| TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX | mycompany.com/registry | Set default image registry |
44-
| RYUK_CONTAINER_IMAGE | testcontainers/ryuk:0.11.0 | Custom image for ryuk |
45-
| SSHD_CONTAINER_IMAGE | testcontainers/sshd:1.1.0 | Custom image for SSHd |
46-
| TESTCONTAINERS_REUSE_ENABLE | true | Enable reusable containers |
35+
| Variable | Example | Description |
36+
| ------------------------------------- | -------------------------- | -------------------------------------------- |
37+
| TESTCONTAINERS_HOST_OVERRIDE | tcp://docker:2375 | Docker's host on which ports are exposed |
38+
| TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE | /var/run/docker.sock | Path to Docker's socket used by ryuk |
39+
| TESTCONTAINERS_RYUK_PRIVILEGED | true | Run ryuk as a privileged container |
40+
| TESTCONTAINERS_RYUK_DISABLED | true | Disable ryuk |
41+
| TESTCONTAINERS_RYUK_PORT | 65515 | Set ryuk host port (not recommended) |
42+
| TESTCONTAINERS_SSHD_PORT | 65515 | Set SSHd host port (not recommended) |
43+
| TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX | mycompany.com/registry | Set default image registry |
44+
| RYUK_CONTAINER_IMAGE | testcontainers/ryuk:0.11.0 | Custom image for ryuk |
45+
| SSHD_CONTAINER_IMAGE | testcontainers/sshd:1.1.0 | Custom image for SSHd |
46+
| TESTCONTAINERS_REUSE_ENABLE | true | Enable reusable containers |
47+
| TESTCONTAINERS_RYUK_VERBOSE | true | Sets RYUK_VERBOSE env var in ryuk container |
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ContainerRuntimeClient, getContainerRuntimeClient } from "../container-runtime";
2+
3+
describe("Reaper", { timeout: 120_000 }, () => {
4+
let client: ContainerRuntimeClient;
5+
6+
const getReaper = async () => await (await import("./reaper")).getReaper(client);
7+
8+
beforeEach(async () => {
9+
vi.resetModules();
10+
vitest.unstubAllEnvs();
11+
12+
client = await getContainerRuntimeClient();
13+
});
14+
15+
it("should create Reaper container without RYUK_VERBOSE env var by default", async () => {
16+
vi.spyOn(client.container, "list").mockResolvedValue([]);
17+
const reaper = await getReaper();
18+
19+
const reaperContainer = client.container.getById(reaper.containerId);
20+
const reaperContainerEnv = (await reaperContainer.inspect()).Config.Env;
21+
expect(reaperContainerEnv).not.toContain("RYUK_VERBOSE=true");
22+
expect(reaperContainerEnv).not.toContain("RYUK_VERBOSE=false");
23+
});
24+
25+
it("should propagate TESTCONTAINERS_RYUK_VERBOSE into Reaper container", async () => {
26+
vitest.stubEnv("TESTCONTAINERS_RYUK_VERBOSE", "true");
27+
28+
vi.spyOn(client.container, "list").mockResolvedValue([]);
29+
const reaper = await getReaper();
30+
31+
const reaperContainer = client.container.getById(reaper.containerId);
32+
expect((await reaperContainer.inspect()).Config.Env).toContain("RYUK_VERBOSE=true");
33+
});
34+
});

packages/testcontainers/src/reaper/reaper.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Socket } from "net";
33
import { IntervalRetry, log, RandomUuid, withFileLock } from "../common";
44
import { ContainerRuntimeClient, ImageName } from "../container-runtime";
55
import { GenericContainer } from "../generic-container/generic-container";
6-
import { LABEL_TESTCONTAINERS_SESSION_ID } from "../utils/labels";
6+
import { LABEL_TESTCONTAINERS_RYUK, LABEL_TESTCONTAINERS_SESSION_ID } from "../utils/labels";
77
import { Wait } from "../wait-strategies/wait";
88

99
export const REAPER_IMAGE = process.env["RYUK_CONTAINER_IMAGE"]
@@ -13,6 +13,8 @@ export const REAPER_IMAGE = process.env["RYUK_CONTAINER_IMAGE"]
1313
export interface Reaper {
1414
sessionId: string;
1515

16+
containerId: string;
17+
1618
addSession(sessionId: string): void;
1719

1820
addComposeProject(projectName: string): void;
@@ -28,10 +30,10 @@ export async function getReaper(client: ContainerRuntimeClient): Promise<Reaper>
2830

2931
reaper = await withFileLock("testcontainers-node.lock", async () => {
3032
const reaperContainer = await findReaperContainer(client);
31-
sessionId = reaperContainer?.Labels["org.testcontainers.session-id"] ?? new RandomUuid().nextUuid();
33+
sessionId = reaperContainer?.Labels[LABEL_TESTCONTAINERS_SESSION_ID] ?? new RandomUuid().nextUuid();
3234

3335
if (process.env.TESTCONTAINERS_RYUK_DISABLED === "true") {
34-
return new DisabledReaper(sessionId);
36+
return new DisabledReaper(sessionId, "");
3537
} else if (reaperContainer) {
3638
return await useExistingReaper(reaperContainer, sessionId, client.info.containerRuntime.host);
3739
} else {
@@ -46,7 +48,7 @@ export async function getReaper(client: ContainerRuntimeClient): Promise<Reaper>
4648
async function findReaperContainer(client: ContainerRuntimeClient): Promise<ContainerInfo | undefined> {
4749
const containers = await client.container.list();
4850
return containers.find(
49-
(container) => container.State === "running" && container.Labels["org.testcontainers.ryuk"] === "true"
51+
(container) => container.State === "running" && container.Labels[LABEL_TESTCONTAINERS_RYUK] === "true"
5052
);
5153
}
5254

@@ -60,7 +62,7 @@ async function useExistingReaper(reaperContainer: ContainerInfo, sessionId: stri
6062

6163
const socket = await connectToReaperSocket(host, reaperPort, reaperContainer.Id);
6264

63-
return new RyukReaper(sessionId, socket);
65+
return new RyukReaper(sessionId, reaperContainer.Id, socket);
6466
}
6567

6668
async function createNewReaper(sessionId: string, remoteSocketPath: string): Promise<Reaper> {
@@ -76,6 +78,8 @@ async function createNewReaper(sessionId: string, remoteSocketPath: string): Pro
7678
.withBindMounts([{ source: remoteSocketPath, target: "/var/run/docker.sock" }])
7779
.withLabels({ [LABEL_TESTCONTAINERS_SESSION_ID]: sessionId })
7880
.withWaitStrategy(Wait.forLogMessage(/.*Started.*/));
81+
if (process.env["TESTCONTAINERS_RYUK_VERBOSE"])
82+
container.withEnvironment({ RYUK_VERBOSE: process.env["TESTCONTAINERS_RYUK_VERBOSE"] });
7983

8084
if (process.env.TESTCONTAINERS_RYUK_PRIVILEGED === "true") {
8185
container.withPrivilegedMode();
@@ -89,7 +93,7 @@ async function createNewReaper(sessionId: string, remoteSocketPath: string): Pro
8993
startedContainer.getId()
9094
);
9195

92-
return new RyukReaper(sessionId, socket);
96+
return new RyukReaper(sessionId, startedContainer.getId(), socket);
9397
}
9498

9599
async function connectToReaperSocket(host: string, port: number, containerId: string): Promise<Socket> {
@@ -135,6 +139,7 @@ async function connectToReaperSocket(host: string, port: number, containerId: st
135139
class RyukReaper implements Reaper {
136140
constructor(
137141
public readonly sessionId: string,
142+
public readonly containerId: string,
138143
private readonly socket: Socket
139144
) {}
140145

@@ -148,7 +153,10 @@ class RyukReaper implements Reaper {
148153
}
149154

150155
class DisabledReaper implements Reaper {
151-
constructor(public readonly sessionId: string) {}
156+
constructor(
157+
public readonly sessionId: string,
158+
public readonly containerId: string
159+
) {}
152160

153161
addComposeProject(): void {}
154162

packages/testcontainers/src/utils/labels.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const LABEL_TESTCONTAINERS_VERSION = "org.testcontainers.version";
66
export const LABEL_TESTCONTAINERS_SESSION_ID = "org.testcontainers.session-id";
77
export const LABEL_TESTCONTAINERS_SSHD = "org.testcontainers.sshd";
88
export const LABEL_TESTCONTAINERS_CONTAINER_HASH = "org.testcontainers.container-hash";
9+
export const LABEL_TESTCONTAINERS_RYUK = "org.testcontainers.ryuk";
910

1011
export function createLabels(): Record<string, string> {
1112
return {

0 commit comments

Comments
 (0)