[jbpm-commits] JBoss JBPM SVN: r1676 - in jbpm4/pvm/trunk/modules/core/src: test/java/org/jbpm/pvm/timer and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Jul 18 11:41:20 EDT 2008


Author: pascal.verdage
Date: 2008-07-18 11:41:20 -0400 (Fri, 18 Jul 2008)
New Revision: 1676

Modified:
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java
Log:
update some timer tests
+ use setters in ExecutionImpl instead of direct field access (problems with hibernate proxies)
+ destroyTimers implementation

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2008-07-18 14:11:32 UTC (rev 1675)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2008-07-18 15:41:20 UTC (rev 1676)
@@ -152,7 +152,7 @@
    * null and is only created from the executions in case its needed.  Note
    * that not all executions are forced to have a name and duplicates are allowed.
    * In case the {@link #executions} change, the executionsMap can be nulled or
-   * also updated (but a check needs to be added wether it exists). */
+   * also updated (but a check needs to be added whether it exists). */
   protected transient Map<String, OpenExecution> executionsMap = null;
 
   // transient members
@@ -235,12 +235,12 @@
     ExecutionImpl child = createExecution(scope.getName());
     
     // copy the current state from the child execution to the parent execution
-    child.node = node;
-    child.transition = transition;
-    child.propagation = propagation;
-    child.transitionOrigin = transitionOrigin;
-    child.previousTransition = previousTransition;
-    child.previousNode = previousNode;
+    child.setNode(getNode());
+    child.setTransition(getTransition());
+    child.setPropagation(getPropagation());
+    child.setTransitionOrigin(getTransitionOrigin());
+    child.setPreviousTransition(getPreviousTransition());
+    child.setPreviousNode(getPreviousNode());
     
     child.initializeVariables(scope, this);
     child.initializeTimers(scope);
@@ -253,12 +253,12 @@
     destroyVariables(scope, parent);
     
     // copy the current state from the child execution to the parent execution
-    parent.node = node;
-    parent.transition = transition;
-    parent.propagation = propagation;
-    parent.transitionOrigin = transitionOrigin;
-    parent.previousTransition = previousTransition;
-    parent.previousNode = previousNode;
+    getParent().setNode(getNode());
+    getParent().setTransition(getTransition());
+    getParent().setPropagation(getPropagation());
+    getParent().setTransitionOrigin(getTransitionOrigin());
+    getParent().setPreviousTransition(getPreviousTransition());
+    getParent().setPreviousNode(getPreviousNode());
     
     end();
     parent.removeExecution(this);
@@ -413,12 +413,12 @@
   public void take(Transition transition) {
     checkLock();
 
-    this.propagation = Propagation.EXPLICIT;
-    this.transition = (TransitionImpl) transition;
+    setPropagation(Propagation.EXPLICIT);
+    setTransition((TransitionImpl) transition);
     // copy the current node as the transition origin.  the origin can be different from 
     // the transition source in case a transition is taken from an enclosing node
-    this.transitionOrigin = node;
-    this.previousTransition = null;
+    setTransitionOrigin(getNode());
+    setPreviousTransition(null);
 
     performAtomicOperation(TAKE_TRANSITION);
   }
@@ -463,7 +463,7 @@
   public void proceed() {
     checkLock();
 
-    // in graph based processDefinition langauges we assume that a
+    // in graph based processDefinition languages we assume that a
     // default transition is available
     TransitionImpl defaultTransition = findDefaultTransition();
     if (defaultTransition!=null) {
@@ -504,8 +504,8 @@
   public void moveTo(NodeImpl destination) {
     // if the parent node needs to know the previous node
     if (destination.isPreviousNeeded()) {
-      this.previousNode = node;
-      this.previousTransition = transition;
+      setPreviousNode(getNode());
+      setPreviousTransition(getTransition());
     } else {
       this.previousNode = null;
       this.previousTransition = null;
@@ -802,7 +802,13 @@
   }
 
   protected void destroyTimers(CompositeElementImpl scope) {
-    // TODO
+    // TODO: is it correct?
+    TimerSession timerSession = Environment.getCurrent().get(TimerSession.class);
+    if (hasTimers && timers!=null && !timers.isEmpty()) {
+      for (Timer timer : timers) {
+        timerSession.cancel(timer);
+      }
+    }
   }
 
   public void createTimer(String eventName, String signalName, String dueDateDescription) {
@@ -814,15 +820,13 @@
   }
 
   public void createTimer(String eventName, String signalName, String dueDateDescription, Date dueDate, String repeat, Boolean isExclusive, Integer retries) {
-    CompositeElementImpl compositeElement = null;
-
     if ( (eventName==null)
          && (signalName==null)
        ) {
       throw new PvmException("no event or signal specified");
     }
     if (log.isDebugEnabled()) {
-      log.debug("creating timer on "+compositeElement);
+      log.debug("creating timer on "+this.toString());
     }
     
     // instantiate the timer

Modified: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java	2008-07-18 14:11:32 UTC (rev 1675)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java	2008-07-18 15:41:20 UTC (rev 1676)
@@ -21,32 +21,27 @@
 
 /**
  * @author Pascal Verdage
+ * 
+ * static variables allows not to create the hibernate mapping
  */
 public class IncrementCounterWaitState implements ExternalActivity {
   private static final long serialVersionUID = 1L;
   private static final Log log = Log.getLog(IncrementCounterWaitState.class.getName());
   
-  public static final String COUNTER = "counter";
-  public static final int MAX_COUNTER_VALUE = 5;
+  static final String COUNTER = "counter";
+  static final int MAX_COUNTER_VALUE = 5;
 
   public void signal(ActivityExecution execution, String signalName, Map<String, Object> parameters) throws Exception {
     boolean continueToWait = true;
     if ("increment".equals(signalName)) {
       Object variable = execution.getVariable(COUNTER);
-      if (variable instanceof Integer) {
-        log.debug("incrementing integer counter");
-        int counter = ((Integer) variable) + 1;
-        execution.setVariable(COUNTER, counter);
-        if (counter >= MAX_COUNTER_VALUE) {
-          continueToWait = false;
-        }
-      } else if (variable instanceof String) {
+      if (variable instanceof String) {
         log.debug("incrementing string counter");
         String tmp = ((String) variable);
         try {
           int counter = Integer.valueOf(tmp);
           counter += 1;
-          execution.setVariable(COUNTER, counter);
+          execution.setVariable(COUNTER, Integer.toString(counter));
           if (counter >= MAX_COUNTER_VALUE) {
             continueToWait = false;
           }
@@ -54,11 +49,13 @@
           log.debug("string variable is not an integer");
         }
       } else {
-        log.debug("variable is neither an integer nor a string");
+        log.debug("variable is not a string");
       }
     }
     if (continueToWait) {
       execution.waitForSignal();
+    } else {
+      execution.take("timeout");
     }
   }
 

Modified: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java	2008-07-18 14:11:32 UTC (rev 1675)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java	2008-07-18 15:41:20 UTC (rev 1676)
@@ -14,123 +14,302 @@
 package org.jbpm.pvm.timer;
 
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-import org.jbpm.pvm.test.base.JbpmTestCase;
+import org.jbpm.pvm.Execution;
+import org.jbpm.pvm.ExecutionService;
+import org.jbpm.pvm.ProcessService;
+import org.jbpm.pvm.activity.ActivityExecution;
+import org.jbpm.pvm.activity.ExternalActivity;
+import org.jbpm.pvm.env.Environment;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.NodeImpl;
+import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.pvm.job.Job;
+import org.jbpm.pvm.job.JobTestHelper;
+import org.jbpm.pvm.job.Timer;
+import org.jbpm.pvm.model.OpenExecution;
+import org.jbpm.pvm.model.ProcessDefinition;
+import org.jbpm.pvm.model.ProcessFactory;
+import org.jbpm.pvm.session.DbSession;
+import org.jbpm.pvm.session.PvmDbSession;
+import org.jbpm.pvm.test.base.DbTestCase;
 
 /**
  * @author Pascal Verdage
  */
-public class TimerIntegrationTest extends JbpmTestCase {
+public class TimerIntegrationTest extends DbTestCase {
+  public static class WaitState implements ExternalActivity {
 
-  protected Date getDueDate(long duration) {
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ActivityExecution execution) {
+      execution.waitForSignal();
+    }
+
+    public void signal(ActivityExecution execution, 
+                       String signalName, 
+                       Map<String, Object> parameters) {
+      if (signalName!=null) {
+        execution.take(signalName);
+      }
+    }
+  }
+
+  private static Date getDueDate(long duration) {
     return new Date(System.currentTimeMillis() + duration);
   }
+  
+  private static long twoDaysDuration = 2*24*60*60*1000;
 
-  /*
-  TODO finish after refactoring
+  private static ExecutionService getExecutionService() {
+    return Environment.getCurrent().get(ExecutionService.class);
+  }
 
+  private static ExecutionImpl deployAndInstanciateProcess(ProcessDefinition definition) {
+    ProcessService processService = Environment.getCurrent().get(ProcessService.class);
+    processService.deploy(definition);
 
-  public void testFixedDateTimer() {
-    Date now = new Date();
-    long twoDaysDuration = 2*24*60*60*1000;
-    String processName = "fixedDateTimer";
+    Execution processInstance = getExecutionService().startExecution(definition.getName());   
 
-    ProcessDefinition processDefinition = ProcessFactory.build(processName)
-      .node("get input").initial().behaviour(WaitState.class)
-        .timer(getDueDate(twoDaysDuration), "escalate")
-        .transition("escalate").to("manager decision")
-        .transition("submit").to("process input")
-      .node("process input").behaviour(WaitState.class)
-      .node("manager decision").behaviour(WaitState.class)
+    return (ExecutionImpl) processInstance;
+  }
+
+  public void testTimerDefinition() {
+    ProcessDefinition processDefinition = ProcessFactory.build("timerDefinition")
+      .node("request").initial().behaviour(WaitState.class)
+        .transition().to("decide")
+      .node("decide").behaviour(WaitState.class)
+        .timer(getDueDate(twoDaysDuration), "timeout")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
     .done();
+    
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
 
+    Execution execution = processInstance;
+    assertEquals("request", execution.getNodeName());
+    // first node is a wait state with no timer
+    execution = getExecutionService().signalExecution(execution.getDbid());
+    assertEquals("decide", execution.getNodeName());
+
+    assertTrue(execution instanceof OpenExecution);
+    OpenExecution openExecution = (OpenExecution) execution;
+
+    // timer are created in a child execution
+    assertFalse(openExecution.hasTimers());
+
+    assertEquals(1, openExecution.getExecutions().size());
+    OpenExecution child = openExecution.getExecutions().iterator().next();
+
+    NodeImpl node1 = (NodeImpl) openExecution.getNode();
+    NodeImpl node2 = (NodeImpl) child.getNode();
+    assertEquals(node1, node2);
+    assertEquals("decide", node1.getName());
+    assertNotNull(node1.getTimerDefinitions());
+
+    assertTrue(child.hasTimers());
+    Set<Timer> timers = child.getTimers();
+    assertEquals(1, timers.size());
+  }
+
+  private static ExecutionImpl loadExecutionFromDb(long id) {
+    return Environment.getCurrent().get(DbSession.class).get(ExecutionImpl.class, id);
+  }
+
+  public void testTimerExecution() {
+    ProcessDefinition processDefinition = ProcessFactory.build("timerExecution")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer(getDueDate(twoDaysDuration), "timeout")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
     
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
     
-    ProcessService processService = TimerConfiguration.getProcessService();
-    processService.deploy(processDefinition);
+    Execution execution = processInstance;
+    assertEquals("decide", execution.getNodeName());
 
-    long twoDaysFromNow = now.getTime() + twoDaysDuration;
+    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
+    assertEquals("decide", child.getNodeName());
+    Timer timer = child.getTimers().iterator().next();
 
-    ExecutionService executionService = TimerConfiguration.getExecutionService();
-    System.out.println("execution service: '"+executionService+"' ");
-    Execution execution = executionService.startExecution(processDefinition.getName());
+    JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
+    child = (OpenExecution) jobTestHelper.executeTimer(timer.getDbid());
+    assertEquals(Execution.STATE_ENDED, child.getState());
 
-    assertEquals("get input", execution.getNodeName());
+    // check that the subExecution was deleted
+    child = loadExecutionFromDb(child.getDbid());
+    assertNull(child);
+
+    // check that timers have been deleted
+    List<Job> jobs = Environment.getCurrent().get(PvmDbSession.class).findAllJobs();
+    assertNotNull(jobs);
+    assertTrue(jobs.isEmpty());
+
+    // check that process is in the right state
+    execution = loadExecutionFromDb(processInstance.getDbid());
+    assertEquals("reassign", execution.getNodeName());
+  }
+
+  public void testCanceledTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("timerCanceled")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer(getDueDate(twoDaysDuration), "timeout")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
+
+    Execution execution = processInstance;
+    assertEquals("decide", execution.getNodeName());
+
+    // signal child execution
+    Execution child = ((OpenExecution)execution).getExecutions().iterator().next();
+    execution = getExecutionService().signalExecution(child.getDbid());
+    assertEquals(Execution.STATE_ENDED, execution.getState());
+
+    // check that the subExecution was deleted
+    child = loadExecutionFromDb(child.getDbid());
+    assertNull(child);
     
-    org.jbpm.pvm.job.Timer timer = activityInstance
-    .getTimers()
-    .iterator()
-    .next();
+    // check that timers have been deleted
+    List<Job> jobs = Environment.getCurrent().get(PvmDbSession.class).findAllJobs();
+    assertNotNull(jobs);
+    assertTrue(jobs.isEmpty());
 
-    assertTrue(twoDaysFromNow <= timer.getDueDate().getTime());
+    // check that process is in the right state
+    execution = loadExecutionFromDb(processInstance.getDbid());
+    assertEquals("response", execution.getNodeName());
+  }
 
-    EnvironmentFactory environmentFactory = TimerConfiguration.getEnvironmentFactory();
-    JobTestHelper jobTestHelper = environmentFactory.get(JobTestHelper.class);
-    execution = jobTestHelper.executeTimer(timer.getDbid());
+  public void testFixedDateTimer() {
+    Date now = new Date();
+    long twoDaysFromNow = now.getTime() + twoDaysDuration;
 
-    assertEquals("manager decision", execution.getNode().getName());
+    ProcessDefinition processDefinition = ProcessFactory.build("fixedDateTimer")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer(getDueDate(twoDaysDuration), "timeout")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
+
+    Execution execution = processInstance;
+    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
+    assertEquals("decide", child.getNodeName());
+
+    // check that timer's dueDate is good
+    Timer timer = child.getTimers().iterator().next();
+    assertTrue(twoDaysFromNow <= timer.getDueDate().getTime());
+    
+    // timer execution is tested in testTimerExecution
   }
-  
-  public void testRepeatedTimer() {
-    long dayDuration = 24*60*60*1000;
-    String processName = "repeatedTimer";
 
-    ProcessDefinition processDefinition = ProcessFactory.build(processName)
-    .node("get input").initial().behaviour(IncrementCounterWaitState.class)
-      .variable(IncrementCounterWaitState.COUNTER, "0")
-      .timer("1 day", "increment", "1 day")
-      .transition("submit").to("process input")
-    .node("process input").behaviour(WaitState.class)
+  public void testDueDateDescriptionTimer() {
+    Date now = new Date();
+    long twoDaysFromNow = now.getTime() + twoDaysDuration;
+
+    ProcessDefinition processDefinition = ProcessFactory.build("dueDateDescriptionTimer")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("2 days", "timeout")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
     .done();
 
-    ProcessService processService = TimerConfiguration.getProcessService();
-    processService.deploy(processDefinition);
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
 
-    long minimumDueDate = Clock.getCurrentTime().getTime() + dayDuration;
+    Execution execution = processInstance;
+    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
+    assertEquals("decide", child.getNodeName());
+
+    // check that timer's dueDate is good
+    Timer timer = child.getTimers().iterator().next();
+    assertTrue(twoDaysFromNow <= timer.getDueDate().getTime());
     
-    ExecutionService executionService = TimerConfiguration.getExecutionService();
-    Execution execution = executionService.startExecution(processName);
-    long executionId = execution.getDbid();
+    // timer execution is tested in testTimerExecution
+  }
 
-    EnvironmentFactory environmentFactory = TimerConfiguration.getEnvironmentFactory();
-    JobTestHelper jobTestHelper = environmentFactory.get(JobTestHelper.class);
-    
-    for (int i=0;i<IncrementCounterWaitState.MAX_COUNTER_VALUE;i++) {
-      long timerId;
-      environmentFactory.openEnvironment();
-      try {
-        execution = Environment.getCurrent().get(PvmDbSession.class).get(ExecutionImpl.class, executionId);
-        ActivityInstance activityInstance = execution.getActivityInstance();
-        Node node = activityInstance.getNode();
-        assertEquals("get input", node.getName());
-        Set<Timer> timers = activityInstance.getTimers();
-        assertNotNull(timers);
-        assertEquals(1, timers.size());
-        Timer timer = timers.iterator().next();
-        
-        long difference = timer.getDueDate().getTime() - minimumDueDate;
-        assertTrue(difference+" should be positive (iteration "+i+")", difference >= -200);
-        minimumDueDate = Clock.getCurrentTime().getTime() + dayDuration;
-        timerId = timer.getDbid();
-      } finally {
-        Environment.getCurrent().close();
-      }
-      execution = jobTestHelper.executeTimer(timerId);
+  //TODO: the test fails because the child execution is not deleted and the timer
+  // still exist.
+  //Still, main execution is in the the good state
+  public void testReschedulingTimer() {
+    Date now = Clock.getCurrentTime();
+    long twoDaysFromNow = now.getTime() + twoDaysDuration;
+
+    ProcessDefinition processDefinition = ProcessFactory.build("reschedulingTimer")
+      .node("decide").initial().behaviour(IncrementCounterWaitState.class)
+        .variable(IncrementCounterWaitState.COUNTER, "0")
+        .timer("2 days", "increment", "2 days")
+        .transition("decision made").to("response") // first defined transition is the default one
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
+
+    Execution execution = processInstance;
+    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
+
+    for (int i=0; i<IncrementCounterWaitState.MAX_COUNTER_VALUE; i++) {
+      // check that the execution is in the right node
+      assertNotNull(child);
+      assertEquals("decide", child.getNodeName());
+      assertEquals(Execution.STATE_ACTIVE, child.getState());
+
+      // check there is one timer
+      assertTrue(child.hasTimers());
+      assertEquals(1, child.getTimers().size());
+
+      // check that timer's dueDate is good
+      Timer timer = child.getTimers().iterator().next();
+      assertTrue("error is "+(timer.getDueDate().getTime()-twoDaysFromNow)+" millis",
+          twoDaysFromNow <= timer.getDueDate().getTime());
+
+      // execute timer
+      twoDaysFromNow = Clock.getCurrentTime().getTime() + twoDaysDuration - 100;
+      JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
+      jobTestHelper.executeTimer(timer.getDbid());
+      child = loadExecutionFromDb(child.getDbid());
     }
-    
-    environmentFactory.openEnvironment();
-    try {
-      execution = Environment.getCurrent().get(PvmDbSession.class).get(ExecutionImpl.class, executionId);
-      Node node = execution.getNode();
-      assertEquals("process input", node.getName());
-      
-      assertTrue(execution.getTimers().isEmpty());
-    } finally {
-      Environment.getCurrent().close();
+
+    // check that the subExecution was deleted
+    if (child!=null) {
+      System.out.println(child.getNodeName());
+      System.out.println(child.getVariable("counter"));
+      execution = loadExecutionFromDb(processInstance.getDbid());
+      System.out.println(execution.getNodeName());
     }
-    
+    assertNull(child);
+
+    // check that timers have been deleted
+    List<Job> jobs = Environment.getCurrent().get(PvmDbSession.class).findAllJobs();
+    assertNotNull(jobs);
+    assertTrue(jobs.isEmpty());
+
+    // check that process is in the right state
+    execution = loadExecutionFromDb(processInstance.getDbid());
+    assertEquals("reassign", execution.getNodeName());
   }
 
+  /*
+  TODO finish after refactoring
+
   public void testTimerEndingProcess() {
     ProcessDefinition processDefinition = ProcessFactory.build("timed2")
       .node("get input").initial().behaviour(WaitState.class)




More information about the jbpm-commits mailing list