nextDatabase = new SynchronousQueue<>();
- PrepPipeline(EmbeddedPostgres pg)
- {
+ PrepPipeline(EmbeddedPostgres pg) {
this.pg = pg;
}
- PrepPipeline start()
- {
+ PrepPipeline start() {
final ExecutorService service = Executors.newSingleThreadExecutor(r -> {
final Thread t = new Thread(r);
t.setDaemon(true);
@@ -180,12 +190,11 @@ PrepPipeline start()
return this;
}
- DbInfo getNextDb() throws SQLException
- {
+ DbInfo getNextDb() throws SQLException {
try {
final DbInfo next = nextDatabase.take();
if (next.ex != null) {
- throw next.ex;
+ throw new SQLException(next.ex);
}
return next;
} catch (final InterruptedException e) {
@@ -195,19 +204,18 @@ DbInfo getNextDb() throws SQLException
}
@Override
- public void run()
- {
+ public void run() {
while (true) {
- final String newDbName = RandomStringUtils.randomAlphabetic(12).toLowerCase(Locale.ENGLISH);
+ final String newDbName = "pge_" + RandomStringUtils.randomAlphabetic(12).toLowerCase(Locale.ENGLISH);
SQLException failure = null;
try {
- create(pg.getPostgresDatabase(), newDbName, "postgres");
+ create(pg.getPostgresDatabase(), newDbName, pg.getUserName());
} catch (SQLException e) {
failure = e;
}
try {
if (failure == null) {
- nextDatabase.put(DbInfo.ok(newDbName, pg.getPort(), "postgres"));
+ nextDatabase.put(DbInfo.ok(pg.getJdbcUrl(newDbName), pg.getUserName(), pg.getPassword(), pg.getHost(), pg.getPort()));
} else {
nextDatabase.put(DbInfo.error(failure));
}
@@ -219,9 +227,7 @@ public void run()
}
}
- @SuppressFBWarnings({"OBL_UNSATISFIED_OBLIGATION", "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"})
- private static void create(final DataSource connectDb, final String dbName, final String userName) throws SQLException
- {
+ private static void create(final DataSource connectDb, final String dbName, final String userName) throws SQLException {
if (dbName == null) {
throw new IllegalStateException("the database name must not be null!");
}
@@ -230,7 +236,8 @@ private static void create(final DataSource connectDb, final String dbName, fina
}
try (Connection c = connectDb.getConnection();
- PreparedStatement stmt = c.prepareStatement(String.format("CREATE DATABASE %s OWNER %s ENCODING = 'utf8'", dbName, userName))) {
+ PreparedStatement stmt = c.prepareStatement(String.format("CREATE DATABASE %s OWNER %s ENCODING = 'utf8'", dbName, userName))) {
+ LOG.debug("Statement: {}", stmt);
stmt.execute();
}
}
@@ -265,34 +272,40 @@ public int hashCode() {
}
}
- public static class DbInfo
- {
- public static DbInfo ok(final String dbName, final int port, final String user) {
- return new DbInfo(dbName, port, user, null);
+ public static class DbInfo {
+ public static DbInfo ok(final String url, final String user, final String password, final String host, final int port) {
+ return new DbInfo(url, user, password, null, host, port);
}
public static DbInfo error(SQLException e) {
- return new DbInfo(null, -1, null, e);
+ return new DbInfo(null, null, null, e, null, -1);
}
- private final String dbName;
- private final int port;
+ private final String url;
private final String user;
+ private final String password;
private final SQLException ex;
+ private final String host;
+ private final int port;
- private DbInfo(final String dbName, final int port, final String user, final SQLException e) {
- this.dbName = dbName;
- this.port = port;
+ private DbInfo(final String url, final String user, final String password, final SQLException e, final String host, final int port) {
+ this.url = url;
this.user = user;
- this.ex = null;
+ this.password = password;
+ this.ex = e;
+ this.host = host;
+ this.port = port;
+ }
+
+ public String getHost() {
+ return host;
}
public int getPort() {
return port;
}
-
- public String getDbName() {
- return dbName;
+ public String getUrl() {
+ return url;
}
public String getUser() {
@@ -306,5 +319,9 @@ public SQLException getException() {
public boolean isSuccess() {
return ex == null;
}
+
+ public String getPassword() {
+ return password;
+ }
}
}
diff --git a/src/main/java/com/opentable/db/postgres/embedded/ProcessOutputLogger.java b/src/main/java/com/opentable/db/postgres/embedded/ProcessOutputLogger.java
deleted file mode 100644
index b1c989ae..00000000
--- a/src/main/java/com/opentable/db/postgres/embedded/ProcessOutputLogger.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.opentable.db.postgres.embedded;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Field;
-import java.nio.charset.StandardCharsets;
-import java.util.Optional;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import org.slf4j.Logger;
-
-/**
- * Read standard output of process and write lines to given {@link Logger} as INFO;
- * depends on {@link ProcessBuilder#redirectErrorStream(boolean)} being set to {@code true} (since only stdout is
- * read).
- *
- *
- * The use of the input stream is threadsafe since it's used only in a single thread—the one launched by this
- * code.
- */
-final class ProcessOutputLogger implements Runnable {
- @SuppressWarnings("PMD.LoggerIsNotStaticFinal")
- private final Logger logger;
- private final Process process;
- private final BufferedReader reader;
-
- private ProcessOutputLogger(final Logger logger, final Process process) {
- this.logger = logger;
- this.process = process;
- reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
- }
-
- @Override
- public void run() {
- try {
- while (process.isAlive()) {
- try {
- Optional.ofNullable(reader.readLine()).ifPresent(logger::info);
- } catch (final IOException e) {
- logger.error("while reading output", e);
- return;
- }
- }
- } finally {
- try {
- reader.close();
- } catch (final IOException e) {
- logger.error("caught i/o exception closing reader", e);
- }
- }
- }
-
- static void logOutput(final Logger logger, final Process process) {
- final Thread t = new Thread(new ProcessOutputLogger(logger, process));
- t.setName("log:" + describe(process));
- t.setDaemon(true);
- t.start();
- }
-
- @SuppressFBWarnings("REC_CATCH_EXCEPTION") // expected and ignored
- private static String describe(Process process) {
- try { // java 9+
- return String.format("pid(%s)", MethodHandles.lookup().findVirtual(Process.class, "pid", MethodType.methodType(long.class)).invoke(process));
- } catch (Throwable ignored) {} // NOPMD since MethodHandles.invoke throws Throwable
- try { // openjdk / oraclejdk 8
- final Field pid = process.getClass().getDeclaredField("pid");
- pid.setAccessible(true);
- return String.format("pid(%s)", pid.getInt(process));
- } catch (Exception ignored) {}
- return process.toString(); // anything goes wrong
- }
-}
diff --git a/src/main/java/com/opentable/db/postgres/embedded/UncompressBundleDirectoryResolver.java b/src/main/java/com/opentable/db/postgres/embedded/UncompressBundleDirectoryResolver.java
deleted file mode 100644
index 58e64c80..00000000
--- a/src/main/java/com/opentable/db/postgres/embedded/UncompressBundleDirectoryResolver.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.opentable.db.postgres.embedded;
-
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.LOCK_FILE_NAME;
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.extractTxz;
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.getArchitecture;
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.getOS;
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.getWorkingDirectory;
-import static com.opentable.db.postgres.embedded.EmbeddedUtil.mkdirs;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.channels.FileLock;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class UncompressBundleDirectoryResolver implements PgDirectoryResolver {
-
- private static volatile UncompressBundleDirectoryResolver DEFAULT_INSTANCE;
-
- public static synchronized UncompressBundleDirectoryResolver getDefault() {
- if (DEFAULT_INSTANCE == null) {
- DEFAULT_INSTANCE = new UncompressBundleDirectoryResolver(new BundledPostgresBinaryResolver());
- }
- return DEFAULT_INSTANCE;
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(EmbeddedPostgres.class);
- private final Lock prepareBinariesLock = new ReentrantLock();
-
- private final PgBinaryResolver pgBinaryResolver;
-
- public UncompressBundleDirectoryResolver(PgBinaryResolver pgBinaryResolver) {
- this.pgBinaryResolver = pgBinaryResolver;
- }
-
- private final Map prepareBinaries = new HashMap<>();
-
- @Override
- public File getDirectory(Optional overrideWorkingDirectory) {
- prepareBinariesLock.lock();
- try {
- if (prepareBinaries.containsKey(pgBinaryResolver) && prepareBinaries.get(pgBinaryResolver).exists()) {
- return prepareBinaries.get(pgBinaryResolver);
- }
-
- final String system = getOS();
- final String machineHardware = getArchitecture();
-
- LOG.info("Detected a {} {} system", system, machineHardware);
- File pgDir;
- final InputStream pgBinary; // NOPMD
- try {
- pgBinary = pgBinaryResolver.getPgBinary(system, machineHardware);
- } catch (final IOException e) {
- throw new ExceptionInInitializerError(e);
- }
-
- if (pgBinary == null) {
- throw new IllegalStateException("No Postgres binary found for " + system + " / " + machineHardware);
- }
-
- try (DigestInputStream pgArchiveData = new DigestInputStream(pgBinary, MessageDigest.getInstance("MD5"));
- ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
- IOUtils.copy(pgArchiveData, baos);
- pgArchiveData.close();
-
- String pgDigest = Hex.encodeHexString(pgArchiveData.getMessageDigest().digest());
- File workingDirectory = overrideWorkingDirectory.isPresent() ? overrideWorkingDirectory.get()
- : getWorkingDirectory();
- pgDir = new File(workingDirectory, String.format("PG-%s", pgDigest));
-
- mkdirs(pgDir);
- final File unpackLockFile = new File(pgDir, LOCK_FILE_NAME);
- final File pgDirExists = new File(pgDir, ".exists");
-
- if (!pgDirExists.exists()) {
- try (FileOutputStream lockStream = new FileOutputStream(unpackLockFile);
- FileLock unpackLock = lockStream.getChannel().tryLock()) {
- if (unpackLock != null) {
- try {
- if (pgDirExists.exists()) {
- throw new IllegalStateException(
- "unpack lock acquired but .exists file is present " + pgDirExists);
- }
- LOG.info("Extracting Postgres...");
- try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
- extractTxz(bais, pgDir.getPath());
- }
- if (!pgDirExists.createNewFile()) {
- throw new IllegalStateException("couldn't make .exists file " + pgDirExists);
- }
- } catch (Exception e) {
- LOG.error("while unpacking Postgres", e);
- }
- } else {
- // the other guy is unpacking for us.
- int maxAttempts = 60;
- while (!pgDirExists.exists() && --maxAttempts > 0) { // NOPMD
- Thread.sleep(1000L);
- }
- if (!pgDirExists.exists()) {
- throw new IllegalStateException(
- "Waited 60 seconds for postgres to be unpacked but it never finished!");
- }
- }
- } finally {
- if (unpackLockFile.exists() && !unpackLockFile.delete()) {
- LOG.error("could not remove lock file {}", unpackLockFile.getAbsolutePath());
- }
- }
- }
- } catch (final IOException | NoSuchAlgorithmException e) {
- throw new ExceptionInInitializerError(e);
- } catch (final InterruptedException ie) {
- Thread.currentThread().interrupt();
- throw new ExceptionInInitializerError(ie);
- }
- prepareBinaries.put(pgBinaryResolver, pgDir);
- LOG.info("Postgres binaries at {}", pgDir);
- return pgDir;
- } finally {
- prepareBinariesLock.unlock();
- }
- }
-}
diff --git a/src/main/java/com/opentable/db/postgres/junit/EmbeddedPostgresRules.java b/src/main/java/com/opentable/db/postgres/junit/EmbeddedPostgresRules.java
index a590fc5b..89e8294f 100644
--- a/src/main/java/com/opentable/db/postgres/junit/EmbeddedPostgresRules.java
+++ b/src/main/java/com/opentable/db/postgres/junit/EmbeddedPostgresRules.java
@@ -13,7 +13,6 @@
*/
package com.opentable.db.postgres.junit;
-import org.junit.rules.TestRule;
import com.opentable.db.postgres.embedded.DatabasePreparer;
@@ -23,14 +22,17 @@ private EmbeddedPostgresRules() {
/**
* Create a vanilla Postgres cluster -- just initialized, no customizations applied.
+ * @return SingleInstancePostgresRule
*/
public static SingleInstancePostgresRule singleInstance() {
return new SingleInstancePostgresRule();
}
/**
- * Returns a {@link TestRule} to create a Postgres cluster, shared amongst all test cases in this JVM.
+ * Returns a {@link PreparedDbRule} to create a Postgres cluster, shared amongst all test cases in this JVM.
* The rule contributes Config switches to configure each test case to get its own database.
+ * @param preparer DatabasePreparer
+ * @return SingleInstancePostgresRule
*/
public static PreparedDbRule preparedDatabase(DatabasePreparer preparer)
{
diff --git a/src/main/java/com/opentable/db/postgres/junit5/EmbeddedPostgresExtension.java b/src/main/java/com/opentable/db/postgres/junit5/EmbeddedPostgresExtension.java
index 7c446aab..9165a1bc 100644
--- a/src/main/java/com/opentable/db/postgres/junit5/EmbeddedPostgresExtension.java
+++ b/src/main/java/com/opentable/db/postgres/junit5/EmbeddedPostgresExtension.java
@@ -14,7 +14,6 @@
package com.opentable.db.postgres.junit5;
import com.opentable.db.postgres.embedded.DatabasePreparer;
-import org.junit.rules.TestRule;
public final class EmbeddedPostgresExtension {
@@ -22,14 +21,17 @@ private EmbeddedPostgresExtension() {}
/**
* Create a vanilla Postgres cluster -- just initialized, no customizations applied.
+ * @return SingleInstancePostgresExtension
*/
public static SingleInstancePostgresExtension singleInstance() {
return new SingleInstancePostgresExtension();
}
/**
- * Returns a {@link TestRule} to create a Postgres cluster, shared amongst all test cases in this JVM.
+ * Returns a {@link PreparedDbExtension} to create a Postgres cluster, shared amongst all test cases in this JVM.
* The rule contributes Config switches to configure each test case to get its own database.
+ * @return PreparedDBExtension
+ * @param preparer DatabasePreparer
*/
public static PreparedDbExtension preparedDatabase(DatabasePreparer preparer)
{
diff --git a/src/main/java/com/opentable/db/postgres/junit5/LegacySingleInstancePostgresExtension.java b/src/main/java/com/opentable/db/postgres/junit5/LegacySingleInstancePostgresExtension.java
new file mode 100644
index 00000000..dc8c9dcd
--- /dev/null
+++ b/src/main/java/com/opentable/db/postgres/junit5/LegacySingleInstancePostgresExtension.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opentable.db.postgres.junit5;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+
+import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
+import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import com.opentable.db.postgres.embedded.EmbeddedPostgres;
+
+/*
+ This is a legacy version of this class that implements the old lifecycle behavior.
+ Late in our testing for 1.0, we ran into a test case where the new EmbeddedPostgresExtension
+ failed to work properly.
+
+ This is DEPRECATED until we figure out what's going on ;) and can be removed
+ in a minor version. Until then this is a workaround should anyone else run into this.
+
+ */
+@Deprecated
+public class LegacySingleInstancePostgresExtension implements AfterTestExecutionCallback, BeforeTestExecutionCallback {
+
+ private volatile EmbeddedPostgres epg;
+ private volatile Connection postgresConnection;
+ private final List> builderCustomizers = new CopyOnWriteArrayList<>();
+
+ @Override
+ public void beforeTestExecution(ExtensionContext context) throws Exception {
+ epg = pg();
+ postgresConnection = epg.getPostgresDatabase().getConnection();
+ }
+
+ private EmbeddedPostgres pg() throws IOException {
+ final EmbeddedPostgres.Builder builder = EmbeddedPostgres.builder();
+ builderCustomizers.forEach(c -> c.accept(builder));
+ return builder.start();
+ }
+
+ public LegacySingleInstancePostgresExtension customize(Consumer customizer) {
+ if (epg != null) {
+ throw new AssertionError("already started");
+ }
+ builderCustomizers.add(customizer);
+ return this;
+ }
+
+ public EmbeddedPostgres getEmbeddedPostgres()
+ {
+ EmbeddedPostgres epg = this.epg;
+ if (epg == null) {
+ throw new AssertionError("JUnit test not started yet!");
+ }
+ return epg;
+ }
+
+ @Override
+ public void afterTestExecution(ExtensionContext context) {
+ try {
+ postgresConnection.close();
+ } catch (SQLException e) {
+ throw new AssertionError(e);
+ }
+ try {
+ epg.close();
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/src/main/java/com/opentable/db/postgres/junit5/SingleInstancePostgresExtension.java b/src/main/java/com/opentable/db/postgres/junit5/SingleInstancePostgresExtension.java
index 6797d418..9a5caf04 100644
--- a/src/main/java/com/opentable/db/postgres/junit5/SingleInstancePostgresExtension.java
+++ b/src/main/java/com/opentable/db/postgres/junit5/SingleInstancePostgresExtension.java
@@ -13,11 +13,6 @@
*/
package com.opentable.db.postgres.junit5;
-import com.opentable.db.postgres.embedded.EmbeddedPostgres;
-import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
-import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
@@ -25,7 +20,34 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
-public class SingleInstancePostgresExtension implements AfterTestExecutionCallback, BeforeTestExecutionCallback {
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import com.opentable.db.postgres.embedded.EmbeddedPostgres;
+
+/*
+ Implementing AfterTestExecutionCallback and BeforeTestExecutionCallback does not work if you want to use the EmbeddedPostgres in a @BeforeEach
+ or @BeforeAll method because it isn't instantiated then.
+
+ The order in which the methods are called with BeforeTestExecutionCallback is:
+ @BeforeAll method of the test class
+ @BeforeEach method of the test class
+ beforeTestExecution(ExtensionContext) method of
+ SingleInstancePostgresExtension
+ Actual test method of the test class
+
+ And using BeforeAllCallback instead it will be:
+ beforeAll(ExtensionContext) method of SingleInstancePostgresExtension
+ @BeforeAll method of the test class
+ @BeforeEach method of the test class
+ Actual test method of the test class
+
+ See: https://github.com/opentable/otj-pg-embedded/pull/138.
+ Credits: https://github.com/qutax
+
+ */
+public class SingleInstancePostgresExtension implements AfterAllCallback, BeforeAllCallback {
private volatile EmbeddedPostgres epg;
private volatile Connection postgresConnection;
@@ -34,7 +56,7 @@ public class SingleInstancePostgresExtension implements AfterTestExecutionCallba
SingleInstancePostgresExtension() { }
@Override
- public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
+ public void beforeAll(ExtensionContext context) throws Exception {
epg = pg();
postgresConnection = epg.getPostgresDatabase().getConnection();
}
@@ -63,7 +85,7 @@ public EmbeddedPostgres getEmbeddedPostgres()
}
@Override
- public void afterTestExecution(ExtensionContext extensionContext) {
+ public void afterAll(ExtensionContext context) {
try {
postgresConnection.close();
} catch (SQLException e) {
diff --git a/src/test/java/com/opentable/db/postgres/embedded/EmbeddedPostgresTest.java b/src/test/java/com/opentable/db/postgres/embedded/EmbeddedPostgresTest.java
index f448a36d..5c91c1dd 100644
--- a/src/test/java/com/opentable/db/postgres/embedded/EmbeddedPostgresTest.java
+++ b/src/test/java/com/opentable/db/postgres/embedded/EmbeddedPostgresTest.java
@@ -20,13 +20,19 @@
import java.io.IOException;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
+import javax.sql.DataSource;
+
import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.testcontainers.utility.DockerImageName;
public class EmbeddedPostgresTest
{
@@ -46,15 +52,6 @@ public void testEmbeddedPg() throws Exception
}
}
- @Test
- public void testEmbeddedPgCreationWithNestedDataDirectory() throws Exception
- {
- try (EmbeddedPostgres pg = EmbeddedPostgres.builder()
- .setDataDirectory(tf.newFolder("data-dir-parent") + "/data-dir")
- .start()) {
- // nothing to do
- }
- }
@Test
public void testValidLocaleSettingsPassthrough() throws IOException {
@@ -81,4 +78,71 @@ public void testValidLocaleSettingsPassthrough() throws IOException {
fail("Failed to set locale settings: " + e.getLocalizedMessage());
}
}
+
+ @Test
+ public void testImageOptions() {
+ // Ugly hack, since OT already has this defined as an ENV VAR, which can't really be cleared
+ Assume.assumeTrue(System.getenv(EmbeddedPostgres.ENV_DOCKER_PREFIX) == null);
+ System.clearProperty(EmbeddedPostgres.ENV_DOCKER_PREFIX);
+ System.clearProperty(EmbeddedPostgres.ENV_DOCKER_IMAGE);
+
+ DockerImageName defaultImage = EmbeddedPostgres.builder().getDefaultImage();
+ assertEquals(EmbeddedPostgres.DOCKER_DEFAULT_IMAGE_NAME.withTag(EmbeddedPostgres.DOCKER_DEFAULT_TAG).toString(), defaultImage.toString());
+
+ System.setProperty(EmbeddedPostgres.ENV_DOCKER_PREFIX, "dockerhub.otenv.com/");
+ defaultImage = EmbeddedPostgres.builder().getDefaultImage();
+ assertEquals("dockerhub.otenv.com/" + EmbeddedPostgres.DOCKER_DEFAULT_IMAGE_NAME.getUnversionedPart() + ":" + EmbeddedPostgres.DOCKER_DEFAULT_TAG, defaultImage.toString());
+
+ System.clearProperty(EmbeddedPostgres.ENV_DOCKER_PREFIX);
+ System.setProperty(EmbeddedPostgres.ENV_DOCKER_IMAGE, "dockerhub.otenv.com/ot-pg:14-latest");
+
+ EmbeddedPostgres.Builder b = EmbeddedPostgres.builder();
+ defaultImage = b.getDefaultImage();
+ assertEquals("dockerhub.otenv.com/ot-pg:14-latest", defaultImage.toString());
+ assertEquals("dockerhub.otenv.com/ot-pg:14-latest", b.getImage().toString());
+ b.setImage(DockerImageName.parse("foo").withTag("15-latest"));
+ assertEquals("foo:15-latest", b.getImage().toString());
+
+ System.clearProperty(EmbeddedPostgres.ENV_DOCKER_IMAGE);
+ }
+
+ @Test
+ public void testDatabaseName() throws IOException, SQLException {
+ EmbeddedPostgres db = EmbeddedPostgres.builder().start();
+ try {
+ testSpecificDatabaseName(db, EmbeddedPostgres.POSTGRES);
+ } finally {
+ db.close();
+ }
+ db = EmbeddedPostgres.builder().setDatabaseName("mike").start();
+ try {
+ testSpecificDatabaseName(db, "mike");
+ } finally {
+ db.close();
+ }
+
+ }
+
+ @Test
+ public void testTemplateDatabase() throws IOException, SQLException {
+ EmbeddedPostgres db = EmbeddedPostgres.builder().start();
+ try {
+ testSpecificDatabaseName(db.getTemplateDatabase(), db, "template1");
+ } finally {
+ db.close();
+ }
+ }
+
+ private void testSpecificDatabaseName(EmbeddedPostgres db, String expectedName) throws SQLException, IOException {
+ testSpecificDatabaseName(db.getPostgresDatabase(), db,expectedName);
+ }
+ private void testSpecificDatabaseName(DataSource dataSource, EmbeddedPostgres db, String expectedName) throws IOException, SQLException {
+ try (Connection c = dataSource.getConnection()) {
+ try (Statement statement = c.createStatement();
+ ResultSet resultSet = statement.executeQuery("SELECT current_database()")) {
+ resultSet.next();
+ assertEquals(expectedName, resultSet.getString(1));
+ }
+ }
+ }
}
diff --git a/src/test/java/com/opentable/db/postgres/embedded/LocalDirectoryPostgresTest.java b/src/test/java/com/opentable/db/postgres/embedded/LocalDirectoryPostgresTest.java
index 7f4d80bc..54a9cfc3 100644
--- a/src/test/java/com/opentable/db/postgres/embedded/LocalDirectoryPostgresTest.java
+++ b/src/test/java/com/opentable/db/postgres/embedded/LocalDirectoryPostgresTest.java
@@ -27,13 +27,12 @@
public class LocalDirectoryPostgresTest {
- private static final File USR_LOCAL = new File("/usr/local");
private static final File USR_LOCAL_BIN_POSTGRES = new File("/usr/local/bin/postgres");
@Test
public void testEmbeddedPg() throws Exception {
Assume.assumeTrue("PostgreSQL binary must exist", USR_LOCAL_BIN_POSTGRES.exists());
- try (EmbeddedPostgres pg = EmbeddedPostgres.builder().setPostgresBinaryDirectory(USR_LOCAL).start();
+ try (EmbeddedPostgres pg = EmbeddedPostgres.builder().start();
Connection c = pg.getPostgresDatabase().getConnection()) {
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT 1");
diff --git a/src/test/java/com/opentable/db/postgres/embedded/PreparedDbCustomizerTest.java b/src/test/java/com/opentable/db/postgres/embedded/PreparedDbCustomizerTest.java
index 3f2a1045..6f89ffdc 100644
--- a/src/test/java/com/opentable/db/postgres/embedded/PreparedDbCustomizerTest.java
+++ b/src/test/java/com/opentable/db/postgres/embedded/PreparedDbCustomizerTest.java
@@ -13,15 +13,17 @@
*/
package com.opentable.db.postgres.embedded;
-import com.opentable.db.postgres.junit.EmbeddedPostgresRules;
-import com.opentable.db.postgres.junit.PreparedDbRule;
-import org.junit.Rule;
-import org.junit.Test;
+import static com.opentable.db.postgres.embedded.EmbeddedPostgres.DEFAULT_PG_STARTUP_WAIT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import java.time.Duration;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.opentable.db.postgres.junit.EmbeddedPostgresRules;
+import com.opentable.db.postgres.junit.PreparedDbRule;
public class PreparedDbCustomizerTest {
@@ -32,23 +34,23 @@ public class PreparedDbCustomizerTest {
@Rule
public PreparedDbRule dbA2 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> {});
@Rule
- public PreparedDbRule dbA3 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(Duration.ofSeconds(10)));
+ public PreparedDbRule dbA3 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(DEFAULT_PG_STARTUP_WAIT));
@Rule
- public PreparedDbRule dbB1 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(Duration.ofSeconds(11)));
+ public PreparedDbRule dbB1 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(Duration.ofSeconds(DEFAULT_PG_STARTUP_WAIT.getSeconds() + 1)));
@Rule
- public PreparedDbRule dbB2 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(Duration.ofSeconds(11)));
+ public PreparedDbRule dbB2 = EmbeddedPostgresRules.preparedDatabase(EMPTY_PREPARER).customize(builder -> builder.setPGStartupWait(Duration.ofSeconds(DEFAULT_PG_STARTUP_WAIT.getSeconds() + 1)));
@Test
public void testCustomizers() {
- int dbA1Port = dbA1.getConnectionInfo().getPort();
- int dbA2Port = dbA2.getConnectionInfo().getPort();
- int dbA3Port = dbA3.getConnectionInfo().getPort();
+ int dbA1Port = JdbcUrlUtils.getPort(dbA1.getConnectionInfo().getUrl());
+ int dbA2Port = JdbcUrlUtils.getPort(dbA2.getConnectionInfo().getUrl());
+ int dbA3Port = JdbcUrlUtils.getPort(dbA3.getConnectionInfo().getUrl());
assertEquals(dbA1Port, dbA2Port);
assertEquals(dbA1Port, dbA3Port);
- int dbB1Port = dbB1.getConnectionInfo().getPort();
- int dbB2Port = dbB2.getConnectionInfo().getPort();
+ int dbB1Port = JdbcUrlUtils.getPort(dbB1.getConnectionInfo().getUrl());
+ int dbB2Port = JdbcUrlUtils.getPort(dbB2.getConnectionInfo().getUrl());
assertEquals(dbB1Port, dbB2Port);