ebean-orm / ebean-orm/ebean

application-test.yaml seems to be ignored when test makes second call to DatabaseConfig.loadFromProperties

Open
#2,997 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.5k
Forks
267
Avg merge
3d 20h
Merged PRs (30d)
5

Description

Background

Often when testing in Spring, multiple application contexts can be created and destroyed. When using programatic configuration of ebeans this could create a situation where multiple calls are made to DatabaseConfig.loadFromProperties method.

Expected behavior

It doesn't matter how many times the tests call DatabaseConfig.loadFromProperties, the test configuration is found and used each time.

Actual behavior

Only the first call to DatabaseConfig.loadFromProperties succeeds. When trying to use a Database created from the DatabaseConfig that was created by a second call to DatabaseConfig.loadFromProperties we get exception:

    io.ebean.datasource.DataSourceConfigurationException: DataSource user is not set? url is [null]
        at app//io.ebean.datasource.pool.ConnectionPool.<init>(ConnectionPool.java:121)
        at app//io.ebean.datasource.pool.ConnectionPoolFactory.createPool(ConnectionPoolFactory.java:14)
        at app//io.ebean.datasource.DataSourceFactory.create(DataSourceFactory.java:25)
        at app//io.ebeaninternal.server.core.InitDataSource.create(InitDataSource.java:113)
        at app//io.ebeaninternal.server.core.InitDataSource.createFromConfig(InitDataSource.java:104)
        at app//io.ebeaninternal.server.core.InitDataSource.initDataSource(InitDataSource.java:44)
        at app//io.ebeaninternal.server.core.InitDataSource.initialise(InitDataSource.java:33)
        at app//io.ebeaninternal.server.core.InitDataSource.init(InitDataSource.java:24)
        at app//io.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:220)
        at app//io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:86)
        at app//io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:29)
        at app//io.ebean.DatabaseFactory.createInternal(DatabaseFactory.java:136)
        at app//io.ebean.DatabaseFactory.create(DatabaseFactory.java:85)
        at app//org.example.PetTest.testDouble(PetTest.java:44)

It appears as though the test configuration isn't found.

Steps to reproduce

I've created a sample project with code at https://github.com/simontankersley/programatic-ebean-test

This code fails

        // simulate using a custom object mapper
        ObjectMapper mapper = new ObjectMapper();

        // simulate creating a database configuration twice
        // this often happens when using spring tests where several
        // contexts can be created and destroyed - causing multiple
        // calls to create the database configuration from properties
        DatabaseConfig dbConfig = new DatabaseConfig();
        dbConfig.loadFromProperties();
        dbConfig.setObjectMapper(mapper);
        Database db = DatabaseFactory.create(dbConfig);

        dbConfig = new DatabaseConfig();
        dbConfig.loadFromProperties();
        dbConfig.setObjectMapper(mapper);
        db = DatabaseFactory.create(dbConfig);
        db.save(new Pet());

If you want to see a base line vs a failing test see below

Success when running a test with a single call to DatabaseConfig.loadFromProperties
git clone git@github.com:simontankersley/programatic-ebean-test.git
cd programatic-ebean-test
./gradlew test --tests '*testSingle'

gives

> Task :test

PetTest > testSingle() PASSED
Failure when running a test with a multiple calls to DatabaseConfig.loadFromProperties
./gradlew test --tests '*testDouble'

gives

> Task :test

PetTest > testDouble() FAILED
    io.ebean.datasource.DataSourceConfigurationException: DataSource user is not set? url is [null]
        at app//io.ebean.datasource.pool.ConnectionPool.<init>(ConnectionPool.java:121)
        at app//io.ebean.datasource.pool.ConnectionPoolFactory.createPool(ConnectionPoolFactory.java:14)
        at app//io.ebean.datasource.DataSourceFactory.create(DataSourceFactory.java:25)
        at app//io.ebeaninternal.server.core.InitDataSource.create(InitDataSource.java:113)
        at app//io.ebeaninternal.server.core.InitDataSource.createFromConfig(InitDataSource.java:104)
        at app//io.ebeaninternal.server.core.InitDataSource.initDataSource(InitDataSource.java:44)
        at app//io.ebeaninternal.server.core.InitDataSource.initialise(InitDataSource.java:33)
        at app//io.ebeaninternal.server.core.InitDataSource.init(InitDataSource.java:24)
        at app//io.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:220)
        at app//io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:86)
        at app//io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:29)
        at app//io.ebean.DatabaseFactory.createInternal(DatabaseFactory.java:136)
        at app//io.ebean.DatabaseFactory.create(DatabaseFactory.java:85)
        at app//org.example.PetTest.testDouble(PetTest.java:44)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing DatabaseConfig.loadFromProperties and DatabaseFactory.create, then reproduce the issue with the linked sample project using ./gradlew test --tests '*testDouble'. Compare the first and second configuration loads; done means the second call finds application-test.yaml and PetTest.testDouble passes without the DataSourceConfigurationException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.