diff --git a/docs/modules/redis.md b/docs/modules/redis.md index bc3205ad7..96dc9bc78 100644 --- a/docs/modules/redis.md +++ b/docs/modules/redis.md @@ -40,12 +40,6 @@ Choose an image from the [container registry](https://hub.docker.com/_/redis) an [](../../packages/modules/redis/src/redis-container.test.ts) inside_block:withPredefinedData -### Redis stack - - -[](../../packages/modules/redis/src/redis-container.test.ts) inside_block:startWithRedisStack - - ### Execute a command inside the container diff --git a/package-lock.json b/package-lock.json index 1a3b130a0..e76fcac94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15774,7 +15774,6 @@ "version": "12.2.1", "license": "MIT", "dependencies": { - "compare-versions": "^6.1.1", "testcontainers": "^12.2.1" }, "devDependencies": { diff --git a/packages/modules/kafka/src/kafka-container-7.test.ts b/packages/modules/kafka/src/kafka-container-7.test.ts index aa74fa152..1b0a0b14c 100644 --- a/packages/modules/kafka/src/kafka-container-7.test.ts +++ b/packages/modules/kafka/src/kafka-container-7.test.ts @@ -222,40 +222,10 @@ describe("KafkaContainer", { timeout: 240_000 }, () => { await assertMessageProducedAndConsumed(container); }); - it("should throw an error when using kraft and and confluence platfom below 7.0.0", async () => { - expect(() => new KafkaContainer("confluentinc/cp-kafka:6.2.14").withKraft()).toThrow( - "Provided Confluent Platform's version 6.2.14 is not supported in Kraft mode (must be 7.0.0 or above)" - ); - }); - it("should connect using kraft and custom network", async () => { await using network = await new Network().start(); await using container = await new KafkaContainer(IMAGE).withKraft().withNetwork(network).start(); await assertMessageProducedAndConsumed(container); }); - - it("should throw an error when using kraft wit sasl and confluence platfom below 7.5.0", async () => { - const kafkaContainer = new KafkaContainer("confluentinc/cp-kafka:7.4.0").withKraft().withSaslSslListener({ - port: 9094, - sasl: { - mechanism: "SCRAM-SHA-512", - user: { - name: "app-user", - password: "userPassword", - }, - }, - keystore: { - content: "fake", - passphrase: "serverKeystorePassword", - }, - truststore: { - content: "fake", - passphrase: "serverTruststorePassword", - }, - }); - await expect(() => kafkaContainer.start()).rejects.toThrow( - "Provided Confluent Platform's version 7.4.0 is not supported in Kraft mode with sasl (must be 7.5.0 or above)" - ); - }); }); diff --git a/packages/modules/kafka/src/kafka-container.ts b/packages/modules/kafka/src/kafka-container.ts index 67c937321..47f65981e 100644 --- a/packages/modules/kafka/src/kafka-container.ts +++ b/packages/modules/kafka/src/kafka-container.ts @@ -22,10 +22,6 @@ const DEFAULT_CLUSTER_ID = "4L6g3nShT-eMCtK--X86sw"; const STARTER_SCRIPT = "/tmp/testcontainers_start.sh"; const WAIT_FOR_SCRIPT_MESSAGE = "Waiting for script..."; -// https://docs.confluent.io/platform/7.0.0/release-notes/index.html#ak-raft-kraft -const MIN_KRAFT_VERSION = "7.0.0"; -const MIN_KRAFT_SASL_VERSION = "7.5.0"; - export interface SaslSslListenerOptions { sasl: SaslOptions; port: number; @@ -93,7 +89,6 @@ export class KafkaContainer extends GenericContainer { } public withKraft(): this { - this.verifyMinKraftVersion(); this.mode = KafkaMode.KRAFT; this.zooKeeperHost = undefined; this.zooKeeperPort = undefined; @@ -147,15 +142,6 @@ export class KafkaContainer extends GenericContainer { } public override async start(): Promise { - if ( - this.mode === KafkaMode.KRAFT && - this.saslSslConfig && - satisfies(this.imageName.tag, `<${MIN_KRAFT_SASL_VERSION}`) - ) { - throw new Error( - `Provided Confluent Platform's version ${this.imageName.tag} is not supported in Kraft mode with sasl (must be ${MIN_KRAFT_SASL_VERSION} or above)` - ); - } return new StartedKafkaContainer(await super.start()); } @@ -168,7 +154,7 @@ export class KafkaContainer extends GenericContainer { // exporting KAFKA_ADVERTISED_LISTENERS with the container hostname command += `export KAFKA_ADVERTISED_LISTENERS=${advertisedListeners}\n`; - if (this.mode !== KafkaMode.KRAFT || satisfies(this.imageName.tag, "<7.4.0")) { + if (this.mode !== KafkaMode.KRAFT) { // Optimization: skip the checks command += "echo '' > /etc/confluent/docker/ensure \n"; } @@ -176,9 +162,6 @@ export class KafkaContainer extends GenericContainer { if (this.saslSslConfig) { command += this.commandKraftCreateUser(this.saslSslConfig); } - if (satisfies(this.imageName.tag, "<7.4.0")) { - command += this.commandKraft(); - } } else if (this.mode === KafkaMode.EMBEDDED_ZOOKEEPER) { command += this.commandZookeeper(); } @@ -275,14 +258,6 @@ export class KafkaContainer extends GenericContainer { } } - private verifyMinKraftVersion() { - if (satisfies(this.imageName.tag, `<${MIN_KRAFT_VERSION}`)) { - throw new Error( - `Provided Confluent Platform's version ${this.imageName.tag} is not supported in Kraft mode (must be ${MIN_KRAFT_VERSION} or above)` - ); - } - } - private commandKraftCreateUser(saslOptions: SaslSslListenerOptions): string { return ( "echo 'kafka-storage format --ignore-formatted " + @@ -292,15 +267,6 @@ export class KafkaContainer extends GenericContainer { ); } - private commandKraft(): string { - let command = "sed -i '/KAFKA_ZOOKEEPER_CONNECT/d' /etc/confluent/docker/configure\n"; - command += - "echo 'kafka-storage format --ignore-formatted " + - `-t "${this.environment.CLUSTER_ID}" ` + - "-c /etc/kafka/kafka.properties' >> /etc/confluent/docker/configure\n"; - return command; - } - private commandZookeeper(): string { let command = `echo 'clientPort=${DEFAULT_ZOOKEEPER_PORT}' > zookeeper.properties\n`; command += "echo 'dataDir=/var/lib/zookeeper/data' >> zookeeper.properties\n"; diff --git a/packages/modules/mongodb/package.json b/packages/modules/mongodb/package.json index 98bdc4529..9af056a5e 100644 --- a/packages/modules/mongodb/package.json +++ b/packages/modules/mongodb/package.json @@ -32,7 +32,6 @@ "mongoose": "^9.10.4" }, "dependencies": { - "compare-versions": "^6.1.1", "testcontainers": "^12.2.1" } } diff --git a/packages/modules/mongodb/src/mongodb-container.ts b/packages/modules/mongodb/src/mongodb-container.ts index 5b4f3e60a..c9c568aa7 100644 --- a/packages/modules/mongodb/src/mongodb-container.ts +++ b/packages/modules/mongodb/src/mongodb-container.ts @@ -1,4 +1,3 @@ -import { satisfies } from "compare-versions"; import { AbstractStartedContainer, GenericContainer, type StartedTestContainer, Wait } from "testcontainers"; const MONGODB_PORT = 27017; @@ -63,12 +62,7 @@ export class MongoDBContainer extends GenericContainer { } private buildMongoEvalCommand(command: string) { - const args = []; - if (this.isV5OrLater()) { - args.push("mongosh"); - } else { - args.push("mongo", "admin"); - } + const args = ["mongosh"]; if (this.username && this.password) { args.push("-u", this.username, "-p", this.password); } @@ -77,18 +71,7 @@ export class MongoDBContainer extends GenericContainer { } private getRsInitCmd() { - if (this.isV5OrLater()) { - return `'try { rs.status(); } catch (e) { rs.initiate(); } while (db.runCommand({isMaster: 1}).ismaster==false) { sleep(100); }'`; - } - return `'try { rs.initiate(); } catch (e) {} while (db.runCommand({isMaster: 1}).ismaster==false) { sleep(100); }'`; - } - - private isV5OrLater() { - try { - return satisfies(this.imageName.tag, ">=5.0.0"); - } catch { - return false; - } + return `'try { rs.status(); } catch (e) { rs.initiate(); } while (db.runCommand({isMaster: 1}).ismaster==false) { sleep(100); }'`; } } diff --git a/packages/modules/neo4j/src/neo4j-container.ts b/packages/modules/neo4j/src/neo4j-container.ts index 8567215a2..037be614e 100755 --- a/packages/modules/neo4j/src/neo4j-container.ts +++ b/packages/modules/neo4j/src/neo4j-container.ts @@ -71,10 +71,9 @@ export class Neo4jContainer extends GenericContainer { .join(","); this.withEnvironment({ - NEO4JLABS_PLUGINS: JSON.stringify(this.plugins), // Older variant for older images. NEO4J_PLUGINS: JSON.stringify(this.plugins), NEO4J_dbms_security_procedures_unrestricted: whitelists, - NEO4J_dbms_security_procedures_whitelist: whitelists, + NEO4J_dbms_security_procedures_allowlist: whitelists, }); } return new StartedNeo4jContainer(await super.start(), this.password); diff --git a/packages/modules/redis/Dockerfile b/packages/modules/redis/Dockerfile index 32a2e71ba..4214967b7 100644 --- a/packages/modules/redis/Dockerfile +++ b/packages/modules/redis/Dockerfile @@ -1,2 +1 @@ FROM redis:8.10 -FROM redis/redis-stack-server:7.4.0-v4 \ No newline at end of file diff --git a/packages/modules/redis/src/redis-container.test.ts b/packages/modules/redis/src/redis-container.test.ts index 7f4dc5908..41e2ce8af 100644 --- a/packages/modules/redis/src/redis-container.test.ts +++ b/packages/modules/redis/src/redis-container.test.ts @@ -5,7 +5,6 @@ import { getImage } from "../../../testcontainers/src/utils/test-helper"; import { RedisContainer } from "./redis-container"; const IMAGES = ["redis:6.2.24", "redis:7.4.11", getImage(__dirname)]; -const REDISSTACK_IMAGE = getImage(__dirname, 1); describe.each(IMAGES)("RedisContainer (%s)", { concurrent: false, timeout: 240_000 }, (image) => { it.concurrent("should connect and execute set-get", async () => { @@ -161,57 +160,3 @@ describe.each(IMAGES)("RedisContainer (%s)", { concurrent: false, timeout: 240_0 fs.rmSync(sourcePath, { force: true, recursive: true }); }); }); - -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 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.Env).toEqual(["REDIS_ARGS=--loglevel verbose"]); - - const client = createClient({ url: startedContainer.getConnectionUrl() }); - await client.connect(); - - await client.set("key", "val"); - expect(await client.get("key")).toBe("val"); - - client.destroy(); - }); - - it("should start redis-stack with custom env and keeping default args", async () => { - const sourcePath = fs.mkdtempSync("redis-"); - - const container = new RedisContainer(REDISSTACK_IMAGE) - .withEnvironment({ REDIS_ARGS: "--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 --save 1 1 --appendonly yes"]); - - const client = createClient({ url: startedContainer.getConnectionUrl() }); - await client.connect(); - - await client.set("key", "val"); - expect(await client.get("key")).toBe("val"); - - client.destroy(); - fs.rmSync(sourcePath, { force: true, recursive: true }); - }); -}); diff --git a/packages/modules/redis/src/redis-container.ts b/packages/modules/redis/src/redis-container.ts index 2f1a3fe78..c019c3568 100644 --- a/packages/modules/redis/src/redis-container.ts +++ b/packages/modules/redis/src/redis-container.ts @@ -43,23 +43,9 @@ export class RedisContainer extends GenericContainer { ...(this.password ? [`--requirepass ${this.password}`] : []), ...(this.persistenceVolume ? ["--save 1 1 ", "--appendonly yes"] : []), ]; - if (this.imageName.image.includes("redis-stack")) { - const existingRedisArgs = this.environment.REDIS_ARGS ?? ""; - - // merge with filter to remove empty items - const mergedRedisArgs = [existingRedisArgs, ...redisArgs].filter(Boolean).join(" "); - - // remove existing REDIS_ARGS to avoid duplicates - this.createOpts.Env = (this.createOpts.Env || []).filter((e) => !e.startsWith("REDIS_ARGS=")); - - this.withEnvironment({ - REDIS_ARGS: mergedRedisArgs, - }).withEntrypoint(["/entrypoint.sh"]); - } else { - const existingCmd = this.createOpts.Cmd || []; - const baseCmd = existingCmd.length ? existingCmd : ["redis-server"]; - this.withCommand([...baseCmd, ...redisArgs]); - } + const existingCmd = this.createOpts.Cmd || []; + const baseCmd = existingCmd.length ? existingCmd : ["redis-server"]; + this.withCommand([...baseCmd, ...redisArgs]); if (this.persistenceVolume) { this.withBindMounts([{ mode: "rw", source: this.persistenceVolume, target: "/data" }]); }