package org.springframework.issues;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.hamcrest.CoreMatchers;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.support.GenericXmlApplicationContext;
/**
* Unit test that reproduces an issue reported against SPR JIRA. @Test methods within need not pass with the green bar!
* Rather they should fail in such a way that demonstrates the reported issue.
*/
public class ReproTests {
private static final int TIMES = 10000;
ExecutorService executor;
@Test
public void checkTestSanity() throws Exception {
executor = Executors.newCachedThreadPool();
try {
for (int i = 0; i < TIMES; ++i) {
if (i % 100 == 0) System.out.println(i);
reproOnce(1);
}
} finally {
executor.shutdownNow();
}
}
@Test
public void repro() throws Exception {
executor = Executors.newCachedThreadPool();
try {
for (int i = 0; i < TIMES; ++i) {
if (i % 100 == 0) System.out.println(i);
try {
reproOnce(4);
} catch (Error e) {
throw new Error("Failed at " + i, e);
} catch (Exception e) {
throw new Exception("Failed at " + i, e);
}
}
} finally {
executor.shutdownNow();
}
}
private void reproOnce(int threads) throws Exception {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:org/springframework/issues/ReproTests-context.xml");
ctx.refresh();
List<Foo> foos = getFoos(ctx, threads);
for (Foo foo : foos) {
assertThat(foo.getBar(), CoreMatchers.notNullValue());
}
}
private List<Foo> getFoos(GenericXmlApplicationContext ctx, int threads) throws Exception {
List<Callable<List<Foo>>> callables = new ArrayList<Callable<List<Foo>>>();
for (int i = 0; i < threads; ++i) {
callables.add(new GetFoos(ctx));
}
List<Future<List<Foo>>> results = executor.invokeAll(callables);
List<Foo> foos = new ArrayList<Foo>();
for (Future<List<Foo>> future : results) {
foos.addAll(future.get());
}
return foos;
}
private static class GetFoos implements Callable<List<Foo>> {
final GenericXmlApplicationContext ctx;
public GetFoos(GenericXmlApplicationContext ctx) {
super();
this.ctx = ctx;
}
@Override
public List<Foo> call() throws Exception {
List<Foo> foos = new ArrayList<Foo>();
foos.add((Foo) ctx.getBean("foo"));
foos.add((Foo) ctx.getBean("foo"));
foos.add((Foo) ctx.getBean("foo"));
foos.add((Foo) ctx.getBean("foo"));
foos.add((Foo) ctx.getBean("foo"));
return foos;
}
}
}