package org.drools.compiler.integrationtests; import java.util.List; import java.util.Map; import org.drools.compiler.Cheese; import org.drools.compiler.CommonTestMethodBase; import org.drools.compiler.Person; import org.drools.compiler.integrationtests.facts.FactWithList; import org.drools.core.base.ClassObjectType; import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.JoinNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.MethodCountingAlphaNode; import org.drools.core.reteoo.MethodCountingLeftInputAdapterNode; import org.drools.core.reteoo.MethodCountingObjectTypeNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.builder.MethodCountingNodeFactory; import org.drools.core.reteoo.builder.NodeFactory; import org.junit.Test; import org.kie.api.definition.rule.Rule; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.internal.KnowledgeBase; import org.kie.internal.utils.KieHelper; import static org.drools.core.util.DroolsTestUtil.rulestoMap; public class SharingTest extends CommonTestMethodBase { private KnowledgeBase kbase; private Map<String, Rule> rules; private AlphaNode alphaNode_1; private AlphaNode alphaNode_2; private LeftInputAdapterNode lian_1; private LeftInputAdapterNode lian_2; private ObjectTypeNode otn; private JoinNode joinNode; public void setupKnowledgeBase() throws Exception { NodeFactory nodeFactory = MethodCountingNodeFactory.getInstance(); kbase = loadKnowledgeBaseFromString( nodeFactory, getRules()); rules = rulestoMap(kbase); otn = getObjectTypeNode(kbase, Person.class ); alphaNode_1 = ( AlphaNode ) otn.getObjectSinkPropagator().getSinks()[0]; //AlphaNode name == "Mark" alphaNode_2 = (AlphaNode) alphaNode_1.getObjectSinkPropagator().getSinks()[0]; // 2nd level (age = 50) lian_1 = (LeftInputAdapterNode) alphaNode_1.getObjectSinkPropagator().getSinks()[1]; lian_2 = (LeftInputAdapterNode) alphaNode_2.getObjectSinkPropagator().getSinks()[0]; AlphaNode an = ( AlphaNode ) otn.getObjectSinkPropagator().getSinks()[1]; // name = "John" LeftInputAdapterNode lian =(LeftInputAdapterNode) an.getObjectSinkPropagator().getSinks()[1]; joinNode = (JoinNode) lian.getSinkPropagator().getSinks()[0]; //this == $personCheese } public static ObjectTypeNode getObjectTypeNode(KnowledgeBase kbase, Class<?> nodeClass) { List<ObjectTypeNode> nodes = ((KnowledgeBaseImpl)kbase).getRete().getObjectTypeNodes(); for ( ObjectTypeNode n : nodes ) { if ( ((ClassObjectType)n.getObjectType()).getClassType() == nodeClass ) { return n; } } return null; } private String getRules() { String drl = ""; drl += "package org.drools.compiler.test\n"; drl += "import " + Person.class.getCanonicalName() + "\n"; drl += "import " + Cheese.class.getCanonicalName() + "\n"; drl += "rule r1\n"; drl += "when\n"; drl += " Person(name == \"Mark\")\n"; drl += "then\n"; drl += "end\n"; drl += "rule r2\n"; drl += "when\n"; drl += " Person(name == \"Mark\")\n"; drl += "then\n"; drl += "end\n"; drl += "rule r3\n"; drl += "when\n"; drl += " Person(name == \"Mark\", age == 50)\n"; drl += "then\n"; drl += "end\n"; drl += "rule r4\n"; drl += "when\n"; drl += " Person(name == \"Mark\", age == 50)\n"; drl += "then\n"; drl += "end\n"; drl += "rule r5\n"; drl += "when\n"; drl += " Person(name == \"John\", age == 50)\n"; drl += "then\n"; drl += "end\n"; drl += "rule r6\n"; drl += "when\n"; drl += " Person(name == \"John\",$personCheese: cheese)\n"; drl += "Cheese(this == $personCheese )"; drl += "then\n"; drl += "end\n"; drl += "rule r7\n"; drl += "when\n"; drl += " Person(name == \"John\",$personCheese: cheese)\n"; drl += "Cheese(this == $personCheese )"; drl += "then\n"; drl += "end\n"; return drl; } @Test public void testOTNSharing() throws Exception { setupKnowledgeBase(); assertEquals( 2, otn.getObjectSinkPropagator().size() ); assertEquals(7, otn.getAssociationsSize()); } @Test public void testAlphaNodeSharing() throws Exception { setupKnowledgeBase(); assertEquals( 2, alphaNode_1.getObjectSinkPropagator().size()); assertEquals( 4, alphaNode_1.getAssociationsSize() ); assertTrue( alphaNode_1.isAssociatedWith(rules.get("r1"))); assertTrue( alphaNode_1.isAssociatedWith(rules.get("r2"))); assertTrue( alphaNode_1.isAssociatedWith(rules.get("r3"))); assertTrue( alphaNode_1.isAssociatedWith(rules.get("r4"))); Map<String, Integer> countingMap = ((MethodCountingAlphaNode)alphaNode_1).getMethodCountMap(); assertNotNull(countingMap); assertEquals(6,countingMap.get("thisNodeEquals").intValue()); //Check 2nd level of sharing (age = 50) assertEquals( 1, alphaNode_2.getObjectSinkPropagator().size() ); assertEquals( 2, alphaNode_2.getAssociationsSize() ); assertTrue( alphaNode_2.isAssociatedWith(rules.get("r3"))); assertTrue( alphaNode_2.isAssociatedWith(rules.get("r4"))); countingMap = ((MethodCountingAlphaNode)alphaNode_2).getMethodCountMap(); assertNotNull(countingMap); assertEquals(1,countingMap.get("thisNodeEquals").intValue()); assertNull (countingMap.get("equals")); //Make sure we are not using recursive "equals" method } @Test public void testLeftInputAdapterNodeSharing() throws Exception { setupKnowledgeBase(); //Check first level of lian sharing assertEquals( 2, lian_1.getSinkPropagator().size() ); assertTrue( lian_1.isAssociatedWith(rules.get("r1"))); assertTrue( lian_1.isAssociatedWith(rules.get("r2"))); RuleTerminalNode rtn1 = (RuleTerminalNode) lian_1.getSinkPropagator().getSinks()[0]; assertTrue(rtn1.isAssociatedWith(rules.get("r1"))); RuleTerminalNode rtn2 = (RuleTerminalNode) lian_1.getSinkPropagator().getSinks()[1]; assertTrue(rtn2.isAssociatedWith(rules.get("r2"))); Map<String, Integer> countingMap = ((MethodCountingLeftInputAdapterNode)lian_1).getMethodCountMap(); assertNotNull(countingMap); assertEquals(3,countingMap.get("thisNodeEquals").intValue()); //Check 2nd level of lian sharing assertEquals( 2, lian_2.getAssociationsSize()); assertEquals( 2, lian_2.getSinkPropagator().size() ); assertTrue( lian_2.isAssociatedWith(rules.get("r3"))); assertTrue( lian_2.isAssociatedWith(rules.get("r4"))); rtn1 = (RuleTerminalNode) lian_2.getSinkPropagator().getSinks()[0]; assertTrue(rtn1.isAssociatedWith(rules.get("r3"))); rtn2 = (RuleTerminalNode) lian_2.getSinkPropagator().getSinks()[1]; assertTrue(rtn2.isAssociatedWith(rules.get("r4"))); countingMap = ((MethodCountingLeftInputAdapterNode)lian_2).getMethodCountMap(); assertNotNull(countingMap); assertEquals(1,countingMap.get("thisNodeEquals").intValue()); assertNull (countingMap.get("equals")); //Make sure we are not using recursive "equals" method } @Test public void testJoinNodeSharing() throws Exception { setupKnowledgeBase(); assertEquals( 2, joinNode.getSinkPropagator().size() ); assertEquals( 2, joinNode.getAssociationsSize()); assertTrue( joinNode.isAssociatedWith(rules.get("r6"))); assertTrue( joinNode.isAssociatedWith(rules.get("r7"))); MethodCountingObjectTypeNode betaOTN = (MethodCountingObjectTypeNode) joinNode.getRightInput(); Map<String, Integer> countingMap = betaOTN.getMethodCountMap(); assertNull(countingMap); } public static class TestStaticUtils { public static int return1() { return 1; } } @Test public void testShouldAlphaShareBecauseSameConstantDespiteDifferentSyntax() { // DROOLS-1404 String drl1 = "package c;\n" + "import " + Misc2Test.TestObject.class.getCanonicalName() + "\n" + "rule fileArule1 when\n" + " TestObject(value == 1)\n" + "then\n" + "end\n" + ""; String drl2 = "package iTzXzx;\n" + // <<- keep the different package "import " + Misc2Test.TestObject.class.getCanonicalName() + "\n" + "import " + TestStaticUtils.class.getCanonicalName() + "\n" + "rule fileBrule1 when\n" + " TestObject(value == TestStaticUtils.return1() )\n" + "then\n" + "end\n" + "rule fileBrule2 when\n" + // <<- keep this rule " TestObject(value == 0 )\n" + "then\n" + "end\n" + ""; KieSession kieSession = new KieHelper() .addContent( drl1, ResourceType.DRL ) .addContent(drl2, ResourceType.DRL) .build().newKieSession(); kieSession.insert(new Misc2Test.TestObject( 1) ); assertEquals(2, kieSession.fireAllRules() ); } @Test public void testShouldAlphaShareNotEqualsInDifferentPackages() { // DROOLS-1404 String drl1 = "package c;\n" + "import " + Misc2Test.TestObject.class.getCanonicalName() + "\n" + "rule fileArule1 when\n" + " TestObject(value >= 1 )\n" + "then\n" + "end\n" + ""; String drl2 = "package iTzXzx;\n" + // <<- keep the different package "import " + Misc2Test.TestObject.class.getCanonicalName() + "\n" + "rule fileBrule1 when\n" + " TestObject(value >= 1 )\n" + "then\n" + "end\n" + "rule fileBrule2 when\n" + // <<- keep this rule " TestObject(value >= 2 )\n" + "then\n" + "end\n" + ""; KieSession kieSession = new KieHelper() .addContent(drl1, ResourceType.DRL) .addContent(drl2, ResourceType.DRL) .build().newKieSession(); kieSession.insert(new Misc2Test.TestObject( 1) ); assertEquals(2, kieSession.fireAllRules() ); } @Test public void testShouldAlphaShareNotEqualsInDifferentPackages2() { // DROOLS-1404 String drl1 = "package c;\n" + "import " + FactWithList.class.getCanonicalName() + "\n" + "\n" + "rule fileArule1 when\n" + " FactWithList(items contains \"test\")\n" + "then\n" + "end\n" + ""; String drl2 = "package iTzXzx;\n" + // <<- keep the different package "import " + FactWithList.class.getCanonicalName() + "\n" + "rule fileBrule1 when\n" + " FactWithList(items contains \"test\")\n" + "then\n" + "end\n" + "rule fileBrule2 when\n" + // <<- keep this rule " FactWithList(items contains \"testtest\")\n" + "then\n" + "end\n" + ""; KieSession kieSession = new KieHelper() .addContent(drl1, ResourceType.DRL) .addContent(drl2, ResourceType.DRL) .build().newKieSession(); final FactWithList factWithList = new FactWithList("test"); kieSession.insert(factWithList); assertEquals(2, kieSession.fireAllRules() ); } }