On 7/14/07, Mark Proctor <[EMAIL PROTECTED]> wrote:
We are going to need an integration test, to reproduce this, can you
supply one?
Okay, I've just converted the simple test that I added earlier to a
Junit test. The test is not guaranteed to fail if there are thread
safety errors, just very likely to fail (don't know if this is
acceptable for you). Initially, I wrote a test which guaranteed that
calls to the addPackage() and getPackage() methods were interleaved by
different threads, but, annoyingly, this test passed. It seems that a
context-switch halfway through one of these methods is necessary to
provoke the problem (which is difficult to guarantee :-)
Dean.
package org.drools.integrationtests;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.drools.compiler.PackageBuilderConfiguration;
import org.drools.compiler.PackageBuilderErrors;
import org.drools.lang.descr.FunctionDescr;
import org.drools.lang.descr.ImportDescr;
import org.drools.lang.descr.PackageDescr;
public class PackageBuilderThreadSafetyTest extends TestCase {
private static final int _NUMBER_OF_THREADS = 100;
private static final int _SLEEP_TIME_MS = 100;
public void testThreadSafety() {
final List<PackageBuilderErrors> errors = new ArrayList<PackageBuilderErrors>();
final List<Exception> exceptions= new ArrayList<Exception>();
Thread[] threads = new Thread[_NUMBER_OF_THREADS];
for (int i = 0; i < _NUMBER_OF_THREADS; i++) {
Thread testThread = new Thread() {
public void run() {
try {
PackageBuilderConfiguration packageBuilderConfig = new PackageBuilderConfiguration();
org.drools.compiler.PackageBuilder builder = null;
try {
builder = new org.drools.compiler.PackageBuilder(packageBuilderConfig);
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException(t);
}
PackageDescr packageDescr = new PackageDescr("MyRulebase");
addImports(packageDescr);
addFunctions(packageDescr);
// added some arbitrary sleep statements to encourage
// context switching and hope this provokes exceptions
sleep(_SLEEP_TIME_MS);
builder.addPackage(packageDescr);
sleep(_SLEEP_TIME_MS);
builder.getPackage();
sleep(_SLEEP_TIME_MS);
if (builder.hasErrors()) {
errors.add(builder.getErrors());
}
} catch (Exception e) {
e.printStackTrace();
exceptions.add(e);
}
}
};
threads[i] = testThread;
try {
testThread.start();
} catch (Exception e) {
assertTrue(false);
}
}
for (int i = 0; i < _NUMBER_OF_THREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
threads[i].interrupt();
}
}
assertTrue("Exceptions during package compilation (number=" + exceptions.size() + ")" , exceptions.isEmpty());
assertTrue("PackageBuilderErrors during package compilation (number=" + errors.size() + ")", errors.isEmpty());
}
private static void addImports(PackageDescr packageDescr) {
packageDescr.addImport(new ImportDescr("java.util.List"));
packageDescr.addImport(new ImportDescr("java.util.ArrayList"));
packageDescr.addImport(new ImportDescr("java.util.LinkedList"));
packageDescr.addImport(new ImportDescr("java.util.Set"));
packageDescr.addImport(new ImportDescr("java.util.HashSet"));
packageDescr.addImport(new ImportDescr("java.util.SortedSet"));
packageDescr.addImport(new ImportDescr("java.util.TreeSet"));
}
private static void addFunctions(PackageDescr packageDescr) {
FunctionDescr functionDescr = new FunctionDescr("foo", "void");
functionDescr.addParameter("String", "arg1");
String body =
"Set myHashSet = new HashSet();" +
"myHashSet.add(arg1);" +
"List myArrayList = new ArrayList();" +
"myArrayList.add(arg1);" +
"List myLinkedList = new LinkedList();" +
"myLinkedList.add(arg1);" +
"Set myTreeSet = new TreeSet();" +
"myTreeSet.add(arg1);";
functionDescr.setText(body);
packageDescr.addFunction(functionDescr);
}
}
_______________________________________________
rules-users mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/rules-users