@Test
public void testActivationGroup() {
final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) ruleBase.newStatefulSession();
final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
final List list = new ArrayList();
// create the consequence
final Consequence consequence = new Consequence() {
private static final long serialVersionUID = 510l;
public void evaluate(KnowledgeHelper knowledgeHelper,
WorkingMemory workingMemory) {
list.add(knowledgeHelper.getRule());
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
}
public void writeExternal(ObjectOutput out) throws IOException {
}
public String getName() {
return "default";
}
};
// create a rule for each agendaGroup
final Rule rule0 = new Rule("test-rule0");
rule0.setActivationGroup("activation-group-0");
final RuleTerminalNode node0 = new RuleTerminalNode(3,
new MockTupleSource(2),
rule0,
rule0.getLhs(),
0,
buildContext);
rule0.setConsequence(consequence);
final PropagationContext context0 = pctxFactory.createPropagationContext(0,
PropagationContext.INSERTION,
rule0,
null,
new DefaultFactHandle());
final Rule rule1 = new Rule("test-rule1");
rule1.setActivationGroup("activation-group-0");
rule1.setSalience(new SalienceInteger(10));
final RuleTerminalNode node1 = new RuleTerminalNode(5,
new MockTupleSource(4),
rule1,
rule1.getLhs(),
0,
buildContext);
rule1.setConsequence(consequence);
final PropagationContext context1 = pctxFactory.createPropagationContext(0,
PropagationContext.INSERTION,
rule1,
null,
new DefaultFactHandle());
final Rule rule2 = new Rule("test-rule2");
rule2.setSalience(new SalienceInteger(-5));
final RuleTerminalNode node2 = new RuleTerminalNode(7,
new MockTupleSource(6),
rule2,
rule2.getLhs(),
0,
buildContext);
rule2.setConsequence(consequence);
final PropagationContext context2 = pctxFactory.createPropagationContext(0,
PropagationContext.INSERTION,
rule2,
null,
new DefaultFactHandle());
final Rule rule3 = new Rule("test-rule3",
"agendaGroup3");
rule3.setSalience(new SalienceInteger(-10));
rule3.setActivationGroup("activation-group-3");
final RuleTerminalNode node3 = new RuleTerminalNode(9,
new MockTupleSource(8),
rule3,
rule3.getLhs(),
0,
buildContext);
rule3.setConsequence(consequence);
final PropagationContext context3 = pctxFactory.createPropagationContext(0,
PropagationContext.INSERTION,
rule3,
null,
new DefaultFactHandle());
final RuleTerminalNodeLeftTuple tuple1 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node1, true);
final RuleTerminalNodeLeftTuple tuple3 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node1, true);
final RuleTerminalNodeLeftTuple tuple4 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node1, true);
final RuleTerminalNodeLeftTuple tuple5 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node1, true);
final RuleTerminalNodeLeftTuple tuple6 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node1, true);
final RuleTerminalNodeLeftTuple tuple7 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node2, true);
final RuleTerminalNodeLeftTuple tuple8 = new RuleTerminalNodeLeftTuple(new DefaultFactHandle(1, "cheese"), node3, true);
// Assert the tuple and check it was added to activation-group-0
node0.assertLeftTuple(tuple1,
context0,
workingMemory);
agenda.unstageActivations();
final ActivationGroup activationGroup0 = agenda.getActivationGroup("activation-group-0");
assertEquals(1,
activationGroup0.size());
// Removing a tuple should remove the activation from the activation-group-0 again
node0.retractLeftTuple(tuple1,
context0,
workingMemory);
assertEquals(0,
activationGroup0.size());
// Assert the tuple again and check it was added to activation-group-0
node0.assertLeftTuple(tuple3,
context0,
workingMemory);
agenda.unstageActivations();
assertEquals(1,
activationGroup0.size());
// Assert another tuple and check it was added to activation-group-0
node1.assertLeftTuple(tuple4,
context1,
workingMemory);
agenda.unstageActivations();
assertEquals(2,
activationGroup0.size());
// There should now be two potential activations to fire
assertEquals(2,
agenda.focusStackSize());
// The first tuple should fire, adding itself to the List and clearing and cancelling the other Activations in the activation-group-0
agenda.fireNextItem(null, 0, -1);
// Make sure the activation-group-0 is clear
assertEquals(0,
activationGroup0.size());
// Make sure the Agenda is empty
assertEquals(0,
agenda.focusStackSize());
// List should only have a single item, "rule0"
assertEquals(1,
list.size());
assertSame(rule1,
list.get(0));
list.clear();
//-------------------
// Now try a more complex scenario involving two Xor Groups and one rule not in a Group
node0.assertLeftTuple(tuple5,
context0,
workingMemory);
node1.assertLeftTuple(tuple6,
context1,
workingMemory);
node2.assertLeftTuple(tuple7,
context2,
workingMemory);
node3.assertLeftTuple(tuple8,
context3,
workingMemory);
agenda.unstageActivations();
// activation-group-0 should be populated again
assertEquals(2,
activationGroup0.size());
// make sure the activation-group-3 is cleared when we can clear the Agenda Group for the activation that is in both
final ActivationGroup activationGroup3 = agenda.getActivationGroup("activation-group-3");
assertEquals(4,
agenda.agendaSize());
assertEquals(1,
activationGroup3.size());
agenda.clearAndCancelAgendaGroup("agendaGroup3");
assertEquals(3,
agenda.agendaSize());
assertEquals(0,
activationGroup3.size());
// Activation for activation-group-0 should be next - the activation in no activation/agenda group should remain on the agenda
agenda.fireNextItem(null, 0, -1);
assertEquals(1,
agenda.agendaSize());
assertEquals(0,
activationGroup0.size());
// Fire the last activation and make sure the Agenda Empties
agenda.fireNextItem(null, 0, -1);
assertEquals(0,
agenda.agendaSize());
assertEquals(2,
list.size());
assertEquals(rule1,
list.get(0));