diff --git a/spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java b/spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java index 9ad1e3068aa..a5ee5b264a9 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java +++ b/spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -79,7 +79,7 @@ public @interface ActiveProfiles { *

The default value is {@code true}, which means that a test * class will inherit bean definition profiles defined by a * test superclass. Specifically, the bean definition profiles for a test - * class will be appended to the list of bean definition profiles + * class will be added to the list of bean definition profiles * defined by a test superclass. Thus, subclasses have the option of * extending the list of bean definition profiles. *

If {@code inheritProfiles} is set to {@code false}, the bean diff --git a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index f434b14022a..db37af2f02b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 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. @@ -19,8 +19,8 @@ package org.springframework.test.context; import java.io.Serializable; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashSet; import java.util.Set; +import java.util.TreeSet; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; @@ -533,8 +533,8 @@ public class MergedContextConfiguration implements Serializable { return EMPTY_STRING_ARRAY; } - // Active profiles must be unique - Set profilesSet = new LinkedHashSet<>(Arrays.asList(activeProfiles)); + // Active profiles must be unique and sorted + Set profilesSet = new TreeSet<>(Arrays.asList(activeProfiles)); return StringUtils.toStringArray(profilesSet); } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java index f56d935f16a..5e2c76582ab 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java @@ -16,11 +16,8 @@ package org.springframework.test.context.support; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; +import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -70,7 +67,7 @@ abstract class ActiveProfilesUtils { static String[] resolveActiveProfiles(Class testClass) { Assert.notNull(testClass, "Class must not be null"); - final List profileArrays = new ArrayList<>(); + Set activeProfiles = new TreeSet<>(); Class annotationType = ActiveProfiles.class; AnnotationDescriptor descriptor = @@ -109,25 +106,17 @@ abstract class ActiveProfilesUtils { String[] profiles = resolver.resolve(rootDeclaringClass); if (!ObjectUtils.isEmpty(profiles)) { - profileArrays.add(profiles); + for (String profile : profiles) { + if (StringUtils.hasText(profile)) { + activeProfiles.add(profile.trim()); + } + } } descriptor = (annotation.inheritProfiles() ? MetaAnnotationUtils.findAnnotationDescriptor( rootDeclaringClass.getSuperclass(), annotationType) : null); } - // Reverse the list so that we can traverse "down" the hierarchy. - Collections.reverse(profileArrays); - - final Set activeProfiles = new LinkedHashSet<>(); - for (String[] profiles : profileArrays) { - for (String profile : profiles) { - if (StringUtils.hasText(profile)) { - activeProfiles.add(profile.trim()); - } - } - } - return StringUtils.toStringArray(activeProfiles); } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java b/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java index da65af7d78a..83ee7d6909f 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -16,8 +16,8 @@ package org.springframework.test.context.support; -import java.util.LinkedHashSet; import java.util.Set; +import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,7 +59,7 @@ public class DefaultActiveProfilesResolver implements ActiveProfilesResolver { public String[] resolve(Class testClass) { Assert.notNull(testClass, "Class must not be null"); - final Set activeProfiles = new LinkedHashSet<>(); + Set activeProfiles = new TreeSet<>(); Class annotationType = ActiveProfiles.class; AnnotationDescriptor descriptor = findAnnotationDescriptor(testClass, annotationType); diff --git a/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java b/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java index 85020c7b13a..3311f14443a 100644 --- a/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -339,7 +339,7 @@ class MergedContextConfigurationTests { EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader); MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles2, loader); - assertThat(mergedConfig2).isNotEqualTo(mergedConfig1); + assertThat(mergedConfig2).isEqualTo(mergedConfig1); } @Test diff --git a/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java b/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java index 202af4bb4b1..357535ce41e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -90,8 +90,8 @@ class ContextCacheTests { int size = 0, hit = 0, miss = 0; loadCtxAndAssertStats(FooBarProfilesTestCase.class, ++size, hit, ++miss); loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss); - // Profiles {foo, bar} should not hash to the same as {bar,foo} - loadCtxAndAssertStats(BarFooProfilesTestCase.class, ++size, hit, ++miss); + // Profiles {foo, bar} MUST hash to the same as {bar, foo} + loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss); loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss); loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss); loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss); diff --git a/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java index b192b34ee24..7228415d140 100644 --- a/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java @@ -67,12 +67,12 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests { @Test void resolveActiveProfilesWithDuplicatedProfiles() { - assertResolvedProfiles(DuplicatedProfiles.class, "foo", "bar", "baz"); + assertResolvedProfiles(DuplicatedProfiles.class, "bar", "baz", "foo"); } @Test void resolveActiveProfilesWithLocalAndInheritedDuplicatedProfiles() { - assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "foo", "bar", "baz", "cat", "dog"); + assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "bar", "baz", "cat", "dog", "foo"); } @Test @@ -92,12 +92,12 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests { @Test void resolveActiveProfilesWithLocalAndInheritedAnnotations() { - assertResolvedProfiles(LocationsBar.class, "foo", "bar"); + assertResolvedProfiles(LocationsBar.class, "bar", "foo"); } @Test void resolveActiveProfilesWithOverriddenAnnotation() { - assertResolvedProfiles(Animals.class, "dog", "cat"); + assertResolvedProfiles(Animals.class, "cat", "dog"); } /** @@ -129,7 +129,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests { */ @Test void resolveActiveProfilesWithLocalAndInheritedMetaAnnotations() { - assertResolvedProfiles(MetaLocationsBar.class, "foo", "bar"); + assertResolvedProfiles(MetaLocationsBar.class, "bar", "foo"); } /** @@ -137,7 +137,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests { */ @Test void resolveActiveProfilesWithOverriddenMetaAnnotation() { - assertResolvedProfiles(MetaAnimals.class, "dog", "cat"); + assertResolvedProfiles(MetaAnimals.class, "cat", "dog"); } /** @@ -161,7 +161,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests { */ @Test void resolveActiveProfilesWithMergedInheritedResolver() { - assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "foo", "bar"); + assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "bar", "foo"); } /**