testcontainers-scala icon indicating copy to clipboard operation
testcontainers-scala copied to clipboard

Added method to get the jdbc url with the ip(Postgres)

Open albertoadami opened this issue 4 years ago • 4 comments

Right now with Postgres, the JDBC url generated is using localhost, but in my use case it's not enough. In some tests I used a container that needs the Postgres connection, using the PostgreSQLContainer.jdbcUrl is not working because the url is using localhost.

My tests defined the containers with something like this:

lazy val postgresContainer: PostgreSQLContainer =
    PostgreSQLContainer(databaseName = s"user-${Random.nextInt(5)}")

lazy val myCustomContainer: GenericContainer = GenericContainer(
    dockerImage = "my-service:latest",
    exposedPorts = Seq(8080),
    waitStrategy = Wait.forHttp("/health").forStatusCode(204),
    env = Map(
      "POSTGRES_USER" -> postgresContainer.username,
      "POSTGRES_PASSWORD" -> postgresContainer.password,
      "POSTGRES_URL" -> postgresContainer.jdbcUrl
    )
  )
 override val container: MultipleContainers =
    MultipleContainers(LazyContainer(postgresContainer), LazyContainer(userApiContainer))

As a workaround I used basically the method that I defined in this PR, would be useful from my point of view if this possibility will be present directly in the Postgres container itself.

albertoadami avatar May 02 '20 14:05 albertoadami

@albertoadami thank you for your contribution. Can you share more detail on your use case? If it is generic enough, I think it should be added to the Java library and then used in the scala wrapper.

cc @bsideup

dimafeng avatar May 04 '20 02:05 dimafeng

@albertoadami I think you faced well known testcontainers problem. I suggest you read these: 1, 2, 3.

And also I agree with @dimafeng. testcontainers-scala is a wrapper library. If you have a feature request like this you should discuss it with testcontainers-java maintainers. And after that testcontainers-scala will support it.

LMnet avatar May 04 '20 03:05 LMnet

@LMnet I would not call it a problem. People may have expectations, the expectations may not reflect the reality.

getSomething-like methods on containers return values for the tests' environment. If one wants to do container-to-container communication, they should be using networks and aliases, as described in the docs: https://www.testcontainers.org/features/networking/#advanced-networking

bsideup avatar May 04 '20 12:05 bsideup

@dimafeng thank you for the reply, My use case it to test a REST webservice that needs a POSTGRES connection available.

I try the approach suggested by @bsideup but the jdbcUrl is returning a localhost string also using the network. My test code is something like this:

class ApiTest extends SpecBase with ForAllTestContainer {

  val network: Network = Network.newNetwork()

  lazy val postgresContainer: PostgreSQLContainer =
    PostgreSQLContainer(databaseName = s"user-${Random.nextInt(5)}").configure {c =>
      c.withNetwork(network)
    }

  private val ExposedPort = 8080
  lazy val customContainer: GenericContainer = GenericContainer(
    dockerImage = s"custom-service",
    exposedPorts = Seq(ExposedPort),
    waitStrategy = Wait.forHttp("/health").forStatusCode(204),
    env = Map(
      "POSTGRES_USER" -> postgresContainer.username,
      "POSTGRES_PASSWORD" -> postgresContainer.password,
      "POSTGRES_URL" -> postgresContainer.jdbcUrl
    )
  ).configure {c =>
    c.withNetwork(network)
  }

   override val container: MultipleContainers =
    MultipleContainers(LazyContainer(postgresContainer), LazyContainer(userApiContainer))

    "Api" when {
        "GET /version is called" should {
            "return Ok" in {
                //some code that use my customContainer with rest client
            }
        }
    }
}

From my service I can see that there are some errors with the jdbc string:

09:52:27 ERROR HikariPool {com.zaxxer.hikari.pool.HikariPool throwPoolInitializationException} - HikariPool-1 - Exception during pool initialization.
org.postgresql.util.PSQLException: Connection to localhost:33045 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:211)
	at org.postgresql.Driver.makeConnection(Driver.java:458)
	at org.postgresql.Driver.connect(Driver.java:260)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:353)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
	at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:56)
	at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:80)
	at org.flywaydb.core.Flyway.execute(Flyway.java:449)
	at org.flywaydb.core.Flyway.migrate(Flyway.java:153)
	at 
...........

Am I wronging something?

albertoadami avatar May 08 '20 10:05 albertoadami

Closing due to no activity

dimafeng avatar Nov 21 '22 01:11 dimafeng