Merge pull request #46211 from nosan
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Trigger Docs Build (push) Blocked by required conditions Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:24], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:24], map[id:windows-latest name:Windows]) (push) Waiting to run Details
Run CodeQL Analysis / run-analysis (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:false version:17]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:true version:21]) (push) Waiting to run Details

* pr/46211:
  Add @EnabledOnLocale annotation for locale-based tests

Closes gh-46211
This commit is contained in:
Stéphane Nicoll 2025-06-27 13:00:56 +02:00
commit c0d66d1984
7 changed files with 105 additions and 0 deletions

View File

@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.testsupport.junit.EnabledOnLocale;
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@ -87,6 +88,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
}
@Test
@EnabledOnLocale(language = "en")
void elasticsearchIsDown() throws Exception {
this.server.shutdown();
Health health = this.healthIndicator.health().block(TIMEOUT);

View File

@ -26,6 +26,8 @@ import java.util.stream.Stream;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.testsupport.junit.EnabledOnLocale;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.contentOf;
@ -125,6 +127,7 @@ class AotTests {
}
@TestTemplate
@EnabledOnLocale(language = "en")
void whenAotRunsWithInvalidCompilerArgumentsCompileFails(MavenBuild mavenBuild) {
mavenBuild.project("aot-compiler-arguments")
.goals("package")

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012-present 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.boot.testsupport.junit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
/**
* {@code @EnabledOnLocale} annotation is used to conditionally enable a test method based
* on the specified locale attributes.
*
* @author Dmytro Nosan
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(EnabledOnLocaleCondition.class)
public @interface EnabledOnLocale {
/**
* Specifies the language code for which the test method should be enabled.
* @return the language code
*/
String language();
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2012-present 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.boot.testsupport.junit;
import java.util.Locale;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.commons.support.AnnotationSupport;
/**
* An implementation of {@link ExecutionCondition} that conditionally enables or disables
* the execution of a test method or class based on the specified locale attributes.
*
* @author Dmytro Nosan
*/
class EnabledOnLocaleCondition implements ExecutionCondition {
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
return AnnotationSupport.findAnnotation(context.getElement(), EnabledOnLocale.class)
.map(this::evaluate)
.orElseGet(() -> ConditionEvaluationResult.enabled("No @EnabledOnLocale annotation found"));
}
private ConditionEvaluationResult evaluate(EnabledOnLocale annotation) {
Locale locale = Locale.getDefault();
String language = locale.getLanguage();
if (!annotation.language().equals(language)) {
return ConditionEvaluationResult.disabled("Disabled on language: " + language);
}
return ConditionEvaluationResult.enabled("Enabled on language: " + language);
}
}

View File

@ -38,6 +38,7 @@ import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import org.springframework.boot.testsupport.junit.EnabledOnLocale;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests;
import org.springframework.boot.web.server.PortInUseException;
@ -226,6 +227,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto
}
@Test
@EnabledOnLocale(language = "en")
void portClashOfPrimaryConnectorResultsInPortInUseException() throws Exception {
doWithBlockedPort((port) -> assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> {
AbstractReactiveWebServerFactory factory = getFactory();

View File

@ -83,6 +83,7 @@ import org.mockito.InOrder;
import org.springframework.boot.ssl.DefaultSslBundleRegistry;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.boot.testsupport.junit.EnabledOnLocale;
import org.springframework.boot.testsupport.system.CapturedOutput;
import org.springframework.boot.web.server.PortInUseException;
import org.springframework.boot.web.server.Shutdown;
@ -367,6 +368,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory
}
@Test
@EnabledOnLocale(language = "en")
void startupFailureDoesNotResultInUnstoppedThreadsBeingReported(CapturedOutput output) throws Exception {
super.portClashOfPrimaryConnectorResultsInPortInUseException();
assertThat(output).doesNotContain("appears to have started a thread named [main]");

View File

@ -126,6 +126,7 @@ import org.springframework.boot.system.ApplicationHome;
import org.springframework.boot.system.ApplicationTemp;
import org.springframework.boot.testsupport.classpath.resources.ResourcePath;
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
import org.springframework.boot.testsupport.junit.EnabledOnLocale;
import org.springframework.boot.testsupport.system.CapturedOutput;
import org.springframework.boot.testsupport.system.OutputCaptureExtension;
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
@ -1071,6 +1072,7 @@ public abstract class AbstractServletWebServerFactoryTests {
}
@Test
@EnabledOnLocale(language = "en")
protected void portClashOfPrimaryConnectorResultsInPortInUseException() throws Exception {
doWithBlockedPort((port) -> {
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> {
@ -1083,6 +1085,7 @@ public abstract class AbstractServletWebServerFactoryTests {
}
@Test
@EnabledOnLocale(language = "en")
protected void portClashOfSecondaryConnectorResultsInPortInUseException() throws Exception {
doWithBlockedPort((port) -> {
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> {