Merged HEAD-BUG-FIX (5.1/Cloud) to HEAD (5.0/Cloud)

88886: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud)
      88846: MNT-12473: Merged V4.2.2 (4.2.2.16) to V4.2-BUG-FIX (4.2.4)
         88606: MNT-12574: CLONE - cyclic groups can be created bringing the server down
         During build of the AuthorityBridgeTableAsynchronouslyRefreshedCache check and fix all cyclic groups. Add unit test.
      88847: MNT-12473: Merged V4.2.2 (4.2.2.16) to V4.2-BUG-FIX (4.2.4)
         88650: MNT-12574: CLONE - cyclic groups can be created bringing the server down
         Do the cyclic check only in case of ConcurrentModificationException.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@94588 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2015-01-31 10:09:03 +00:00
parent 624e6e63f3
commit e1e306d219
5 changed files with 257 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2013 Alfresco Software Limited.
* Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,15 @@
*/
package org.alfresco.repo.security.authority;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ConcurrentModificationException;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
@@ -37,7 +46,10 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.test_category.OwnJVMTestsCategory;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.junit.experimental.categories.Category;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.context.ApplicationContext;
@Category(OwnJVMTestsCategory.class)
@@ -154,4 +166,94 @@ public class AuthorityBridgeTableAsynchronouslyRefreshedCacheTest extends TestCa
}
}, false, true);
}
/**
* See MNT-12473
*/
public void testCyclicGroups()
{
List<AuthorityBridgeLink> cyclicLinks = new LinkedList<AuthorityBridgeLink>();
// no cycle
cyclicLinks.add(createAuthorityBridgeLink("a1", "a2"));
cyclicLinks.add(createAuthorityBridgeLink("g1", "g2"));
cyclicLinks.add(createAuthorityBridgeLink("g2", "g3"));
cyclicLinks.add(createAuthorityBridgeLink("g3", "g4"));
// 1st cycle
cyclicLinks.add(createAuthorityBridgeLink("g4", "g1"));
cyclicLinks.add(createAuthorityBridgeLink("b1", "b2"));
// child with no cycle
cyclicLinks.add(createAuthorityBridgeLink("b2", "a1"));
cyclicLinks.add(createAuthorityBridgeLink("b2", "b3"));
// 2nd cycle
cyclicLinks.add(createAuthorityBridgeLink("b3", "b1"));
cyclicLinks.add(createAuthorityBridgeLink("d1", "d2"));
cyclicLinks.add(createAuthorityBridgeLink("d2", "d3"));
// 3rd cycle
cyclicLinks.add(createAuthorityBridgeLink("d3", "d1"));
cyclicLinks.add(createAuthorityBridgeLink("d2", "d4"));
// 4th cycle
cyclicLinks.add(createAuthorityBridgeLink("d4", "d1"));
cyclicLinks.add(createAuthorityBridgeLink("d3", "d5"));
// 5th cycle
cyclicLinks.add(createAuthorityBridgeLink("d5", "d1"));
AuthorityBridgeDAO authorityBridgeDAOMock = mock(AuthorityBridgeDAO.class);
when(authorityBridgeDAOMock.getAuthorityBridgeLinks()).thenReturn(cyclicLinks);
AuthorityDAO authorityDAOMock = mock(AuthorityDAO.class);
class Counter
{
private int removed = 0;
public int getRemoved()
{
return removed;
}
public void increase()
{
this.removed++;
}
}
;
final Counter cycles = new Counter();
doAnswer(new Answer<Object>()
{
public Object answer(InvocationOnMock invocation)
{
cycles.increase();
return null;
}
}).when(authorityDAOMock).removeAuthority(anyString(), anyString(), anyBoolean());
AuthorityBridgeTableAsynchronouslyRefreshedCache cache = new AuthorityBridgeTableAsynchronouslyRefreshedCache();
cache.setAuthorityBridgeDAO(authorityBridgeDAOMock);
cache.setAuthorityDAO(authorityDAOMock);
cache.setTenantAdminService(tenantAdminService);
cache.setRetryingTransactionHelper(transactionService.getRetryingTransactionHelper());
try
{
cache.buildCache(tenantAdminService.getCurrentUserDomain());
}
catch (AlfrescoRuntimeException e1)
{
assertTrue(e1.getMessage().contains("Cyclic links were detected"));
assertEquals(5, cycles.getRemoved());
}
catch (ConcurrentModificationException e2)
{
fail("Cyclic links were NOT detected and processed");
}
}
private AuthorityBridgeLink createAuthorityBridgeLink(String parentName, String childName)
{
AuthorityBridgeLink link = new AuthorityBridgeLink();
link.setParentName(parentName);
link.setChildName(childName);
return link;
}
}