diff --git a/spring-cloud-test-support/pom.xml b/spring-cloud-test-support/pom.xml index 73321a30..9a9f4c94 100644 --- a/spring-cloud-test-support/pom.xml +++ b/spring-cloud-test-support/pom.xml @@ -15,49 +15,41 @@ spring-cloud-test-support Spring Cloud Test Support - 1.0.2.v20150114 - 3.3.9 + 3.5.4 + 1.1.1 - org.eclipse.aether - aether-api - ${aether.version} + org.apache.maven.resolver + maven-resolver-connector-basic + ${maven-resolver.version} - org.eclipse.aether - aether-connector-basic - ${aether.version} - - - org.eclipse.aether - aether-impl - ${aether.version} - - - org.eclipse.aether - aether-spi - ${aether.version} - - - org.eclipse.aether - aether-transport-file - ${aether.version} - - - org.eclipse.aether - aether-transport-http - ${aether.version} - - - org.eclipse.aether - aether-util - ${aether.version} + org.apache.maven.resolver + maven-resolver-impl + ${maven-resolver.version} org.apache.maven - maven-core + maven-resolver-provider ${maven.version} + + + com.google.guava + guava + + + + + org.apache.maven.resolver + maven-resolver-transport-http + ${maven-resolver.version} + + + jcl-over-slf4j + org.slf4j + + junit @@ -72,5 +64,21 @@ spring-boot-starter-test test + + org.hibernate.validator + hibernate-validator + test + + + javax.validation + validation-api + + + + + jakarta.validation + jakarta.validation-api + test + diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java index f1acbf33..7d5c0753 100644 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java +++ b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java @@ -52,14 +52,17 @@ import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.TestClass; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.util.AntPathMatcher; import org.springframework.util.StringUtils; /** * A custom {@link BlockJUnit4ClassRunner} that runs tests using a modified class path. - * Entries are excluded from the class path using {@link ClassPathExclusions} and - * overridden using {@link ClassPathOverrides} on the test class. A class loader is + * Entries are excluded from the class path using + * {@link ClassPathExclusions @ClassPathExclusions} and overridden using + * {@link ClassPathOverrides @ClassPathOverrides} on the test class. A class loader is * created with the customized class path and is used both to load the test class and as * the thread context class loader while the test is being run. * @@ -178,9 +181,14 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { } private URL[] processUrls(URL[] urls, Class testClass) throws Exception { - ClassPathEntryFilter filter = new ClassPathEntryFilter(testClass); + MergedAnnotations annotations = MergedAnnotations.from(testClass, + SearchStrategy.EXHAUSTIVE); + ClassPathEntryFilter filter = new ClassPathEntryFilter( + annotations.get(ClassPathExclusions.class)); List processedUrls = new ArrayList<>(); - processedUrls.addAll(getAdditionalUrls(testClass)); + List additionalUrls = getAdditionalUrls( + annotations.get(ClassPathOverrides.class)); + processedUrls.addAll(additionalUrls); for (URL url : urls) { if (!filter.isExcluded(url)) { processedUrls.add(url); @@ -189,13 +197,12 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { return processedUrls.toArray(new URL[0]); } - private List getAdditionalUrls(Class testClass) throws Exception { - ClassPathOverrides overrides = AnnotationUtils.findAnnotation(testClass, - ClassPathOverrides.class); - if (overrides == null) { + private List getAdditionalUrls(MergedAnnotation annotation) + throws Exception { + if (!annotation.isPresent()) { return Collections.emptyList(); } - return resolveCoordinates(overrides.value()); + return resolveCoordinates(annotation.getStringArray(MergedAnnotation.VALUE)); } private List resolveCoordinates(String[] coordinates) throws Exception { @@ -243,13 +250,13 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { private final AntPathMatcher matcher = new AntPathMatcher(); - private ClassPathEntryFilter(Class testClass) throws Exception { + private ClassPathEntryFilter(MergedAnnotation annotation) + throws Exception { this.exclusions = new ArrayList<>(); this.exclusions.add("log4j-*.jar"); - ClassPathExclusions exclusions = AnnotationUtils.findAnnotation(testClass, - ClassPathExclusions.class); - if (exclusions != null) { - this.exclusions.addAll(Arrays.asList(exclusions.value())); + if (annotation.isPresent()) { + this.exclusions.addAll( + Arrays.asList(annotation.getStringArray(MergedAnnotation.VALUE))); } } diff --git a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java new file mode 100644 index 00000000..b2f1e7df --- /dev/null +++ b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed 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.springframework.cloud.test; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.isA; + +/** + * Tests for {@link ModifiedClassPathRunner} excluding entries from the class path. + * + * @author Andy Wilkinson + */ +@RunWith(ModifiedClassPathRunner.class) +@ClassPathExclusions("hibernate-validator-*.jar") +public class ModifiedClassPathRunnerExclusionsTests { + + private static final String EXCLUDED_RESOURCE = "META-INF/services/" + + "javax.validation.spi.ValidationProvider"; + + @Test + public void entriesAreFilteredFromTestClassClassLoader() { + assertThat(getClass().getClassLoader().getResource(EXCLUDED_RESOURCE)).isNull(); + } + + @Test + public void entriesAreFilteredFromThreadContextClassLoader() { + assertThat(Thread.currentThread().getContextClassLoader() + .getResource(EXCLUDED_RESOURCE)).isNull(); + } + + @Test + public void testsThatUseHamcrestWorkCorrectly() { + Matcher matcher = isA(IllegalStateException.class); + assertThat(matcher.matches(new IllegalStateException())).isTrue(); + } + +} diff --git a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java new file mode 100644 index 00000000..7f82f88e --- /dev/null +++ b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed 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.springframework.cloud.test; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.context.ApplicationContext; +import org.springframework.util.StringUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ModifiedClassPathRunner} overriding entries on the class path. + * + * @author Andy Wilkinson + */ +@RunWith(ModifiedClassPathRunner.class) +@ClassPathOverrides("org.springframework:spring-context:4.1.0.RELEASE") +public class ModifiedClassPathRunnerOverridesTests { + + @Test + public void classesAreLoadedFromOverride() { + assertThat(ApplicationContext.class.getProtectionDomain().getCodeSource() + .getLocation().toString()).endsWith("spring-context-4.1.0.RELEASE.jar"); + } + + @Test + public void classesAreLoadedFromTransitiveDependencyOfOverride() { + assertThat(StringUtils.class.getProtectionDomain().getCodeSource().getLocation() + .toString()).endsWith("spring-core-4.1.0.RELEASE.jar"); + } + +}