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 1bbaf8bee5..b9b8ddfd64 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-2020 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -83,7 +83,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 added to the list of bean definition profiles
+ * class will be appended 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 db37af2f02..f434b14022 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-2020 the original author or authors.
+ * Copyright 2002-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.
@@ -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 and sorted
- Set profilesSet = new TreeSet<>(Arrays.asList(activeProfiles));
+ // Active profiles must be unique
+ Set profilesSet = new LinkedHashSet<>(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 901b1d3a72..927cd9acc4 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,8 +16,11 @@
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,8 +73,8 @@ abstract class ActiveProfilesUtils {
static String[] resolveActiveProfiles(Class> testClass) {
Assert.notNull(testClass, "Class must not be null");
- Set activeProfiles = new TreeSet<>();
AnnotationDescriptor descriptor = findAnnotationDescriptor(testClass, ActiveProfiles.class);
+ List profileArrays = new ArrayList<>();
if (descriptor == null && logger.isDebugEnabled()) {
logger.debug(String.format(
@@ -107,16 +110,24 @@ abstract class ActiveProfilesUtils {
String[] profiles = resolver.resolve(rootDeclaringClass);
if (!ObjectUtils.isEmpty(profiles)) {
- for (String profile : profiles) {
- if (StringUtils.hasText(profile)) {
- activeProfiles.add(profile.trim());
- }
- }
+ profileArrays.add(profiles);
}
descriptor = (annotation.inheritProfiles() ? descriptor.next() : null);
}
+ // Reverse the list so that we can traverse "down" the hierarchy.
+ Collections.reverse(profileArrays);
+
+ 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/test/java/org/springframework/test/context/MergedContextConfigurationTests.java b/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java
index 25c8530c49..002da9c991 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-2020 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -143,7 +143,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).hasSameHashCodeAs(mergedConfig1);
+ assertThat(mergedConfig2.hashCode()).isNotEqualTo(mergedConfig1.hashCode());
}
@Test
@@ -339,13 +339,13 @@ 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).isEqualTo(mergedConfig1);
+ assertThat(mergedConfig2).isNotEqualTo(mergedConfig1);
}
@Test
void equalsWithSameDuplicateProfiles() {
String[] activeProfiles1 = new String[] { "catbert", "dogbert" };
- String[] activeProfiles2 = new String[] { "dogbert", "catbert", "dogbert", "catbert" };
+ String[] activeProfiles2 = new String[] { "catbert", "dogbert", "catbert", "dogbert", "catbert" };
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(),
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader);
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(),
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 357535ce41..202af4bb4b 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-2020 the original author or authors.
+ * Copyright 2002-2019 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} MUST hash to the same as {bar, foo}
- loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss);
+ // Profiles {foo, bar} should not 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 7228415d14..b192b34ee2 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, "bar", "baz", "foo");
+ assertResolvedProfiles(DuplicatedProfiles.class, "foo", "bar", "baz");
}
@Test
void resolveActiveProfilesWithLocalAndInheritedDuplicatedProfiles() {
- assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "bar", "baz", "cat", "dog", "foo");
+ assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "foo", "bar", "baz", "cat", "dog");
}
@Test
@@ -92,12 +92,12 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests {
@Test
void resolveActiveProfilesWithLocalAndInheritedAnnotations() {
- assertResolvedProfiles(LocationsBar.class, "bar", "foo");
+ assertResolvedProfiles(LocationsBar.class, "foo", "bar");
}
@Test
void resolveActiveProfilesWithOverriddenAnnotation() {
- assertResolvedProfiles(Animals.class, "cat", "dog");
+ assertResolvedProfiles(Animals.class, "dog", "cat");
}
/**
@@ -129,7 +129,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests {
*/
@Test
void resolveActiveProfilesWithLocalAndInheritedMetaAnnotations() {
- assertResolvedProfiles(MetaLocationsBar.class, "bar", "foo");
+ assertResolvedProfiles(MetaLocationsBar.class, "foo", "bar");
}
/**
@@ -137,7 +137,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests {
*/
@Test
void resolveActiveProfilesWithOverriddenMetaAnnotation() {
- assertResolvedProfiles(MetaAnimals.class, "cat", "dog");
+ assertResolvedProfiles(MetaAnimals.class, "dog", "cat");
}
/**
@@ -161,7 +161,7 @@ class ActiveProfilesUtilsTests extends AbstractContextConfigurationUtilsTests {
*/
@Test
void resolveActiveProfilesWithMergedInheritedResolver() {
- assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "bar", "foo");
+ assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "foo", "bar");
}
/**
diff --git a/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java
index 4336ec5c83..c44b90e9aa 100644
--- a/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java
@@ -373,6 +373,8 @@ class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigurationUt
void buildMergedConfigWithDuplicateConfigurationOnEnclosingClassAndNestedClass() {
compareApplesToApples(AppleConfigTestCase.class, AppleConfigTestCase.Nested.class);
compareApplesToApples(AppleConfigTestCase.Nested.class, AppleConfigTestCase.Nested.DoubleNested.class);
+ compareApplesToOranges(ApplesAndOrangesConfigTestCase.class, ApplesAndOrangesConfigTestCase.Nested.class);
+ compareApplesToOranges(ApplesAndOrangesConfigTestCase.Nested.class, ApplesAndOrangesConfigTestCase.Nested.DoubleNested.class);
}
private void compareApplesToApples(Class> parent, Class> child) {
@@ -400,7 +402,7 @@ class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigurationUt
DelegatingSmartContextLoader.class);
assertThat(parentMergedConfig.getActiveProfiles()).as("active profiles")
- .containsExactly("apples", "oranges")
+ .containsExactly("oranges", "apples")
.isEqualTo(childMergedConfig.getActiveProfiles());
assertThat(parentMergedConfig).isEqualTo(childMergedConfig);
}
@@ -531,7 +533,7 @@ class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigurationUt
}
@ContextConfiguration(classes = AppleConfig.class)
- @ActiveProfiles({"apples", "oranges"})
+ @ActiveProfiles({"oranges", "apples"})
static class ApplesAndOrangesConfigTestCase {
@ContextConfiguration(classes = AppleConfig.class)
@@ -539,19 +541,19 @@ class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigurationUt
class Nested {
@ContextConfiguration(classes = AppleConfig.class)
- @ActiveProfiles(profiles = {"apples", "oranges", "apples"}, inheritProfiles = false)
+ @ActiveProfiles(profiles = {"oranges", "apples", "oranges"}, inheritProfiles = false)
class DoubleNested {
}
}
}
@ContextConfiguration(classes = AppleConfig.class)
- @ActiveProfiles(profiles = {"oranges", "apples"}, inheritProfiles = false)
+ @ActiveProfiles(profiles = {"oranges", "apples", "oranges"}, inheritProfiles = false)
static class DuplicateConfigApplesAndOrangesConfigTestCase extends ApplesAndOrangesConfigTestCase {
}
@ContextConfiguration(classes = AppleConfig.class)
- @ActiveProfiles(profiles = {"apples", "oranges", "apples"}, inheritProfiles = false)
+ @ActiveProfiles(profiles = {"oranges", "apples", "oranges"}, inheritProfiles = false)
static class SubDuplicateConfigApplesAndOrangesConfigTestCase extends DuplicateConfigApplesAndOrangesConfigTestCase {
}