From 3dc60f1627675b8029c0c9283a75bd2b1b5d6a1e Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 7 Oct 2022 11:01:02 +0200 Subject: [PATCH 1/2] Backport changes to PathMatchingResourcePatternResolverTests --- ...hMatchingResourcePatternResolverTests.java | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java index 31b3d6938cb..f04cecec072 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; @@ -48,9 +49,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; class PathMatchingResourcePatternResolverTests { private static final String[] CLASSES_IN_CORE_IO_SUPPORT = { "EncodedResource.class", - "LocalizedResourceHelper.class", "PathMatchingResourcePatternResolver.class", "PropertiesLoaderSupport.class", - "PropertiesLoaderUtils.class", "ResourceArrayPropertyEditor.class", "ResourcePatternResolver.class", - "ResourcePatternUtils.class", "SpringFactoriesLoader.class" }; + "LocalizedResourceHelper.class", "PathMatchingResourcePatternResolver.class", "PropertiesLoaderSupport.class", + "PropertiesLoaderUtils.class", "ResourceArrayPropertyEditor.class", "ResourcePatternResolver.class", + "ResourcePatternUtils.class", "SpringFactoriesLoader.class" }; private static final String[] TEST_CLASSES_IN_CORE_IO_SUPPORT = { "PathMatchingResourcePatternResolverTests.class" }; @@ -67,7 +68,6 @@ class PathMatchingResourcePatternResolverTests { void invalidPrefixWithPatternElementInItThrowsException() { assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(() -> resolver.getResources("xx**:**/*.xy")); } - } @@ -93,18 +93,22 @@ class PathMatchingResourcePatternResolverTests { @Test void usingClasspathStarProtocol() { String pattern = "classpath*:org/springframework/core/io/**/resource#test*.txt"; + String pathPrefix = ".+org/springframework/core/io/"; + assertExactFilenames(pattern, "resource#test1.txt", "resource#test2.txt"); + assertExactSubPaths(pattern, pathPrefix, "support/resource#test1.txt", "support/resource#test2.txt"); } @Test - void usingFilePrototol() { + void usingFileProtocol() { Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); String pattern = String.format("file:%s/scanned-resources/**", testResourcesDir); + String pathPrefix = ".+scanned-resources/"; + assertExactFilenames(pattern, "resource#test1.txt", "resource#test2.txt"); + assertExactSubPaths(pattern, pathPrefix, "resource#test1.txt", "resource#test2.txt"); } - } - } @@ -142,7 +146,6 @@ class PathMatchingResourcePatternResolverTests { .as("Could not find aspectj_1_5_0.dtd in the root of the aspectjweaver jar") .containsExactly("aspectj_1_5_0.dtd"); } - } @@ -181,4 +184,30 @@ class PathMatchingResourcePatternResolverTests { } } + private void assertExactSubPaths(String pattern, String pathPrefix, String... subPaths) { + try { + Resource[] resources = resolver.getResources(pattern); + List actualSubPaths = Arrays.stream(resources) + .map(resource -> getPath(resource).replaceFirst(pathPrefix, "")) + .sorted() + .collect(Collectors.toList()); + assertThat(actualSubPaths).containsExactlyInAnyOrder(subPaths); + } + catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + + private String getPath(Resource resource) { + // Tests fail if we use resouce.getURL().getPath(). They would also fail on Mac OS when + // using resouce.getURI().getPath() if the resource paths are not Unicode normalized. + // + // On the JVM, all tests should pass when using resouce.getFile().getPath(); however, + // we use FileSystemResource#getPath since this test class is sometimes run within a + // GraalVM native image which cannot support Path#toFile. + // + // See: https://github.com/spring-projects/spring-framework/issues/29243 + return ((FileSystemResource) resource).getPath(); + } + } From 8caed88c148a0912aee277cf081cd45e8321fe3d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 7 Oct 2022 11:27:57 +0200 Subject: [PATCH 2/2] Test status quo for URI/URL for scanned filesystem resources See gh-29275 --- .../PathMatchingResourcePatternResolverTests.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java index f04cecec072..ced415af9df 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java @@ -108,6 +108,21 @@ class PathMatchingResourcePatternResolverTests { assertExactFilenames(pattern, "resource#test1.txt", "resource#test2.txt"); assertExactSubPaths(pattern, pathPrefix, "resource#test1.txt", "resource#test2.txt"); } + + @Test + void usingFileProtocolAndAssertingUrlAndUriSyntax() throws Exception { + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); + String pattern = String.format("file:%s/scanned-resources/**/resource#test1.txt", testResourcesDir); + Resource[] resources = resolver.getResources(pattern); + assertThat(resources).hasSize(1); + Resource resource = resources[0]; + assertThat(resource.getFilename()).isEqualTo("resource#test1.txt"); + // The following assertions serve as regression tests for the lack of the + // "authority component" (//) in the returned URI/URL. For example, we are + // expecting file:/my/path (or file:/C:/My/Path) instead of file:///my/path. + assertThat(resource.getURL().toString()).matches("^file:\\/[^\\/].+test1\\.txt$"); + assertThat(resource.getURI().toString()).matches("^file:\\/[^\\/].+test1\\.txt$"); + } } }