Merge branch '6.0.x'

This commit is contained in:
Sam Brannen
2023-04-25 18:11:35 +02:00
5 changed files with 379 additions and 192 deletions

View File

@@ -56,6 +56,8 @@ package org.springframework.core.env;
* of property sources prior to application context {@code refresh()}. * of property sources prior to application context {@code refresh()}.
* *
* @author Chris Beams * @author Chris Beams
* @author Phillip Webb
* @author Sam Brannen
* @since 3.1 * @since 3.1
* @see PropertyResolver * @see PropertyResolver
* @see EnvironmentCapable * @see EnvironmentCapable
@@ -94,25 +96,56 @@ public interface Environment extends PropertyResolver {
String[] getDefaultProfiles(); String[] getDefaultProfiles();
/** /**
* Return whether one or more of the given profiles is active or, in the case of no * Determine whether one or more of the given profiles is active — or
* explicit active profiles, whether one or more of the given profiles is included in * in the case of no explicit {@linkplain #getActiveProfiles() active profiles},
* the set of default profiles. If a profile begins with '!' the logic is inverted, * whether one or more of the given profiles is included in the set of
* i.e. the method will return {@code true} if the given profile is <em>not</em> active. * {@linkplain #getDefaultProfiles() default profiles}.
* For example, {@code env.acceptsProfiles("p1", "!p2")} will return {@code true} if * <p>If a profile begins with '!' the logic is inverted, meaning this method
* profile 'p1' is active or 'p2' is not active. * will return {@code true} if the given profile is <em>not</em> active. For
* @throws IllegalArgumentException if called with zero arguments * example, {@code env.acceptsProfiles("p1", "!p2")} will return {@code true}
* or if any profile is {@code null}, empty, or whitespace only * if profile 'p1' is active or 'p2' is not active.
* @throws IllegalArgumentException if called with a {@code null} array, an
* empty array, zero arguments or if any profile is {@code null}, empty, or
* whitespace only
* @see #getActiveProfiles * @see #getActiveProfiles
* @see #getDefaultProfiles * @see #getDefaultProfiles
* @see #matchesProfiles(String...)
* @see #acceptsProfiles(Profiles) * @see #acceptsProfiles(Profiles)
* @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)} * @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)} or
* {@link #matchesProfiles(String...)}
*/ */
@Deprecated @Deprecated
boolean acceptsProfiles(String... profiles); boolean acceptsProfiles(String... profiles);
/** /**
* Return whether the {@linkplain #getActiveProfiles() active profiles} * Determine whether one of the given profile expressions matches the
* match the given {@link Profiles} predicate. * {@linkplain #getActiveProfiles() active profiles} &mdash; or in the case
* of no explicit active profiles, whether one of the given profile expressions
* matches the {@linkplain #getDefaultProfiles() default profiles}.
* <p>Profile expressions allow for complex, boolean profile logic to be
* expressed &mdash; for example {@code "p1 & p2"}, {@code "(p1 & p2) | p3"},
* etc. See {@link Profiles#of(String...)} for details on the supported
* expression syntax.
* <p>This method is a convenient shortcut for
* {@code env.acceptsProfiles(Profiles.of(profileExpressions))}.
* @since 5.3.28
* @see Profiles#of(String...)
* @see #acceptsProfiles(Profiles)
*/
default boolean matchesProfiles(String... profileExpressions) {
return acceptsProfiles(Profiles.of(profileExpressions));
}
/**
* Determine whether the given {@link Profiles} predicate matches the
* {@linkplain #getActiveProfiles() active profiles} &mdash; or in the case
* of no explicit active profiles, whether the given {@code Profiles} predicate
* matches the {@linkplain #getDefaultProfiles() default profiles}.
* <p>If you wish provide profile expressions directly as strings, use
* {@link #matchesProfiles(String...)} instead.
* @since 5.1
* @see #matchesProfiles(String...)
* @see Profiles#of(String...)
*/ */
boolean acceptsProfiles(Profiles profiles); boolean acceptsProfiles(Profiles profiles);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -43,32 +43,32 @@ public interface Profiles {
/** /**
* Create a new {@link Profiles} instance that checks for matches against * Create a new {@link Profiles} instance that checks for matches against
* the given <em>profile strings</em>. * the given <em>profile expressions</em>.
* <p>The returned instance will {@linkplain Profiles#matches(Predicate) match} * <p>The returned instance will {@linkplain Profiles#matches(Predicate) match}
* if any one of the given profile strings matches. * if any one of the given profile expressions matches.
* <p>A profile string may contain a simple profile name (for example * <p>A profile expression may contain a simple profile name (for example
* {@code "production"}) or a profile expression. A profile expression allows * {@code "production"}) or a compound expression. A compound expression allows
* for more complicated profile logic to be expressed, for example * for more complicated profile logic to be expressed, for example
* {@code "production & cloud"}. * {@code "production & cloud"}.
* <p>The following operators are supported in profile expressions. * <p>The following operators are supported in profile expressions.
* <ul> * <ul>
* <li>{@code !} - A logical <em>NOT</em> of the profile or profile expression</li> * <li>{@code !} - A logical <em>NOT</em> of the profile name or compound expression</li>
* <li>{@code &} - A logical <em>AND</em> of the profiles or profile expressions</li> * <li>{@code &} - A logical <em>AND</em> of the profile names or compound expressions</li>
* <li>{@code |} - A logical <em>OR</em> of the profiles or profile expressions</li> * <li>{@code |} - A logical <em>OR</em> of the profile names or compound expressions</li>
* </ul> * </ul>
* <p>Please note that the {@code &} and {@code |} operators may not be mixed * <p>Please note that the {@code &} and {@code |} operators may not be mixed
* without using parentheses. For example {@code "a & b | c"} is not a valid * without using parentheses. For example, {@code "a & b | c"} is not a valid
* expression; it must be expressed as {@code "(a & b) | c"} or * expression: it must be expressed as {@code "(a & b) | c"} or
* {@code "a & (b | c)"}. * {@code "a & (b | c)"}.
* <p>As of Spring Framework 5.1.17, two {@code Profiles} instances returned * <p>As of Spring Framework 5.1.17, two {@code Profiles} instances returned
* by this method are considered equivalent to each other (in terms of * by this method are considered equivalent to each other (in terms of
* {@code equals()} and {@code hashCode()} semantics) if they are created * {@code equals()} and {@code hashCode()} semantics) if they are created
* with identical <em>profile strings</em>. * with identical <em>profile expressions</em>.
* @param profiles the <em>profile strings</em> to include * @param profileExpressions the <em>profile expressions</em> to include
* @return a new {@link Profiles} instance * @return a new {@link Profiles} instance
*/ */
static Profiles of(String... profiles) { static Profiles of(String... profileExpressions) {
return ProfilesParser.parse(profiles); return ProfilesParser.parse(profileExpressions);
} }
} }

View File

@@ -43,7 +43,7 @@ final class ProfilesParser {
static Profiles parse(String... expressions) { static Profiles parse(String... expressions) {
Assert.notEmpty(expressions, "Must specify at least one profile"); Assert.notEmpty(expressions, "Must specify at least one profile expression");
Profiles[] parsed = new Profiles[expressions.length]; Profiles[] parsed = new Profiles[expressions.length];
for (int i = 0; i < expressions.length; i++) { for (int i = 0; i < expressions.length; i++) {
parsed[i] = parseExpression(expressions[i]); parsed[i] = parseExpression(expressions[i]);
@@ -136,8 +136,8 @@ final class ProfilesParser {
return activeProfile -> activeProfile.test(profile); return activeProfile -> activeProfile.test(profile);
} }
private static Predicate<Profiles> isMatch(Predicate<String> activeProfile) { private static Predicate<Profiles> isMatch(Predicate<String> activeProfiles) {
return profiles -> profiles.matches(activeProfile); return profiles -> profiles.matches(activeProfiles);
} }

View File

@@ -40,30 +40,30 @@ class ProfilesTests {
@Test @Test
void ofWhenNullThrowsException() { void ofWhenNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException()
Profiles.of((String[]) null)) .isThrownBy(() -> Profiles.of((String[]) null))
.withMessageContaining("Must specify at least one profile"); .withMessage("Must specify at least one profile expression");
} }
@Test @Test
void ofWhenEmptyThrowsException() { void ofWhenEmptyThrowsException() {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(Profiles::of) .isThrownBy(Profiles::of)
.withMessageContaining("Must specify at least one profile"); .withMessage("Must specify at least one profile expression");
} }
@Test @Test
void ofNullElement() { void ofNullElement() {
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException()
Profiles.of((String) null)) .isThrownBy(() -> Profiles.of((String) null))
.withMessageContaining("must contain text"); .withMessage("Invalid profile expression [null]: must contain text");
} }
@Test @Test
void ofEmptyElement() { void ofEmptyElement() {
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException()
Profiles.of(" ")) .isThrownBy(() -> Profiles.of(" "))
.withMessageContaining("must contain text"); .withMessage("Invalid profile expression [ ]: must contain text");
} }
@Test @Test
@@ -381,7 +381,7 @@ class ProfilesTests {
private static void assertMalformed(Supplier<Profiles> supplier) { private static void assertMalformed(Supplier<Profiles> supplier) {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(supplier::get) .isThrownBy(supplier::get)
.withMessageContaining("Malformed"); .withMessageStartingWith("Malformed profile expression");
} }
private static Predicate<String> activeProfiles(String... profiles) { private static Predicate<String> activeProfiles(String... profiles) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
package org.springframework.core.env; package org.springframework.core.env;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.core.SpringProperties; import org.springframework.core.SpringProperties;
@@ -37,8 +37,7 @@ import static org.springframework.core.env.AbstractEnvironment.RESERVED_DEFAULT_
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Sam Brannen * @author Sam Brannen
*/ */
@SuppressWarnings("deprecation") class StandardEnvironmentTests {
public class StandardEnvironmentTests {
private static final String ALLOWED_PROPERTY_NAME = "theanswer"; private static final String ALLOWED_PROPERTY_NAME = "theanswer";
private static final String ALLOWED_PROPERTY_VALUE = "42"; private static final String ALLOWED_PROPERTY_VALUE = "42";
@@ -78,8 +77,8 @@ public class StandardEnvironmentTests {
assertThat(parent.getProperty("parentKey")).isEqualTo("parentVal"); assertThat(parent.getProperty("parentKey")).isEqualTo("parentVal");
assertThat(parent.getProperty("bothKey")).isEqualTo("parentBothVal"); assertThat(parent.getProperty("bothKey")).isEqualTo("parentBothVal");
assertThat(child.getActiveProfiles()).isEqualTo(new String[]{"c1","c2"}); assertThat(child.getActiveProfiles()).containsExactly("c1", "c2");
assertThat(parent.getActiveProfiles()).isEqualTo(new String[]{"p1","p2"}); assertThat(parent.getActiveProfiles()).containsExactly("p1", "p2");
child.merge(parent); child.merge(parent);
@@ -91,8 +90,8 @@ public class StandardEnvironmentTests {
assertThat(parent.getProperty("parentKey")).isEqualTo("parentVal"); assertThat(parent.getProperty("parentKey")).isEqualTo("parentVal");
assertThat(parent.getProperty("bothKey")).isEqualTo("parentBothVal"); assertThat(parent.getProperty("bothKey")).isEqualTo("parentBothVal");
assertThat(child.getActiveProfiles()).isEqualTo(new String[]{"c1","c2","p1","p2"}); assertThat(child.getActiveProfiles()).containsExactly("c1", "c2", "p1", "p2");
assertThat(parent.getActiveProfiles()).isEqualTo(new String[]{"p1","p2"}); assertThat(parent.getActiveProfiles()).containsExactly("p1", "p2");
} }
@Test @Test
@@ -118,16 +117,14 @@ public class StandardEnvironmentTests {
@Test @Test
void defaultProfilesContainsDefaultProfileByDefault() { void defaultProfilesContainsDefaultProfileByDefault() {
assertThat(environment.getDefaultProfiles()).hasSize(1); assertThat(environment.getDefaultProfiles()).containsExactly("default");
assertThat(environment.getDefaultProfiles()[0]).isEqualTo("default");
} }
@Test @Test
void setActiveProfiles() { void setActiveProfiles() {
environment.setActiveProfiles("local", "embedded"); environment.setActiveProfiles("local", "embedded");
String[] activeProfiles = environment.getActiveProfiles(); String[] activeProfiles = environment.getActiveProfiles();
assertThat(activeProfiles).contains("local", "embedded"); assertThat(activeProfiles).containsExactly("local", "embedded");
assertThat(activeProfiles).hasSize(2);
} }
@Test @Test
@@ -174,15 +171,12 @@ public class StandardEnvironmentTests {
void addActiveProfile() { void addActiveProfile() {
assertThat(environment.getActiveProfiles()).isEmpty(); assertThat(environment.getActiveProfiles()).isEmpty();
environment.setActiveProfiles("local", "embedded"); environment.setActiveProfiles("local", "embedded");
assertThat(environment.getActiveProfiles()).contains("local", "embedded"); assertThat(environment.getActiveProfiles()).containsExactly("local", "embedded");
assertThat(environment.getActiveProfiles()).hasSize(2);
environment.addActiveProfile("p1"); environment.addActiveProfile("p1");
assertThat(environment.getActiveProfiles()).contains("p1"); assertThat(environment.getActiveProfiles()).containsExactly("local", "embedded", "p1");
assertThat(environment.getActiveProfiles()).hasSize(3);
environment.addActiveProfile("p2"); environment.addActiveProfile("p2");
environment.addActiveProfile("p3"); environment.addActiveProfile("p3");
assertThat(environment.getActiveProfiles()).contains("p2", "p3"); assertThat(environment.getActiveProfiles()).containsExactly("local", "embedded", "p1", "p2", "p3");
assertThat(environment.getActiveProfiles()).hasSize(5);
} }
@Test @Test
@@ -192,24 +186,17 @@ public class StandardEnvironmentTests {
env.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1")); env.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
assertThat(env.getProperty(ACTIVE_PROFILES_PROPERTY_NAME)).isEqualTo("p1"); assertThat(env.getProperty(ACTIVE_PROFILES_PROPERTY_NAME)).isEqualTo("p1");
env.addActiveProfile("p2"); env.addActiveProfile("p2");
assertThat(env.getActiveProfiles()).contains("p1", "p2"); assertThat(env.getActiveProfiles()).containsExactly("p1", "p2");
} }
@Test @Test
void reservedDefaultProfile() { void reservedDefaultProfile() {
assertThat(environment.getDefaultProfiles()).isEqualTo(new String[]{RESERVED_DEFAULT_PROFILE_NAME}); assertThat(environment.getDefaultProfiles()).containsExactly(RESERVED_DEFAULT_PROFILE_NAME);
System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "d0");
assertThat(environment.getDefaultProfiles()).isEqualTo(new String[]{"d0"});
environment.setDefaultProfiles("d1", "d2");
assertThat(environment.getDefaultProfiles()).isEqualTo(new String[]{"d1","d2"});
System.clearProperty(DEFAULT_PROFILES_PROPERTY_NAME);
}
@Test
void defaultProfileWithCircularPlaceholder() {
try { try {
System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "${spring.profiles.default}"); System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "d0");
assertThatIllegalArgumentException().isThrownBy(environment::getDefaultProfiles); assertThat(environment.getDefaultProfiles()).containsExactly("d0");
environment.setDefaultProfiles("d1", "d2");
assertThat(environment.getDefaultProfiles()).containsExactly("d1","d2");
} }
finally { finally {
System.clearProperty(DEFAULT_PROFILES_PROPERTY_NAME); System.clearProperty(DEFAULT_PROFILES_PROPERTY_NAME);
@@ -217,40 +204,23 @@ public class StandardEnvironmentTests {
} }
@Test @Test
void getActiveProfiles_systemPropertiesEmpty() { void defaultProfileWithCircularPlaceholder() {
assertThat(environment.getActiveProfiles()).isEmpty(); try {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, ""); System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "${spring.profiles.default}");
assertThat(environment.getActiveProfiles()).isEmpty(); assertThatIllegalArgumentException()
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME); .isThrownBy(environment::getDefaultProfiles)
} .withMessage("Circular placeholder reference 'spring.profiles.default' in property definitions");
}
@Test finally {
void getActiveProfiles_fromSystemProperties() { System.clearProperty(DEFAULT_PROFILES_PROPERTY_NAME);
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo"); }
assertThat(Arrays.asList(environment.getActiveProfiles())).contains("foo");
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
@Test
void getActiveProfiles_fromSystemProperties_withMultipleProfiles() {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo,bar");
assertThat(environment.getActiveProfiles()).contains("foo", "bar");
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
@Test
void getActiveProfiles_fromSystemProperties_withMultipleProfiles_withWhitespace() {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, " bar , baz "); // notice whitespace
assertThat(environment.getActiveProfiles()).contains("bar", "baz");
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
} }
@Test @Test
void getDefaultProfiles() { void getDefaultProfiles() {
assertThat(environment.getDefaultProfiles()).isEqualTo(new String[] {RESERVED_DEFAULT_PROFILE_NAME}); assertThat(environment.getDefaultProfiles()).containsExactly(RESERVED_DEFAULT_PROFILE_NAME);
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(DEFAULT_PROFILES_PROPERTY_NAME, "pd1")); environment.getPropertySources().addFirst(new MockPropertySource().withProperty(DEFAULT_PROFILES_PROPERTY_NAME, "pd1"));
assertThat(environment.getDefaultProfiles()).hasSize(1); assertThat(environment.getDefaultProfiles()).containsExactly("pd1");
assertThat(Arrays.asList(environment.getDefaultProfiles())).contains("pd1");
} }
@Test @Test
@@ -258,82 +228,9 @@ public class StandardEnvironmentTests {
environment.setDefaultProfiles(); environment.setDefaultProfiles();
assertThat(environment.getDefaultProfiles()).isEmpty(); assertThat(environment.getDefaultProfiles()).isEmpty();
environment.setDefaultProfiles("pd1"); environment.setDefaultProfiles("pd1");
assertThat(Arrays.asList(environment.getDefaultProfiles())).contains("pd1"); assertThat(environment.getDefaultProfiles()).containsExactly("pd1");
environment.setDefaultProfiles("pd2", "pd3"); environment.setDefaultProfiles("pd2", "pd3");
assertThat(environment.getDefaultProfiles()).doesNotContain("pd1"); assertThat(environment.getDefaultProfiles()).containsExactly("pd2", "pd3");
assertThat(environment.getDefaultProfiles()).contains("pd2", "pd3");
}
@Test
void acceptsProfiles_withEmptyArgumentList() {
assertThatIllegalArgumentException().isThrownBy(
environment::acceptsProfiles);
}
@Test
void acceptsProfiles_withNullArgumentList() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles((String[]) null));
}
@Test
void acceptsProfiles_withNullArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles((String) null));
}
@Test
void acceptsProfiles_withEmptyArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles(""));
}
@Test
void acceptsProfiles_activeProfileSetProgrammatically() {
assertThat(environment.acceptsProfiles("p1", "p2")).isFalse();
environment.setActiveProfiles("p1");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p2");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p1", "p2");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
}
@Test
void acceptsProfiles_activeProfileSetViaProperty() {
assertThat(environment.acceptsProfiles("p1")).isFalse();
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
assertThat(environment.acceptsProfiles("p1")).isTrue();
}
@Test
void acceptsProfiles_defaultProfile() {
assertThat(environment.acceptsProfiles("pd")).isFalse();
environment.setDefaultProfiles("pd");
assertThat(environment.acceptsProfiles("pd")).isTrue();
environment.setActiveProfiles("p1");
assertThat(environment.acceptsProfiles("pd")).isFalse();
assertThat(environment.acceptsProfiles("p1")).isTrue();
}
@Test
void acceptsProfiles_withNotOperator() {
assertThat(environment.acceptsProfiles("p1")).isFalse();
assertThat(environment.acceptsProfiles("!p1")).isTrue();
environment.addActiveProfile("p1");
assertThat(environment.acceptsProfiles("p1")).isTrue();
assertThat(environment.acceptsProfiles("!p1")).isFalse();
}
@Test
void acceptsProfiles_withInvalidNotOperator() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles("p1", "!"));
}
@Test
void acceptsProfiles_withProfileExpression() {
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isFalse();
environment.addActiveProfile("p1");
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isFalse();
environment.addActiveProfile("p2");
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isTrue();
} }
@Test @Test
@@ -343,48 +240,59 @@ public class StandardEnvironmentTests {
protected void validateProfile(String profile) { protected void validateProfile(String profile) {
super.validateProfile(profile); super.validateProfile(profile);
if (profile.contains("-")) { if (profile.contains("-")) {
throw new IllegalArgumentException( throw new IllegalArgumentException("Invalid profile [" + profile + "]: must not contain dash character");
"Invalid profile [" + profile + "]: must not contain dash character");
} }
} }
}; };
env.addActiveProfile("validProfile"); // succeeds env.addActiveProfile("validProfile"); // succeeds
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException()
env.addActiveProfile("invalid-profile")) .isThrownBy(() -> env.addActiveProfile("invalid-profile"))
.withMessage("Invalid profile [invalid-profile]: must not contain dash character"); .withMessage("Invalid profile [invalid-profile]: must not contain dash character");
} }
@Test @Test
void suppressGetenvAccessThroughSystemProperty() { void suppressGetenvAccessThroughSystemProperty() {
System.setProperty("spring.getenv.ignore", "true"); try {
assertThat(environment.getSystemEnvironment().isEmpty()).isTrue(); System.setProperty("spring.getenv.ignore", "true");
System.clearProperty("spring.getenv.ignore"); assertThat(environment.getSystemEnvironment()).isEmpty();
}
finally {
System.clearProperty("spring.getenv.ignore");
}
} }
@Test @Test
void suppressGetenvAccessThroughSpringProperty() { void suppressGetenvAccessThroughSpringProperty() {
SpringProperties.setProperty("spring.getenv.ignore", "true"); try {
assertThat(environment.getSystemEnvironment().isEmpty()).isTrue(); SpringProperties.setProperty("spring.getenv.ignore", "true");
SpringProperties.setProperty("spring.getenv.ignore", null); assertThat(environment.getSystemEnvironment()).isEmpty();
}
finally {
SpringProperties.setProperty("spring.getenv.ignore", null);
}
} }
@Test @Test
void suppressGetenvAccessThroughSpringFlag() { void suppressGetenvAccessThroughSpringFlag() {
SpringProperties.setFlag("spring.getenv.ignore"); try {
assertThat(environment.getSystemEnvironment().isEmpty()).isTrue(); SpringProperties.setFlag("spring.getenv.ignore");
SpringProperties.setProperty("spring.getenv.ignore", null); assertThat(environment.getSystemEnvironment()).isEmpty();
}
finally {
SpringProperties.setProperty("spring.getenv.ignore", null);
}
} }
@Test @Test
void getSystemProperties() { void getSystemProperties() {
System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE);
System.setProperty(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE);
System.getProperties().put(STRING_PROPERTY_NAME, NON_STRING_PROPERTY_VALUE);
System.getProperties().put(NON_STRING_PROPERTY_NAME, STRING_PROPERTY_VALUE);
try { try {
System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE);
System.setProperty(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE);
System.getProperties().put(STRING_PROPERTY_NAME, NON_STRING_PROPERTY_VALUE);
System.getProperties().put(NON_STRING_PROPERTY_NAME, STRING_PROPERTY_VALUE);
Map<?, ?> systemProperties = environment.getSystemProperties(); Map<?, ?> systemProperties = environment.getSystemProperties();
assertThat(systemProperties).isNotNull(); assertThat(systemProperties).isNotNull();
assertThat(System.getProperties()).isSameAs(systemProperties); assertThat(System.getProperties()).isSameAs(systemProperties);
@@ -408,4 +316,250 @@ public class StandardEnvironmentTests {
assertThat(System.getenv()).isSameAs(systemEnvironment); assertThat(System.getenv()).isSameAs(systemEnvironment);
} }
@Nested
class GetActiveProfiles {
@Test
void systemPropertiesEmpty() {
assertThat(environment.getActiveProfiles()).isEmpty();
try {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "");
assertThat(environment.getActiveProfiles()).isEmpty();
}
finally {
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
}
@Test
void fromSystemProperties() {
try {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo");
assertThat(environment.getActiveProfiles()).containsExactly("foo");
}
finally {
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
}
@Test
void fromSystemProperties_withMultipleProfiles() {
try {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo,bar");
assertThat(environment.getActiveProfiles()).containsExactly("foo", "bar");
}
finally {
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
}
@Test
void fromSystemProperties_withMultipleProfiles_withWhitespace() {
try {
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, " bar , baz "); // notice whitespace
assertThat(environment.getActiveProfiles()).containsExactly("bar", "baz");
}
finally {
System.clearProperty(ACTIVE_PROFILES_PROPERTY_NAME);
}
}
}
@Nested
class AcceptsProfilesTests {
@Test
@SuppressWarnings("deprecation")
void withEmptyArgumentList() {
assertThatIllegalArgumentException().isThrownBy(environment::acceptsProfiles);
}
@Test
@SuppressWarnings("deprecation")
void withNullArgumentList() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles((String[]) null));
}
@Test
@SuppressWarnings("deprecation")
void withNullArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles((String) null));
}
@Test
@SuppressWarnings("deprecation")
void withEmptyArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles(""));
}
@Test
@SuppressWarnings("deprecation")
void activeProfileSetProgrammatically() {
assertThat(environment.acceptsProfiles("p1", "p2")).isFalse();
environment.setActiveProfiles("p1");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p2");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p1", "p2");
assertThat(environment.acceptsProfiles("p1", "p2")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void activeProfileSetViaProperty() {
assertThat(environment.acceptsProfiles("p1")).isFalse();
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
assertThat(environment.acceptsProfiles("p1")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void defaultProfile() {
assertThat(environment.acceptsProfiles("pd")).isFalse();
environment.setDefaultProfiles("pd");
assertThat(environment.acceptsProfiles("pd")).isTrue();
environment.setActiveProfiles("p1");
assertThat(environment.acceptsProfiles("pd")).isFalse();
assertThat(environment.acceptsProfiles("p1")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void withNotOperator() {
assertThat(environment.acceptsProfiles("p1")).isFalse();
assertThat(environment.acceptsProfiles("!p1")).isTrue();
environment.addActiveProfile("p1");
assertThat(environment.acceptsProfiles("p1")).isTrue();
assertThat(environment.acceptsProfiles("!p1")).isFalse();
}
@Test
@SuppressWarnings("deprecation")
void withInvalidNotOperator() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.acceptsProfiles("p1", "!"));
}
@Test
void withProfileExpression() {
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isFalse();
environment.addActiveProfile("p1");
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isFalse();
environment.addActiveProfile("p2");
assertThat(environment.acceptsProfiles(Profiles.of("p1 & p2"))).isTrue();
}
}
@Nested
class MatchesProfilesTests {
@Test
@SuppressWarnings("deprecation")
void withEmptyArgumentList() {
assertThatIllegalArgumentException().isThrownBy(environment::matchesProfiles);
}
@Test
@SuppressWarnings("deprecation")
void withNullArgumentList() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String[]) null));
}
@Test
@SuppressWarnings("deprecation")
void withNullArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String) null));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", null));
}
@Test
@SuppressWarnings("deprecation")
void withEmptyArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles(""));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", ""));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", " "));
}
@Test
@SuppressWarnings("deprecation")
void withInvalidNotOperator() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", "!"));
}
@Test
@SuppressWarnings("deprecation")
void withInvalidCompoundExpressionGrouping() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 | p2 & p3"));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & p2 | p3"));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & (p2 | p3) | p4"));
}
@Test
@SuppressWarnings("deprecation")
void activeProfileSetProgrammatically() {
assertThat(environment.matchesProfiles("p1", "p2")).isFalse();
environment.setActiveProfiles("p1");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p2");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
environment.setActiveProfiles("p1", "p2");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void activeProfileSetViaProperty() {
assertThat(environment.matchesProfiles("p1")).isFalse();
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
assertThat(environment.matchesProfiles("p1")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void defaultProfile() {
assertThat(environment.matchesProfiles("pd")).isFalse();
environment.setDefaultProfiles("pd");
assertThat(environment.matchesProfiles("pd")).isTrue();
environment.setActiveProfiles("p1");
assertThat(environment.matchesProfiles("pd")).isFalse();
assertThat(environment.matchesProfiles("p1")).isTrue();
}
@Test
@SuppressWarnings("deprecation")
void withNotOperator() {
assertThat(environment.matchesProfiles("p1")).isFalse();
assertThat(environment.matchesProfiles("!p1")).isTrue();
environment.addActiveProfile("p1");
assertThat(environment.matchesProfiles("p1")).isTrue();
assertThat(environment.matchesProfiles("!p1")).isFalse();
}
@Test
void withProfileExpressions() {
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();
environment.addActiveProfile("p1");
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();
environment.addActiveProfile("p2");
assertThat(environment.matchesProfiles("p1 & p2")).isTrue();
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
assertThat(environment.matchesProfiles("foo | p1", "p2")).isTrue();
assertThat(environment.matchesProfiles("foo | p2", "p1")).isTrue();
assertThat(environment.matchesProfiles("foo | (p2 & p1)")).isTrue();
assertThat(environment.matchesProfiles("p2 & (foo | p1)")).isTrue();
assertThat(environment.matchesProfiles("foo", "(p2 & p1)")).isTrue();
}
}
} }