[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