mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged BRANCHES/V4.1 to HEAD:
40010: Enhancement to TemporaryNodes JUnit @Rule so that it gracefully handles checked-out nodes during test code. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@40012 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -31,6 +31,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
@@ -41,12 +42,13 @@ import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* A JUnit rule designed to help with the automatic cleanup of temporary test nodes.
|
||||
*
|
||||
* @author Neil Mc Erlean
|
||||
* @since Odin
|
||||
* @since 4.1
|
||||
*/
|
||||
public class TemporaryNodes extends ExternalResource
|
||||
{
|
||||
@@ -73,8 +75,11 @@ public class TemporaryNodes extends ExternalResource
|
||||
|
||||
@Override protected void after()
|
||||
{
|
||||
final RetryingTransactionHelper transactionHelper = (RetryingTransactionHelper) appContextRule.getApplicationContext().getBean("retryingTransactionHelper");
|
||||
final NodeService nodeService = (NodeService) appContextRule.getApplicationContext().getBean("nodeService");
|
||||
final ApplicationContext springContext = appContextRule.getApplicationContext();
|
||||
|
||||
final RetryingTransactionHelper transactionHelper = springContext.getBean("retryingTransactionHelper", RetryingTransactionHelper.class);
|
||||
final CheckOutCheckInService cociService = springContext.getBean("CheckOutCheckInService", CheckOutCheckInService.class);
|
||||
final NodeService nodeService = springContext.getBean("NodeService", NodeService.class);
|
||||
|
||||
// Run as admin to ensure all non-system nodes can be deleted irrespecive of which user created them.
|
||||
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||
@@ -88,8 +93,16 @@ public class TemporaryNodes extends ExternalResource
|
||||
// Although we loop through all nodes, this is a cascade-delete and so we may only need to delete the first node.
|
||||
for (NodeRef node : temporaryNodeRefs)
|
||||
{
|
||||
// If it's already been deleted, don't worry about it.
|
||||
if (nodeService.exists(node))
|
||||
{
|
||||
// If it has been checked out, cancel the checkout before deletion.
|
||||
if (cociService.isCheckedOut(node))
|
||||
{
|
||||
log.debug("Cancelling checkout of temporary node " + nodeService.getProperty(node, ContentModel.PROP_NAME));
|
||||
NodeRef workingCopy = cociService.getWorkingCopy(node);
|
||||
cociService.cancelCheckout(workingCopy);
|
||||
}
|
||||
log.debug("Deleting temporary node " + nodeService.getProperty(node, ContentModel.PROP_NAME));
|
||||
nodeService.deleteNode(node);
|
||||
}
|
||||
@@ -100,7 +113,7 @@ public class TemporaryNodes extends ExternalResource
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getAdminUserName());
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -22,8 +22,11 @@ package org.alfresco.util.test.junitrules;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
@@ -31,6 +34,7 @@ import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -46,8 +50,8 @@ import org.junit.rules.RuleChain;
|
||||
/**
|
||||
* Test class for {@link TemporaryNodes}.
|
||||
*
|
||||
* @author Neil McErlean
|
||||
* @since Odin
|
||||
* @author Neil Mc Erlean
|
||||
* @since 4.1
|
||||
*/
|
||||
public class TemporaryNodesTest
|
||||
{
|
||||
@@ -74,6 +78,7 @@ public class TemporaryNodesTest
|
||||
@Rule public RunAsFullyAuthenticatedRule runAsRule = new RunAsFullyAuthenticatedRule(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
// Various services
|
||||
private static CheckOutCheckInService COCI_SERVICE;
|
||||
private static ContentService CONTENT_SERVICE;
|
||||
private static NodeService NODE_SERVICE;
|
||||
private static RetryingTransactionHelper TRANSACTION_HELPER;
|
||||
@@ -85,6 +90,7 @@ public class TemporaryNodesTest
|
||||
|
||||
@BeforeClass public static void initStaticData() throws Exception
|
||||
{
|
||||
COCI_SERVICE = APP_CONTEXT_INIT.getApplicationContext().getBean("checkOutCheckInService", CheckOutCheckInService.class);
|
||||
CONTENT_SERVICE = APP_CONTEXT_INIT.getApplicationContext().getBean("contentService", ContentService.class);
|
||||
NODE_SERVICE = APP_CONTEXT_INIT.getApplicationContext().getBean("nodeService", NodeService.class);
|
||||
TRANSACTION_HELPER = APP_CONTEXT_INIT.getApplicationContext().getBean("retryingTransactionHelper", RetryingTransactionHelper.class);
|
||||
@@ -131,4 +137,57 @@ public class TemporaryNodesTest
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test public void ensureCheckedOutNodesAreCleanedUp() throws Throwable
|
||||
{
|
||||
// Note that because we need to test that the Rule's 'after' behaviour has worked correctly, we cannot
|
||||
// use the Rule that has been declared in the normal way - otherwise nothing would be cleaned up until
|
||||
// after our test method.
|
||||
// Therefore we have to manually poke the Rule to get it to cleanup during test execution.
|
||||
// NOTE! This is *not* how a JUnit Rule would normally be used.
|
||||
TemporaryNodes myTemporaryNodes = new TemporaryNodes(APP_CONTEXT_INIT);
|
||||
|
||||
// Currently this is a no-op, but just in case that changes.
|
||||
myTemporaryNodes.before();
|
||||
|
||||
|
||||
// Create some test nodes.
|
||||
final List<NodeRef> nodesThatShouldBeDeletedByRule = new ArrayList<NodeRef>();
|
||||
|
||||
nodesThatShouldBeDeletedByRule.add(myTemporaryNodes.createNode(COMPANY_HOME, "normal node", ContentModel.TYPE_CONTENT, TEST_USER1.getUsername()));
|
||||
final NodeRef checkedoutNode = myTemporaryNodes.createNode(COMPANY_HOME, "checkedout node", ContentModel.TYPE_CONTENT, TEST_USER1.getUsername());
|
||||
nodesThatShouldBeDeletedByRule.add(checkedoutNode);
|
||||
|
||||
// and check one of them out.
|
||||
TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
NodeRef workingCopy = COCI_SERVICE.checkout(checkedoutNode);
|
||||
|
||||
// Ensure that the working copy is cleaned up too.
|
||||
nodesThatShouldBeDeletedByRule.add(workingCopy);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Now trigger the Rule's cleanup behaviour.
|
||||
myTemporaryNodes.after();
|
||||
|
||||
// and ensure that the nodes are all gone.
|
||||
TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
for (NodeRef node : nodesThatShouldBeDeletedByRule)
|
||||
{
|
||||
if (NODE_SERVICE.exists(node))
|
||||
{
|
||||
fail("Node '" + NODE_SERVICE.getProperty(node, ContentModel.PROP_NAME) + "' still exists.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user