use of org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter in project alfresco-repository by Alfresco.
the class ActionTrackingServiceImplTest method xtestExecutionTrackingOnExecution.
// =================================================================== //
/**
* Tests that when we run an action, either synchronously or asynchronously, with it working or failing, that the
* action execution service correctly sets the flags
*/
public void xtestExecutionTrackingOnExecution() throws Exception {
// FIXME: This test fails intermittently for no apparent reason.
// Removed until a reason/resolution can be found
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) ctx.getBean(SleepActionExecuter.NAME);
sleepActionExec.setSleepMs(10);
Action action;
NodeRef actionNode;
// We need real transactions
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
// ===========================================================
// Execute a transient Action that works, synchronously
// ===========================================================
action = createWorkingSleepAction(null);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef);
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// ===========================================================
// Execute a transient Action that fails, synchronously
// ===========================================================
action = createFailingMoveAction();
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
try {
this.actionService.executeAction(action, this.nodeRef);
fail("Action should have failed, and the error been thrown");
} catch (Exception e) {
}
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
// Tidy up from the action failure
txn.rollback();
txn = transactionService.getUserTransaction();
txn.begin();
// ===========================================================
// Execute a stored Action that works, synchronously
// ===========================================================
action = createWorkingSleepAction(null);
this.actionService.saveAction(this.nodeRef, action);
actionNode = action.getNodeRef();
assertNotNull(actionNode);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef);
// Check our copy
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// Let the update change the stored node
// (Can't use policy as the action has already finished!)
txn.commit();
Thread.sleep(150);
txn = transactionService.getUserTransaction();
txn.begin();
// Now re-load and check the stored one
action = runtimeActionService.createAction(actionNode);
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// ===========================================================
// Execute a stored Action that fails, synchronously
// ===========================================================
action = createFailingMoveAction();
this.actionService.saveAction(this.nodeRef, action);
actionNode = action.getNodeRef();
String actionId = action.getId();
assertNotNull(actionNode);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
// Save this
txn.commit();
txn = transactionService.getUserTransaction();
txn.begin();
// Run the action - will fail and trigger a rollback
try {
this.actionService.executeAction(action, this.nodeRef);
fail("Action should have failed, and the error been thrown");
} catch (Exception e) {
}
// Check our copy
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
// Wait for the post-rollback update to complete
// (The stored one gets updated asynchronously)
txn.rollback();
Thread.sleep(150);
txn = transactionService.getUserTransaction();
txn.begin();
// Now re-load and check the stored one
action = runtimeActionService.createAction(actionNode);
assertEquals(actionId, action.getId());
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
// Tidy up from the action failure
txn.commit();
txn = transactionService.getUserTransaction();
txn.begin();
// ===========================================================
// Execute a transient Action that works, asynchronously
// ===========================================================
action = createWorkingSleepAction(null);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef, false, true);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
// End the transaction. Should allow the async action
// to be executed
asyncOccurs.awaitExecution(txn, null, action.getActionDefinitionName());
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// Put things back ready for the next check
txn = transactionService.getUserTransaction();
txn.begin();
// ===========================================================
// Execute a transient Action that fails, asynchronously
// ===========================================================
action = createFailingMoveAction();
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef, false, true);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
// End the transaction, and await the failure
// (Can't use the policy as fails not suceeds)
txn.commit();
Thread.sleep(150);
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
// Put things back ready for the next check
txn = transactionService.getUserTransaction();
txn.begin();
// ===========================================================
// Execute a stored Action that works, asynchronously
// ===========================================================
action = createWorkingSleepAction(null);
this.actionService.saveAction(this.nodeRef, action);
actionNode = action.getNodeRef();
assertNotNull(actionNode);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef, false, true);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
// End the transaction. Should allow the async action
// to be executed
asyncOccurs.awaitExecution(txn, null, action.getActionDefinitionName());
// Need to allow the post-commit update to the stored node
Thread.sleep(250);
txn = transactionService.getUserTransaction();
txn.begin();
// Check our copy
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// Now re-load and check the stored one
action = runtimeActionService.createAction(actionNode);
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
// ===========================================================
// Execute a stored Action that fails, asynchronously
// ===========================================================
action = createFailingMoveAction();
this.actionService.saveAction(this.nodeRef, action);
actionNode = action.getNodeRef();
assertNotNull(actionNode);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
this.actionService.executeAction(action, this.nodeRef, false, true);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
// End the transaction, and await the failure
// (Can't use the policy as fails not suceeds)
txn.commit();
// Now also wait for the on-rollback to kick in and update
// the persisted copy of the action node too
Thread.sleep(400);
txn = transactionService.getUserTransaction();
txn.begin();
// Check our copy
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
// Now re-load and check the stored one
action = runtimeActionService.createAction(actionNode);
assertNotNull(action.getExecutionStartDate());
assertNotNull(action.getExecutionEndDate());
assertBefore(action.getExecutionStartDate(), action.getExecutionEndDate());
assertBefore(action.getExecutionEndDate(), new Date());
assertNotNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
txn.commit();
}
use of org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter in project alfresco-repository by Alfresco.
the class ActionTrackingServiceImplTest method testJavascriptAPI.
public void testJavascriptAPI() throws Exception {
// We need a background action to sleep for long enough for
// it still to be running when the JS fires off
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) ctx.getBean(SleepActionExecuter.NAME);
sleepActionExec.setSleepMs(2000);
ActionImpl sleepAction;
ActionImpl action;
// Create three test actions:
((ActionTrackingServiceImpl) actionTrackingService).resetNextExecutionId();
// Sleep one that will still be running
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
sleepAction = (ActionImpl) createWorkingSleepAction(null);
// This isn't true!
sleepAction.setNodeRef(nodeRef);
this.actionService.executeAction(sleepAction, null, false, true);
txn.commit();
// Move one that will appear to be "running"
action = (ActionImpl) createFailingMoveAction();
actionTrackingService.recordActionExecuting(action);
// Finally one that has "failed"
// (Shouldn't show up in any lists)
txn = transactionService.getUserTransaction();
txn.begin();
action = (ActionImpl) createWorkingSleepAction(null);
action.setExecutionStartDate(new Date(1234));
action.setExecutionEndDate(new Date(54321));
action.setExecutionStatus(ActionStatus.Failed);
this.actionService.saveAction(this.nodeRef, action);
txn.commit();
// Call the test
Map<String, Object> model = new HashMap<String, Object>();
model.put("NodeRef", nodeRef.toString());
model.put("SleepAction", sleepAction);
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/action/script/test_actionTrackingService.js");
this.scriptService.executeScript(location, model);
}
use of org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter in project alfresco-repository by Alfresco.
the class ScheduledPersistedActionServiceTest method testMultipleExecutions.
/**
* Tests that when we have more than one schedule defined and active, then the correct things run at the correct
* times, and we never get confused
*/
@Test
public void testMultipleExecutions() throws Exception {
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) applicationContext.getBean(SleepActionExecuter.NAME);
sleepActionExec.resetTimesExecuted();
sleepActionExec.setSleepMs(1);
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
// Create one that starts running in 2 seconds, runs every 2
// seconds
// until 9 seconds are up (will run 4 times)
ScheduledPersistedActionImpl scheduleA = (ScheduledPersistedActionImpl) service.createSchedule(testAction);
scheduleA.setScheduleStart(new Date(System.currentTimeMillis() + 2000));
scheduleA.setScheduleEnd(new Date(System.currentTimeMillis() + 9000));
scheduleA.setScheduleIntervalCount(2);
scheduleA.setScheduleIntervalPeriod(IntervalPeriod.Second);
service.saveSchedule(scheduleA);
// Create one that starts running now, every second until 9.5
// seconds
// are up (will run 9-10 times)
ScheduledPersistedActionImpl scheduleB = (ScheduledPersistedActionImpl) service.createSchedule(testAction2);
scheduleB.setScheduleStart(new Date(System.currentTimeMillis()));
scheduleB.setScheduleEnd(new Date(System.currentTimeMillis() + 9500));
scheduleB.setScheduleIntervalCount(1);
scheduleB.setScheduleIntervalPeriod(IntervalPeriod.Second);
service.saveSchedule(scheduleB);
return null;
}
}, false, true);
// Set them going
scheduler.start();
// Wait for 10 seconds for them to run and finish
Thread.sleep(10 * 1000);
// Check that they really did run properly
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
ScheduledPersistedAction scheduleA = service.getSchedule(testAction);
ScheduledPersistedAction scheduleB = service.getSchedule(testAction2);
// Both should have last run at some point in the last second
// or two
assertEquals((double) System.currentTimeMillis(), (double) scheduleA.getScheduleLastExecutedAt().getTime(), 2500);
assertEquals((double) System.currentTimeMillis(), (double) scheduleB.getScheduleLastExecutedAt().getTime(), 2500);
// A should have run ~4 times
// B should have run ~9 times
assertEquals("Didn't run enough - " + sleepActionExec.getTimesExecuted(), true, sleepActionExec.getTimesExecuted() >= 11);
assertEquals("Ran too much - " + sleepActionExec.getTimesExecuted(), true, sleepActionExec.getTimesExecuted() < 16);
return null;
}
}, false, true);
}
use of org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter in project alfresco-repository by Alfresco.
the class ActionTrackingServiceImplTest method performFailingActionImpl.
private Action performFailingActionImpl(boolean fatalFailure, String actionId) throws Exception {
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) ctx.getBean(SleepActionExecuter.NAME);
sleepActionExec.setSleepMs(10000);
// Have it run asynchronously
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
Action action = createFailingSleepAction(actionId, fatalFailure);
assertNull(action.getExecutionStartDate());
assertNull(action.getExecutionEndDate());
assertNull(action.getExecutionFailureMessage());
assertEquals(ActionStatus.New, action.getExecutionStatus());
String key = ActionTrackingServiceImpl.generateCacheKey(action);
assertEquals(null, executingActionsCache.get(key));
this.actionService.executeAction(action, this.nodeRef, false, true);
// End the transaction. Should allow the async action
// to be started, and move into its sleeping phase
txn.commit();
Thread.sleep(150);
// Will get an execution instance id, so a new key
key = ActionTrackingServiceImpl.generateCacheKey(action);
// Check it's in the cache
System.out.println("Checking the cache for " + key);
assertNotNull(executingActionsCache.get(key));
ExecutionSummary s = ActionTrackingServiceImpl.buildExecutionSummary(action);
ExecutionDetails d = actionTrackingService.getExecutionDetails(s);
assertNotNull(d.getExecutionSummary());
assertEquals("sleep-action", d.getActionType());
assertEquals(actionId, d.getActionId());
assertEquals(1, d.getExecutionInstance());
assertEquals(null, d.getPersistedActionRef());
// let's be more resilient and try a number of times with a delay
long start = System.currentTimeMillis();
// 1s
int sleepTime = 1000;
for (int i = 0; i < 10; i++) {
if (d.getStartedAt() == null) {
Thread.sleep(sleepTime);
// increase by 100ms
sleepTime += 100;
continue;
} else {
break;
}
}
long end = System.currentTimeMillis();
assertNotNull("Started at time is null, the action has not yet started after " + (end - start) + "ms", d.getStartedAt());
// Tell it to stop sleeping
// Then wait for it to finish and go bang
// (Need to do it by hand, as it won't fire the complete policy
// as the action has failed)
sleepActionExec.getExecutingThread().interrupt();
Thread.sleep(150);
// Ensure it went away again
assertEquals(null, executingActionsCache.get(key));
d = actionTrackingService.getExecutionDetails(s);
assertEquals(null, d);
return action;
}
use of org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter in project alfresco-repository by Alfresco.
the class ActionTrackingServiceImplTest method testCancellation.
/**
* Cancel related
*/
public void testCancellation() throws Exception {
// Ensure we get the right answers checking
CancellableSleepAction sleepAction1 = (CancellableSleepAction) createWorkingSleepAction(null);
CancellableSleepAction sleepAction2 = (CancellableSleepAction) createWorkingSleepAction(null);
actionTrackingService.recordActionExecuting(sleepAction1);
actionTrackingService.recordActionExecuting(sleepAction2);
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction1));
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction2));
// Cancel with the action
actionTrackingService.requestActionCancellation(sleepAction1);
assertEquals(true, actionTrackingService.isCancellationRequested(sleepAction1));
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction2));
// Cancel with the summary
ExecutionSummary s2 = ActionTrackingServiceImpl.buildExecutionSummary(sleepAction2);
actionTrackingService.requestActionCancellation(s2);
assertEquals(true, actionTrackingService.isCancellationRequested(sleepAction1));
assertEquals(true, actionTrackingService.isCancellationRequested(sleepAction2));
// If the action had gone missing from the cache,
// then a check will put it back
CancellableSleepAction sleepAction3 = (CancellableSleepAction) createWorkingSleepAction(null);
String key3 = ActionTrackingServiceImpl.generateCacheKey(sleepAction3);
assertNull(executingActionsCache.get(key3));
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction3));
assertNotNull(executingActionsCache.get(key3));
executingActionsCache.remove(key3);
assertNull(executingActionsCache.get(key3));
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction3));
assertNotNull(executingActionsCache.get(key3));
actionTrackingService.requestActionCancellation(sleepAction3);
assertEquals(true, actionTrackingService.isCancellationRequested(sleepAction3));
assertNotNull(executingActionsCache.get(key3));
// Now have one execute and cancel it, ensure it does
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) ctx.getBean(SleepActionExecuter.NAME);
sleepActionExec.setSleepMs(10000);
UserTransaction txn = transactionService.getUserTransaction();
txn.begin();
executingActionsCache.remove(key3);
this.actionService.executeAction(sleepAction3, this.nodeRef, false, true);
// End the transaction. Should allow the async action
// to be started
txn.commit();
Thread.sleep(150);
// Get the updated key, and check
key3 = ActionTrackingServiceImpl.generateCacheKey(sleepAction3);
ExecutionSummary s3 = ActionTrackingServiceImpl.buildExecutionSummary(key3);
assertEquals(false, actionTrackingService.isCancellationRequested(sleepAction3));
assertEquals(false, actionTrackingService.getExecutionDetails(s3).isCancelRequested());
assertNotNull(executingActionsCache.get(key3));
actionTrackingService.requestActionCancellation(sleepAction3);
assertEquals(true, actionTrackingService.isCancellationRequested(sleepAction3));
assertEquals(true, actionTrackingService.getExecutionDetails(s3).isCancelRequested());
assertNotNull(executingActionsCache.get(key3));
// Have it finish sleeping, will have been cancelled
// (Can't use the policy, as cancel is counted as a failure)
sleepActionExec.getExecutingThread().interrupt();
Thread.sleep(150);
// Ensure the proper cancelled tracking
assertEquals(ActionStatus.Cancelled, sleepAction3.getExecutionStatus());
assertEquals(null, sleepAction3.getExecutionFailureMessage());
}
Aggregations