Skip to content

Commit 7135fa0

Browse files
committed
feat: easier configuration of the postgres command
1 parent 165c724 commit 7135fa0

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
55
import org.testcontainers.utility.DockerImageName;
66

7+
import lombok.NonNull;
8+
79
import java.time.Duration;
810
import java.time.temporal.ChronoUnit;
11+
import java.util.Map;
12+
import java.util.HashMap;
913
import java.util.Set;
14+
import java.util.stream.Collectors;
1015

1116
/**
1217
* Testcontainers implementation for PostgreSQL.
@@ -39,7 +44,7 @@ public class PostgreSQLContainer<SELF extends PostgreSQLContainer<SELF>> extends
3944

4045
private String password = "test";
4146

42-
private static final String FSYNC_OFF_OPTION = "fsync=off";
47+
private final Map<String, String> CONFIG_OPTIONS = new HashMap<>(Map.of("fsync", "off"));
4348

4449
/**
4550
* @deprecated use {@link #PostgreSQLContainer(DockerImageName)} or {@link #PostgreSQLContainer(String)} instead
@@ -62,7 +67,6 @@ public PostgreSQLContainer(final DockerImageName dockerImageName) {
6267
.withRegEx(".*database system is ready to accept connections.*\\s")
6368
.withTimes(2)
6469
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS));
65-
this.setCommand("postgres", "-c", FSYNC_OFF_OPTION);
6670

6771
addExposedPort(POSTGRESQL_PORT);
6872
}
@@ -85,6 +89,35 @@ protected void configure() {
8589
addEnv("POSTGRES_DB", databaseName);
8690
addEnv("POSTGRES_USER", username);
8791
addEnv("POSTGRES_PASSWORD", password);
92+
93+
// If user never configured a command, and CONFIG_OPTIONS exist, then generate command
94+
if (this.getContainerDef().getCommand().length == 0 && CONFIG_OPTIONS.size() > 0) {
95+
this.setCommand("postgres -c " + CONFIG_OPTIONS.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(" -c ")));
96+
}
97+
}
98+
99+
/**
100+
* Collects a set of configurations that will be set as a startup command of the PostgreSQL container.
101+
* Note: configuration options will be ignored if a command is set using either withCommand() or setCommand()
102+
*
103+
* <pre>
104+
* For example:
105+
* postgresql.withConfigOption("max_prepared_transactions", "5").withConfigOption("log_destination", "'syslog'");
106+
*
107+
* Will result in the startup command:
108+
* postgres -c max_prepared_transactions=5 -c log_destination='syslog'
109+
* </pre>
110+
*
111+
* @param key The configuration name
112+
* @param value the configuration value
113+
* @return self
114+
*/
115+
public SELF withConfigOption(@NonNull String key, @NonNull String value) {
116+
if(!key.matches("[a-zA-Z0-9_]")) {
117+
throw new IllegalArgumentException("PostgreSQL configuration option with key: " + key + " is an invalid configuration string.");
118+
}
119+
CONFIG_OPTIONS.put(key, value);
120+
return self();
88121
}
89122

90123
@Override

modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ public void testUnsetCommand() throws SQLException {
6060
}
6161
}
6262

63+
@Test
64+
public void testWithConfigOption() throws SQLException {
65+
try (
66+
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(PostgreSQLTestImages.POSTGRES_TEST_IMAGE)
67+
.withConfigOption("max_connections", "42")
68+
) {
69+
postgres.start();
70+
71+
ResultSet resultSet = performQuery(postgres, "SELECT current_setting('max_connections')");
72+
String result = resultSet.getString(1);
73+
assertThat(result).as("max_connections should be overriden").isEqualTo("42");
74+
75+
// Ensure default config
76+
resultSet = performQuery(postgres, "SELECT current_setting('fsync')");
77+
result = resultSet.getString(1);
78+
assertThat(result).as("fsync should not overriden").isEqualTo("off");
79+
}
80+
}
81+
6382
@Test
6483
public void testMissingInitScript() {
6584
try (

0 commit comments

Comments
 (0)