Skip to content

Commit 775f4e6

Browse files
author
Sven Obser
committed
Add ThrottleIntegrationTest
1 parent 6b55c9f commit 775f4e6

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

gradle/libs.versions.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[versions]
22
kotlin = "2.2.20"
3-
43
ktor = "3.3.1"
4+
55
dokka = "2.1.0"
66
kover = "0.9.2"
77
ktlint = "13.1.0"
@@ -10,6 +10,11 @@ researchgate-release = "3.1.0"
1010

1111
[libraries]
1212
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
13+
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
14+
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
15+
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
16+
ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }
17+
ktor-server-rate-limit = { module = "io.ktor:ktor-server-rate-limit", version.ref = "ktor" }
1318

1419
[plugins]
1520
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }

library/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ kotlin {
4141

4242
commonTest.dependencies {
4343
implementation(kotlin("test"))
44+
implementation(libs.ktor.client.cio)
45+
implementation(libs.ktor.client.logging)
46+
implementation(libs.ktor.server.core)
47+
implementation(libs.ktor.server.cio)
48+
implementation(libs.ktor.server.rate.limit)
4449
}
4550
}
4651
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package throttle
2+
3+
import de.brudaswen.ktor.client.throttle.HttpRequestThrottle
4+
import io.ktor.client.HttpClient
5+
import io.ktor.client.engine.cio.CIO
6+
import io.ktor.client.plugins.logging.LogLevel
7+
import io.ktor.client.plugins.logging.Logger
8+
import io.ktor.client.plugins.logging.Logging
9+
import io.ktor.client.plugins.logging.SIMPLE
10+
import io.ktor.client.request.get
11+
import io.ktor.client.request.parameter
12+
import io.ktor.server.application.install
13+
import io.ktor.server.engine.embeddedServer
14+
import io.ktor.server.plugins.ratelimit.RateLimit
15+
import io.ktor.server.response.respondText
16+
import io.ktor.server.routing.get
17+
import io.ktor.server.routing.routing
18+
import kotlinx.coroutines.runBlocking
19+
import kotlin.test.Test
20+
import kotlin.time.Duration.Companion.seconds
21+
import kotlin.time.measureTimedValue
22+
import io.ktor.server.cio.CIO as ServerCIO
23+
24+
internal class ThrottleIntegrationTest {
25+
26+
private val server = embeddedServer(ServerCIO, port = 8080) {
27+
install(RateLimit) {
28+
global {
29+
rateLimiter(
30+
limit = 5,
31+
refillPeriod = 2.seconds,
32+
)
33+
}
34+
}
35+
36+
routing {
37+
get("/") {
38+
call.respondText("Hello, world!")
39+
}
40+
}
41+
}
42+
43+
@Test
44+
fun `client should not fail if refillPeriod is large enough`() = runBlocking {
45+
server.startSuspend()
46+
47+
val client = HttpClient(CIO) {
48+
expectSuccess = true
49+
50+
install(HttpRequestThrottle) {
51+
throttler(
52+
limit = 5,
53+
refillPeriod = 3.seconds,
54+
retry = false,
55+
)
56+
}
57+
58+
install(Logging) {
59+
logger = Logger.SIMPLE
60+
level = LogLevel.HEADERS
61+
}
62+
}
63+
val stats = List(10) { it }.map { id ->
64+
measureTimedValue {
65+
client.get("http://localhost:8080/") {
66+
parameter("id", id)
67+
}.status
68+
}.let { (status, duration) ->
69+
"Request $id took $duration: $status"
70+
}
71+
}
72+
73+
println(stats.joinToString("\n"))
74+
75+
server.stopSuspend()
76+
}
77+
78+
@Test
79+
fun `client should retry failed 429 requests`() = runBlocking {
80+
server.startSuspend()
81+
82+
val client = HttpClient(CIO) {
83+
expectSuccess = true
84+
85+
install(HttpRequestThrottle) {
86+
throttler(
87+
limit = 5,
88+
refillPeriod = 2.seconds,
89+
retry = true,
90+
)
91+
}
92+
93+
install(Logging) {
94+
logger = Logger.SIMPLE
95+
level = LogLevel.HEADERS
96+
}
97+
}
98+
val stats = List(10) { it }.map { id ->
99+
measureTimedValue {
100+
client.get("http://localhost:8080/") {
101+
parameter("id", id)
102+
}.status
103+
}.let { (status, duration) ->
104+
"Request $id took $duration: $status"
105+
}
106+
}
107+
108+
println(stats.joinToString("\n"))
109+
110+
server.stopSuspend()
111+
}
112+
}

0 commit comments

Comments
 (0)