diff --git a/modules/mongodb/src/main/java/org/testcontainers/mongodb/MongoDBContainer.java b/modules/mongodb/src/main/java/org/testcontainers/mongodb/MongoDBContainer.java index c61be6675ba..a6b482e0769 100644 --- a/modules/mongodb/src/main/java/org/testcontainers/mongodb/MongoDBContainer.java +++ b/modules/mongodb/src/main/java/org/testcontainers/mongodb/MongoDBContainer.java @@ -10,6 +10,8 @@ import org.testcontainers.utility.MountableFile; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * Testcontainers implementation for MongoDB. @@ -45,6 +47,8 @@ public class MongoDBContainer extends GenericContainer { private boolean rsEnabled; + private final List initScripts = new ArrayList<>(); + public MongoDBContainer(@NonNull String dockerImageName) { this(DockerImageName.parse(dockerImageName)); } @@ -61,6 +65,12 @@ protected void containerIsStarting(InspectContainerResponse containerInfo) { if (this.shardingEnabled) { copyFileToContainer(MountableFile.forClasspathResource("/sharding.sh", 0777), STARTER_SCRIPT); } + for (int i = 0; i < initScripts.size(); i++) { + copyFileToContainer(initScripts.get(i), "/docker-entrypoint-initdb.d/init-" + i + ".js"); + } + if (this.rsEnabled && !initScripts.isEmpty()) { + waitingFor(Wait.forLogMessage("(?i).*waiting for connections.*", 2)); + } } @Override @@ -161,6 +171,18 @@ public MongoDBContainer withReplicaSet() { return this; } + /** + * Adds a JavaScript init script to be executed by MongoDB on first startup. + * Scripts are copied to {@code /docker-entrypoint-initdb.d/} and run in the order they were added. + * + * @param initScript the script to copy into the container + * @return this + */ + public MongoDBContainer withInitScript(MountableFile initScript) { + this.initScripts.add(initScript); + return this; + } + /** * Enables sharding on the cluster * diff --git a/modules/mongodb/src/test/java/org/testcontainers/mongodb/MongoDBContainerTest.java b/modules/mongodb/src/test/java/org/testcontainers/mongodb/MongoDBContainerTest.java index 816243d769e..94c4350d0ca 100644 --- a/modules/mongodb/src/test/java/org/testcontainers/mongodb/MongoDBContainerTest.java +++ b/modules/mongodb/src/test/java/org/testcontainers/mongodb/MongoDBContainerTest.java @@ -1,6 +1,10 @@ package org.testcontainers.mongodb; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import org.bson.Document; import org.junit.jupiter.api.Test; +import org.testcontainers.utility.MountableFile; import static org.assertj.core.api.Assertions.assertThat; @@ -38,4 +42,37 @@ void shouldTestDatabaseName() { assertThat(mongoDBContainer.getReplicaSetUrl(databaseName)).endsWith(databaseName); } } + + @Test + void shouldRunInitScriptWithReplicaSet() { + try ( + MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.0.10") + .withReplicaSet() + .withInitScript(MountableFile.forClasspathResource("init-db.js")) + ) { + mongoDBContainer.start(); + + try (MongoClient client = MongoClients.create(mongoDBContainer.getReplicaSetUrl("testdb"))) { + Document doc = client.getDatabase("testdb").getCollection("items").find().first(); + assertThat(doc).isNotNull(); + assertThat(doc.getString("name")).isEqualTo("testcontainers"); + } + } + } + + @Test + void shouldRunInitScriptWithoutReplicaSet() { + try ( + MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.0.10") + .withInitScript(MountableFile.forClasspathResource("init-db.js")) + ) { + mongoDBContainer.start(); + + try (MongoClient client = MongoClients.create(mongoDBContainer.getConnectionString())) { + Document doc = client.getDatabase("testdb").getCollection("items").find().first(); + assertThat(doc).isNotNull(); + assertThat(doc.getString("name")).isEqualTo("testcontainers"); + } + } + } } diff --git a/modules/mongodb/src/test/resources/init-db.js b/modules/mongodb/src/test/resources/init-db.js new file mode 100644 index 00000000000..ec3efeb6b50 --- /dev/null +++ b/modules/mongodb/src/test/resources/init-db.js @@ -0,0 +1,2 @@ +db = db.getSiblingDB('testdb'); +db.items.insertOne({ name: 'testcontainers' });