mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-06-30 00:36:49 +08:00
Merge branch 'framework-6.2'
Closes gh-41177
This commit is contained in:
commit
6d9977087a
|
@ -14,7 +14,7 @@ junitJupiterVersion=5.10.2
|
|||
kotlinVersion=1.9.24
|
||||
mavenVersion=3.9.4
|
||||
nativeBuildToolsVersion=0.10.2
|
||||
springFrameworkVersion=6.1.10
|
||||
springFrameworkVersion=6.2.0-M4
|
||||
springFramework60xVersion=6.0.21
|
||||
tomcatVersion=10.1.25
|
||||
snakeYamlVersion=2.2
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 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,7 +16,6 @@
|
|||
|
||||
package org.springframework.boot.actuate.scheduling;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -46,7 +45,6 @@ import org.springframework.scheduling.config.Task;
|
|||
import org.springframework.scheduling.config.TriggerTask;
|
||||
import org.springframework.scheduling.support.CronTrigger;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
import org.springframework.scheduling.support.ScheduledMethodRunnable;
|
||||
|
||||
/**
|
||||
* {@link Endpoint @Endpoint} to expose information about an application's scheduled
|
||||
|
@ -284,13 +282,7 @@ public class ScheduledTasksEndpoint {
|
|||
private final String target;
|
||||
|
||||
private RunnableDescriptor(Runnable runnable) {
|
||||
if (runnable instanceof ScheduledMethodRunnable scheduledMethodRunnable) {
|
||||
Method method = scheduledMethodRunnable.getMethod();
|
||||
this.target = method.getDeclaringClass().getName() + "." + method.getName();
|
||||
}
|
||||
else {
|
||||
this.target = runnable.getClass().getName();
|
||||
}
|
||||
this.target = runnable.toString();
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
|
|
|
@ -80,7 +80,7 @@ class ScheduledTasksEndpointTests {
|
|||
assertThat(tasks.getCron()).hasSize(1);
|
||||
CronTaskDescriptor description = (CronTaskDescriptor) tasks.getCron().get(0);
|
||||
assertThat(description.getExpression()).isEqualTo("0 0 0/6 1/1 * ?");
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(CronTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(CronTriggerRunnable.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ class ScheduledTasksEndpointTests {
|
|||
FixedDelayTaskDescriptor description = (FixedDelayTaskDescriptor) tasks.getFixedDelay().get(0);
|
||||
assertThat(description.getInitialDelay()).isEqualTo(2000);
|
||||
assertThat(description.getInterval()).isEqualTo(1000);
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(FixedDelayTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(FixedDelayTriggerRunnable.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ class ScheduledTasksEndpointTests {
|
|||
FixedDelayTaskDescriptor description = (FixedDelayTaskDescriptor) tasks.getFixedDelay().get(0);
|
||||
assertThat(description.getInitialDelay()).isEqualTo(0);
|
||||
assertThat(description.getInterval()).isEqualTo(1000);
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(FixedDelayTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(FixedDelayTriggerRunnable.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ class ScheduledTasksEndpointTests {
|
|||
FixedRateTaskDescriptor description = (FixedRateTaskDescriptor) tasks.getFixedRate().get(0);
|
||||
assertThat(description.getInitialDelay()).isEqualTo(3000);
|
||||
assertThat(description.getInterval()).isEqualTo(2000);
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(FixedRateTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(FixedRateTriggerRunnable.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ class ScheduledTasksEndpointTests {
|
|||
FixedRateTaskDescriptor description = (FixedRateTaskDescriptor) tasks.getFixedRate().get(0);
|
||||
assertThat(description.getInitialDelay()).isEqualTo(0);
|
||||
assertThat(description.getInterval()).isEqualTo(2000);
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(FixedRateTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(FixedRateTriggerRunnable.class.getName());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ class ScheduledTasksEndpointTests {
|
|||
assertThat(tasks.getFixedRate()).isEmpty();
|
||||
assertThat(tasks.getCustom()).hasSize(1);
|
||||
CustomTriggerTaskDescriptor description = (CustomTriggerTaskDescriptor) tasks.getCustom().get(0);
|
||||
assertThat(description.getRunnable().getTarget()).isEqualTo(CustomTriggerRunnable.class.getName());
|
||||
assertThat(description.getRunnable().getTarget()).contains(CustomTriggerRunnable.class.getName());
|
||||
assertThat(description.getTrigger()).isEqualTo(CustomTriggerTask.trigger.toString());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ public class DataSourceAutoConfiguration {
|
|||
return StringUtils.hasText(environment.getProperty(DATASOURCE_URL_PROPERTY));
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// NOTE: This should be PlaceholderResolutionException
|
||||
// Ignore unresolvable placeholder errors
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 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.
|
||||
|
@ -146,7 +146,7 @@ class HttpMessageConvertersTests {
|
|||
}
|
||||
assertThat(converterClasses).containsExactly(ByteArrayHttpMessageConverter.class,
|
||||
StringHttpMessageConverter.class, ResourceHttpMessageConverter.class,
|
||||
MappingJackson2HttpMessageConverter.class);
|
||||
MappingJackson2HttpMessageConverter.class, MappingJackson2CborHttpMessageConverter.class);
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> extractFormPartConverters(List<HttpMessageConverter<?>> converters) {
|
||||
|
|
|
@ -16,27 +16,18 @@
|
|||
|
||||
package org.springframework.boot.test.mock.mockito;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldCallback;
|
||||
|
||||
/**
|
||||
* {@link TestExecutionListener} to enable {@link MockBean @MockBean} and
|
||||
* {@link SpyBean @SpyBean} support. Also triggers
|
||||
* {@link MockitoAnnotations#openMocks(Object)} when any Mockito annotations used,
|
||||
* primarily to allow {@link Captor @Captor} annotations.
|
||||
* {@link SpyBean @SpyBean} support.
|
||||
* <p>
|
||||
* To use the automatic reset support of {@code @MockBean} and {@code @SpyBean}, configure
|
||||
* {@link ResetMocksTestExecutionListener} as well.
|
||||
|
@ -49,8 +40,6 @@ import org.springframework.util.ReflectionUtils.FieldCallback;
|
|||
*/
|
||||
public class MockitoTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
private static final String MOCKS_ATTRIBUTE_NAME = MockitoTestExecutionListener.class.getName() + ".mocks";
|
||||
|
||||
@Override
|
||||
public final int getOrder() {
|
||||
return 1950;
|
||||
|
@ -58,8 +47,6 @@ public class MockitoTestExecutionListener extends AbstractTestExecutionListener
|
|||
|
||||
@Override
|
||||
public void prepareTestInstance(TestContext testContext) throws Exception {
|
||||
closeMocks(testContext);
|
||||
initMocks(testContext);
|
||||
injectFields(testContext);
|
||||
}
|
||||
|
||||
|
@ -67,41 +54,10 @@ public class MockitoTestExecutionListener extends AbstractTestExecutionListener
|
|||
public void beforeTestMethod(TestContext testContext) throws Exception {
|
||||
if (Boolean.TRUE.equals(
|
||||
testContext.getAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE))) {
|
||||
closeMocks(testContext);
|
||||
initMocks(testContext);
|
||||
reinjectFields(testContext);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestMethod(TestContext testContext) throws Exception {
|
||||
closeMocks(testContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestClass(TestContext testContext) throws Exception {
|
||||
closeMocks(testContext);
|
||||
}
|
||||
|
||||
private void initMocks(TestContext testContext) {
|
||||
if (hasMockitoAnnotations(testContext)) {
|
||||
testContext.setAttribute(MOCKS_ATTRIBUTE_NAME, MockitoAnnotations.openMocks(testContext.getTestInstance()));
|
||||
}
|
||||
}
|
||||
|
||||
private void closeMocks(TestContext testContext) throws Exception {
|
||||
Object mocks = testContext.getAttribute(MOCKS_ATTRIBUTE_NAME);
|
||||
if (mocks instanceof AutoCloseable closeable) {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMockitoAnnotations(TestContext testContext) {
|
||||
MockitoAnnotationCollection collector = new MockitoAnnotationCollection();
|
||||
ReflectionUtils.doWithFields(testContext.getTestClass(), collector);
|
||||
return collector.hasAnnotations();
|
||||
}
|
||||
|
||||
private void injectFields(TestContext testContext) {
|
||||
postProcessFields(testContext, (mockitoField, postProcessor) -> postProcessor.inject(mockitoField.field,
|
||||
mockitoField.target, mockitoField.definition));
|
||||
|
@ -130,28 +86,6 @@ public class MockitoTestExecutionListener extends AbstractTestExecutionListener
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FieldCallback} to collect Mockito annotations.
|
||||
*/
|
||||
private static final class MockitoAnnotationCollection implements FieldCallback {
|
||||
|
||||
private final Set<Annotation> annotations = new LinkedHashSet<>();
|
||||
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException {
|
||||
for (Annotation annotation : field.getDeclaredAnnotations()) {
|
||||
if (annotation.annotationType().getName().startsWith("org.mockito")) {
|
||||
this.annotations.add(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasAnnotations() {
|
||||
return !this.annotations.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class MockitoField {
|
||||
|
||||
private final Field field;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 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.
|
||||
|
@ -53,14 +53,6 @@ class MockitoTestExecutionListenerTests {
|
|||
@Mock
|
||||
private MockitoPostProcessor postProcessor;
|
||||
|
||||
@Test
|
||||
void prepareTestInstanceShouldInitMockitoAnnotations() throws Exception {
|
||||
WithMockitoAnnotations instance = new WithMockitoAnnotations();
|
||||
this.listener.prepareTestInstance(mockTestContext(instance));
|
||||
assertThat(instance.mock).isNotNull();
|
||||
assertThat(instance.captor).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void prepareTestInstanceShouldInjectMockBean() throws Exception {
|
||||
given(this.applicationContext.getBean(MockitoPostProcessor.class)).willReturn(this.postProcessor);
|
||||
|
|
|
@ -27,9 +27,10 @@ import org.springframework.core.env.MapPropertySource;
|
|||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.util.PlaceholderResolutionException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootTestRandomPortEnvironmentPostProcessor}.
|
||||
|
@ -169,7 +170,7 @@ class SpringBootTestRandomPortEnvironmentPostProcessorTests {
|
|||
addTestPropertySource("0", null);
|
||||
this.propertySources
|
||||
.addLast(new MapPropertySource("other", Collections.singletonMap("management.server.port", "${port}")));
|
||||
assertThatIllegalArgumentException()
|
||||
assertThatExceptionOfType(PlaceholderResolutionException.class)
|
||||
.isThrownBy(() -> this.postProcessor.postProcessEnvironment(this.environment, null))
|
||||
.withMessage("Could not resolve placeholder 'port' in value \"${port}\"");
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ class SpringBootTestRandomPortEnvironmentPostProcessorTests {
|
|||
source.put("server.port", "${port}");
|
||||
source.put("management.server.port", "9090");
|
||||
this.propertySources.addLast(new MapPropertySource("other", source));
|
||||
assertThatIllegalArgumentException()
|
||||
assertThatExceptionOfType(PlaceholderResolutionException.class)
|
||||
.isThrownBy(() -> this.postProcessor.postProcessEnvironment(this.environment, null))
|
||||
.withMessage("Could not resolve placeholder 'port' in value \"${port}\"");
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ class ConfigDataEnvironmentContributorPlaceholdersResolver implements Placeholde
|
|||
this.failOnResolveFromInactiveContributor = failOnResolveFromInactiveContributor;
|
||||
this.conversionService = conversionService;
|
||||
this.helper = new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true);
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR,
|
||||
SystemPropertyUtils.ESCAPE_CHARACTER, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2024 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.
|
||||
|
@ -47,8 +47,10 @@ public class PropertySourcesPlaceholdersResolver implements PlaceholdersResolver
|
|||
|
||||
public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources, PropertyPlaceholderHelper helper) {
|
||||
this.sources = sources;
|
||||
this.helper = (helper != null) ? helper : new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true);
|
||||
this.helper = (helper != null) ? helper
|
||||
: new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
|
||||
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR,
|
||||
SystemPropertyUtils.ESCAPE_CHARACTER, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user