/* * Copyright 2014 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.workbench.models.testscenarios.backend; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.drools.core.impl.StatefulKnowledgeSessionImpl; import org.drools.workbench.models.testscenarios.shared.Scenario; import org.junit.internal.AssumptionViolatedException; import org.junit.internal.runners.model.EachTestNotifier; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.InitializationError; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.FactHandle; public class ScenarioRunner4JUnit extends Runner { private final int maxRuleFirings; // The description of the test suite private Description descr; // the actual scenario test to be executed private List<Scenario> scenarios; private Map<String, KieSession> ksessions; public ScenarioRunner4JUnit( final Scenario scenario, final Map<String, KieSession> ksessions, final int maxRuleFirings ) throws InitializationError { this.scenarios = new ArrayList<Scenario>(); this.scenarios.add( scenario ); this.ksessions = ksessions; this.descr = Description.createSuiteDescription( "Scenario test cases" ); this.maxRuleFirings = maxRuleFirings; } public ScenarioRunner4JUnit( final Scenario scenario, final Map<String, KieSession> ksessions ) throws InitializationError { this( scenario, ksessions, 0 ); } public ScenarioRunner4JUnit( final List<Scenario> scenarios, final Map<String, KieSession> ksessions ) throws InitializationError { this( scenarios, ksessions, 0 ); } public ScenarioRunner4JUnit( final List<Scenario> scenarios, final Map<String, KieSession> ksessions, final int maxRuleFirings ) throws InitializationError { this.scenarios = scenarios; this.ksessions = ksessions; this.descr = Description.createSuiteDescription( "Scenario test cases" ); this.maxRuleFirings = maxRuleFirings; } @Override public Description getDescription() { return descr; } @Override public void run( RunNotifier notifier ) { for ( Scenario scenario : scenarios ) { runScenario( notifier, scenario ); } } private void runScenario( RunNotifier notifier, Scenario scenario ) { Description childDescription = Description.createTestDescription( getClass(), scenario.getName() ); descr.addChild( childDescription ); EachTestNotifier eachNotifier = new EachTestNotifier( notifier, childDescription ); try { eachNotifier.fireTestStarted(); //If a KieSession is not available, fail fast if ( ksessions == null || ksessions.values().isEmpty() ) { eachNotifier.addFailure( new NullKieSessionException( "Unable to get a Session to run tests. Check the project for build errors." ) ); } else { KieSession ksession = getKSession( scenario.getKSessions() ); if ( ksession == null ) { String ksessionName = getKSessionName( scenario.getKSessions() ); if ( ksessionName == null ) { eachNotifier.addFailure( new NullPointerException( "Test scenario runner could not find the default knowledge session." ) ); } else { eachNotifier.addFailure( new NullPointerException( "Test Scenarios require Stateful KieSession to run." ) ); } } else { final ScenarioRunner runner = new ScenarioRunner( ksession, maxRuleFirings ); runner.run( scenario ); if ( !scenario.wasSuccessful() ) { StringBuilder builder = new StringBuilder(); for ( String message : scenario.getFailureMessages() ) { builder.append( message ).append( "\n" ); } eachNotifier.addFailedAssumption( new AssumptionViolatedException( builder.toString() ) ); } // FLUSSSSSH! for ( FactHandle factHandle : ksession.getFactHandles() ) { ksession.delete( factHandle ); } resetKieSession( ksession ); } } } catch ( Throwable t ) { eachNotifier.addFailure( t ); } finally { // has to always be called as per junit docs eachNotifier.fireTestFinished(); } } private void resetKieSession( final KieSession kieSession ) { final StatefulKnowledgeSessionImpl statefulKnowledgeSession = (StatefulKnowledgeSessionImpl) kieSession; statefulKnowledgeSession.reset(); } private KieSession getKSession( List<String> ksessionNames ) { String ksessionName = getKSessionName( ksessionNames ); if ( ksessions.containsKey( ksessionName ) ) { return ksessions.get( ksessionName ); } else { return null; } } private String getKSessionName( List<String> ksessionNames ) { if ( ksessionNames != null && !ksessionNames.isEmpty() ) { return ksessionNames.iterator().next(); } else { return null; } } }