Skip to content

Commit c508a35

Browse files
committed
Support dynamic ports
This commit adds a ApplicationContext.localServerPort extension to Kofu and updates Jafu and Kofu tests to leverage dynamic ports. Fixes gh-121
1 parent 9830eb2 commit c508a35

File tree

8 files changed

+93
-63
lines changed

8 files changed

+93
-63
lines changed

jafu/src/test/java/org/springframework/fu/jafu/web/JacksonDslTests.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ public class JacksonDslTests {
2424

2525
@Test
2626
void enableJacksonModuleOnServerCreateAndRequestAJSONEndpoint() {
27-
var app = webApplication(a -> a.enable(server(s -> s.codecs(c -> c.jackson()).router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian")))))));
27+
var app = webApplication(a -> a.enable(server(s -> s.port(0).codecs(c -> c.jackson()).router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian")))))));
2828

2929
var context = app.run();
30-
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:8080").build();
30+
var port = context.getEnvironment().getProperty("local.server.port");
31+
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
3132
client.get().uri("/user").exchange()
3233
.expectStatus().is2xxSuccessful()
3334
.expectHeader().contentType(APPLICATION_JSON_UTF8_VALUE)
@@ -39,11 +40,12 @@ void enableJacksonModuleOnServerCreateAndRequestAJSONEndpoint() {
3940
@Test
4041
void enableJacksonModuleOnClientAndServerCreateAndRequestAJSONEndpoint() {
4142
var app = webApplication(a ->
42-
a.enable(server(s -> s.codecs(c -> c.jackson()).router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian"))))))
43+
a.enable(server(s -> s.port(0).codecs(c -> c.jackson()).router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian"))))))
4344
.enable(client(c -> c.codecs(codecs -> codecs.jackson()))));
4445
var context = app.run();
46+
var port = context.getEnvironment().getProperty("local.server.port");
4547
var client = context.getBean(WebClient.Builder.class).build();
46-
var response = client.get().uri("http://127.0.0.1:8080/user").exchange();
48+
var response = client.get().uri("http://127.0.0.1:" + port + "/user").exchange();
4749

4850
StepVerifier.create(response)
4951
.consumeNextWith(it -> {
@@ -58,9 +60,10 @@ void enableJacksonModuleOnClientAndServerCreateAndRequestAJSONEndpoint() {
5860

5961
@Test
6062
void noJacksonCodecOnServerWhenNotDeclared() {
61-
var app = webApplication(a -> a.enable(server(s -> s.router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian")))))));
63+
var app = webApplication(a -> a.enable(server(s -> s.port(0).router(r -> r.GET("/user", request -> ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(new User("Brian")))))));
6264
var context = app.run();
63-
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:8080").build();
65+
var port = context.getEnvironment().getProperty("local.server.port");
66+
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
6467
client.get().uri("/user").exchange().expectStatus().is5xxServerError();
6568
context.close();
6669
}

jafu/src/test/java/org/springframework/fu/jafu/web/MustacheDslTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ public class MustacheDslTests {
1414

1515
@Test
1616
void createAndRequestAMustacheView() {
17-
var app = webApplication(a -> a.enable(server(s -> s.mustache().router(r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world")))))));
17+
var app = webApplication(a -> a.enable(server(s -> s.port(0).mustache().router(r -> r.GET("/view", request -> ok().render("template", Collections.singletonMap("name", "world")))))));
1818

1919
var context = app.run();
20-
var client = WebTestClient.bindToServer().baseUrl("http://0.0.0.0:8080").build();
20+
var port = context.getEnvironment().getProperty("local.server.port");
21+
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
2122
client.get().uri("/view").exchange()
2223
.expectStatus().is2xxSuccessful()
2324
.expectBody(String.class)

jafu/src/test/java/org/springframework/fu/jafu/web/WebServerDslTests.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,39 +46,40 @@
4646
*/
4747
class WebServerDslTests {
4848

49-
private int port = 8080;
50-
5149
@Test
5250
void createAnApplicationWithAnEmptyServer() {
53-
var app = webApplication(a -> a.enable(server()));
51+
var app = webApplication(a -> a.enable(server(s -> s.port(0))));
5452
var context = app.run();
5553
context.close();
5654
}
5755

5856
@Test
5957
void createAnApplicationWithAServerAndAFilter() {
60-
var app = webApplication(a -> a.enable(server(s -> s.filter(MyFilter.class))));
58+
var app = webApplication(a -> a.enable(server(s -> s.port(0).filter(MyFilter.class))));
6159
var context = app.run();
60+
var port = context.getEnvironment().getProperty("local.server.port");
6261
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
6362
client.get().uri("/foo"). accept(MediaType.TEXT_PLAIN).exchange().expectStatus().isEqualTo(UNAUTHORIZED);
6463
context.close();
6564
}
6665

6766
@Test
6867
void createAndRequestAnEndpoint() {
69-
var app = webApplication(a -> a.enable(server(s -> s.router(r -> r.GET("/foo", request -> noContent().build())))));
68+
var app = webApplication(a -> a.enable(server(s -> s.port(0).router(r -> r.GET("/foo", request -> noContent().build())))));
7069

7170
var context = app.run();
71+
var port = context.getEnvironment().getProperty("local.server.port");
7272
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
7373
client.get().uri("/foo"). accept(MediaType.TEXT_PLAIN).exchange().expectStatus().is2xxSuccessful();
7474
context.close();
7575
}
7676

7777
@Test
7878
void createAndRequestAnEndpointWithACustomizedEngine() {
79-
var app = webApplication(a -> a.enable(server(s -> s.engine(new TomcatReactiveWebServerFactory()).router(r -> r.GET("/foo", request -> noContent().build())))));
79+
var app = webApplication(a -> a.enable(server(s -> s.port(0).engine(new TomcatReactiveWebServerFactory()).router(r -> r.GET("/foo", request -> noContent().build())))));
8080

8181
var context = app.run();
82+
var port = context.getEnvironment().getProperty("local.server.port");
8283
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
8384
client.get().uri("/foo"). accept(MediaType.TEXT_PLAIN).exchange().expectStatus().is2xxSuccessful();
8485
context.close();
@@ -87,23 +88,25 @@ void createAndRequestAnEndpointWithACustomizedEngine() {
8788
@Test
8889
void createAWebClientAndRequestAnEndpoint() {
8990
var app = webApplication(a ->
90-
a.enable(server(s -> s.router(r -> r.GET("/", request -> noContent().build()))))
91-
.enable(client(c -> c.baseUrl("http://127.0.0.1:" + port))));
91+
a.enable(server(s -> s.port(0).router(r -> r.GET("/", request -> noContent().build()))))
92+
.enable(client()));
9293

9394
var context = app.run();
95+
var port = context.getEnvironment().getProperty("local.server.port");
9496
var client = context.getBean(WebClient.Builder.class).build();
95-
StepVerifier.create(client.get().uri("/").exchange())
97+
StepVerifier.create(client.get().uri("http://127.0.0.1:" + port).exchange())
9698
.consumeNextWith(consumer -> assertEquals(NO_CONTENT, consumer.statusCode()))
9799
.verifyComplete();
98100
context.close();
99101
}
100102

101103
@Test
102104
void declare2RouterBlocks() {
103-
var app = webApplication(a -> a.enable(server(s -> s
105+
var app = webApplication(a -> a.enable(server(s -> s.port(0)
104106
.router(r -> r.GET("/foo", request -> noContent().build()))
105107
.router(r -> r.GET("/bar", request -> ok().build())))));
106108
var context = app.run();
109+
var port = context.getEnvironment().getProperty("local.server.port");
107110
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
108111
client.get().uri("/foo").exchange().expectStatus().isNoContent();
109112
client.get().uri("/bar").exchange().expectStatus().isOk();
@@ -113,28 +116,29 @@ void declare2RouterBlocks() {
113116
@Test
114117
void declare2ServerBlocks() {
115118
var app = webApplication(a -> a
116-
.enable(server())
117-
.enable(server(s -> s.port(8181))));
119+
.enable(server(s -> s.port(0)))
120+
.enable(server(s -> s.port(0))));
118121
Assertions.assertThrows(IllegalStateException.class, app::run);
119122
}
120123

121124
@Test
122125
void checkThatConcurrentModificationExceptionIsNotThrown() {
123126
var app = webApplication(a ->
124-
a.enable(server(s -> s
127+
a.enable(server(s -> s.port(0)
125128
.codecs(c -> c.string().jackson())
126129
.router(r -> r.GET("/", request -> noContent().build()))))
127130
.logging(l -> l.level(LogLevel.DEBUG))
128131
.enable(mongo()));
129132
var context = app.run();
133+
var port = context.getEnvironment().getProperty("local.server.port");
130134
var client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:" + port).build();
131135
client.get().uri("/").exchange().expectStatus().is2xxSuccessful();
132136
context.close();
133137
}
134138

135139
@Test
136140
void runAnApplication2Times() {
137-
var app = webApplication(a -> a.enable(server()));
141+
var app = webApplication(a -> a.enable(server(s -> s.port(0))));
138142
var context = app.run();
139143
context.close();
140144
context = app.run();

kofu/src/main/kotlin/org/springframework/fu/kofu/web/WebFluxServerDsl.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory
1111
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory
1212
import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory
1313
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory
14+
import org.springframework.context.ApplicationContext
15+
import org.springframework.context.ConfigurableApplicationContext
1416
import org.springframework.context.support.GenericApplicationContext
1517
import org.springframework.context.support.registerBean
18+
import org.springframework.core.env.get
1619
import org.springframework.fu.kofu.AbstractDsl
1720
import org.springframework.fu.kofu.ConfigurationDsl
1821
import org.springframework.web.function.server.CoRouterFunctionDsl
@@ -280,3 +283,9 @@ open class WebFluxServerDsl(private val init: WebFluxServerDsl.() -> Unit): Abst
280283
fun ConfigurationDsl.server(dsl: WebFluxServerDsl.() -> Unit = {}) {
281284
WebFluxServerDsl(dsl).initialize(context)
282285
}
286+
287+
/**
288+
* Shortcut for `environment["local.server.port"]`.
289+
*/
290+
val ApplicationContext.localServerPort: String
291+
get() = environment["local.server.port"]!!

kofu/src/test/kotlin/org/springframework/fu/kofu/web/CorsDslTests.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package org.springframework.fu.kofu.web
1919
import org.junit.jupiter.api.Test
2020
import org.springframework.fu.kofu.webApplication
2121
import org.springframework.test.web.reactive.server.WebTestClient
22-
import org.springframework.web.reactive.function.server.router
2322

2423
/**
2524
* @author Ireneusz Kozłowski
@@ -30,6 +29,7 @@ class CorsDslTests {
3029
fun `Enable cors module on server, create and request a JSON endpoint`() {
3130
val app = webApplication {
3231
server {
32+
port = 0
3333
router {
3434
GET("/") { noContent().build() }
3535
}
@@ -55,9 +55,8 @@ class CorsDslTests {
5555
}
5656
with(app.run()) {
5757
assert(containsBean("corsFilter"))
58-
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:8080").build()
59-
client.get().uri("/").exchange()
60-
.expectStatus().is2xxSuccessful
58+
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:$localServerPort").build()
59+
client.get().uri("/").exchange().expectStatus().is2xxSuccessful
6160
close()
6261
}
6362
}

kofu/src/test/kotlin/org/springframework/fu/kofu/web/JacksonDslTests.kt

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE
2929
import org.springframework.test.web.reactive.server.WebTestClient
3030
import org.springframework.test.web.reactive.server.expectBody
3131
import org.springframework.web.reactive.function.client.WebClient
32-
import org.springframework.web.reactive.function.server.router
3332
import reactor.test.test
3433

3534
/**
@@ -41,6 +40,7 @@ class JacksonDslTests {
4140
fun `Enable jackson module on server, create and request a JSON endpoint`() {
4241
val app = webApplication {
4342
server {
43+
port = 0
4444
codecs {
4545
jackson()
4646
}
@@ -51,20 +51,22 @@ class JacksonDslTests {
5151
}
5252
}
5353
}
54-
val context = app.run()
55-
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:8080").build()
56-
client.get().uri("/user").exchange()
57-
.expectStatus().is2xxSuccessful
58-
.expectHeader().contentType(APPLICATION_JSON_UTF8_VALUE)
59-
.expectBody<User>()
60-
.isEqualTo(User("Brian"))
61-
context.close()
54+
with (app.run()) {
55+
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:$localServerPort").build()
56+
client.get().uri("/user").exchange()
57+
.expectStatus().is2xxSuccessful
58+
.expectHeader().contentType(APPLICATION_JSON_UTF8_VALUE)
59+
.expectBody<User>()
60+
.isEqualTo(User("Brian"))
61+
close()
62+
}
6263
}
6364

6465
@Test
6566
fun `Enable jackson module on client and server, create and request a JSON endpoint`() {
6667
val app = webApplication {
6768
server {
69+
port = 0
6870
codecs {
6971
jackson()
7072
}
@@ -82,7 +84,7 @@ class JacksonDslTests {
8284
}
8385
with(app.run()) {
8486
val client = getBean<WebClient.Builder>().build()
85-
val response = client.get().uri("http://127.0.0.1:8080/user").exchange()
87+
val response = client.get().uri("http://127.0.0.1:$localServerPort/user").exchange()
8688
response.test()
8789
.consumeNextWith {
8890
assertEquals(HttpStatus.OK, it.statusCode())
@@ -99,18 +101,19 @@ class JacksonDslTests {
99101
fun `No Jackson codec on server when not declared`() {
100102
val app = webApplication {
101103
server {
104+
port = 0
102105
router {
103106
GET("/user") {
104107
ok().header(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE).syncBody(User("Brian"))
105108
}
106109
}
107110
}
108111
}
109-
val context = app.run()
110-
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:8080").build()
111-
client.get().uri("/user").exchange()
112-
.expectStatus().is5xxServerError
113-
context.close()
112+
with(app.run()) {
113+
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:$localServerPort").build()
114+
client.get().uri("/user").exchange().expectStatus().is5xxServerError
115+
close()
116+
}
114117
}
115118

116119
data class User(val name: String)

kofu/src/test/kotlin/org/springframework/fu/kofu/web/MustacheDslTests.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,21 @@ class MustacheDslTests {
3030
fun `Create and request a Mustache view`() {
3131
val app = webApplication {
3232
server {
33+
port = 0
3334
mustache()
3435
router {
3536
GET("/view") { ok().render("template", mapOf("name" to "world")) }
3637
}
3738
}
3839
}
39-
val context = app.run()
40-
val client = WebTestClient.bindToServer().baseUrl("http://0.0.0.0:8080").build()
41-
client.get().uri("/view").exchange()
42-
.expectStatus().is2xxSuccessful
43-
.expectBody<String>()
44-
.isEqualTo("Hello world!")
45-
context.close()
40+
with(app.run()) {
41+
val client = WebTestClient.bindToServer().baseUrl("http://127.0.0.1:$localServerPort").build()
42+
client.get().uri("/view").exchange()
43+
.expectStatus().is2xxSuccessful
44+
.expectBody<String>()
45+
.isEqualTo("Hello world!")
46+
close()
47+
}
4648
}
4749

4850
}

0 commit comments

Comments
 (0)