package org.nate.threadsafetytest; import static java.util.Collections.singletonMap; import static org.junit.Assert.assertThat; import static org.nate.testutil.WhiteSpaceIgnoringXmlMatcher.matchesXmlIgnoringWhiteSpace; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; import org.junit.Test; import org.nate.Engine; import org.nate.Nate; public class TestOfNateThreadSafety { private static final int NUM_THREADS = 20; private static final long DURATION_IN_MILLIS = 60 * 1000; private static final CyclicBarrier START_BARRIER = new CyclicBarrier(NUM_THREADS); private static final Engine ENGINE = Nate.newWith( "<div><p>apple</p><section>banana</section></div>", Nate.encoders().encoderFor("XMLF")); private static final List<Throwable> errors = Collections.synchronizedList(new ArrayList<Throwable>()); @Test public void shouldBeThreadSafe() throws Throwable { ArrayList<Thread> threads = new ArrayList<Thread>(); long finishTime = System.currentTimeMillis() + DURATION_IN_MILLIS; for(int i = 0; i < NUM_THREADS; i++) { Thread thread = new Thread(new ThreadSafetyTask(finishTime)); thread.start(); threads.add(thread); } for (Thread thread : threads) { thread.join(2 * DURATION_IN_MILLIS); } if (!errors.isEmpty()) { throw errors.get(0); } } private static class ThreadSafetyTask implements Runnable { private final long finishTime; public ThreadSafetyTask(long finishTime) { this.finishTime = finishTime; } @Override public void run() { try { START_BARRIER.await(2, TimeUnit.SECONDS); while(System.currentTimeMillis() < finishTime) { for(int i = 0; i < 10; i++) { executeTask(); } } } catch (Throwable e) { errors.add(e); e.printStackTrace(); } } private void executeTask() throws Exception { Engine result1 = ENGINE.inject(singletonMap("section", ENGINE.select("p"))); Engine result2 = ENGINE.inject(singletonMap("section", ENGINE.select("##p"))); assertThat(result1.render(), matchesXmlIgnoringWhiteSpace("<div><p>apple</p><section><p>apple</p></section></div>")); assertThat(result2.render(), matchesXmlIgnoringWhiteSpace("<div><p>apple</p><section>apple</section></div>")); } } }