This is an automated email from the ASF dual-hosted git repository.
apolovtsev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 4f16d3f39d0 IGNITE-27806 Fix network tests on Mac (#7574)
4f16d3f39d0 is described below
commit 4f16d3f39d0929e2b83dab2511ec398dda362e59
Author: Alexander Polovtcev <[email protected]>
AuthorDate: Wed Feb 11 12:48:11 2026 +0200
IGNITE-27806 Fix network tests on Mac (#7574)
---
.../scalecube/ItMulticastNodeFinderTest.java | 8 ++-
.../internal/network/MulticastNodeFinder.java | 75 ++++++++++++++--------
.../internal/network/netty/NettyServerTest.java | 3 +
3 files changed, 55 insertions(+), 31 deletions(-)
diff --git
a/modules/network/src/integrationTest/java/org/apache/ignite/internal/network/scalecube/ItMulticastNodeFinderTest.java
b/modules/network/src/integrationTest/java/org/apache/ignite/internal/network/scalecube/ItMulticastNodeFinderTest.java
index f4d2aa7afe6..e314eeb3a87 100644
---
a/modules/network/src/integrationTest/java/org/apache/ignite/internal/network/scalecube/ItMulticastNodeFinderTest.java
+++
b/modules/network/src/integrationTest/java/org/apache/ignite/internal/network/scalecube/ItMulticastNodeFinderTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.network.scalecube;
import static org.apache.ignite.internal.network.MulticastNodeFinder.MAX_TTL;
import static
org.apache.ignite.internal.network.MulticastNodeFinder.UNSPECIFIED_TTL;
+import static
org.apache.ignite.internal.network.MulticastNodeFinder.isReservedMacOsInterface;
import static
org.apache.ignite.internal.network.utils.ClusterServiceTestUtils.clusterService;
import static
org.apache.ignite.internal.network.utils.ClusterServiceTestUtils.findLocalAddresses;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
@@ -85,10 +86,10 @@ class ItMulticastNodeFinderTest extends IgniteAbstractTest {
int nodeCount = 5;
List<NetworkAddress> addresses = findLocalAddresses(INIT_PORT,
INIT_PORT + nodeCount);
- for (int i = 0; i < addresses.size(); i++) {
- NodeFinder finder = startMulticastNodeFinder(addresses.get(i),
ttl);
+ for (NetworkAddress address : addresses) {
+ NodeFinder finder = startMulticastNodeFinder(address, ttl);
finders.add(finder);
- services.add(startNetwork(addresses.get(i), finder));
+ services.add(startNetwork(address, finder));
}
for (ClusterService service : services) {
@@ -123,6 +124,7 @@ class ItMulticastNodeFinderTest extends IgniteAbstractTest {
private static NodeFinder startMulticastNodeFinder(NetworkAddress addr,
int ttl) throws SocketException {
Set<NetworkAddress> addressesToAdvertise =
NetworkInterface.networkInterfaces()
+ .filter(itf -> !isReservedMacOsInterface(itf))
.flatMap(NetworkInterface::inetAddresses)
.map(address -> new NetworkAddress(address.getHostName(),
addr.port()))
.collect(Collectors.toUnmodifiableSet());
diff --git
a/modules/network/src/main/java/org/apache/ignite/internal/network/MulticastNodeFinder.java
b/modules/network/src/main/java/org/apache/ignite/internal/network/MulticastNodeFinder.java
index 50bd8693e81..7cf4eee7969 100644
---
a/modules/network/src/main/java/org/apache/ignite/internal/network/MulticastNodeFinder.java
+++
b/modules/network/src/main/java/org/apache/ignite/internal/network/MulticastNodeFinder.java
@@ -131,7 +131,7 @@ public class MulticastNodeFinder implements NodeFinder {
public Collection<NetworkAddress> findNodes() {
Set<NetworkAddress> result = new HashSet<>();
- // Creates multicast sockets for all eligible interfaces and an
unbound socket. Will throw an exception if no sockets were created.
+ // Create sockets for sending discovery requests.
List<MulticastSocket> sockets = createSockets(0, resultWaitMillis,
false);
ExecutorService executor = Executors.newFixedThreadPool(
@@ -140,12 +140,10 @@ public class MulticastNodeFinder implements NodeFinder {
);
try {
- // Will contain nodes, found on all eligible interfaces and an
unbound socket.
List<CompletableFuture<Collection<NetworkAddress>>> futures =
sockets.stream()
.map(socket -> supplyAsync(() -> findOnSocket(socket),
executor))
.collect(toList());
- // Collect results.
for (CompletableFuture<Collection<NetworkAddress>> future :
futures) {
try {
result.addAll(future.get(resultWaitMillis * REQ_ATTEMPTS *
2L, TimeUnit.MILLISECONDS));
@@ -226,7 +224,9 @@ public class MulticastNodeFinder implements NodeFinder {
return false;
}
- }).collect(toSet());
+ })
+ .filter(itf -> !isReservedMacOsInterface(itf))
+ .collect(toSet());
} catch (SocketException e) {
LOG.error("Error getting network interfaces for multicast node
finder", e);
@@ -234,6 +234,17 @@ public class MulticastNodeFinder implements NodeFinder {
}
}
+ /**
+ * Returns {@code true} if the given network interface is a macOS-specfic
interface.
+ *
+ * <p>These interfaces may support multicast but third-party applications
may not be able to bind to them.
+ */
+ public static boolean isReservedMacOsInterface(NetworkInterface
networkInterface) {
+ String name = networkInterface.getName();
+
+ return name.startsWith("llw") || name.startsWith("awdl") ||
name.startsWith("utun");
+ }
+
@Override
public void close() {
stopped = true;
@@ -243,14 +254,10 @@ public class MulticastNodeFinder implements NodeFinder {
@Override
public void start() {
- // Create multicast sockets for all eligible interfaces and an unbound
socket. Will throw an exception if no sockets were created.
+ // Create sockets for listening to multicast requests.
List<MulticastSocket> sockets = createSockets(multicastPort,
POLLING_TIMEOUT_MILLIS, true);
- if (sockets.isEmpty()) {
- throw new IgniteInternalException(INTERNAL_ERR, "No sockets for
multicast listener were created.");
- }
-
- listenerThreadPool.submit(() -> {
+ listenerThreadPool.execute(() -> {
byte[] responseData =
NetworkAddressesSerializer.serialize(addressesToAdvertise);
byte[] requestBuffer = new byte[REQUEST_MESSAGE.length];
@@ -267,7 +274,7 @@ public class MulticastNodeFinder implements NodeFinder {
byte[] received = receiveDatagramData(socket,
requestPacket);
if (!Arrays.equals(received, REQUEST_MESSAGE)) {
- LOG.error("Received unexpected request on
multicast socket");
+ LOG.error("Received unexpected request on
multicast socket {}", socket.getLocalSocketAddress());
continue;
}
@@ -306,27 +313,29 @@ public class MulticastNodeFinder implements NodeFinder {
List<MulticastSocket> sockets = new ArrayList<>();
for (NetworkInterface networkInterface :
getEligibleNetworkInterfaces()) {
- addSocket(sockets, port, networkInterface, soTimeout, joinGroup);
+ MulticastSocket socket = createSocket(port, networkInterface,
soTimeout, joinGroup);
- if (joinGroup) {
- LOG.info("Multicast listener socket created for interface:
{}", networkInterface.getDisplayName());
- } else {
- LOG.info("Multicast node finder socket created for interface:
{}", networkInterface.getDisplayName());
+ if (socket != null) {
+ sockets.add(socket);
}
}
- addSocket(sockets, multicastPort, null, soTimeout, joinGroup);
-
+ // Use the unbound socket as a fallback.
if (sockets.isEmpty()) {
- throw new IgniteInternalException(INTERNAL_ERR, "No multicast
sockets were created.");
+ MulticastSocket unboundSocket = createSocket(port, null,
soTimeout, joinGroup);
+
+ if (unboundSocket == null) {
+ throw new IgniteInternalException(INTERNAL_ERR, "No multicast
sockets were created.");
+ }
+
+ sockets.add(unboundSocket);
}
return sockets;
}
- /** Create socket, configure it with given parameters and add it to the
given collection. */
- private void addSocket(
- Collection<MulticastSocket> sockets,
+ /** Creates a multicast socket and configures it with the given
parameters. Returns {@code null} if a socket could not be created. */
+ private @Nullable MulticastSocket createSocket(
int port,
@Nullable NetworkInterface networkInterface,
int soTimeout,
@@ -357,13 +366,19 @@ public class MulticastNodeFinder implements NodeFinder {
socket.joinGroup(multicastSocketAddress, networkInterface);
}
- sockets.add(socket);
- } catch (IOException e) {
- if (networkInterface != null) {
- LOG.error("Failed to create multicast socket for interface
{}", e, networkInterface.getName());
- } else {
- LOG.error("Failed to create multicast socket for an unbound
interface", e);
+ if (LOG.isInfoEnabled()) {
+ if (joinGroup) {
+ LOG.info("Multicast listener socket created: {}/{}",
displayName(networkInterface), port);
+ } else {
+ LOG.info("Multicast node finder socket created: {}",
displayName(networkInterface));
+ }
}
+
+ return socket;
+ } catch (IOException e) {
+ LOG.error("Failed to create multicast socket: {}/{}", e,
displayName(networkInterface), port);
+
+ return null;
}
}
@@ -384,4 +399,8 @@ public class MulticastNodeFinder implements NodeFinder {
LOG.error("Could not close multicast listeners", e);
}
}
+
+ private static String displayName(@Nullable NetworkInterface
networkInterface) {
+ return networkInterface != null ? networkInterface.getDisplayName() :
"unbound";
+ }
}
diff --git
a/modules/network/src/test/java/org/apache/ignite/internal/network/netty/NettyServerTest.java
b/modules/network/src/test/java/org/apache/ignite/internal/network/netty/NettyServerTest.java
index 6e3beff664c..91aa32d05c4 100644
---
a/modules/network/src/test/java/org/apache/ignite/internal/network/netty/NettyServerTest.java
+++
b/modules/network/src/test/java/org/apache/ignite/internal/network/netty/NettyServerTest.java
@@ -72,6 +72,8 @@ import
org.apache.ignite.internal.network.serialization.UserObjectSerializationC
import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InOrder;
import org.mockito.Mockito;
@@ -162,6 +164,7 @@ public class NettyServerTest extends BaseIgniteAbstractTest
{
/**
* Tests that bootstrap tries to bind to address specified in
configuration.
*/
+ @DisabledOnOs(value = OS.MAC, disabledReason = "On MAC the target address
is not a loopback address.")
@Test
public void testBindWithAddress() {
String host = "127.0.0.7";