Skip to content

Commit

Permalink
Optimize Redis integration tests
Browse files Browse the repository at this point in the history
This commit ensures that Redis Testcontainers used for integration testing are managed by Spring to ensure proper ordering on shutdown.

Previously, Redis Testcontainer was closed before LettuceConnectionFactory which caused pending commands to hang and added a lot of wait to project build.

Closes gh-1086
  • Loading branch information
vpavic committed Jun 1, 2018
1 parent f55b793 commit 63f1050
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 228 deletions.
Expand Up @@ -17,9 +17,7 @@
package sample;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
Expand All @@ -31,10 +29,9 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
Expand All @@ -46,25 +43,11 @@
*/
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(classes = FindByUsernameApplication.class, webEnvironment = WebEnvironment.MOCK)
@ContextConfiguration(initializers = FindByUsernameTests.Initializer.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class FindByUsernameTests {

private static final String DOCKER_IMAGE = "redis:4.0.9";

private static GenericContainer container = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);

@BeforeClass
public static void setUpClass() {
container.start();
}

@AfterClass
public static void tearDownClass() {
container.stop();
}

@Autowired
private MockMvc mockMvc;

Expand Down Expand Up @@ -96,16 +79,21 @@ public void login() {
home.terminateButtonDisabled();
}

static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@TestConfiguration
static class Config {

@Bean
public GenericContainer redisContainer() {
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);
redisContainer.start();
return redisContainer;
}

@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.redis.host=" + container.getContainerIpAddress(),
"spring.redis.port=" + container.getFirstMappedPort())
.applyTo(configurableApplicationContext.getEnvironment());
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(),
redisContainer().getFirstMappedPort());
}

}
Expand Down
Expand Up @@ -19,9 +19,7 @@
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
Expand All @@ -34,10 +32,9 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
Expand All @@ -49,26 +46,12 @@
* @author Vedran Pavic
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureMockMvc
@ContextConfiguration(initializers = HttpRedisJsonTest.Initializer.class)
public class HttpRedisJsonTest {

private static final String DOCKER_IMAGE = "redis:4.0.9";

private static GenericContainer container = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);

@BeforeClass
public static void setUpClass() {
container.start();
}

@AfterClass
public static void tearDownClass() {
container.stop();
}

@Autowired
private MockMvc mockMvc;

Expand Down Expand Up @@ -120,16 +103,21 @@ public void createAttribute() {
assertThat(attributes).extracting("attributeValue").contains("Demo Value");
}

static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@TestConfiguration
static class Config {

@Bean
public GenericContainer redisContainer() {
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);
redisContainer.start();
return redisContainer;
}

@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.redis.host=" + container.getContainerIpAddress(),
"spring.redis.port=" + container.getFirstMappedPort())
.applyTo(configurableApplicationContext.getEnvironment());
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(),
redisContainer().getFirstMappedPort());
}

}
Expand Down
Expand Up @@ -16,20 +16,17 @@

package sample;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.testcontainers.containers.GenericContainer;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -39,25 +36,11 @@
* @author Vedran Pavic
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@ContextConfiguration(initializers = RedisSerializerTest.Initializer.class)
@SpringBootTest
public class RedisSerializerTest {

private static final String DOCKER_IMAGE = "redis:4.0.9";

private static GenericContainer container = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);

@BeforeClass
public static void setUpClass() {
container.start();
}

@AfterClass
public static void tearDownClass() {
container.stop();
}

@SpringSessionRedisOperations
private RedisTemplate<Object, Object> sessionRedisTemplate;

Expand All @@ -69,16 +52,21 @@ public void testRedisTemplate() {
.isInstanceOf(GenericJackson2JsonRedisSerializer.class);
}

static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@TestConfiguration
static class Config {

@Bean
public GenericContainer redisContainer() {
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);
redisContainer.start();
return redisContainer;
}

@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.redis.host=" + container.getContainerIpAddress(),
"spring.redis.port=" + container.getFirstMappedPort())
.applyTo(configurableApplicationContext.getEnvironment());
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(),
redisContainer().getFirstMappedPort());
}

}
Expand Down
48 changes: 18 additions & 30 deletions samples/boot/redis/src/integration-test/java/sample/BootTests.java
Expand Up @@ -17,9 +17,7 @@
package sample;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
Expand All @@ -31,10 +29,9 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
Expand All @@ -45,25 +42,11 @@
*/
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK)
@ContextConfiguration(initializers = BootTests.Initializer.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class BootTests {

private static final String DOCKER_IMAGE = "redis:4.0.9";

private static GenericContainer container = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);

@BeforeClass
public static void setUpClass() {
container.start();
}

@AfterClass
public static void tearDownClass() {
container.stop();
}

@Autowired
private MockMvc mockMvc;

Expand Down Expand Up @@ -102,16 +85,21 @@ public void logout() {
login.assertAt();
}

static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@TestConfiguration
static class Config {

@Bean
public GenericContainer redisContainer() {
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);
redisContainer.start();
return redisContainer;
}

@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.redis.host=" + container.getContainerIpAddress(),
"spring.redis.port=" + container.getFirstMappedPort())
.applyTo(configurableApplicationContext.getEnvironment());
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(),
redisContainer().getFirstMappedPort());
}

}
Expand Down

0 comments on commit 63f1050

Please sign in to comment.