Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow customization of data dir between database initialization and start #145

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.stream.Stream;

import static java.nio.file.StandardOpenOption.CREATE;
Expand Down Expand Up @@ -114,14 +115,14 @@ public class EmbeddedPostgres implements Closeable
PgBinaryResolver pgBinaryResolver, ProcessBuilder.Redirect errorRedirector, ProcessBuilder.Redirect outputRedirector) throws IOException
{
this(parentDirectory, dataDirectory, cleanDataDirectory, postgresConfig, localeConfig, port, connectConfig,
pgBinaryResolver, errorRedirector, outputRedirector, DEFAULT_PG_STARTUP_WAIT, null);
pgBinaryResolver, errorRedirector, outputRedirector, DEFAULT_PG_STARTUP_WAIT, null, null);
}

EmbeddedPostgres(File parentDirectory, File dataDirectory, boolean cleanDataDirectory,
Map<String, String> postgresConfig, Map<String, String> localeConfig, int port, Map<String, String> connectConfig,
PgBinaryResolver pgBinaryResolver, ProcessBuilder.Redirect errorRedirector,
ProcessBuilder.Redirect outputRedirector, Duration pgStartupWait,
File overrideWorkingDirectory) throws IOException
File overrideWorkingDirectory, Consumer<File> dataDirectoryCustomizer) throws IOException
{
this.cleanDataDirectory = cleanDataDirectory;
this.postgresConfig = new HashMap<>(postgresConfig);
Expand Down Expand Up @@ -158,6 +159,11 @@ public class EmbeddedPostgres implements Closeable
}

lock();

if (dataDirectoryCustomizer != null) {
dataDirectoryCustomizer.accept(dataDirectory);
}

startPostmaster();
}

Expand Down Expand Up @@ -495,6 +501,7 @@ public static class Builder
private final Map<String, String> connectConfig = new HashMap<>();
private PgBinaryResolver pgBinaryResolver = DefaultPostgresBinaryResolver.INSTANCE;
private Duration pgStartupWait = DEFAULT_PG_STARTUP_WAIT;
private Consumer<File> dataDirectoryCustomizer;

private ProcessBuilder.Redirect errRedirector = ProcessBuilder.Redirect.PIPE;
private ProcessBuilder.Redirect outRedirector = ProcessBuilder.Redirect.PIPE;
Expand Down Expand Up @@ -573,6 +580,11 @@ public Builder setPgBinaryResolver(PgBinaryResolver pgBinaryResolver) {
return this;
}

public Builder setDataDirectoryCustomizer(final Consumer<File> dataDirectoryCustomizer) {
this.dataDirectoryCustomizer = dataDirectoryCustomizer;
return this;
}

public EmbeddedPostgres start() throws IOException {
if (builderPort == 0)
{
Expand All @@ -583,7 +595,7 @@ public EmbeddedPostgres start() throws IOException {
}
return new EmbeddedPostgres(parentDirectory, builderDataDirectory, builderCleanDataDirectory, config,
localeConfig, builderPort, connectConfig, pgBinaryResolver, errRedirector, outRedirector,
pgStartupWait, overrideWorkingDirectory);
pgStartupWait, overrideWorkingDirectory, dataDirectoryCustomizer);
}

@Override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new variable needs to be included in the equals and hashCode method implementations. Comparing lambda functions isn't easy, so in this case, I would suggest comparing the results of getClass() calls, see the example below:

Objects.equals(dataDirectoryCustomizer != null ? dataDirectoryCustomizer.getClass() : null, builder.dataDirectoryCustomizer != null ? builder.dataDirectoryCustomizer.getClass() : null)

And similar logic in the hashCode method implementation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I would fix this. Thanx for advice!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.atomic.AtomicBoolean;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
Expand All @@ -47,10 +48,18 @@ public void testEmbeddedPg() throws Exception
@Test
public void testEmbeddedPgCreationWithNestedDataDirectory() throws Exception
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test feels a little bit contrived. Instead of this approach, it would be better to actually modify a configuration file (like postgres.conf, doesn't have to be pg_hba.conf) and then verify through SQL queries that this change is correctly applied.

Similar to this test: https://github.com/zonkyio/embedded-database-spring-test/blob/master/embedded-database-spring-test/src/test/java/io/zonky/test/db/config/ConfigurationPropertiesIntegrationTest.java

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole point of this test is to verify that lambda is called with the proper dir, not to test lambda logic or abilities—it can be anything useful between init and start, even modifications of template databases. So why do we need to check the distinct file modification effect, what do we verify by that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We verify that the entire concept works. The purpose of this pull request is to enable changes to the Postgres process configuration, not just to ensure that the lambda function is called with the correct parameters.

If you make the change below, the test will still pass, but the customizer will have no effect. This means that the test is insufficient. That’s my point.

        lock();

//        if (dataDirectoryCustomizer != null) {
//            dataDirectoryCustomizer.accept(dataDirectory);
//        }

        startPostmaster();

        if (dataDirectoryCustomizer != null) {
            dataDirectoryCustomizer.accept(dataDirectory);
        }

{
AtomicBoolean called = new AtomicBoolean(false);
Path dataDir = Files.createDirectories(tf.resolve("data-dir-parent").resolve("data-dir"));
try (EmbeddedPostgres pg = EmbeddedPostgres.builder()
.setDataDirectory(Files.createDirectories(tf.resolve("data-dir-parent").resolve("data-dir")))
.setDataDirectory(dataDir)
.setDataDirectoryCustomizer(dd -> {
called.set(true);
assertEquals(dataDir, dd.toPath());
assertTrue(Files.isRegularFile(dd.toPath().resolve("pg_hba.conf")));
})
.start()) {
// nothing to do
}
assertTrue(called.get());
}
}