@testcontainers/redpanda
Version:
Redpanda module for Testcontainers
94 lines (93 loc) • 4.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StartedRedpandaContainer = exports.RedpandaContainer = void 0;
const fs_1 = __importDefault(require("fs"));
const handlebars_1 = require("handlebars");
const path_1 = __importDefault(require("path"));
const testcontainers_1 = require("testcontainers");
const REDPANDA_PORT = 9092;
const REDPANDA_ADMIN_PORT = 9644;
const SCHEMA_REGISTRY_PORT = 8081;
const REST_PROXY_PORT = 8082;
const STARTER_SCRIPT = "/testcontainers_start.sh";
const WAIT_FOR_SCRIPT_MESSAGE = "Waiting for script...";
class RedpandaContainer extends testcontainers_1.GenericContainer {
originalWaitStrategy;
constructor(image) {
super(image);
this.withExposedPorts(REDPANDA_PORT, REDPANDA_ADMIN_PORT, SCHEMA_REGISTRY_PORT, REST_PROXY_PORT)
.withUser("root:root")
.withWaitStrategy(testcontainers_1.Wait.forLogMessage("Successfully started Redpanda!"))
.withCopyFilesToContainer([
{
source: path_1.default.join(__dirname, "assets", "bootstrap.yaml"),
target: "/etc/redpanda/.bootstrap.yaml",
},
]);
this.originalWaitStrategy = this.waitStrategy;
}
async start() {
return new StartedRedpandaContainer(await super.start());
}
async beforeContainerCreated() {
// Change the wait strategy to wait for a log message from a fake starter script
// so that we can put a real starter script in place at that moment
this.originalWaitStrategy = this.waitStrategy;
this.waitStrategy = testcontainers_1.Wait.forLogMessage(WAIT_FOR_SCRIPT_MESSAGE);
this.withEntrypoint(["sh"]);
this.withCommand([
"-c",
`echo '${WAIT_FOR_SCRIPT_MESSAGE}'; while [ ! -f ${STARTER_SCRIPT} ]; do sleep 0.1; done; ${STARTER_SCRIPT}`,
]);
}
async containerStarted(container, inspectResult) {
const command = "#!/bin/bash\nrpk redpanda start --mode dev-container --smp=1 --memory=1G";
await container.copyContentToContainer([{ content: command, target: STARTER_SCRIPT, mode: 0o777 }]);
await container.copyContentToContainer([
{
content: this.renderRedpandaFile(container.getHost(), container.getMappedPort(REDPANDA_PORT)),
target: "/etc/redpanda/redpanda.yaml",
},
]);
const client = await (0, testcontainers_1.getContainerRuntimeClient)();
const dockerContainer = client.container.getById(container.getId());
const dockerInspectResult = await client.container.inspect(dockerContainer);
const boundPorts = testcontainers_1.BoundPorts.fromInspectResult(client.info.containerRuntime.hostIps, inspectResult).filter(this.exposedPorts);
const waitStrategy = await this.selectWaitStrategy(client, dockerInspectResult, this.originalWaitStrategy);
if (this.startupTimeoutMs !== undefined) {
waitStrategy.withStartupTimeout(this.startupTimeoutMs);
}
await (0, testcontainers_1.waitForContainer)(client, dockerContainer, waitStrategy, boundPorts);
}
renderRedpandaFile(host, port) {
const template = (0, handlebars_1.compile)(fs_1.default.readFileSync(path_1.default.join(__dirname, "assets", "redpanda.yaml.hbs"), "utf-8"));
return template({
kafkaApi: {
advertisedHost: host,
advertisedPort: port,
},
});
}
}
exports.RedpandaContainer = RedpandaContainer;
class StartedRedpandaContainer extends testcontainers_1.AbstractStartedContainer {
constructor(startedTestContainer) {
super(startedTestContainer);
}
getBootstrapServers() {
return `${this.getHost()}:${this.getMappedPort(REDPANDA_PORT)}`;
}
getSchemaRegistryAddress() {
return `http://${this.getHost()}:${this.getMappedPort(SCHEMA_REGISTRY_PORT)}`;
}
getAdminAddress() {
return `http://${this.getHost()}:${this.getMappedPort(REDPANDA_ADMIN_PORT)}`;
}
getRestProxyAddress() {
return `http://${this.getHost()}:${this.getMappedPort(REST_PROXY_PORT)}`;
}
}
exports.StartedRedpandaContainer = StartedRedpandaContainer;