/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.testcoverage.functional; import org.assertj.core.api.Assertions; import org.drools.testcoverage.common.listener.OrderListener; import org.drools.testcoverage.common.util.KieBaseTestConfiguration; import org.drools.testcoverage.common.util.KieBaseUtil; import org.drools.testcoverage.common.util.KieUtil; import org.drools.testcoverage.common.util.TestConstants; import org.junit.Test; import org.kie.api.KieBase; import org.kie.api.KieBaseConfiguration; import org.kie.api.KieServices; import org.kie.api.builder.KieModule; import org.kie.api.builder.ReleaseId; import org.kie.api.conf.DeclarativeAgendaOption; import org.kie.api.io.Resource; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.FactHandle; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * * Declarative agenda test. Activation of rule creates * Activation fact which can be used to control other rules. */ public class DeclarativeAgendaTest { // rule activation is blocked and after several iterations (fireAllRules) it // is unblocked and the rule fires @Test(timeout = 60000L) public void testSimpleActivationBlock() { final KieBase kbase = buildKieBase("declarative-agenda-simple-block.drl"); final KieSession ksession = kbase.newKieSession(); OrderListener listener = new OrderListener(); ksession.addEventListener(listener); // first run - just run rules without any blocking final FactHandle fireRules = ksession.insert("fireRules"); final FactHandle fireBlockerRule = ksession.insert("fireBlockerRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected = { "blocker", "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected[i]); } // second run - add blocker rule ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(0); // third run ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.delete(fireBlockerRule); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(1); final String[] expected3 = { "sales1" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected3[i]); } // fourth run ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(0); // fifth run ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.update(fireRules, "fireRules"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected5 = { "sales1", "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected5[i]); } ksession.dispose(); } // test activation block together with agenda group // BZ 999360 @Test(timeout = 60000L) public void testActivationBlock() { final KieBase kbase = buildKieBase("declarative-agenda-block.drl"); final KieSession ksession = kbase.newKieSession(); OrderListener listener = new OrderListener(); ksession.addEventListener(listener); // first run ksession.insert("startAgenda"); ksession.insert("fireRules"); final FactHandle fireBlockerRule = ksession.insert("fireBlockerRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(6); final String[] expected = { "startAgenda", "catering1", "sales1", "salesBlocker", "catering2", "salesBlocker" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected[i]); } // second run ksession.delete(fireBlockerRule); ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(1); // BZ 1038076 final String[] expected2 = { "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected2[i]); } ksession.dispose(); } // test activation count, test case from doc @Test(timeout = 60000L) public void testActivationCount() { final KieBase kbase = buildKieBase("declarative-agenda-count.drl"); final KieSession ksession = kbase.newKieSession(); final List<String> list = new ArrayList<String>(); ksession.setGlobal("list", list); // first run final FactHandle go1 = ksession.insert("go1"); ksession.fireAllRules(); Assertions.assertThat(list.size()).isEqualTo(3); // second run list.clear(); ksession.delete(go1); ksession.fireAllRules(); Assertions.assertThat(list).isEmpty(); ksession.insert("go1"); ksession.insert("go2"); ksession.fireAllRules(); Assertions.assertThat(list.size()).isEqualTo(2); ksession.dispose(); } // testing unblockall command @Test(timeout = 60000L) public void testUnblockAll() { final KieBase kbase = buildKieBase("declarative-agenda-unblockall.drl"); final KieSession ksession = kbase.newKieSession(); final OrderListener listener = new OrderListener(); ksession.addEventListener(listener); // first run ksession.insert("fireRules"); ksession.insert("fireBlockerRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected = { "salesBlocker", "salesBlocker" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected[i]); } // second run ksession.insert("fireUnblockerRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(8); final String[] expected2 = { "salesBlocker", "salesBlocker", "salesUnblocker", "sales1", "salesBlocker", "salesUnblocker", "sales2", "salesBlocker" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected2[i]); } ksession.dispose(); } @Test(timeout = 60000L) public void testSimpleCancel() { final KieBase kbase = buildKieBase("declarative-agenda-cancel.drl"); final KieSession ksession = kbase.newKieSession(); final OrderListener listener = new OrderListener(); ksession.addEventListener(listener); // fires only sales1 rule, sales2 rule activation is canceled by // salesCancel rule ksession.insert("fireRules"); ksession.insert("fireCancelRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected = { "salesCancel", "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected[i]); } ksession.dispose(); } // very complicated // rule firing and canceling depends also on order of inserting facts into // working memory // but activationListener('direct') annotation should guarantee priority to // fire @Test(timeout = 60000L) public void testCancelWithUpdatingFacts() { final KieBase kbase = buildKieBase("declarative-agenda-cancel.drl"); final KieSession ksession = kbase.newKieSession(); OrderListener listener = new OrderListener(); ksession.addEventListener(listener); // first run - with cancelling rule, it should cancel activation of // sales1 final FactHandle fireRules = ksession.insert("fireRules"); final FactHandle fireCancelRule = ksession.insert("fireCancelRule"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected = { "salesCancel", "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected[i]); } // second run ksession.removeEventListener(listener); listener = new OrderListener(); ksession.addEventListener(listener); ksession.update(fireCancelRule, "fireCancelRule"); ksession.update(fireRules, "fireRules"); ksession.fireAllRules(); Assertions.assertThat(listener.size()).isEqualTo(2); final String[] expected2 = { "salesCancel", "sales2" }; for (int i = 0; i < listener.size(); i++) { Assertions.assertThat(listener.get(i)).isEqualTo(expected2[i]); } ksession.dispose(); } private KieBase buildKieBase(final String drlFile) { final KieServices kieServices = KieServices.Factory.get(); final Resource resource = kieServices.getResources().newClassPathResource(drlFile, getClass()); final KieModule kieModule = KieBaseUtil.getKieModuleAndBuildInstallModule(TestConstants.PACKAGE_FUNCTIONAL, KieBaseTestConfiguration.CLOUD_IDENTITY, resource); final KieBaseConfiguration kbconf = kieServices.newKieBaseConfiguration(); kbconf.setOption(DeclarativeAgendaOption.ENABLED); return kieServices.newKieContainer(kieModule.getReleaseId()).newKieBase(kbconf); } }