Skip to content

Commit

Permalink
Use no-op lambda as default action for step action
Browse files Browse the repository at this point in the history
Prior to this commit the StartupStep.end method was being
called from the default step action. However when overriding
the default step action this might lead to the StartupStep.end
method not being called. As in the case of a failure, as that
enriches the information being written.

This commit also introduces a test for the failure case showing that
there is a missed call to end with the initial solution.

See: spring-projectsgh-22776
  • Loading branch information
mdeinum committed Aug 11, 2020
1 parent 969dd35 commit 2e9934c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,16 @@ private void callFailedListener(SpringApplicationRunListener listener, Configura
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {
doWithListeners(stepName, listenerAction, StartupStep::end);
doWithListeners(stepName, listenerAction, (step) -> {
});
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
Consumer<StartupStep> stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
stepAction.accept(step);
step.end();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
* @author Madhura Bhave
* @author Brian Clozel
* @author Artsiom Yudovin
* @author Marten Deinum
*/
@ExtendWith(OutputCaptureExtension.class)
class SpringApplicationTests {
Expand Down Expand Up @@ -1179,6 +1180,29 @@ void customApplicationStartupPublishStartupSteps() {
assertThat(startCount).isEqualTo(endCount);
}

@Test
void customApplicationStartupPublishStartupStepsWithFailure() {
ApplicationStartup applicationStartup = mock(ApplicationStartup.class);
StartupStep startupStep = mock(StartupStep.class);
given(applicationStartup.start(anyString())).willReturn(startupStep);
given(startupStep.tag(anyString(), anyString())).willReturn(startupStep);
given(startupStep.tag(anyString(), ArgumentMatchers.<Supplier<String>>any())).willReturn(startupStep);
SpringApplication application = new SpringApplication(BrokenPostConstructConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.setApplicationStartup(applicationStartup);
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(application::run);

verify(applicationStartup).start("spring.boot.application.starting");
verify(applicationStartup).start("spring.boot.application.environment-prepared");
verify(applicationStartup).start("spring.boot.application.failed");

long startCount = mockingDetails(applicationStartup).getInvocations().stream()
.filter((invocation) -> invocation.getMethod().toString().contains("start(")).count();
long endCount = mockingDetails(startupStep).getInvocations().stream()
.filter((invocation) -> invocation.getMethod().toString().contains("end(")).count();
assertThat(startCount).isEqualTo(endCount);
}

private <S extends AvailabilityState> ArgumentMatcher<ApplicationEvent> isAvailabilityChangeEventWithState(
S state) {
return (argument) -> (argument instanceof AvailabilityChangeEvent<?>)
Expand Down

0 comments on commit 2e9934c

Please sign in to comment.