This is an automated email from the ASF dual-hosted git repository.

ppkarwasz pushed a commit to branch feat/2.x/uniform-uri-conversion
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 7edba86f2669cc2e5bfc39ac972eafbc866ba2f6
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Sat Jun 27 13:40:14 2026 +0200

    Add cross-platform tests for `NetUtils.toURI` conversion
    
    Rework `NetUtilsTest` into parameterized cases that pin down how a string
    (a URI or a file system path) is converted to a `URI` on both UNIX and
    Windows. Every input is exercised on every OS; only the expected result
    differs, selected through `SystemUtils.IS_OS_WINDOWS`.
    
    These tests describe the intended, uniform behavior and therefore fail
    against the current `NetUtils.toURI` implementation. The fix follows in
    the next commit.
    
    Assisted-By: Claude Opus 4.8 <[email protected]>
---
 .../logging/log4j/core/util/NetUtilsTest.java      | 118 +++++++++++++--------
 1 file changed, 76 insertions(+), 42 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
index 9afa5f2069..562140351d 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
@@ -18,67 +18,101 @@ package org.apache.logging.log4j.core.util;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assumptions.assumeThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
-import java.io.File;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.UnknownHostException;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.SystemUtils;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledOnOs;
-import org.junit.jupiter.api.condition.OS;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 class NetUtilsTest {
 
-    @Test
-    void testToUriWithoutBackslashes() {
-        final String config = "file:///path/to/something/on/unix";
-        URI uri = NetUtils.toURI(config);
-
-        assertNotNull(uri, "The URI should not be null.");
-        assertEquals("file:///path/to/something/on/unix", uri.toString(), "The 
URI is not correct.");
-
-        final String properUriPath = "/path/without/spaces";
-        uri = NetUtils.toURI(properUriPath);
-
-        assertNotNull(uri, "The URI should not be null.");
-        assertEquals(properUriPath, uri.toString(), "The URI is not correct.");
+    /**
+     * {@link NetUtils#toURI(String)} over a mix of URIs and file system paths.
+     *
+     * <p>Every input is exercised on every OS. Only the expected result 
differs.</p>
+     */
+    @ParameterizedTest
+    @MethodSource
+    void toUriConvertsLocationsToUris(final String input, final String 
expected) {
+        assertThat(NetUtils.toURI(input)).hasToString(expected);
     }
 
-    @Test
-    void testToUriUnixWithSpaces() {
-        final String pathWithSpaces = "/ path / with / spaces";
-        final URI uri = NetUtils.toURI(pathWithSpaces);
-
-        assertNotNull(uri, "The URI should not be null.");
-        assertEquals(new File(pathWithSpaces).toURI().toString(), 
uri.toString(), "The URI is not correct.");
+    static Stream<Arguments> toUriConvertsLocationsToUris() {
+        return Stream.of(
+                // Genuine absolute URIs are returned verbatim on every 
platform.
+                arguments("file:///path/to/something/on/unix", 
"file:///path/to/something/on/unix"),
+                arguments("classpath:log4j2.xml", "classpath:log4j2.xml"),
+                arguments("classloader:log4j2.xml", "classloader:log4j2.xml"),
+                arguments("vfsfile:/some/path/log4j2.xml", 
"vfsfile:/some/path/log4j2.xml"),
+                // Well-formed layered Apache Commons VFS URLs are valid 
(opaque) URIs, returned verbatim.
+                arguments("zip:file:///path/a.zip!/dir/log4j2.xml", 
"zip:file:///path/a.zip!/dir/log4j2.xml"),
+                arguments(
+                        
"tar:gz:http://example.com/a.tar.gz!/a.tar!/log4j2.xml";,
+                        
"tar:gz:http://example.com/a.tar.gz!/a.tar!/log4j2.xml";),
+                // Blanks are illegal in a URI: a hierarchical URL is rebuilt 
with them encoded, preserving user info,
+                // host, port and query.
+                arguments(
+                        "http://example.com/a b/log4j2.xml?env=prod x",
+                        "http://example.com/a%20b/log4j2.xml?env=prod%20x";),
+                arguments(
+                        "https://[email protected]:8443/a b/log4j2.xml",
+                        "https://[email protected]:8443/a%20b/log4j2.xml";),
+                // A relative path stays a scheme-less relative URI on every 
platform.
+                arguments("relative/path/log4j2.xml", 
"relative/path/log4j2.xml"),
+                // The remaining inputs are file system paths: absolute on one 
OS (resolved to a `file:` URI) and
+                // relative on the other (a scheme-less URI, any drive-letter 
colon escaped to `%3A`).
+                perOs("/path/without/spaces", "/path/without/spaces", 
"file:/path/without/spaces"),
+                perOs(
+                        "/ path / with / spaces",
+                        "/%20path%20/%20with%20/%20spaces",
+                        "file:/%20path%20/%20with%20/%20spaces"),
+                perOs("C:/dir/log4j2.xml", "file:/C:/dir/log4j2.xml", 
"C%3A/dir/log4j2.xml"),
+                perOs("C:\\dir\\log4j2.xml", "file:/C:/dir/log4j2.xml", 
"C%3A%5Cdir%5Clog4j2.xml"),
+                perOs(
+                        "D:\\path\\to\\something\\on\\windows",
+                        "file:/D:/path/to/something/on/windows",
+                        "D%3A%5Cpath%5Cto%5Csomething%5Con%5Cwindows"),
+                perOs(
+                        "file:///D:\\path\\to\\something/on/windows",
+                        "file:///D:/path/to/something/on/windows",
+                        "file:///D:%5Cpath%5Cto%5Csomething/on/windows"));
     }
 
-    @Test
-    @EnabledOnOs(OS.WINDOWS)
-    void testToUriWindowsWithBackslashes() {
-        final String config = "file:///D:\\path\\to\\something/on/windows";
-        final URI uri = NetUtils.toURI(config);
-
-        assertNotNull(uri, "The URI should not be null.");
-        assertEquals("file:///D:/path/to/something/on/windows", 
uri.toString(), "The URI is not correct.");
+    /**
+     * Builds a case whose expected {@code toString()} differs between Windows 
and the other platforms.
+     */
+    private static Arguments perOs(final String input, final String onWindows, 
final String onUnix) {
+        return arguments(input, SystemUtils.IS_OS_WINDOWS ? onWindows : 
onUnix);
     }
 
-    @Test
-    @EnabledOnOs(OS.WINDOWS)
-    void testToUriWindowsAbsolutePath() {
-        final String config = "D:\\path\\to\\something\\on\\windows";
-        final URI uri = NetUtils.toURI(config);
+    @ParameterizedTest
+    @MethodSource
+    void toUrisSplitsOnComma(final String input, final String[] expected) {
+        
assertThat(NetUtils.toURIs(input)).extracting(URI::toString).containsExactly(expected);
+    }
 
-        assertNotNull(uri, "The URI should not be null.");
-        assertEquals("file:/D:/path/to/something/on/windows", uri.toString(), 
"The URI is not correct.");
+    static Stream<Arguments> toUrisSplitsOnComma() {
+        return Stream.of(
+                // A single location yields a single URI.
+                arguments("classpath:log4j2.xml", new String[] 
{"classpath:log4j2.xml"}),
+                // The scheme of the first location is propagated to the 
following ones, and blanks around the comma are
+                // trimmed.
+                arguments("classpath:first.xml, second.xml", new String[] 
{"classpath:first.xml", "classpath:second.xml"
+                }),
+                // Without a scheme each (relative) location is kept as-is.
+                arguments("a/first.xml,b/second.xml", new String[] 
{"a/first.xml", "b/second.xml"}));
     }
 
     @Test
-    void testCanonicalHostName() throws UnknownHostException {
+    void canonicalHostNameContainsDot() throws UnknownHostException {
         
assumeThat(InetAddress.getLocalHost().getCanonicalHostName()).contains(".");
-        // If this fails the host might be misconfigured
+        // If this fails the host might be misconfigured.
         assertThat(NetUtils.getCanonicalLocalHostname()).contains(".");
     }
 }

Reply via email to