Prior to this commit, MockServerContainerContextCustomizerFactory did
not find @WebAppConfiguration on an enclosing class and therefore
failed to create a MockServerContainerContextCustomizer for a @Nested
test class.
This commit addresses this by using TestContextAnnotationUtils to
determine if the test class is "annotated" with @WebAppConfiguration.
Closes gh-29037
Since MockServerContainerContextCustomizerFactory already has a
`webSocketPresent` check, there should be no need to instantiate
MockServerContainerContextCustomizer via reflection.
See gh-29028
Closes gh-29035
With this commit, if a ContextCustomizerFactory cannot be loaded due to
a ClassNotFoundException or NoClassDefFoundError, we skip it and log a
DEBUG message.
This aligns with the "skipping" logic already in place for
TestExecutionListeners.
Closes gh-29034
With this commit we now log an identical message (without a stack
trace) for a TestExecutionListener skipped due to a
ClassNotFoundException like we already do for a listener skipped due to
a NoClassDefFoundError.
Prior to this commit, we logged which default TestExecutionListeners
were discovered and which listeners were used, but we did not log
anything for ContextCustomizerFactory and ContextCustomizer.
This commit therefore introduces similar logging for
ContextCustomizerFactory and ContextCustomizer to improve diagnostics.
Closes gh-29036
This commit makes TestClassScanner and TestContextAotGenerator public so
that the Spring Boot team can take over implementation of the
TestAotProcessor to integrate it into the AOT and native build plugins.
This commit introduces support for Netty 5's Buffer, in the form of
Netty5DataBuffer. Because of the new API offered by Buffer, several
changes have been made to the DataBuffer API:
- CloseableDataBuffer is a simpler alternative to PooledDataBuffer, and
implemented by Netty5DataBuffer. DataBufferUtils::release can now
handle CloseableDataBuffer as well as PooledDataBuffer.
- PooledDataBuffer::touch has been moved into a separate interface:
TouchableDataBuffer, which is implemented by Netty5DataBuffer.
- The capacity of DataBuffers can no longer be reduced, they can only
grow larger. As a consequence, DataBuffer::capacity(int) has been
deprecated, but ensureWritable (formally ensureCapacity) still exists.
- DataBuffer::slice and retainedSlice have been deprecated in favor of
split, a new method that ensures that memory regions do not overlap.
- DataBuffer::asByteBuffer has been deprecated in favor of toByteBuffer,
a new method that returns a copy, instead of shared data.
- DataBufferFactory::allocateBuffer has been deprecated in favor of
allocateBuffer(int).
Closes gh-28874
This commit introduces TestAotProcessor which replaces
ProcessTestsAheadOfTimeCommand, removes the dependency on picocli, and
aligns with the implementation of the AotProcessor in Spring Boot.
TestAotProcessor is a command-line application (CLI) that scans the
provided classpath roots for Spring integration test classes and then
generates AOT artifacts for those test classes in the provided output
directories.
This CLI is only intended to be used by build tools.
Closes gh-28825
This commit introduces ProcessTestsAheadOfTimeCommand, a command-line
application (CLI) that scans the provided classpath roots for Spring
integration test classes and then generates AOT artifacts for those
test classes in the provided output directories.
This CLI is only intended to be used by build tools.
Closes gh-28825
This commit introduces initial AOT run-time support in the Spring
TestContext Framework.
- DefaultCacheAwareContextLoaderDelegate: when running in AOT mode, now
loads a test's ApplicationContext via the AotContextLoader SPI
instead of via the standard SmartContextLoader and ContextLoader SPIs.
- DependencyInjectionTestExecutionListener: when running in AOT mode,
now injects dependencies into a test instance using a local instance
of AutowiredAnnotationBeanPostProcessor instead of relying on
AutowireCapableBeanFactory support.
Closes gh-28205
TestContextAotGenerator now uses AotTestMappingsCodeGenerator to
generate a AotTestMappings__Generated.java class which is loaded in
AotTestMappings via reflection in order to retrieve access to
ApplicationContextIntializers generated during AOT processing.
Furthermore, the processAheadOfTimeAndGenerateAotTestMappings() method
in TestContextAotGeneratorTests now performs a rather extensive test
including:
- emulating TestClassScanner to find test classes
- processing all test classes and generating ApplicationContextIntializers
- generating mappings for AotTestMappings
- compiling all generated code
- loading AotTestMappings
- using AotTestMappings to instantiate the generated ApplicationContextIntializer
- using the AotContextLoader API to load the AOT-optimized ApplicationContext
- asserting the behavior of the loaded ApplicationContext
See gh-28205
Closes gh-28204
This commit introduces a dedicated AotContextLoader extension of
SmartContextLoader and reverts the recent changes to the existing
contract for SmartContextLoader. This allows existing
SmartContextLoader implementations to continue working unaffected by
AOT support unless they opt into AOT support by explicitly implementing
the new AotContextLoader contract.
In addition, existing SmartContextLoader implementations in the
spring-test module have been modified to implement AotContextLoader
instead of SmartContextLoader. This allows the core framework to
provide built-in AOT support in the TestContext framework, and it also
allows third-party extensions to built-in SmartContextLoaders to
participate in AOT processing and run-time support transparently (or at
least as transparent as possible).
Closes gh-28906
This commit introduces TestContextAotGenerator for processing Spring
integration test classes and generating AOT artifacts. Specifically,
this class performs the following.
- bootstraps the TCF for a given test class
- builds the MergedContextConfiguration for each test class and tracks
all test classes that share the same MergedContextConfiguration
- loads each test ApplicationContext without refreshing it
- passes the test ApplicationContext to ApplicationContextAotGenerator
to generate the AOT optimized ApplicationContextInitializer
- The GenerationContext passed to ApplicationContextAotGenerator uses
a feature name of the form "TestContext###_", where "###" is a
3-digit sequence ID left padded with zeros.
This commit also includes tests using the TestCompiler to verify that
each generated ApplicationContextInitializer can be used to populate a
GenericApplicationContext as expected.
See gh-28204
Prior to this commit it was possible to configure the
DefaultListableBeanFactory used by the GenericWebApplicationContext
created by AbstractWebGenericContextLoader, but it was not possible to
completely replace the bean factory.
This commit introduces a new createContext() factory method in
AbstractWebGenericContextLoader which indirectly allows subclasses to
supply a custom DefaultListableBeanFactory implementation to the
GenericWebApplicationContext.
See gh-25600
Closes gh-28983
Commit d1b65f6d3e introduced a regression for the handling of
NoClassDefFoundError when skipping a TestExecutionListener that cannot
be loaded. Specifically, the DEBUG log message changed and included the
stack trace; whereas, it previously did not include the stack trace.
This commit consistently handles NoClassDefFoundError for a skipped
TestExecutionListener, whether a default listener or a listener
registered via @TestExecutionListeners and aligns with the previous
behavior by omitting the stack trace for a NoClassDefFoundError.
Closes gh-28962
This commit revises 903e9f2a02 based on feedback from the Spring Boot
team.
- The original loadContext(MergedContextConfiguration) method is no
longer deprecated.
- loadContext(MergedContextConfiguration, boolean) has been replaced by
loadContextForAotProcessing(MergedContextConfiguration) which is
implemented as a `default` method that throws an
UnsupportedOperationException.
- Affected code has been refactored to adjust to these changes.
See gh-28906
Prior to this commit, the contract of the loadContext() method in the
SmartContextLoader SPI required that the ApplicationContext be returned
in a fully refreshed state with a JVM shutdown hook registered for it.
However, in order to support AOT processing within the Spring
TestContext Framework (TCF), we need a way to signal to
SmartContextLoader implementations that they should load the test's
ApplicationContext without refreshing it or registering a JVM shutdown
hook.
To address this issue, this commit:
- Introduces a new loadContext(MergedContextConfiguration, boolean)
method. The boolean `refresh` flag controls whether the returned
ApplicationContext should be refreshed and have a JVM shutdown hook
registered for it.
- Deprecates the existing loadContext(MergedContextConfiguration)
method in favor of loadContext(MergedContextConfiguration, boolean).
- Removes all use of the deprecated method within the spring-test
module, excluding the exception mentioned below.
Note that loadContext(MergedContextConfiguration, boolean) is
implemented as an interface `default` method which delegates to the
deprecated loadContext(MergedContextConfiguration) method for backward
compatibility. When migrating a SmartContextLoader to Spring Framework
6.0, implementations that directly implement the SmartContextLoader SPI
(instead of extending AbstractGenericContextLoader or
AbstractGenericWebContextLoader) will need to override the new
loadContext(MergedContextConfiguration, boolean) method in order to
honor the `refresh` flag for AOT processing support. See the
implementation in AbstractGenericContextLoader for an example of how
this can be achieved.
Closes gh-28906
For Spring Framework 6.0 we have decided to deprecate the obsolete
methods in the ContextLoader API in the Spring TestContext Framework in
favor of the methods in the SmartContextLoader API which has been
available since Spring Framework 3.1.
Closes gh-28905
This commit polishes DefaultGenerationContext to make the method
that flushes generated classes more explicit. It now throws an
IOException and TestGenerationContext has been updated to handle
that to ease its use in code that can't throw such an exception.
As this use case is likely to happen outside the Spring Framework,
this commit adds such a convenience to spring-test as well.
Closes gh-28877