This is an automated email from the ASF dual-hosted git repository.
chrisdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new e095044990 fix: Implemented something to gracefully detect if PCAP
libs are not available and to skip the tests related to that.
e095044990 is described below
commit e095044990e21cb4fd5219c2dd200b94651a5648
Author: Christofer Dutz <[email protected]>
AuthorDate: Fri Jun 12 16:31:02 2026 +0200
fix: Implemented something to gracefully detect if PCAP libs are not
available and to skip the tests related to that.
---
.../java/transport/rawsocket/PcapTestSupport.java | 84 ++++++++++++++++++++++
.../rawsocket/RawSocketTransportInstanceTest.java | 24 +------
.../rawsocket/RawSocketTransportTest.java | 39 ++--------
.../rawsocket/SharedRawSocketManagerTest.java | 29 +-------
4 files changed, 94 insertions(+), 82 deletions(-)
diff --git
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/PcapTestSupport.java
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/PcapTestSupport.java
new file mode 100644
index 0000000000..ca7a8987bd
--- /dev/null
+++
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/PcapTestSupport.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.transport.rawsocket;
+
+import org.pcap4j.core.PcapNetworkInterface;
+import org.pcap4j.core.Pcaps;
+
+import java.io.File;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+/**
+ * Helper for the pcap-based tests.
+ * <p>
+ * The pcap4j native library (libpcap on *nix/macOS, wpcap.dll on Windows) is
not
+ * available on all CI nodes - notably Windows runners without WinPcap/Npcap
installed.
+ * When the native library can't be loaded, pcap4j fails by throwing {@link
Error}s
+ * (e.g. {@link NoClassDefFoundError} / {@link UnsatisfiedLinkError} /
+ * {@link ExceptionInInitializerError}) rather than checked exceptions, so a
plain
+ * {@code catch (Exception ...)} doesn't skip the affected tests and the build
fails.
+ * These helpers translate any {@link Throwable} into a JUnit assumption so
the tests
+ * are skipped instead.
+ */
+final class PcapTestSupport {
+
+ private PcapTestSupport() {
+ }
+
+ /**
+ * Points JNA at a libpcap installation in the well-known Homebrew
locations on macOS.
+ * On other platforms this is a no-op and the default library resolution
is used.
+ */
+ static void configureNativeLibraryPath() {
+ // For some reason it doesn't work if we pass this in from the outside.
+ // On an Intel Mac the libs are in:
"/usr/local/Cellar/libpcap/<version>/lib"
+ // On an M1 Mac the libs are in: "/opt/homebrew/opt/libpcap/lib"
+ if (new File("/usr/local/Cellar/libpcap/1.10.1/lib").exists()) {
+ System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.1/lib");
+ } else if (new File("/usr/local/Cellar/libpcap/1.10.5/lib").exists()) {
+ System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.5/lib");
+ } else if (new File("/opt/homebrew/opt/libpcap/lib").exists()) {
+ System.getProperties().setProperty("jna.library.path",
"/opt/homebrew/opt/libpcap/lib");
+ }
+ }
+
+ /**
+ * Returns the available pcap network interfaces, or aborts the current
test (via a
+ * JUnit assumption) if pcap is unavailable - either because the native
library could
+ * not be loaded or because no interfaces were found.
+ *
+ * @return the (non-empty) list of network interfaces
+ */
+ static List<PcapNetworkInterface> findAllDevsOrSkip() {
+ configureNativeLibraryPath();
+ List<PcapNetworkInterface> devs;
+ try {
+ devs = Pcaps.findAllDevs();
+ } catch (Throwable t) {
+ // Native library missing/unloadable (NoClassDefFoundError,
UnsatisfiedLinkError, ...)
+ // or pcap permission issues - skip rather than fail.
+ assumeTrue(false, "pcap native library not available, skipping
test: " + t);
+ throw new AssertionError("unreachable");
+ }
+ assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ return devs;
+ }
+}
diff --git
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportInstanceTest.java
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportInstanceTest.java
index 3b61b695d0..df4a925966 100644
---
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportInstanceTest.java
+++
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportInstanceTest.java
@@ -27,10 +27,8 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.PcapNetworkInterface;
-import org.pcap4j.core.Pcaps;
import org.pcap4j.util.MacAddress;
-import java.io.File;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@@ -53,26 +51,8 @@ class RawSocketTransportInstanceTest {
@BeforeEach
void setUp() {
try {
- // For some reason it doesn't work if we pass this in from the
outside.
- //if (os == "mac") {
- // On my Intel Mac I found the libs in:
"/usr/local/Cellar/libpcap/1.10.1/lib"
- // On my M1 Mac I found the libs in:
"/opt/homebrew/Cellar/libpcap/1.10.1/lib"
- if (new File("/usr/local/Cellar/libpcap/1.10.1/lib").exists())
{
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.1/lib");
- } else if (new
File("/usr/local/Cellar/libpcap/1.10.5/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.5/lib");
- } else if (new File("/opt/homebrew/opt/libpcap/lib").exists())
{
- System.getProperties().setProperty("jna.library.path",
"/opt/homebrew/opt/libpcap/lib");
- }
- //}
- } catch (Error e) {
- e.printStackTrace();
- }
-
- try {
- // Find available network interface
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ // Find available network interface (skips the test if pcap native
libs are unavailable)
+ List<PcapNetworkInterface> devs =
PcapTestSupport.findAllDevsOrSkip();
// Find an Ethernet-capable interface (not loopback, not tunnel)
PcapNetworkInterface selectedNif = null;
diff --git
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportTest.java
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportTest.java
index e20b896df5..37ea129f33 100644
---
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportTest.java
+++
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/RawSocketTransportTest.java
@@ -27,14 +27,11 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.pcap4j.core.PcapNetworkInterface;
-import org.pcap4j.core.Pcaps;
-import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
// Timeout prevents pcap operations from hanging the entire test suite
@Timeout(value = 30, unit = TimeUnit.SECONDS)
@@ -44,23 +41,7 @@ class RawSocketTransportTest {
@BeforeEach
void setUp() {
- try {
- // For some reason it doesn't work if we pass this in from the
outside.
- //if (os == "mac") {
- // On my Intel Mac I found the libs in:
"/usr/local/Cellar/libpcap/1.10.1/lib"
- // On my M1 Mac I found the libs in:
"/opt/homebrew/Cellar/libpcap/1.10.1/lib"
- if (new File("/usr/local/Cellar/libpcap/1.10.1/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.1/lib");
- } else if (new
File("/usr/local/Cellar/libpcap/1.10.5/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.5/lib");
- } else if (new File("/opt/homebrew/opt/libpcap/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/opt/homebrew/opt/libpcap/lib");
- }
- //}
- } catch (Error e) {
- throw new RuntimeException("Could not set JNA library path", e);
- }
-
+ PcapTestSupport.configureNativeLibraryPath();
transport = new RawSocketTransport();
}
@@ -82,8 +63,7 @@ class RawSocketTransportTest {
@Test
void testCreateTransportInstance_dedicated() throws Exception {
// Skip if no network interfaces or no pcap permissions
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
@@ -110,8 +90,7 @@ class RawSocketTransportTest {
@Test
void testCreateTransportInstance_shared() throws Exception {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
@@ -137,8 +116,7 @@ class RawSocketTransportTest {
@Test
//@Disabled("All of a sudden this test hangs ... investigate")
void testCreateTransportInstance_multipleShared() throws Exception {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
@@ -179,8 +157,7 @@ class RawSocketTransportTest {
@Test
void testCreateTransportInstance_withVLAN() throws Exception {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
@@ -207,8 +184,7 @@ class RawSocketTransportTest {
@Test
void testCreateTransportInstance_withCustomBPF() throws Exception {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
@@ -234,8 +210,7 @@ class RawSocketTransportTest {
@Test
void testCreateTransportInstance_promiscuousMode() throws Exception {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
+ List<PcapNetworkInterface> devs = PcapTestSupport.findAllDevsOrSkip();
PcapNetworkInterface nif = devs.get(0);
diff --git
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/SharedRawSocketManagerTest.java
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/SharedRawSocketManagerTest.java
index 90298c17fe..e708ad382f 100644
---
a/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/SharedRawSocketManagerTest.java
+++
b/plc4j/transports/raw-socket/src/test/java/org/apache/plc4x/java/transport/rawsocket/SharedRawSocketManagerTest.java
@@ -21,13 +21,10 @@ package org.apache.plc4x.java.transport.rawsocket;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.pcap4j.core.PcapNetworkInterface;
-import org.pcap4j.core.Pcaps;
-import java.io.File;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
/**
* Tests for SharedRawSocketManager.
@@ -40,32 +37,8 @@ class SharedRawSocketManagerTest {
@BeforeEach
void setUp() {
- try {
- // For some reason it doesn't work if we pass this in from the
outside.
- //if (os == "mac") {
- // On my Intel Mac I found the libs in:
"/usr/local/Cellar/libpcap/1.10.1/lib"
- // On my M1 Mac I found the libs in:
"/opt/homebrew/Cellar/libpcap/1.10.1/lib"
- if (new File("/usr/local/Cellar/libpcap/1.10.1/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.1/lib");
- } else if (new
File("/usr/local/Cellar/libpcap/1.10.5/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/usr/local/Cellar/libpcap/1.10.5/lib");
- } else if (new File("/opt/homebrew/opt/libpcap/lib").exists()) {
- System.getProperties().setProperty("jna.library.path",
"/opt/homebrew/opt/libpcap/lib");
- }
- //}
- } catch (Error e) {
- e.printStackTrace();
- }
-
manager = new SharedRawSocketManager();
-
- try {
- List<PcapNetworkInterface> devs = Pcaps.findAllDevs();
- assumeTrue(devs != null && !devs.isEmpty(), "No network interfaces
found");
- testInterface = devs.get(0);
- } catch (Exception e) {
- assumeTrue(false, "Could not find network interfaces: " +
e.getMessage());
- }
+ testInterface = PcapTestSupport.findAllDevsOrSkip().get(0);
}
@Test