Skip to content

Commit 7795f02

Browse files
committed
Preserve registration order in @activeprofiles
With this commit, bean definition profiles declared via @activeprofiles are once again stored in registration order, in order to support use cases in Spring Boot and other frameworks that depend on the registration order. This effectively reverts the changes made in conjunction with gh-25973. Closes gh-26004
1 parent 0e49291 commit 7795f02

File tree

7 files changed

+44
-47
lines changed

7 files changed

+44
-47
lines changed

spring-test/src/main/java/org/springframework/test/context/ActiveProfiles.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@
7979
* <p>The default value is {@code true}, which means that a test
8080
* class will <em>inherit</em> bean definition profiles defined by a
8181
* test superclass. Specifically, the bean definition profiles for a test
82-
* class will be added to the list of bean definition profiles
82+
* class will be appended to the list of bean definition profiles
8383
* defined by a test superclass. Thus, subclasses have the option of
8484
* <em>extending</em> the list of bean definition profiles.
8585
* <p>If {@code inheritProfiles} is set to {@code false}, the bean

spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@
1919
import java.io.Serializable;
2020
import java.util.Arrays;
2121
import java.util.Collections;
22+
import java.util.LinkedHashSet;
2223
import java.util.Set;
23-
import java.util.TreeSet;
2424

2525
import org.springframework.context.ApplicationContext;
2626
import org.springframework.context.ApplicationContextInitializer;
@@ -533,8 +533,8 @@ private static String[] processActiveProfiles(@Nullable String[] activeProfiles)
533533
return EMPTY_STRING_ARRAY;
534534
}
535535

536-
// Active profiles must be unique and sorted
537-
Set<String> profilesSet = new TreeSet<>(Arrays.asList(activeProfiles));
536+
// Active profiles must be unique
537+
Set<String> profilesSet = new LinkedHashSet<>(Arrays.asList(activeProfiles));
538538
return StringUtils.toStringArray(profilesSet);
539539
}
540540

spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
package org.springframework.test.context.support;
1818

19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.LinkedHashSet;
22+
import java.util.List;
1923
import java.util.Set;
20-
import java.util.TreeSet;
2124

2225
import org.apache.commons.logging.Log;
2326
import org.apache.commons.logging.LogFactory;
@@ -67,7 +70,7 @@ abstract class ActiveProfilesUtils {
6770
static String[] resolveActiveProfiles(Class<?> testClass) {
6871
Assert.notNull(testClass, "Class must not be null");
6972

70-
Set<String> activeProfiles = new TreeSet<>();
73+
List<String[]> profileArrays = new ArrayList<>();
7174

7275
Class<ActiveProfiles> annotationType = ActiveProfiles.class;
7376
AnnotationDescriptor<ActiveProfiles> descriptor =
@@ -106,17 +109,25 @@ static String[] resolveActiveProfiles(Class<?> testClass) {
106109

107110
String[] profiles = resolver.resolve(rootDeclaringClass);
108111
if (!ObjectUtils.isEmpty(profiles)) {
109-
for (String profile : profiles) {
110-
if (StringUtils.hasText(profile)) {
111-
activeProfiles.add(profile.trim());
112-
}
113-
}
112+
profileArrays.add(profiles);
114113
}
115114

116115
descriptor = (annotation.inheritProfiles() ? MetaAnnotationUtils.findAnnotationDescriptor(
117116
rootDeclaringClass.getSuperclass(), annotationType) : null);
118117
}
119118

119+
// Reverse the list so that we can traverse "down" the hierarchy.
120+
Collections.reverse(profileArrays);
121+
122+
Set<String> activeProfiles = new LinkedHashSet<>();
123+
for (String[] profiles : profileArrays) {
124+
for (String profile : profiles) {
125+
if (StringUtils.hasText(profile)) {
126+
activeProfiles.add(profile.trim());
127+
}
128+
}
129+
}
130+
120131
return StringUtils.toStringArray(activeProfiles);
121132
}
122133

spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@
1616

1717
package org.springframework.test.context.support;
1818

19-
import java.util.Set;
20-
import java.util.TreeSet;
21-
2219
import org.apache.commons.logging.Log;
2320
import org.apache.commons.logging.LogFactory;
2421

2522
import org.springframework.test.context.ActiveProfiles;
2623
import org.springframework.test.context.ActiveProfilesResolver;
2724
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
2825
import org.springframework.util.Assert;
29-
import org.springframework.util.StringUtils;
3026

3127
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
3228

@@ -43,6 +39,8 @@
4339
*/
4440
public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
4541

42+
private static final String[] EMPTY_STRING_ARRAY = new String[0];
43+
4644
private static final Log logger = LogFactory.getLog(DefaultActiveProfilesResolver.class);
4745

4846

@@ -58,36 +56,24 @@ public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
5856
@Override
5957
public String[] resolve(Class<?> testClass) {
6058
Assert.notNull(testClass, "Class must not be null");
61-
62-
Set<String> activeProfiles = new TreeSet<>();
63-
64-
Class<ActiveProfiles> annotationType = ActiveProfiles.class;
65-
AnnotationDescriptor<ActiveProfiles> descriptor = findAnnotationDescriptor(testClass, annotationType);
59+
AnnotationDescriptor<ActiveProfiles> descriptor = findAnnotationDescriptor(testClass, ActiveProfiles.class);
6660

6761
if (descriptor == null) {
6862
if (logger.isDebugEnabled()) {
6963
logger.debug(String.format(
7064
"Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]",
71-
annotationType.getName(), testClass.getName()));
65+
ActiveProfiles.class.getName(), testClass.getName()));
7266
}
67+
return EMPTY_STRING_ARRAY;
7368
}
7469
else {
75-
Class<?> declaringClass = descriptor.getDeclaringClass();
7670
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
77-
7871
if (logger.isTraceEnabled()) {
7972
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,
80-
declaringClass.getName()));
81-
}
82-
83-
for (String profile : annotation.profiles()) {
84-
if (StringUtils.hasText(profile)) {
85-
activeProfiles.add(profile.trim());
86-
}
73+
descriptor.getDeclaringClass().getName()));
8774
}
75+
return annotation.profiles();
8876
}
89-
90-
return StringUtils.toStringArray(activeProfiles);
9177
}
9278

9379
}

spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -143,7 +143,7 @@ public void hashCodeWithSameProfilesReversed() {
143143
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader);
144144
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(),
145145
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles2, loader);
146-
assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode());
146+
assertNotEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode());
147147
}
148148

149149
@Test
@@ -339,7 +339,7 @@ public void equalsWithSameProfilesReversed() {
339339
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles1, loader);
340340
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(),
341341
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, activeProfiles2, loader);
342-
assertEquals(mergedConfig1, mergedConfig2);
342+
assertNotEquals(mergedConfig1, mergedConfig2);
343343
}
344344

345345
@Test

spring-test/src/test/java/org/springframework/test/context/cache/ContextCacheTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -90,8 +90,8 @@ public void verifyCacheKeyIsBasedOnActiveProfiles() {
9090
int size = 0, hit = 0, miss = 0;
9191
loadCtxAndAssertStats(FooBarProfilesTestCase.class, ++size, hit, ++miss);
9292
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
93-
// Profiles {foo, bar} MUST hash to the same as {bar, foo}
94-
loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss);
93+
// Profiles {foo, bar} should not hash to the same as {bar,foo}
94+
loadCtxAndAssertStats(BarFooProfilesTestCase.class, ++size, hit, ++miss);
9595
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
9696
loadCtxAndAssertStats(FooBarProfilesTestCase.class, size, ++hit, miss);
9797
loadCtxAndAssertStats(BarFooProfilesTestCase.class, size, ++hit, miss);

spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ public void resolveActiveProfilesWithEmptyProfiles() {
6565

6666
@Test
6767
public void resolveActiveProfilesWithDuplicatedProfiles() {
68-
assertResolvedProfiles(DuplicatedProfiles.class, "bar", "baz", "foo");
68+
assertResolvedProfiles(DuplicatedProfiles.class, "foo", "bar", "baz");
6969
}
7070

7171
@Test
7272
public void resolveActiveProfilesWithLocalAndInheritedDuplicatedProfiles() {
73-
assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "bar", "baz", "cat", "dog", "foo");
73+
assertResolvedProfiles(ExtendedDuplicatedProfiles.class, "foo", "bar", "baz", "cat", "dog");
7474
}
7575

7676
@Test
@@ -90,12 +90,12 @@ public void resolveActiveProfilesWithInheritedAnnotationAndClasses() {
9090

9191
@Test
9292
public void resolveActiveProfilesWithLocalAndInheritedAnnotations() {
93-
assertResolvedProfiles(LocationsBar.class, "bar", "foo");
93+
assertResolvedProfiles(LocationsBar.class, "foo", "bar");
9494
}
9595

9696
@Test
9797
public void resolveActiveProfilesWithOverriddenAnnotation() {
98-
assertResolvedProfiles(Animals.class, "cat", "dog");
98+
assertResolvedProfiles(Animals.class, "dog", "cat");
9999
}
100100

101101
/**
@@ -127,15 +127,15 @@ public void resolveActiveProfilesWithMetaAnnotationAndOverriddenAttributes() {
127127
*/
128128
@Test
129129
public void resolveActiveProfilesWithLocalAndInheritedMetaAnnotations() {
130-
assertResolvedProfiles(MetaLocationsBar.class, "bar", "foo");
130+
assertResolvedProfiles(MetaLocationsBar.class, "foo", "bar");
131131
}
132132

133133
/**
134134
* @since 4.0
135135
*/
136136
@Test
137137
public void resolveActiveProfilesWithOverriddenMetaAnnotation() {
138-
assertResolvedProfiles(MetaAnimals.class, "cat", "dog");
138+
assertResolvedProfiles(MetaAnimals.class, "dog", "cat");
139139
}
140140

141141
/**
@@ -159,7 +159,7 @@ public void resolveActiveProfilesWithInheritedResolver() {
159159
*/
160160
@Test
161161
public void resolveActiveProfilesWithMergedInheritedResolver() {
162-
assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "bar", "foo");
162+
assertResolvedProfiles(MergedInheritedFooActiveProfilesResolverTestCase.class, "foo", "bar");
163163
}
164164

165165
/**

0 commit comments

Comments
 (0)