mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-2245 Mitigate intermittent failure of FixedAclUpdaterTest (#916)
* ACS-2245 - Trigger CI build * ACS-2245 - Add RepeatAtMostRule for flaky tests * ACS-2245 - Add RepeatAtMostRuleTest to the AllUnitTestsSuite * ACS-2245 - Rename RepeatAtMostRule to RetryAtMostRule
This commit is contained in:
@@ -119,6 +119,7 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.util.schemacomp.validator.SchemaVersionValidatorTest.class,
|
org.alfresco.util.schemacomp.validator.SchemaVersionValidatorTest.class,
|
||||||
org.alfresco.util.schemacomp.validator.TypeNameOnlyValidatorTest.class,
|
org.alfresco.util.schemacomp.validator.TypeNameOnlyValidatorTest.class,
|
||||||
org.alfresco.util.test.OmittedTestClassFinderUnitTest.class,
|
org.alfresco.util.test.OmittedTestClassFinderUnitTest.class,
|
||||||
|
org.alfresco.util.test.junitrules.RetryAtMostRuleTest.class,
|
||||||
org.alfresco.util.test.junitrules.TemporaryMockOverrideTest.class,
|
org.alfresco.util.test.junitrules.TemporaryMockOverrideTest.class,
|
||||||
org.alfresco.repo.search.impl.solr.AbstractSolrQueryHTTPClientTest.class,
|
org.alfresco.repo.search.impl.solr.AbstractSolrQueryHTTPClientTest.class,
|
||||||
org.alfresco.repo.search.impl.solr.SpellCheckDecisionManagerTest.class,
|
org.alfresco.repo.search.impl.solr.SpellCheckDecisionManagerTest.class,
|
||||||
|
@@ -4,27 +4,32 @@
|
|||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
* provided under the following open source license terms:
|
* provided under the following open source license terms:
|
||||||
*
|
*
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.domain.permissions;
|
package org.alfresco.repo.domain.permissions;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -61,23 +66,26 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
|
import org.alfresco.util.test.junitrules.RetryAtMostRule;
|
||||||
|
import org.alfresco.util.test.junitrules.RetryAtMostRule.RetryAtMost;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for {@link FixedAclUpdater}
|
* Test class for {@link FixedAclUpdater}
|
||||||
*
|
*
|
||||||
* @author Andreea Dragoi
|
* @author Andreea Dragoi
|
||||||
* @author sglover
|
* @author sglover
|
||||||
* @since 4.2.7
|
* @since 4.2.7
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FixedAclUpdaterTest extends TestCase
|
public class FixedAclUpdaterTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FixedAclUpdaterTest.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FixedAclUpdaterTest.class);
|
||||||
|
|
||||||
@@ -103,7 +111,10 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
private static String TEST_GROUP_NAME_FULL = PermissionService.GROUP_PREFIX + TEST_GROUP_NAME;
|
private static String TEST_GROUP_NAME_FULL = PermissionService.GROUP_PREFIX + TEST_GROUP_NAME;
|
||||||
private static String DEFAULT_PERMISSION = PermissionService.CONTRIBUTOR;
|
private static String DEFAULT_PERMISSION = PermissionService.CONTRIBUTOR;
|
||||||
|
|
||||||
@Override
|
@Rule
|
||||||
|
public RetryAtMostRule retryAtMostRule = new RetryAtMostRule();
|
||||||
|
|
||||||
|
@Before
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
ctx = ApplicationContextHelper.getApplicationContext();
|
ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
@@ -126,7 +137,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
|
setFixedAclMaxTransactionTime(permissionsDaoComponent, homeFolderNodeRef, maxTransactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@After
|
||||||
public void tearDown() throws Exception
|
public void tearDown() throws Exception
|
||||||
{
|
{
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
@@ -202,6 +213,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Test setting permissions explicitly as async
|
* Test setting permissions explicitly as async
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsync()
|
public void testAsync()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncFolder");
|
||||||
@@ -248,6 +260,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* MNT-21847 - Create a new content in folder that has the aspect applied
|
* MNT-21847 - Create a new content in folder that has the aspect applied
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeCreation()
|
public void testAsyncWithNodeCreation()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCreationFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCreationFolder");
|
||||||
@@ -278,6 +291,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* MNT-22009 - Delete node that has the aspect applied before job runs
|
* MNT-22009 - Delete node that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeDeletion()
|
public void testAsyncWithNodeDeletion()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeDeletionFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeDeletionFolder");
|
||||||
@@ -368,6 +382,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* MNT-22040 - Copy node that has the aspect applied before job runs
|
* MNT-22040 - Copy node that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeCopy()
|
public void testAsyncWithNodeCopy()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
||||||
@@ -447,6 +462,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Copy node that has the aspect to another folder that also has the aspect applied before job runs
|
* Copy node that has the aspect to another folder that also has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeCopyToPendingFolder()
|
public void testAsyncWithNodeCopyToPendingFolder()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
||||||
@@ -538,6 +554,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* runs
|
* runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeCopyParentToChildPendingFolder()
|
public void testAsyncWithNodeCopyParentToChildPendingFolder()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeCopyOriginFolder");
|
||||||
@@ -649,6 +666,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* runs
|
* runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeMoveChildToChildPendingFolder()
|
public void testAsyncWithNodeMoveChildToChildPendingFolder()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveChildToChildPendingFolderOrigin");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveChildToChildPendingFolderOrigin");
|
||||||
@@ -734,6 +752,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* ACL
|
* ACL
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithErrorsForceSharedACL()
|
public void testAsyncWithErrorsForceSharedACL()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithErrorsForceSharedACL");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithErrorsForceSharedACL");
|
||||||
@@ -792,6 +811,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* MNT-22040 - Move node that has the aspect applied before job runs
|
* MNT-22040 - Move node that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeMove()
|
public void testAsyncWithNodeMove()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
|
||||||
@@ -868,6 +888,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Move node that has the aspect to another folder that also has the aspect applied before job runs
|
* Move node that has the aspect to another folder that also has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeMoveToPendingFolder()
|
public void testAsyncWithNodeMoveToPendingFolder()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeMoveOriginFolder");
|
||||||
@@ -956,6 +977,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Lock node that has the aspect applied before job runs
|
* Lock node that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeLock()
|
public void testAsyncWithNodeLock()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeLockFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeLockFolder");
|
||||||
@@ -985,6 +1007,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Checkout a node for editing that has the aspect applied before job runs
|
* Checkout a node for editing that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeCheckout()
|
public void testAsyncWithNodeCheckout()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeCheckoutFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeCheckoutFolder");
|
||||||
@@ -1015,6 +1038,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Update the permissions of a node that has the aspect applied (new permissions: fixed)
|
* Update the permissions of a node that has the aspect applied (new permissions: fixed)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeUpdatePermissionsFixed()
|
public void testAsyncWithNodeUpdatePermissionsFixed()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeUpdatePermissionsFixedFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeUpdatePermissionsFixedFolder");
|
||||||
@@ -1056,6 +1080,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Update the permissions of a node that has the aspect applied (new permissions: shared)
|
* Update the permissions of a node that has the aspect applied (new permissions: shared)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeUpdatePermissionsShared()
|
public void testAsyncWithNodeUpdatePermissionsShared()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeUpdatePermissionsSharedFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithNodeUpdatePermissionsSharedFolder");
|
||||||
@@ -1094,6 +1119,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Update the permissions of the parent of a node that has the aspect applied (new permissions: fixed)
|
* Update the permissions of the parent of a node that has the aspect applied (new permissions: fixed)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithParentUpdatePermissionsFixed()
|
public void testAsyncWithParentUpdatePermissionsFixed()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithParentUpdatePermissionsFixedFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithParentUpdatePermissionsFixedFolder");
|
||||||
@@ -1135,6 +1161,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Update the permissions of the parent of a node that has the aspect applied (new permissions: shared)
|
* Update the permissions of the parent of a node that has the aspect applied (new permissions: shared)
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithParentUpdatePermissionsShared()
|
public void testAsyncWithParentUpdatePermissionsShared()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithParentUpdatePermissionsSharedFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncWithParentUpdatePermissionsSharedFolder");
|
||||||
@@ -1173,6 +1200,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncCascadeUpdatePermissions()
|
public void testAsyncCascadeUpdatePermissions()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncCascadeUpdatePermissionsFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncCascadeUpdatePermissionsFolder");
|
||||||
@@ -1225,6 +1253,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Update the content of a node that has the aspect applied before job runs
|
* Update the content of a node that has the aspect applied before job runs
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncWithNodeContentUpdate()
|
public void testAsyncWithNodeContentUpdate()
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeContentUpdateFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFileTests("testAsyncWithNodeContentUpdateFolder");
|
||||||
@@ -1257,6 +1286,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* Test setting permissions concurrently to actually cause the expected concurrency exception
|
* Test setting permissions concurrently to actually cause the expected concurrency exception
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncConcurrentPermissionsUpdate() throws Throwable
|
public void testAsyncConcurrentPermissionsUpdate() throws Throwable
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncConcurrentPermissionsUpdateFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncConcurrentPermissionsUpdateFolder");
|
||||||
@@ -1328,6 +1358,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
* exception but the job should be able to recover
|
* exception but the job should be able to recover
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
public void testAsyncConcurrentUpdateAndJob() throws Throwable
|
public void testAsyncConcurrentUpdateAndJob() throws Throwable
|
||||||
{
|
{
|
||||||
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncConcurrentUpdateAndJobFolder");
|
NodeRef folderRef = createFolderHierarchyInRootForFolderTests("testAsyncConcurrentUpdateAndJobFolder");
|
||||||
@@ -1802,7 +1833,7 @@ public class FixedAclUpdaterTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a level in folder/file hierarchy. Intermediate levels will contain folders and last ones files
|
* Creates a level in folder/file hierarchy. Intermediate levels will contain folders and last ones files
|
||||||
*
|
*
|
||||||
* @param fileFolderService
|
* @param fileFolderService
|
||||||
* @param parent
|
* @param parent
|
||||||
* - parent node of the of hierarchy level
|
* - parent node of the of hierarchy level
|
||||||
|
@@ -99,7 +99,7 @@ public class SecurityTestSuite extends TestSuite
|
|||||||
|
|
||||||
suite.addTest(new JUnit4TestAdapter(HomeFolderProviderSynchronizerTest.class));
|
suite.addTest(new JUnit4TestAdapter(HomeFolderProviderSynchronizerTest.class));
|
||||||
suite.addTest(new JUnit4TestAdapter(AlfrescoSSLSocketFactoryTest.class));
|
suite.addTest(new JUnit4TestAdapter(AlfrescoSSLSocketFactoryTest.class));
|
||||||
suite.addTestSuite(FixedAclUpdaterTest.class);
|
suite.addTest(new JUnit4TestAdapter(FixedAclUpdaterTest.class));
|
||||||
|
|
||||||
suite.addTestSuite(DefaultRemoteUserMapperTest.class);
|
suite.addTestSuite(DefaultRemoteUserMapperTest.class);
|
||||||
suite.addTestSuite(IdentityServiceRemoteUserMapperTest.class);
|
suite.addTestSuite(IdentityServiceRemoteUserMapperTest.class);
|
||||||
|
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.util.test.junitrules;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TestRule;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This JUnit rule can be used to turn existing test code into retryable tests.
|
||||||
|
* The test methods marked with the {@link RetryAtMost} annotation will be attempted at most the specified
|
||||||
|
* amount of times, stopping at the first successful execution.
|
||||||
|
*
|
||||||
|
* @author Domenico Sibilio
|
||||||
|
*/
|
||||||
|
public class RetryAtMostRule implements TestRule
|
||||||
|
{
|
||||||
|
private static final Log LOG = LogFactory.getLog(RetryAtMostRule.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement apply(final Statement statement, final Description description)
|
||||||
|
{
|
||||||
|
RetryAtMost retryAtMost = description.getAnnotation(RetryAtMost.class);
|
||||||
|
|
||||||
|
if (retryAtMost != null)
|
||||||
|
{
|
||||||
|
return new RetryAtMostTestStatement(statement, description, retryAtMost.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RetryAtMostTestStatement extends Statement
|
||||||
|
{
|
||||||
|
private final Statement statement;
|
||||||
|
private final Description description;
|
||||||
|
private final int retryCount;
|
||||||
|
|
||||||
|
private RetryAtMostTestStatement(Statement statement, Description description, int retryCount)
|
||||||
|
{
|
||||||
|
this.statement = statement;
|
||||||
|
this.description = description;
|
||||||
|
this.retryCount = retryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evaluate() throws Throwable
|
||||||
|
{
|
||||||
|
validate();
|
||||||
|
for (int i = 0; i < retryCount; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LOG.debug(
|
||||||
|
"Retryable testing configured for method: " + description.getMethodName()
|
||||||
|
+ " // Attempt #" + (i + 1));
|
||||||
|
statement.evaluate();
|
||||||
|
break; // stop at the first successful execution
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
// ignore failed test runs unless it's the last possible execution
|
||||||
|
if (isLastExecution(i))
|
||||||
|
{
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validate()
|
||||||
|
{
|
||||||
|
if (retryCount < 1)
|
||||||
|
{
|
||||||
|
String methodName = description.getMethodName();
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid value for @RetryAtMost on method " + methodName + ": " + retryCount + " is less than 1.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLastExecution(int i)
|
||||||
|
{
|
||||||
|
return i == retryCount - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation is a marker used to identify a JUnit @{@link Test} method as a retryable test.
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface RetryAtMost
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return The amount of times a test will be attempted, at most.
|
||||||
|
*/
|
||||||
|
int value() default 1;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.util.test.junitrules;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.alfresco.util.test.junitrules.RetryAtMostRule.RetryAtMost;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TestName;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for {@link RetryAtMostRule}.
|
||||||
|
*
|
||||||
|
* @author Domenico Sibilio
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RetryAtMostRuleTest
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final String ANNOTATION_WITH_NEGATIVE_VALUE = "annotationRetryAtMostNegativeTimes";
|
||||||
|
private static final String ANNOTATION_RETRY_AT_MOST_THRICE = "annotationRetryAtMostThrice";
|
||||||
|
private static final AtomicInteger EXECUTION_COUNT = new AtomicInteger(0);
|
||||||
|
@Rule
|
||||||
|
public RetryAtMostRule retryAtMostRule = new RetryAtMostRule();
|
||||||
|
@Rule
|
||||||
|
public TestName testNameRule = new TestName();
|
||||||
|
@Mock
|
||||||
|
private Statement statementMock;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSucceedOnFirstAttempt() throws Throwable
|
||||||
|
{
|
||||||
|
Description description = Description.createTestDescription(RetryAtMostRuleTest.class.getSimpleName(),
|
||||||
|
testNameRule.getMethodName(), getAnnotationByMethodName(ANNOTATION_RETRY_AT_MOST_THRICE));
|
||||||
|
|
||||||
|
Statement statement = retryAtMostRule.apply(statementMock, description);
|
||||||
|
statement.evaluate();
|
||||||
|
verify(statementMock, times(1)).evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSucceedOnSecondAttempt() throws Throwable
|
||||||
|
{
|
||||||
|
doThrow(new AssertionError("First execution should fail")).doNothing().when(statementMock).evaluate();
|
||||||
|
|
||||||
|
Description description = Description.createTestDescription(RetryAtMostRuleTest.class.getSimpleName(),
|
||||||
|
testNameRule.getMethodName(), getAnnotationByMethodName(ANNOTATION_RETRY_AT_MOST_THRICE));
|
||||||
|
|
||||||
|
Statement statement = retryAtMostRule.apply(statementMock, description);
|
||||||
|
statement.evaluate();
|
||||||
|
verify(statementMock, times(2)).evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RetryAtMost(3)
|
||||||
|
public void testSucceedOnThirdAttempt()
|
||||||
|
{
|
||||||
|
int currentExecution = EXECUTION_COUNT.incrementAndGet();
|
||||||
|
assertSame("This test should be executed 3 times", 3, currentExecution);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AssertionError.class)
|
||||||
|
public void testFailAfterMaxAttempts() throws Throwable
|
||||||
|
{
|
||||||
|
doThrow(new AssertionError("All executions should fail")).when(statementMock).evaluate();
|
||||||
|
|
||||||
|
Description description = Description.createTestDescription(RetryAtMostRuleTest.class.getSimpleName(),
|
||||||
|
testNameRule.getMethodName(), getAnnotationByMethodName(ANNOTATION_RETRY_AT_MOST_THRICE));
|
||||||
|
|
||||||
|
Statement statement = retryAtMostRule.apply(statementMock, description);
|
||||||
|
statement.evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testInvalidRetryAtMostTimes() throws Throwable
|
||||||
|
{
|
||||||
|
Description description = Description.createTestDescription(RetryAtMostRuleTest.class.getSimpleName(),
|
||||||
|
testNameRule.getMethodName(), getAnnotationByMethodName(ANNOTATION_WITH_NEGATIVE_VALUE));
|
||||||
|
|
||||||
|
Statement statement = retryAtMostRule.apply(statementMock, description);
|
||||||
|
statement.evaluate();
|
||||||
|
verifyNoInteractions(statementMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Annotation getAnnotationByMethodName(String methodName) throws NoSuchMethodException
|
||||||
|
{
|
||||||
|
return this.getClass().getMethod(methodName).getAnnotation(RetryAtMost.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RetryAtMost(-1)
|
||||||
|
public void annotationRetryAtMostNegativeTimes()
|
||||||
|
{
|
||||||
|
// intentionally empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@RetryAtMost(3)
|
||||||
|
public void annotationRetryAtMostThrice()
|
||||||
|
{
|
||||||
|
// intentionally empty
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user