diff --git a/drools-compiler/src/test/java/org/drools/compiler/integrationtests/sequential/SequentialTest.java b/drools-compiler/src/test/java/org/drools/compiler/integrationtests/sequential/SequentialTest.java index 238da0713a1..57f5c008de4 100644 --- a/drools-compiler/src/test/java/org/drools/compiler/integrationtests/sequential/SequentialTest.java +++ b/drools-compiler/src/test/java/org/drools/compiler/integrationtests/sequential/SequentialTest.java @@ -11,12 +11,10 @@ import org.junit.Before; import org.junit.Test; import org.kie.api.KieBaseConfiguration; -import org.kie.api.event.rule.RuleRuntimeEventListener; -import org.kie.internal.KnowledgeBase; -import org.kie.internal.KnowledgeBaseFactory; -import org.kie.internal.builder.conf.RuleEngineOption; -import org.kie.internal.command.CommandFactory; -import org.kie.internal.conf.SequentialOption; +import org.kie.api.KieServices; +import org.kie.api.builder.KieBuilder; +import org.kie.api.builder.KieFileSystem; +import org.kie.api.builder.Results; import org.kie.api.event.rule.AfterMatchFiredEvent; import org.kie.api.event.rule.AgendaEventListener; import org.kie.api.event.rule.AgendaGroupPoppedEvent; @@ -29,6 +27,14 @@ import org.kie.api.event.rule.ObjectUpdatedEvent; import org.kie.api.event.rule.RuleFlowGroupActivatedEvent; import org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent; +import org.kie.api.event.rule.RuleRuntimeEventListener; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.StatelessKieSession; +import org.kie.internal.KnowledgeBase; +import org.kie.internal.KnowledgeBaseFactory; +import org.kie.internal.builder.conf.RuleEngineOption; +import org.kie.internal.command.CommandFactory; +import org.kie.internal.conf.SequentialOption; import org.kie.internal.runtime.StatelessKnowledgeSession; import java.io.IOException; @@ -215,7 +221,7 @@ public void testBasicOperation() throws Exception { 15 ); - ksession.execute( CommandFactory.newInsertElements(Arrays.asList( new Object[]{p1, stilton, p2, cheddar, p3} )) ); + ksession.execute( CommandFactory.newInsertElements( Arrays.asList( new Object[]{p1, stilton, p2, cheddar, p3} ) ) ); assertEquals( 3, list.size() ); @@ -236,8 +242,8 @@ public void testSalience() throws Exception { list.size() ); assertEquals( "rule 3", list.get( 0 )); - assertEquals( "rule 2", list.get( 1 )); - assertEquals( "rule 1", list.get( 2 )); + assertEquals( "rule 2", list.get( 1 ) ); + assertEquals( "rule 1", list.get( 2 ) ); } @Test @@ -277,76 +283,76 @@ public void testEvents() throws Exception { ksession.addEventListener( new AgendaEventListener() { - public void matchCancelled(MatchCancelledEvent event) { + public void matchCancelled( MatchCancelledEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void matchCreated(MatchCreatedEvent event) { + public void matchCreated( MatchCreatedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void afterMatchFired(AfterMatchFiredEvent event) { + public void afterMatchFired( AfterMatchFiredEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void agendaGroupPopped(AgendaGroupPoppedEvent event) { + public void agendaGroupPopped( AgendaGroupPoppedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void agendaGroupPushed(AgendaGroupPushedEvent event) { + public void agendaGroupPushed( AgendaGroupPushedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void beforeMatchFired(BeforeMatchFiredEvent event) { + public void beforeMatchFired( BeforeMatchFiredEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) { + public void beforeRuleFlowGroupActivated( RuleFlowGroupActivatedEvent event ) { assertNotNull( event.getKieRuntime() ); - list.add( event ); + list.add( event ); } - public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) { + public void afterRuleFlowGroupActivated( RuleFlowGroupActivatedEvent event ) { assertNotNull( event.getKieRuntime() ); - list.add( event ); + list.add( event ); } - public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) { + public void beforeRuleFlowGroupDeactivated( RuleFlowGroupDeactivatedEvent event ) { assertNotNull( event.getKieRuntime() ); - list.add( event ); + list.add( event ); } - public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) { + public void afterRuleFlowGroupDeactivated( RuleFlowGroupDeactivatedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - }); + } ); ksession.addEventListener( new RuleRuntimeEventListener() { - public void objectInserted(ObjectInsertedEvent event) { + public void objectInserted( ObjectInsertedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void objectDeleted(ObjectDeletedEvent event) { + public void objectDeleted( ObjectDeletedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - public void objectUpdated(ObjectUpdatedEvent event) { + public void objectUpdated( ObjectUpdatedEvent event ) { assertNotNull( event.getKieRuntime() ); list.add( event ); } - - }); + + } ); ksession.execute( new Message( "help" ) ); @@ -377,9 +383,9 @@ public void testSequentialWithRulebaseUpdate() throws Exception { assertEquals( "rule 3", list.get( 0 )); assertEquals( "rule 2", list.get( 1 )); assertEquals( "rule 1", list.get( 2 )); - assertEquals( "rule 3", list.get( 3 )); - assertEquals( "rule 2", list.get( 4 )); - assertEquals( "rule 1", list.get( 5 )); + assertEquals( "rule 3", list.get( 3 ) ); + assertEquals( "rule 2", list.get( 4 ) ); + assertEquals( "rule 1", list.get( 5 ) ); assertEquals( person, list.get( 6 )); } @@ -407,7 +413,7 @@ public void testNumberofIterationsSeq() throws Exception { //test throughput runTestProfileManyRulesAndFacts( true, "SEQUENTIAL", - 2000, "sequentialProfile.drl" ); + 2000, "sequentialProfile.drl" ); } @Test @@ -497,4 +503,39 @@ private void runTestProfileManyRulesAndFacts(boolean sequentialMode, } + @Test(timeout = 10000L) + public void testSequentialWithNoLoop() throws Exception { + // BZ-1228098 + String str = + "package org.drools.compiler.test\n" + + "import \n" + Message.class.getCanonicalName() + ";" + + "rule R1 no-loop when\n" + + " $s : String( )" + + " $m : Message( )\n" + + "then\n" + + " modify($m) { setMessage($s) };\n" + + "end\n"; + + KieServices ks = KieServices.Factory.get(); + KieFileSystem kfs = ks.newKieFileSystem(); + kfs.write("src/main/resources/r0.drl", str); + + KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); + Results results = kieBuilder.getResults(); + if (results.hasMessages( org.kie.api.builder.Message.Level.ERROR)) { + throw new RuntimeException(results.getMessages().toString()); + } + KieContainer kieContainer = ks.newKieContainer( ks.getRepository().getDefaultReleaseId() ); + + KieBaseConfiguration kieBaseConf = ks.newKieBaseConfiguration(); + kieBaseConf.setOption( SequentialOption.YES ); + + StatelessKieSession sequentialKsession = kieContainer.newKieBase( kieBaseConf ).newStatelessKieSession(); + List result = (List) sequentialKsession.execute( CommandFactory.newInsertElements(Arrays.asList("test", new Message()))); + assertEquals( 2, result.size() ); + + StatelessKieSession ksession = kieContainer.getKieBase().newStatelessKieSession(); + result = (List) ksession.execute( CommandFactory.newInsertElements(Arrays.asList("test", new Message()))); + assertEquals( 2, result.size() ); + } } diff --git a/drools-core/src/main/java/org/drools/core/common/DefaultAgenda.java b/drools-core/src/main/java/org/drools/core/common/DefaultAgenda.java index 5d2ae6b958c..ad1878c668d 100644 --- a/drools-core/src/main/java/org/drools/core/common/DefaultAgenda.java +++ b/drools-core/src/main/java/org/drools/core/common/DefaultAgenda.java @@ -121,6 +121,7 @@ public class DefaultAgenda protected int activationCounter; private boolean declarativeAgenda; + private boolean sequential; private ObjectTypeConf activationObjectTypeConf; @@ -166,6 +167,7 @@ public DefaultAgenda(InternalKnowledgeBase kBase, } this.declarativeAgenda = kBase.getConfiguration().isDeclarativeAgenda(); + this.sequential = kBase.getConfiguration().isSequential(); } public void readExternal(ObjectInput in) throws IOException, @@ -179,6 +181,7 @@ public void readExternal(ObjectInput in) throws IOException, knowledgeHelper = (KnowledgeHelper) in.readObject(); legacyConsequenceExceptionHandler = (ConsequenceExceptionHandler) in.readObject(); declarativeAgenda = in.readBoolean(); + sequential = in.readBoolean(); } public void writeExternal(ObjectOutput out) throws IOException { @@ -190,7 +193,8 @@ public void writeExternal(ObjectOutput out) throws IOException { out.writeObject( agendaGroupFactory ); out.writeObject( knowledgeHelper ); out.writeObject( legacyConsequenceExceptionHandler ); - out.writeBoolean(declarativeAgenda); + out.writeBoolean( declarativeAgenda ); + out.writeBoolean( sequential ); } public RuleAgendaItem createRuleAgendaItem(final int salience, @@ -257,6 +261,10 @@ public WorkingMemory getWorkingMemory() { @Override public void addEagerRuleAgendaItem(RuleAgendaItem item) { + if ( sequential ) { + return; + } + if ( workingMemory.getSessionConfiguration().getForceEagerActivationFilter().accept(item.getRule()) ) { item.getRuleExecutor().evaluateNetwork(workingMemory); return;