[jboss-svn-commits] JBL Code SVN: r37003 - in labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools: core and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri May 13 23:48:11 EDT 2011
Author: tsurdilovic
Date: 2011-05-13 23:48:10 -0400 (Fri, 13 May 2011)
New Revision: 37003
Added:
labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/
labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/reteoo/
labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/reteoo/BinaryHeapQueueTest.java
Log:
BRMS-586: Rules do not fire according to salience after multiple fact updates
Added: labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/reteoo/BinaryHeapQueueTest.java
===================================================================
--- labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/reteoo/BinaryHeapQueueTest.java (rev 0)
+++ labs/jbossrules/soa_branches/BRMS-5.1.x/drools-compiler/src/test/java/org/drools/core/reteoo/BinaryHeapQueueTest.java 2011-05-14 03:48:10 UTC (rev 37003)
@@ -0,0 +1,412 @@
+package org.drools.core.reteoo;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import org.drools.common.ActivationGroupNode;
+import org.drools.common.ActivationNode;
+import org.drools.common.InternalFactHandle;
+import org.drools.common.LogicalDependency;
+import org.drools.core.util.BinaryHeapQueue;
+import org.drools.core.util.LinkedList;
+import org.drools.core.util.Queueable;
+import org.drools.reteoo.LeftTuple;
+import org.drools.rule.GroupElement;
+import org.drools.rule.Rule;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.spi.Activation;
+import org.drools.spi.AgendaGroup;
+import org.drools.spi.ConflictResolver;
+import org.drools.spi.PropagationContext;
+
+/**
+ * Thes test class uses auxiliary test classes in org.drools.util:
+ * Group and Item as a mock-up for the corresponding Agenda classes.
+ *
+ * The test testShuffled uses a sequence of shuffled Item arrays, inserts
+ * them in the "random" order, retracts and reinserts the Items at an even
+ * position. Finally, Items are retrieved and the order is checked.
+ *
+ * Experience has shown that at least 6 Items are required to demonstrate
+ * a certain bug, so don't reduce the max parameter.
+ *
+ */
+public class BinaryHeapQueueTest extends TestCase {
+
+ private List<Integer[]> perms = new ArrayList<Integer[]>();
+ private final static int max = 6;
+
+ // NOT really permutations, just some shuffling
+ private void shuffle(Integer[] a,
+ int lim) {
+ if ( lim == 0 ) {
+ Integer[] p = a.clone();
+ perms.add( p );
+ } else {
+ shuffle( a,
+ lim - 1 );
+ Integer h = a[lim];
+ a[lim] = a[lim - 1];
+ a[lim - 1] = h;
+ shuffle( a,
+ lim - 1 );
+ }
+ }
+
+ public void setUp() throws Exception {
+ System.out.println( "Running setup" );
+ Integer[] a = new Integer[max];
+ for ( int i = 0; i < max; i++ ) {
+ a[i] = i;
+ }
+ shuffle( a,
+ max - 1 );
+ // System.out.println( "The size is " + perms.size() );
+ }
+
+ public void testShuffled() {
+
+ for ( Integer[] perm : perms ) {
+ Group group = new Group( "group" );
+
+ for ( Integer i : perm ) {
+ Item item = new Item( group,
+ i );
+ group.add( item );
+ }
+
+ Queueable[] elems = group.getQueue();
+ for ( Queueable elem : elems ) {
+ Item item = (Item) elem;
+ // System.out.print( " " + item.getSalience() + "/" + item.getActivationNumber() + "/" + item.getIndex() );
+ if ( item.getIndex() % 2 == 0 ) {
+ group.remove( item );
+ group.add( item );
+ }
+ }
+ boolean ok = true;
+ StringBuilder sb = new StringBuilder( "queue:" );
+ for ( int i = max - 1; i >= 0; i-- ) {
+ int sal = group.getNext().getSalience();
+ sb.append( " " ).append( sal );
+ if ( sal != i ) ok = false;
+ }
+ assertTrue( "incorrect order in " + sb.toString(),
+ ok );
+ // System.out.println( sb.toString() );
+ }
+ }
+
+ public static class Group {
+
+ private static final long serialVersionUID = 510l;
+
+ private String name;
+
+ /** Items in the agenda. */
+ private BinaryHeapQueue queue;
+
+ /**
+ * Construct an <code>AgendaGroup</code> with the given name.
+ *
+ * @param name
+ * The <AgendaGroup> name.
+ */
+ public Group() {
+ }
+
+ public Group(final String name) {
+ this.name = name;
+ this.queue = new BinaryHeapQueue( ItemConflictResolver.INSTANCE );
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void clear() {
+ this.queue.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.spi.AgendaGroup#size()
+ */
+ public int size() {
+ return this.queue.size();
+ }
+
+ public void add(final Item item) {
+ this.queue.enqueue( (Queueable) item );
+ }
+
+ public Item getNext() {
+ return (Item) this.queue.dequeue();
+ }
+
+ /**
+ * Iterates a PriorityQueue removing empty entries until it finds a populated entry and return true,
+ * otherwise it returns false;
+ *
+ * @param priorityQueue
+ * @return
+ */
+ public boolean isEmpty() {
+ return this.queue.isEmpty();
+ }
+
+ public String toString() {
+ return "AgendaGroup '" + this.name + "'";
+ }
+
+ public boolean equal(final Object object) {
+ if ( (object == null) || !(object instanceof Group) ) {
+ return false;
+ }
+
+ if ( ((Group) object).name.equals( this.name ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public int hashCode() {
+ return this.name.hashCode();
+ }
+
+ public void remove(Item agendaItem) {
+ this.queue.dequeue( agendaItem.getIndex() );
+ }
+
+ public Queueable[] getQueue() {
+ return (Queueable[]) this.queue.toArray( new Queueable[size()] );
+ }
+ }
+
+ public static class IsTuple extends BaseMatcher<List<InternalFactHandle>> {
+ private final InternalFactHandle[] expected;
+
+ public IsTuple(List<InternalFactHandle> tupleAsList) {
+ expected = tupleAsList.toArray( new InternalFactHandle[tupleAsList.size()] );
+ }
+
+ public IsTuple(InternalFactHandle[] tuple) {
+ expected = tuple;
+ }
+
+ public boolean matches(Object arg) {
+ if ( arg == null || !(arg.getClass().isArray() && InternalFactHandle.class.isAssignableFrom( arg.getClass().getComponentType() )) ) {
+ return false;
+ }
+ InternalFactHandle[] actual = (InternalFactHandle[]) arg;
+ return Arrays.equals( expected,
+ actual );
+ }
+
+ public void describeTo(Description description) {
+ description.appendValue( expected );
+ }
+
+ /**
+ * Is the value equal to another value, as tested by the
+ * {@link java.lang.Object#equals} invokedMethod?
+ */
+ @Factory
+ public static Matcher<List<InternalFactHandle>> isTuple(List<InternalFactHandle> operand) {
+ return new IsTuple( operand );
+ }
+
+ public static Matcher< ? super List<InternalFactHandle>> isTuple(InternalFactHandle... operands) {
+ return new IsTuple( operands );
+ }
+ }
+
+ public static class Item
+ implements
+ Queueable,
+ Activation {
+
+ private static int actNo = 1;
+
+ private int index;
+ private long activationNumber;
+ private Group group;
+ private int salience;
+
+ public Item(Group group,
+ int salience) {
+ this.group = group;
+ this.salience = salience;
+ this.activationNumber = actNo++;
+ }
+
+ public void dequeue() {
+ if ( this.group != null ) {
+ this.group.remove( this );
+ }
+ this.index = -1;
+ }
+
+ public void enqueued(int index) {
+ this.index = index;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public int getSalience() {
+ return salience;
+ }
+
+ public long getActivationNumber() {
+ return activationNumber;
+ }
+
+ public void addLogicalDependency(LogicalDependency arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public ActivationGroupNode getActivationGroupNode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ActivationNode getActivationNode() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public AgendaGroup getAgendaGroup() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public LinkedList getLogicalDependencies() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public PropagationContext getPropagationContext() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Rule getRule() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public GroupElement getSubRule() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public LeftTuple getTuple() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isActivated() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void remove() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setActivated(boolean arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setActivationGroupNode(ActivationGroupNode arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setActivationNode(ActivationNode arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setLogicalDependencies(LinkedList arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public List<String> getDeclarationIDs() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object getDeclarationValue(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List< ? extends FactHandle> getFactHandles() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List<Object> getObjects() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+
+ public static class ItemConflictResolver
+ implements
+ ConflictResolver {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ public static final ItemConflictResolver INSTANCE = new ItemConflictResolver();
+
+ public static ItemConflictResolver getInstance() {
+ return ItemConflictResolver.INSTANCE;
+ }
+
+ /**
+ * @see ConflictResolver
+ */
+ public final int compare(final Object existing,
+ final Object adding) {
+ return compare( (Item) existing,
+ (Item) adding );
+ }
+
+ public final int compare(final Item existing,
+ final Item adding) {
+ final int s1 = existing.getSalience();
+ final int s2 = adding.getSalience();
+
+ if ( s1 != s2 ) {
+ return s1 - s2;
+ }
+
+ // we know that no two activations will have the same number
+ return (int) (existing.getActivationNumber() - adding.getActivationNumber());
+ }
+
+ public int compare(Activation arg0,
+ Activation arg1) {
+ return 0;
+ }
+
+ }
+}
+
More information about the jboss-svn-commits
mailing list