Skip to content

Commit 3794a57

Browse files
committed
Improve AnnotationProcessorPerformanceTests with Awaitility
1 parent f66eef1 commit 3794a57

File tree

1 file changed

+48
-53
lines changed

1 file changed

+48
-53
lines changed

spring-context/src/test/java/org/springframework/context/annotation/AnnotationProcessorPerformanceTests.java

Lines changed: 48 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616

1717
package org.springframework.context.annotation;
1818

19+
import java.util.concurrent.Executors;
20+
import java.util.concurrent.TimeUnit;
21+
import java.util.concurrent.atomic.AtomicBoolean;
1922
import javax.annotation.Resource;
2023

2124
import org.apache.commons.logging.Log;
2225
import org.apache.commons.logging.LogFactory;
26+
import org.awaitility.Awaitility;
2327
import org.junit.BeforeClass;
2428
import org.junit.Test;
2529

@@ -32,109 +36,100 @@
3236
import org.springframework.tests.TestGroup;
3337
import org.springframework.tests.sample.beans.ITestBean;
3438
import org.springframework.tests.sample.beans.TestBean;
35-
import org.springframework.util.StopWatch;
3639

3740
import static org.assertj.core.api.Assertions.assertThat;
3841

3942
/**
4043
* @author Juergen Hoeller
4144
* @author Chris Beams
45+
* @author Sam Brannen
4246
* @since 2.5
4347
*/
4448
public class AnnotationProcessorPerformanceTests {
4549

4650
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
4751

52+
4853
@BeforeClass
4954
public static void commonAssumptions() {
5055
Assume.group(TestGroup.PERFORMANCE);
5156
Assume.notLogging(factoryLog);
5257
}
5358

5459
@Test
55-
public void testPrototypeCreationWithResourcePropertiesIsFastEnough() {
56-
GenericApplicationContext ctx = new GenericApplicationContext();
57-
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
58-
ctx.refresh();
60+
public void prototypeCreationWithResourcePropertiesIsFastEnough() {
61+
GenericApplicationContext ctx = createContext();
5962

6063
RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class);
6164
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
6265
ctx.registerBeanDefinition("test", rbd);
6366
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
64-
TestBean spouse = (TestBean) ctx.getBean("spouse");
65-
StopWatch sw = new StopWatch();
66-
sw.start("prototype");
67-
for (int i = 0; i < 100000; i++) {
68-
TestBean tb = (TestBean) ctx.getBean("test");
69-
assertThat(tb.getSpouse()).isSameAs(spouse);
70-
}
71-
sw.stop();
72-
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
67+
68+
assertFastEnough(ctx);
7369
}
7470

7571
@Test
76-
public void testPrototypeCreationWithOverriddenResourcePropertiesIsFastEnough() {
77-
GenericApplicationContext ctx = new GenericApplicationContext();
78-
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
79-
ctx.refresh();
72+
public void prototypeCreationWithOverriddenResourcePropertiesIsFastEnough() {
73+
GenericApplicationContext ctx = createContext();
8074

8175
RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class);
8276
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
8377
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
8478
ctx.registerBeanDefinition("test", rbd);
8579
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
86-
TestBean spouse = (TestBean) ctx.getBean("spouse");
87-
StopWatch sw = new StopWatch();
88-
sw.start("prototype");
89-
for (int i = 0; i < 100000; i++) {
90-
TestBean tb = (TestBean) ctx.getBean("test");
91-
assertThat(tb.getSpouse()).isSameAs(spouse);
92-
}
93-
sw.stop();
94-
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
80+
81+
assertFastEnough(ctx);
9582
}
9683

9784
@Test
98-
public void testPrototypeCreationWithAutowiredPropertiesIsFastEnough() {
99-
GenericApplicationContext ctx = new GenericApplicationContext();
100-
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
101-
ctx.refresh();
85+
public void prototypeCreationWithAutowiredPropertiesIsFastEnough() {
86+
GenericApplicationContext ctx = createContext();
10287

10388
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class);
10489
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
10590
ctx.registerBeanDefinition("test", rbd);
10691
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
107-
TestBean spouse = (TestBean) ctx.getBean("spouse");
108-
StopWatch sw = new StopWatch();
109-
sw.start("prototype");
110-
for (int i = 0; i < 100000; i++) {
111-
TestBean tb = (TestBean) ctx.getBean("test");
112-
assertThat(tb.getSpouse()).isSameAs(spouse);
113-
}
114-
sw.stop();
115-
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
92+
93+
assertFastEnough(ctx);
11694
}
11795

11896
@Test
119-
public void testPrototypeCreationWithOverriddenAutowiredPropertiesIsFastEnough() {
120-
GenericApplicationContext ctx = new GenericApplicationContext();
121-
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
122-
ctx.refresh();
97+
public void prototypeCreationWithOverriddenAutowiredPropertiesIsFastEnough() {
98+
GenericApplicationContext ctx = createContext();
12399

124100
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class);
125101
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
126102
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
127103
ctx.registerBeanDefinition("test", rbd);
128104
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
129-
TestBean spouse = (TestBean) ctx.getBean("spouse");
130-
StopWatch sw = new StopWatch();
131-
sw.start("prototype");
132-
for (int i = 0; i < 100000; i++) {
133-
TestBean tb = (TestBean) ctx.getBean("test");
134-
assertThat(tb.getSpouse()).isSameAs(spouse);
135-
}
136-
sw.stop();
137-
assertThat(sw.getTotalTimeMillis() < 6000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
105+
106+
assertFastEnough(ctx);
107+
}
108+
109+
private GenericApplicationContext createContext() {
110+
GenericApplicationContext ctx = new GenericApplicationContext();
111+
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
112+
ctx.refresh();
113+
return ctx;
114+
}
115+
116+
private void assertFastEnough(GenericApplicationContext ctx) {
117+
AtomicBoolean done = new AtomicBoolean();
118+
TestBean spouse = ctx.getBean("spouse", TestBean.class);
119+
Executors.newSingleThreadExecutor().submit(() -> {
120+
for (int i = 0; i < 100_000; i++) {
121+
TestBean tb = ctx.getBean("test", TestBean.class);
122+
assertThat(tb.getSpouse()).isSameAs(spouse);
123+
}
124+
done.set(true);
125+
});
126+
127+
// "fast enough" is of course relative, but we're using 6 seconds with the hope
128+
// that these tests typically pass on the CI server.
129+
Awaitility.await()
130+
.atMost(6, TimeUnit.SECONDS)
131+
.pollInterval(100, TimeUnit.MILLISECONDS)
132+
.untilTrue(done);
138133
}
139134

140135

0 commit comments

Comments
 (0)