Test from @drykovanov.
This was fixed recently by @agentgt but I just wanted to double check that this test now passes. Closes #138.
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// JMustache - A Java implementation of the Mustache templating language
|
||||||
|
// http://github.com/samskivert/jmustache/blob/master/LICENSE
|
||||||
|
|
||||||
|
package com.samskivert.mustache;
|
||||||
|
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Template;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
public class ThreadSafetyTest {
|
||||||
|
|
||||||
|
private static final String templateA = "Template A content\n{{> templateB}}";
|
||||||
|
private static final String templateB = "Template B content";
|
||||||
|
|
||||||
|
private static class CountingLoader implements Mustache.TemplateLoader {
|
||||||
|
private final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
|
||||||
|
@Override public Reader getTemplate (String name) throws Exception {
|
||||||
|
counter.incrementAndGet();
|
||||||
|
if (!"templateB".equals(name)) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
return new StringReader(templateB);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int counter () {
|
||||||
|
return counter.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateLoading () throws InterruptedException {
|
||||||
|
// 4096 works but is disabled as it makes the test take a long time
|
||||||
|
for (int ii : new int[] { 1, 2, 4, 8, 16, 32, 256, 1024/* , 4096 */ }) {
|
||||||
|
templateLoadingIsThreadSafe(ii);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void templateLoadingIsThreadSafe (int nThreads) throws InterruptedException {
|
||||||
|
final CyclicBarrier barrier = new CyclicBarrier(nThreads);
|
||||||
|
final CountingLoader loader = new CountingLoader();
|
||||||
|
final Mustache.Compiler compiler = Mustache.compiler().withLoader(loader);
|
||||||
|
final Template template = compiler.compile(new StringReader(templateA));
|
||||||
|
|
||||||
|
final List<Thread> threads = new LinkedList<>();
|
||||||
|
for (int i = 0; i < nThreads; i++) {
|
||||||
|
final Thread thread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
barrier.await();
|
||||||
|
final String value = template.execute(Map.of());
|
||||||
|
if (!value.contains("Template A content\nTemplate B content")) {
|
||||||
|
fail("Invalid template result " + value);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
threads.add(thread);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1, loader.counter());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user