Browse Source

Improve AnnotationProcessorPerformanceTests with Awaitility

pull/23061/head
Sam Brannen 6 years ago
parent
commit
3794a57651
  1. 101
      spring-context/src/test/java/org/springframework/context/annotation/AnnotationProcessorPerformanceTests.java

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

@ -16,10 +16,14 @@ @@ -16,10 +16,14 @@
package org.springframework.context.annotation;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.awaitility.Awaitility;
import org.junit.BeforeClass;
import org.junit.Test;
@ -32,19 +36,20 @@ import org.springframework.tests.Assume; @@ -32,19 +36,20 @@ import org.springframework.tests.Assume;
import org.springframework.tests.TestGroup;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.util.StopWatch;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @since 2.5
*/
public class AnnotationProcessorPerformanceTests {
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
@BeforeClass
public static void commonAssumptions() {
Assume.group(TestGroup.PERFORMANCE);
@ -52,89 +57,79 @@ public class AnnotationProcessorPerformanceTests { @@ -52,89 +57,79 @@ public class AnnotationProcessorPerformanceTests {
}
@Test
public void testPrototypeCreationWithResourcePropertiesIsFastEnough() {
GenericApplicationContext ctx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
public void prototypeCreationWithResourcePropertiesIsFastEnough() {
GenericApplicationContext ctx = createContext();
RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class);
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
ctx.registerBeanDefinition("test", rbd);
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
TestBean spouse = (TestBean) ctx.getBean("spouse");
StopWatch sw = new StopWatch();
sw.start("prototype");
for (int i = 0; i < 100000; i++) {
TestBean tb = (TestBean) ctx.getBean("test");
assertThat(tb.getSpouse()).isSameAs(spouse);
}
sw.stop();
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
assertFastEnough(ctx);
}
@Test
public void testPrototypeCreationWithOverriddenResourcePropertiesIsFastEnough() {
GenericApplicationContext ctx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
public void prototypeCreationWithOverriddenResourcePropertiesIsFastEnough() {
GenericApplicationContext ctx = createContext();
RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class);
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
ctx.registerBeanDefinition("test", rbd);
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
TestBean spouse = (TestBean) ctx.getBean("spouse");
StopWatch sw = new StopWatch();
sw.start("prototype");
for (int i = 0; i < 100000; i++) {
TestBean tb = (TestBean) ctx.getBean("test");
assertThat(tb.getSpouse()).isSameAs(spouse);
}
sw.stop();
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
assertFastEnough(ctx);
}
@Test
public void testPrototypeCreationWithAutowiredPropertiesIsFastEnough() {
GenericApplicationContext ctx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
public void prototypeCreationWithAutowiredPropertiesIsFastEnough() {
GenericApplicationContext ctx = createContext();
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class);
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
ctx.registerBeanDefinition("test", rbd);
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
TestBean spouse = (TestBean) ctx.getBean("spouse");
StopWatch sw = new StopWatch();
sw.start("prototype");
for (int i = 0; i < 100000; i++) {
TestBean tb = (TestBean) ctx.getBean("test");
assertThat(tb.getSpouse()).isSameAs(spouse);
}
sw.stop();
assertThat(sw.getTotalTimeMillis() < 4000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
assertFastEnough(ctx);
}
@Test
public void testPrototypeCreationWithOverriddenAutowiredPropertiesIsFastEnough() {
GenericApplicationContext ctx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
public void prototypeCreationWithOverriddenAutowiredPropertiesIsFastEnough() {
GenericApplicationContext ctx = createContext();
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class);
rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
ctx.registerBeanDefinition("test", rbd);
ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
TestBean spouse = (TestBean) ctx.getBean("spouse");
StopWatch sw = new StopWatch();
sw.start("prototype");
for (int i = 0; i < 100000; i++) {
TestBean tb = (TestBean) ctx.getBean("test");
assertThat(tb.getSpouse()).isSameAs(spouse);
}
sw.stop();
assertThat(sw.getTotalTimeMillis() < 6000).as("Prototype creation took too long: " + sw.getTotalTimeMillis()).isTrue();
assertFastEnough(ctx);
}
private GenericApplicationContext createContext() {
GenericApplicationContext ctx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
return ctx;
}
private void assertFastEnough(GenericApplicationContext ctx) {
AtomicBoolean done = new AtomicBoolean();
TestBean spouse = ctx.getBean("spouse", TestBean.class);
Executors.newSingleThreadExecutor().submit(() -> {
for (int i = 0; i < 100_000; i++) {
TestBean tb = ctx.getBean("test", TestBean.class);
assertThat(tb.getSpouse()).isSameAs(spouse);
}
done.set(true);
});
// "fast enough" is of course relative, but we're using 6 seconds with the hope
// that these tests typically pass on the CI server.
Awaitility.await()
.atMost(6, TimeUnit.SECONDS)
.pollInterval(100, TimeUnit.MILLISECONDS)
.untilTrue(done);
}

Loading…
Cancel
Save