[jboss-jira] [JBoss JIRA] Created: (JBRULES-2457) Wrong evaluation of rules and PseudoClock NPE

Ví­tor Moreira (JIRA) jira-events at lists.jboss.org
Tue Mar 23 10:38:37 EDT 2010


Wrong evaluation of rules and PseudoClock NPE
---------------------------------------------

                 Key: JBRULES-2457
                 URL: https://jira.jboss.org/jira/browse/JBRULES-2457
             Project: Drools
          Issue Type: Bug
      Security Level: Public (Everyone can see)
    Affects Versions: 5.1.0.M1, 5.0.1.FINAL
         Environment: Windows 7, Eclipse 3.4, Java 1.6.0_u18, JUnit 4
            Reporter: Ví­tor Moreira
            Assignee: Mark Proctor


I've got a DRL file, having the following rules:
- offline event for 3 minutes withou any online event meanwhile => send an offline notification
- online event after offline event (within 3 minute range) => send an online notification

I've also got an junit test:
- insert offline event
- pseudoclock advances 2m50s
- insert online event
- pseudoclock advances 15s
- check if there's any notification

And the result of the junit is:
1) NPE when clock advances 15s
java.lang.NullPointerException
       at org.drools.util.LinkedList.remove(LinkedList.java:113)
       at org.drools.common.Scheduler$DuractionJob.execute(Scheduler.java:71)
       at org.drools.time.impl.PseudoClockScheduler$ScheduledJob.call(PseudoClockScheduler.java:219)
       at org.drools.time.impl.PseudoClockScheduler.runCallBacks(PseudoClockScheduler.java:168)
   at org.drools.time.impl.PseudoClockScheduler.advanceTime(PseudoClockScheduler.java:130)

2) When checking for a notification, it should have one online notification but has on offline notification

At the bottom of this issue, there are snippets of junit code and drools rule file.
Probably, the problem relies on Junit initialization code.

T.I.A.


-- DRL file (snippet) --
dialect "java"

declare Event
    @role( event )
    @expires ( 7d )
end

global ISnmpNotifier snmpNotifier;

/*************************/
/* OFFLINE FOR 3 MINUTES */
/*************************/
rule "bit\dom - events offline (device offline for 3 minutes)"
	when
		$offline : Event( freeField == "101", $offlineLane : lane ) from entry-point "incoming"
		not ( $online : Event (freeField == "102", lane == $offlineLane, this after [0s,3m] $offline ) from entry-point "incoming" )
	then
		snmpNotifier.send( new Notification("101", "offline") );
end
rule "bit\dom - events online (device offline for 3 minutes)"
	when
		$offline: Event( freeField == "101", $lane : lane ) from entry-point "incoming"
		$online : Event( freeField == "102", lane == $lane, this after [3m] $offline ) from entry-point "incoming"
	then
		snmpNotifier.send( new Notification("102", "online") );
end 
-- DRL file (snippet) --

-- JUnit code (snippet) --
package pt.brisa.sam.agent.rules.bit_dom;

import java.util.concurrent.TimeUnit;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.conf.EventProcessingOption;
import org.drools.io.ResourceFactory;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.drools.time.impl.PseudoClockScheduler;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;


public class Jira_Drools {
	
	// values used to create test
	private String offlineEventCode = "101";
	private String onlineEventCode  = "102";
	private String device           = "device";
	
	// drools specific vars
	private WorkingMemoryEntryPoint		workingMemoryEntryPoint;
	private PseudoClockScheduler			clock = null;
	
	private StatefulKnowledgeSession		kSession;
	
	/**
	 * SnmpNotificationEventCase.getNumberOfNotificationsByExample(example)
	 * 	.getNumberOfNotificationsByExample => from the notification queue, returns the number of notifications matching the given example
	 */
	private SnmpNotificationEventCase		snmpNotificationEventCase;
	
	@Before
	public void droolsSetup() {
    	KnowledgeBaseConfiguration baseConfig;
		KnowledgeSessionConfiguration sessionConfig;
		KnowledgeBase kBase;
		KnowledgeBuilder kBuilder;
		
		
		baseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
		baseConfig.setOption( EventProcessingOption.STREAM );		// Use stream mode

		kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kBuilder.add(ResourceFactory.newFileResource( "test.drl"), ResourceType.DRL);

		kBase = KnowledgeBaseFactory.newKnowledgeBase(baseConfig);
		kBase.addKnowledgePackages(kBuilder.getKnowledgePackages());			

		sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
		sessionConfig.setOption( ClockTypeOption.get( "pseudo" ) );
		
		kSession = kBase.newStatefulKnowledgeSession( sessionConfig, null );
        kSession.setGlobal( "snmpNotifier", snmpNotificationEventCase );
        workingMemoryEntryPoint = kSession.getWorkingMemoryEntryPoint("incoming");
		
		clock = (PseudoClockScheduler) kSession.getSessionClock();	
		snmpNotificationEventCase = new SnmpNotificationEventCase();
	}
	
	
    /*    offline            online  3min          */
    /* -----|-------------------|------/----^----- */
    /*                                    check    */
    @Test
    public void deviceOffline_onlineBefore3minutes_checkAfter3minutes() {
    	/* alocates OFFLINE and ONLINE events, EXAMPLE */
    	Event offlineEvent = new Event();
    	Event onlineEvent = new Event();
    	Notification example = new Notification();
    	
		/* configures the events */
		offlineEvent.setFreeField( offlineEventCode );
		offlineEvent.setEventType( (byte)5 );
		offlineEvent.setEventCode( "0001000" + offlineEventCode );
		offlineEvent.setFormattedMessage( "JUnit string test" );
		offlineEvent.setLane( "102" );
		
		onlineEvent.setFreeField( onlineEventCode );
		onlineEvent.setEventType( (byte)3 );
		onlineEvent.setEventCode( "0001000" + onlineEventCode );
		onlineEvent.setFormattedMessage( "JUnit string test" );
		onlineEvent.setLane( "102" );
		
		/* insert offline event */
		workingMemoryEntryPoint.insert( offlineEvent );
		kSession.fireAllRules();
		
		/* intermediary check - offline notification */
		example.setRuleCode( "31" );
		example.setEventCode( offlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 );
		
		/* advances the clock */
		clock.advanceTime(  2, TimeUnit.MINUTES );
		clock.advanceTime( 50, TimeUnit.SECONDS );
				
		/* intermediary check - offline notification */
		example.setRuleCode( "31" );
		example.setEventCode( offlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 );
		
		/* insert online event */
		workingMemoryEntryPoint.insert( onlineEvent );
		kSession.fireAllRules();
		
		/* intermediary check - offline notification */
		example.setRuleCode( "31" );
		example.setEventCode( offlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 );
		/* intermediary check - online notification */
		example.setRuleCode( "31" );
		example.setEventCode( onlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are ONLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 );
		
		/* advances the clock */
		clock.advanceTime( 15, TimeUnit.SECONDS );
			
		/* since there's an ONLINE before the 3 minute's limit, there shouldn't be any trap regarding "last offline 3 minutes ago" */
		example.setRuleCode( "31" );
		example.setEventCode( offlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 );
		example.setRuleCode( "31" );
		example.setEventCode( onlineEventCode );
		Assert.assertTrue(
				"(device "+device+")(ruleCode 31): There are ONLINE notifications, when it shouldn't have",
				snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 1 );
    }

}

-- JUnit code (snippet) --

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       




More information about the jboss-jira mailing list