|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.util.Set;
|
|
|
|
import javax.xml.transform.Source;
|
|
import javax.xml.transform.stream.StreamSource;
|
|
|
|
import org.testng.Assert;
|
|
import org.testng.annotations.BeforeClass;
|
|
import org.testng.annotations.Test;
|
|
|
|
import com.saxonica.config.EnterpriseConfiguration;
|
|
|
|
import net.sf.saxon.lib.StandardURIResolver;
|
|
import net.sf.saxon.s9api.Processor;
|
|
import net.sf.saxon.s9api.XQueryCompiler;
|
|
import net.sf.saxon.s9api.XQueryEvaluator;
|
|
import net.sf.saxon.s9api.XQueryExecutable;
|
|
import net.sf.saxon.s9api.XdmSequenceIterator;
|
|
import net.sf.saxon.trans.XPathException;
|
|
|
|
public class ThreadCountTest2 {
|
|
private Processor saxonProcessor;
|
|
private XQueryCompiler xqueryCompiler;
|
|
|
|
@BeforeClass
|
|
public void beforeClass() throws Exception {
|
|
EnterpriseConfiguration configuration = new EnterpriseConfiguration();
|
|
saxonProcessor = new Processor(configuration);
|
|
xqueryCompiler = saxonProcessor.newXQueryCompiler();
|
|
}
|
|
|
|
@Test
|
|
public void testOpenThreads() throws Exception {
|
|
final int testCount = 10000;
|
|
|
|
Set<Thread> threads0 = threads();
|
|
Set<Thread> threads1 = null;
|
|
|
|
for (int i = 0; i < testCount; ++ i) {
|
|
XQueryExecutable xqueryExecutable = xqueryCompiler.compile("saxon:stream(doc('uriresolver:resolve')/*/*)");
|
|
XQueryEvaluator xqueryEvaluator = xqueryExecutable.load();
|
|
xqueryEvaluator.setURIResolver(new StandardURIResolver() {
|
|
@Override
|
|
public Source resolve(String href, String base) throws XPathException {
|
|
return new StreamSource(strawberryFieldsForever());
|
|
}
|
|
});
|
|
XdmSequenceIterator xdmSequenceIterator = xqueryEvaluator.iterator();
|
|
xdmSequenceIterator.next();
|
|
xdmSequenceIterator.close();
|
|
xqueryEvaluator.close();
|
|
}
|
|
|
|
for (int j = 0; j < 10; ++j) {
|
|
threads1 = threads();
|
|
if (threads0.containsAll(threads1))
|
|
return;
|
|
Thread.sleep(1000);
|
|
}
|
|
|
|
String msg = "number of threads increased from " + threads0.size() + " to " + threads1.size();
|
|
System.err.println(msg);
|
|
for (Thread thread : threads1) {
|
|
if (! threads0.contains(thread)) {
|
|
System.err.println(" " + thread.getName());
|
|
for (StackTraceElement stackTraceElement : thread.getStackTrace())
|
|
System.err.println(" " + stackTraceElement);
|
|
}
|
|
}
|
|
|
|
Assert.fail(msg);
|
|
}
|
|
|
|
private static Set<Thread> threads() {
|
|
return Thread.getAllStackTraces().keySet();
|
|
}
|
|
|
|
private static InputStream strawberryFieldsForever() {
|
|
return new InputStream() {
|
|
private static final String intro =
|
|
"<song>\n";
|
|
private static final String chorus =
|
|
" <chorus>\n" +
|
|
" <line>Let me take you down</line>\n" +
|
|
" <line>Cause I'm going to Strawberry Fields</line>\n" +
|
|
" <line>Nothing is real</line>\n" +
|
|
" <line>And nothing to get hung about</line>\n" +
|
|
" <line>Strawberry Fields forever</line>\n" +
|
|
" </chorus>\n";
|
|
private int i = - intro.length();
|
|
|
|
@Override
|
|
public int read() throws IOException {
|
|
if (i++ < 0) {
|
|
return intro.charAt(i + intro.length() - 1);
|
|
}
|
|
else {
|
|
i %= chorus.length();
|
|
return chorus.charAt(i);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|