Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit 37144f2

Browse files
authored
Merge pull request #2 from asarkar/feature/issue-1
Close #1: Support EmbeddedRedisConfigurer bean
2 parents 6f6ea6d + 3d64b9d commit 37144f2

File tree

10 files changed

+148
-54
lines changed

10 files changed

+148
-54
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public class AutoConfigureWithRandomPortsTest {
4646

4747
If you want to configure the `RedisServer` before it's started, provide an implementation for
4848
[EmbeddedRedisConfigurer](src/main/kotlin/com/asarkar/spring/test/redis/EmbeddedRedisConfigurer.kt), and set the
49-
class name in the annotation element `serverConfigurerClass`.
49+
class name in the annotation element `serverConfigurerClass`. If a Spring bean of this type exists, it'll be used;
50+
otherwise, a new instance will be created using the public no-argument constructor.
5051

5152
See KDoc for more details.
5253

build.gradle.kts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
4848
}
4949
}
5050

51-
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
52-
outputFormat = "html"
53-
outputDirectory = "$buildDir/javadoc"
51+
tasks.dokkaHtml.configure {
52+
outputDirectory.set(buildDir.resolve("javadoc"))
53+
dokkaSourceSets.configureEach {
54+
jdkVersion.set(8)
55+
skipEmptyPackages.set(true)
56+
platform.set(org.jetbrains.dokka.Platform.jvm)
57+
}
5458
}
5559

5660
tasks.test {
@@ -71,7 +75,7 @@ val kdocJar by tasks.creating(Jar::class) {
7175
group = JavaBasePlugin.DOCUMENTATION_GROUP
7276
description = "Creates KDoc"
7377
archiveClassifier.set("javadoc")
74-
from(tasks.dokka)
78+
from(tasks.dokkaHtml)
7579
}
7680

7781
tasks.jar.configure {

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ embeddedRedisVersion=0.7.3
55
lettuceVersion=6.0.1.RELEASE
66
jUnitVersion=5.7.0
77
kotlinVersion=1.4.10
8-
dokkaPluginVersion=0.10.1
8+
dokkaPluginVersion=1.4.10.2
99
ktlintVersion=9.4.0
1010
bintrayPluginVersion=1.8.5
1111

1212
projectGroup=com.asarkar.spring
13-
projectVersion=1.0.0
13+
projectVersion=1.1.0
1414
projectDescription=Starts a Redis server and makes the port available as Spring Boot environment property
1515
projectLabels=spring, spring-boot, redis, embedded-redis, test, integration-test
1616
licenseName=Apache-2.0

settings.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
pluginManagement {
2+
repositories {
3+
gradlePluginPortal()
4+
jcenter()
5+
}
6+
27
val kotlinVersion: String by settings
38
val dokkaPluginVersion: String by settings
49
val ktlintVersion: String by settings

src/main/kotlin/com/asarkar/spring/test/redis/AutoConfigureEmbeddedRedis.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import java.lang.annotation.Inherited
77

88
/**
99
* Annotation for test classes that want to start a Redis server as part of the Spring application Context.
10+
*
1011
* @property serverConfigurerClass [EmbeddedRedisConfigurer] implementation class. Defaults to empty string.
1112
* @property port Redis server port. Defaults to 6379. Set 0 to use a random port.
1213
*

src/main/kotlin/com/asarkar/spring/test/redis/EmbeddedRedisConfigurer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import redis.embedded.RedisServerBuilder
44

55
/**
66
* Class that gets called with a `RedisServerBuilder` giving the user a chance to configure the server before it's
7-
* started. Implementations must have a public no-argument constructor.
7+
* started. If a Spring bean of this type exists, it'll be used; otherwise, a new instance will be created using
8+
* the public no-argument constructor.
89
*
910
* @author Abhijit Sarkar
1011
* @since 1.0.0

src/main/kotlin/com/asarkar/spring/test/redis/EmbeddedRedisLifecycle.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.asarkar.spring.test.redis
22

33
import org.slf4j.LoggerFactory
4+
import org.springframework.beans.factory.annotation.Autowired
45
import org.springframework.beans.factory.annotation.Value
56
import org.springframework.context.SmartLifecycle
67
import org.springframework.util.ReflectionUtils
@@ -15,7 +16,10 @@ open class EmbeddedRedisLifecycle : SmartLifecycle {
1516
@Value("\${embedded-redis.port:-1}")
1617
var port: Int = -1
1718

18-
lateinit var redisServer: RedisServer
19+
@Autowired(required = false)
20+
private var serverConfigurerBean: EmbeddedRedisConfigurer? = null
21+
22+
private lateinit var redisServer: RedisServer
1923

2024
override fun start() {
2125
if (isRunning || port <= 0) return
@@ -31,6 +35,9 @@ open class EmbeddedRedisLifecycle : SmartLifecycle {
3135
private fun serverConfigurer(): EmbeddedRedisConfigurer? {
3236
return if (serverConfigurerClass.isNotEmpty()) {
3337
val clazz = Class.forName(serverConfigurerClass)
38+
if (serverConfigurerBean != null) {
39+
return serverConfigurerBean
40+
}
3441
return try {
3542
ReflectionUtils.accessibleConstructor(clazz as Class<EmbeddedRedisConfigurer>)
3643
.newInstance()

src/test/kotlin/com/asarkar/spring/test/redis/AutoConfigureWithRandomPortsTest.kt

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,13 @@ package com.asarkar.spring.test.redis
22

33
import io.lettuce.core.RedisClient
44
import org.assertj.core.api.Assertions.assertThat
5-
import org.junit.jupiter.api.AfterEach
65
import org.junit.jupiter.api.Test
7-
import org.slf4j.LoggerFactory
86
import org.springframework.beans.factory.annotation.Value
97
import org.springframework.boot.test.context.SpringBootTest
10-
import redis.embedded.RedisServerBuilder
11-
import java.nio.file.Files
12-
import java.nio.file.Paths
13-
import kotlin.random.Random
14-
15-
private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
16-
private val file = Paths.get(AutoConfigureWithRandomPortsTest::class.java.getResource("/").toURI())
17-
.let { testPath ->
18-
generateSequence(testPath) {
19-
if (Files.isDirectory(it) && Files.exists(it.resolve("build.gradle.kts"))) {
20-
null
21-
} else {
22-
it.parent
23-
}
24-
}
25-
.take(10) // should be plenty
26-
.toList()
27-
.last()
28-
.resolve("build")
29-
.resolve(
30-
(1..6)
31-
.map { Random.nextInt(0, charPool.size) }
32-
.map(charPool::get)
33-
.joinToString("")
34-
)
35-
}
368

379
@SpringBootTest
3810
@AutoConfigureEmbeddedRedis(
39-
port = 0,
40-
serverConfigurerClass = "com.asarkar.spring.test.redis.TestEmbeddedRedisConfigurer"
11+
port = 0
4112
)
4213
class AutoConfigureWithRandomPortsTest {
4314
@Value("\${embedded-redis.port:-1}")
@@ -50,20 +21,5 @@ class AutoConfigureWithRandomPortsTest {
5021
val syncCommands = redisClient.connect().sync()
5122
syncCommands.set("key", "value")
5223
assertThat(syncCommands.get("key")).isEqualTo("value")
53-
assertThat(Files.exists(file)).isTrue
54-
}
55-
56-
@AfterEach
57-
fun afterEach() {
58-
Files.deleteIfExists(file)
59-
}
60-
}
61-
62-
class TestEmbeddedRedisConfigurer : EmbeddedRedisConfigurer {
63-
private val log = LoggerFactory.getLogger(TestEmbeddedRedisConfigurer::class.java)
64-
65-
override fun configure(builder: RedisServerBuilder) {
66-
Files.createFile(file)
67-
.also { log.info("Created file: {}", it.toAbsolutePath()) }
6824
}
6925
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.asarkar.spring.test.redis
2+
3+
import io.lettuce.core.RedisClient
4+
import org.assertj.core.api.Assertions.assertThat
5+
import org.junit.jupiter.api.Test
6+
import org.springframework.beans.factory.annotation.Autowired
7+
import org.springframework.beans.factory.annotation.Value
8+
import org.springframework.boot.test.context.SpringBootTest
9+
import org.springframework.boot.test.context.TestConfiguration
10+
import org.springframework.context.annotation.Bean
11+
import org.springframework.context.annotation.Import
12+
import redis.embedded.RedisServerBuilder
13+
14+
@SpringBootTest
15+
@AutoConfigureEmbeddedRedis(
16+
port = 0,
17+
serverConfigurerClass = "com.asarkar.spring.test.redis.TestEmbeddedRedisConfigurerBean"
18+
)
19+
@Import(EmbeddedRedisConfigurerBeanTestConfiguration::class)
20+
class EmbeddedRedisConfigurerBeanTest {
21+
@Value("\${embedded-redis.port:-1}")
22+
private var port: Int = -1
23+
24+
@Autowired
25+
private lateinit var embeddedRedisConfigurer: TestEmbeddedRedisConfigurerBean
26+
27+
@Test
28+
fun testEmbeddedRedisConfigurer() {
29+
val redisClient = RedisClient
30+
.create("redis://localhost:$port/")
31+
val syncCommands = redisClient.connect().sync()
32+
syncCommands.set("key", "value")
33+
assertThat(syncCommands.get("key")).isEqualTo("value")
34+
assertThat(embeddedRedisConfigurer.called).isTrue
35+
}
36+
}
37+
38+
@TestConfiguration
39+
open class EmbeddedRedisConfigurerBeanTestConfiguration {
40+
@Bean
41+
open fun embeddedRedisConfigurer() = TestEmbeddedRedisConfigurerBean()
42+
}
43+
44+
class TestEmbeddedRedisConfigurerBean : EmbeddedRedisConfigurer {
45+
var called: Boolean = false
46+
47+
override fun configure(builder: RedisServerBuilder) {
48+
called = true
49+
}
50+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.asarkar.spring.test.redis
2+
3+
import io.lettuce.core.RedisClient
4+
import org.assertj.core.api.Assertions.assertThat
5+
import org.junit.jupiter.api.AfterEach
6+
import org.junit.jupiter.api.Test
7+
import org.slf4j.LoggerFactory
8+
import org.springframework.beans.factory.annotation.Value
9+
import org.springframework.boot.test.context.SpringBootTest
10+
import redis.embedded.RedisServerBuilder
11+
import java.nio.file.Files
12+
import java.nio.file.Paths
13+
import kotlin.random.Random
14+
15+
private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
16+
private val file = Paths.get(AutoConfigureWithRandomPortsTest::class.java.getResource("/").toURI())
17+
.let { testPath ->
18+
generateSequence(testPath) {
19+
if (Files.isDirectory(it) && Files.exists(it.resolve("build.gradle.kts"))) {
20+
null
21+
} else {
22+
it.parent
23+
}
24+
}
25+
.take(10) // should be plenty
26+
.toList()
27+
.last()
28+
.resolve("build")
29+
.resolve(
30+
(1..6)
31+
.map { Random.nextInt(0, charPool.size) }
32+
.map(charPool::get)
33+
.joinToString("")
34+
)
35+
}
36+
37+
@SpringBootTest
38+
@AutoConfigureEmbeddedRedis(
39+
port = 0,
40+
serverConfigurerClass = "com.asarkar.spring.test.redis.TestEmbeddedRedisConfigurer"
41+
)
42+
class EmbeddedRedisConfigurerTest {
43+
@Value("\${embedded-redis.port:-1}")
44+
private var port: Int = -1
45+
46+
@Test
47+
fun testEmbeddedRedisConfigurer() {
48+
val redisClient = RedisClient
49+
.create("redis://localhost:$port/")
50+
val syncCommands = redisClient.connect().sync()
51+
syncCommands.set("key", "value")
52+
assertThat(syncCommands.get("key")).isEqualTo("value")
53+
assertThat(Files.exists(file)).isTrue
54+
}
55+
56+
@AfterEach
57+
fun afterEach() {
58+
Files.deleteIfExists(file)
59+
}
60+
}
61+
62+
class TestEmbeddedRedisConfigurer : EmbeddedRedisConfigurer {
63+
private val log = LoggerFactory.getLogger(TestEmbeddedRedisConfigurer::class.java)
64+
65+
override fun configure(builder: RedisServerBuilder) {
66+
Files.createFile(file)
67+
.also { log.info("Created file: {}", it.toAbsolutePath()) }
68+
}
69+
}

0 commit comments

Comments
 (0)