Skip to content

Commit

Permalink
Better tests for datasource initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
snicoll committed Jun 28, 2017
1 parent 4e19c47 commit 2892039
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
import org.junit.rules.ExpectedException;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -200,6 +202,14 @@ public void testDefaultDataSourceCanBeOverridden() throws Exception {
assertThat(dataSource).isInstanceOf(BasicDataSource.class);
}

@Test
public void testDataSourceIsInitializedEarly() {
load(TestInitializedDataSourceConfiguration.class,
"spring.datasource.initialize=true");
assertThat(this.context.getBean(
TestInitializedDataSourceConfiguration.class).called).isTrue();
}

@SuppressWarnings("unchecked")
private <T extends DataSource> T autoConfigureDataSource(Class<T> expectedType,
final String... hiddenPackages) {
Expand Down Expand Up @@ -251,6 +261,22 @@ public DataSource dataSource() {

}

@Configuration
static class TestInitializedDataSourceConfiguration {

private boolean called;

@Autowired
public void validateDataSourceIsInitialized(DataSource dataSource) {
// Inject the datasource to validate it is initialized at the injection point
JdbcTemplate template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject("SELECT COUNT(*) from BAR", Integer.class))
.isEqualTo(1);
this.called = true;
}

}

// see testExplicitDriverClassClearsUsername
public static class DatabaseTestDriver implements Driver {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,15 @@ protected void load(Class<?> config, String... environment) {
}

protected void load(Class<?>[] configs, Class<?>[] autoConfigs, String... environment) {
load(configs, autoConfigs, null, environment);
}

protected void load(Class<?>[] configs, Class<?>[] autoConfigs,
ClassLoader classLoader, String... environment) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
if (classLoader != null) {
ctx.setClassLoader(classLoader);
}
TestPropertyValues.of(environment)
.and("spring.datasource.generate-unique-name", "true")
.applyTo(ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@

package org.springframework.boot.autoconfigure.orm.jpa;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
Expand All @@ -30,10 +39,14 @@
import org.junit.rules.ExpectedException;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

Expand Down Expand Up @@ -77,6 +90,17 @@ public void testDataScript() throws Exception {
load("spring.datasource.data:classpath:/city.sql");
}

@Test
public void testDataScriptRunsEarly() {
load(new Class<?>[] { TestInitializedJpaConfiguration.class }, null,
new HideDataScriptClassLoader(),
"spring.jpa.show-sql=true",
"spring.jpa.hibernate.ddl-auto:create-drop",
"spring.datasource.data:classpath:/city.sql");
assertThat(this.context.getBean(
TestInitializedJpaConfiguration.class).called).isTrue();
}

@Test
public void testFlywayPlusValidation() throws Exception {
load(new Class<?>[0], new Class<?>[] { FlywayAutoConfiguration.class },
Expand Down Expand Up @@ -125,6 +149,25 @@ public void testCustomJpaTransactionManagerUsingProperties() throws Exception {
assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue();
}

@Configuration
@TestAutoConfigurationPackage(City.class)
static class TestInitializedJpaConfiguration {

private boolean called;

@Autowired
public void validateDataSourceIsInitialized(
EntityManagerFactory entityManagerFactory) {
// Inject the entity manager to validate it is initialized at the injection point
EntityManager entityManager = entityManagerFactory.createEntityManager();
City city = entityManager.find(City.class, 2000L);
assertThat(city).isNotNull();
assertThat(city.getName()).isEqualTo("Washington");
this.called = true;
}

}

public static class TestJtaPlatform implements JtaPlatform {

@Override
Expand Down Expand Up @@ -159,4 +202,23 @@ public int getCurrentStatus() throws SystemException {

}

private static class HideDataScriptClassLoader extends URLClassLoader {

private static final List<String> HIDDEN_RESOURCES =
Arrays.asList("schema-all.sql", "schema.sql");

HideDataScriptClassLoader() {
super(new URL[0], HideDataScriptClassLoader.class.getClassLoader());
}


@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (HIDDEN_RESOURCES.contains(name)) {
return new Vector().elements();
}
return super.getResources(name);
}
}

}
2 changes: 1 addition & 1 deletion spring-boot-autoconfigure/src/test/resources/city.sql
Original file line number Diff line number Diff line change
@@ -1 +1 @@
INSERT INTO CITY (NAME, STATE, COUNTRY, MAP) values ('Washington', 'DC', 'US', 'Google');
INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google');

0 comments on commit 2892039

Please sign in to comment.