Skip to content

Commit 61c0fbf

Browse files
authored
Fix flaky ServerEphemeralLocalPortTest.builtWithoutLocalPort() (#6665)
Motivation: Fixes #6616 it asserts that the OS assigns different ephemeral port numbers to 127.0.0.1 and ::1. Since these are different network interfaces, the OS is free to assign the same port to both — no conflict exists. This makes the assertion non-deterministic Modifications: - Removed the `distinct().hasSize(2)` assertion in `builtWithoutLocalPort()` - The remaining assertions (`hasSize(2)`, `isLoopbackAddress()`, `portGroup() == 0`) already fully verify the intended behavior Result: - The test no longer fails when the OS assigns the same ephemeral port to both loopback interfaces
1 parent 558100c commit 61c0fbf

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

core/src/test/java/com/linecorp/armeria/server/ServerEphemeralLocalPortTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ protected void configure(ServerBuilder sb) throws Exception {
6262
}
6363
};
6464

65+
@RegisterExtension
66+
static final ServerExtension serverBuiltWithoutLocalPortIpV4 = new ServerExtension() {
67+
@Override
68+
protected void configure(ServerBuilder sb) throws Exception {
69+
sb.http(new InetSocketAddress(NetUtil.LOCALHOST4, 0));
70+
sb.http(new InetSocketAddress(NetUtil.LOCALHOST4, 0));
71+
sb.service("/", (ctx, req) -> HttpResponse.of(200));
72+
}
73+
};
74+
6575
/**
6676
* {@link Server} must use the same port number for all loopback addresses when 1) the port number is 0 and
6777
* 2) the port number was specified with {@link ServerBuilder#localPort(int, Iterable)}.
@@ -125,8 +135,28 @@ void builtWithoutLocalPort() {
125135
assertThat(p.localAddress().getAddress().isLoopbackAddress()).isTrue();
126136
assertThat(p.portGroup()).isZero();
127137
});
138+
}
128139

129-
// Must bound at two different port numbers because we didn't use `localPort()`.
130-
assertThat(ports.stream().mapToInt(p -> p.localAddress().getPort()).distinct()).hasSize(2);
140+
/**
141+
* Similar to {@link #builtWithoutLocalPort()} but we bind two IPv4 loopback addresses only.
142+
* The two ports must have different port numbers and must not belong to any port group.
143+
*/
144+
@Test
145+
void builtWithoutLocalPortIpV4() {
146+
final Collection<ServerPort> ports = serverBuiltWithoutLocalPortIpV4.server().activePorts().values();
147+
148+
// Must bound to both IPv4 loopback addresses.
149+
assertThat(ports).hasSize(2);
150+
151+
// Must be IPv4 loopback addresses and not belong to any port group.
152+
ports.forEach(p -> {
153+
assertThat(p.localAddress().getAddress()).isEqualTo(NetUtil.LOCALHOST4);
154+
assertThat(p.portGroup()).isZero();
155+
});
156+
157+
// Must be bound at different port numbers since they were bound independently.
158+
assertThat(ports.stream()
159+
.mapToInt(p -> p.localAddress().getPort())
160+
.distinct()).hasSize(2);
131161
}
132162
}

0 commit comments

Comments
 (0)