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

Reply via email to