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

Reply via email to