mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS 9256 improve async tests stability (#3191)
* ACS-9256 Improved stability in DynamicallySizedThreadPoolExecutorTest * ACS-9256 Removed unused unstable test in SpringAwareUserTransactionTest * ACS-9256 Improved stability in DynamicallySizedThreadPoolExecutorTest * ACS-9256 Improved stability in ActionServiceImplTest and RuleServiceCoverageTest * ACS-9256 Improved stability in ActionTrackingServiceImplTest * ACS-9256 Improved performance in ComparePropertyValueEvaluatorTest * ACS-9256 Improved performance in LockServiceImplTest * ACS-9256 Improved stability in LockBehaviourImplTest * ACS-9256 Improved stability in ContentMetadataExtracterTest * ACS-9256 Removed unstable and unused tests * ACS-9256 Improve stability in CachedContentCleanupJobTest * ACS-9256 Pre-commit fixes
This commit is contained in:
@@ -1431,26 +1431,6 @@
|
|||||||
"is_secret": false
|
"is_secret": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"repository/src/test/java/org/alfresco/repo/lock/LockBehaviourImplTest.java": [
|
|
||||||
{
|
|
||||||
"type": "Secret Keyword",
|
|
||||||
"filename": "repository/src/test/java/org/alfresco/repo/lock/LockBehaviourImplTest.java",
|
|
||||||
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
|
|
||||||
"is_verified": false,
|
|
||||||
"line_number": 112,
|
|
||||||
"is_secret": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"repository/src/test/java/org/alfresco/repo/lock/LockServiceImplTest.java": [
|
|
||||||
{
|
|
||||||
"type": "Secret Keyword",
|
|
||||||
"filename": "repository/src/test/java/org/alfresco/repo/lock/LockServiceImplTest.java",
|
|
||||||
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
|
|
||||||
"is_verified": false,
|
|
||||||
"line_number": 103,
|
|
||||||
"is_secret": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"repository/src/test/java/org/alfresco/repo/management/JmxDumpUtilTest.java": [
|
"repository/src/test/java/org/alfresco/repo/management/JmxDumpUtilTest.java": [
|
||||||
{
|
{
|
||||||
"type": "Secret Keyword",
|
"type": "Secret Keyword",
|
||||||
@@ -1888,5 +1868,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"generated_at": "2024-12-19T08:58:42Z"
|
"generated_at": "2025-02-11T13:28:51Z"
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,12 @@
|
|||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<version>${dependency.awaitility.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
* Copyright (C) 2005-2025 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.util;
|
package org.alfresco.util;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -26,11 +29,10 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for our instance of {@link java.util.concurrent.ThreadPoolExecutor}
|
* Tests for our instance of {@link java.util.concurrent.ThreadPoolExecutor}
|
||||||
*
|
*
|
||||||
@@ -39,7 +41,8 @@ import junit.framework.TestCase;
|
|||||||
public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(DynamicallySizedThreadPoolExecutorTest.class);
|
private static final Duration MAX_WAIT_TIMEOUT = Duration.ofSeconds(1);
|
||||||
|
private static final Log logger = LogFactory.getLog(DynamicallySizedThreadPoolExecutorTest.class);
|
||||||
private static final int DEFAULT_KEEP_ALIVE_TIME = 90;
|
private static final int DEFAULT_KEEP_ALIVE_TIME = 90;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,9 +51,9 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
SleepUntilAllWake.reset();
|
SleepUntilAllWake.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpToCore() throws Exception
|
public void testUpToCore()
|
||||||
{
|
{
|
||||||
DynamicallySizedThreadPoolExecutor exec = createInstance(5,10, DEFAULT_KEEP_ALIVE_TIME);
|
DynamicallySizedThreadPoolExecutor exec = createInstance(5, 10, DEFAULT_KEEP_ALIVE_TIME);
|
||||||
|
|
||||||
assertEquals(0, exec.getPoolSize());
|
assertEquals(0, exec.getPoolSize());
|
||||||
exec.execute(new SleepUntilAllWake());
|
exec.execute(new SleepUntilAllWake());
|
||||||
@@ -63,13 +66,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
assertEquals(5, exec.getPoolSize());
|
assertEquals(5, exec.getPoolSize());
|
||||||
|
|
||||||
SleepUntilAllWake.wakeAll();
|
SleepUntilAllWake.wakeAll();
|
||||||
Thread.sleep(100);
|
waitForPoolSizeEquals(exec, 5);
|
||||||
assertEquals(5, exec.getPoolSize());
|
assertEquals(5, exec.getPoolSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPastCoreButNotHugeQueue() throws Exception
|
public void testPastCoreButNotHugeQueue()
|
||||||
{
|
{
|
||||||
DynamicallySizedThreadPoolExecutor exec = createInstance(5,10, DEFAULT_KEEP_ALIVE_TIME);
|
DynamicallySizedThreadPoolExecutor exec = createInstance(5, 10, DEFAULT_KEEP_ALIVE_TIME);
|
||||||
|
|
||||||
assertEquals(0, exec.getPoolSize());
|
assertEquals(0, exec.getPoolSize());
|
||||||
assertEquals(0, exec.getQueue().size());
|
assertEquals(0, exec.getQueue().size());
|
||||||
@@ -96,13 +99,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
assertEquals(7, exec.getQueue().size());
|
assertEquals(7, exec.getQueue().size());
|
||||||
|
|
||||||
SleepUntilAllWake.wakeAll();
|
SleepUntilAllWake.wakeAll();
|
||||||
Thread.sleep(100);
|
waitForPoolSizeEquals(exec, 5);
|
||||||
assertEquals(5, exec.getPoolSize());
|
assertEquals(5, exec.getPoolSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testToExpandQueue() throws Exception
|
public void testToExpandQueue() throws Exception
|
||||||
{
|
{
|
||||||
DynamicallySizedThreadPoolExecutor exec = createInstance(2,4,1);
|
DynamicallySizedThreadPoolExecutor exec = createInstance(2, 4, 5);
|
||||||
|
|
||||||
assertEquals(0, exec.getPoolSize());
|
assertEquals(0, exec.getPoolSize());
|
||||||
assertEquals(0, exec.getQueue().size());
|
assertEquals(0, exec.getQueue().size());
|
||||||
@@ -119,13 +122,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
|
|
||||||
// Next should add one
|
// Next should add one
|
||||||
exec.execute(new SleepUntilAllWake());
|
exec.execute(new SleepUntilAllWake());
|
||||||
Thread.sleep(20); // Let the new thread spin up
|
waitForPoolSizeEquals(exec, 3); // Let the new thread spin up
|
||||||
assertEquals(3, exec.getPoolSize());
|
assertEquals(3, exec.getPoolSize());
|
||||||
assertEquals(3, exec.getQueue().size());
|
assertEquals(3, exec.getQueue().size());
|
||||||
|
|
||||||
// And again
|
// And again
|
||||||
exec.execute(new SleepUntilAllWake());
|
exec.execute(new SleepUntilAllWake());
|
||||||
Thread.sleep(20); // Let the new thread spin up
|
waitForPoolSizeEquals(exec, 4); // Let the new thread spin up
|
||||||
assertEquals(4, exec.getPoolSize());
|
assertEquals(4, exec.getPoolSize());
|
||||||
assertEquals(3, exec.getQueue().size());
|
assertEquals(3, exec.getQueue().size());
|
||||||
|
|
||||||
@@ -139,139 +142,10 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
SleepUntilAllWake.wakeAll();
|
SleepUntilAllWake.wakeAll();
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
||||||
// All threads still running, as 1 second timeout
|
// All threads still running, as 5 second timeout
|
||||||
assertEquals(4, exec.getPoolSize());
|
assertEquals(4, exec.getPoolSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offTestToExpandThenContract() throws Exception
|
|
||||||
{
|
|
||||||
DynamicallySizedThreadPoolExecutor exec = createInstance(2,4,1);
|
|
||||||
exec.setKeepAliveTime(30, TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
assertEquals(0, exec.getPoolSize());
|
|
||||||
assertEquals(0, exec.getQueue().size());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
assertEquals(2, exec.getPoolSize());
|
|
||||||
assertEquals(0, exec.getQueue().size());
|
|
||||||
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
assertEquals(2, exec.getPoolSize());
|
|
||||||
assertEquals(3, exec.getQueue().size());
|
|
||||||
|
|
||||||
// Next should add one
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
Thread.sleep(20); // Let the new thread spin up
|
|
||||||
assertEquals(3, exec.getPoolSize());
|
|
||||||
assertEquals(3, exec.getQueue().size());
|
|
||||||
|
|
||||||
// And again
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
Thread.sleep(20); // Let the new thread spin up
|
|
||||||
assertEquals(4, exec.getPoolSize());
|
|
||||||
assertEquals(3, exec.getQueue().size());
|
|
||||||
|
|
||||||
// But no more will be added, as we're at max
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
assertEquals(4, exec.getPoolSize());
|
|
||||||
assertEquals(6, exec.getQueue().size());
|
|
||||||
|
|
||||||
SleepUntilAllWake.wakeAll();
|
|
||||||
Thread.sleep(100);
|
|
||||||
|
|
||||||
// Wait longer than the timeout without any work, which should
|
|
||||||
// let all the extra threads go away
|
|
||||||
// (Depending on how closely your JVM follows the specification,
|
|
||||||
// we may fall back to the core size which is correct, or we
|
|
||||||
// may go to zero which is wrong, but hey, it's the JVM...)
|
|
||||||
logger.debug("Core pool size is " + exec.getCorePoolSize());
|
|
||||||
logger.debug("Current pool size is " + exec.getPoolSize());
|
|
||||||
logger.debug("Queue size is " + exec.getQueue().size());
|
|
||||||
assertTrue(
|
|
||||||
"Pool size should be 0-2 as everything is idle, was " + exec.getPoolSize(),
|
|
||||||
exec.getPoolSize() >= 0
|
|
||||||
);
|
|
||||||
assertTrue(
|
|
||||||
"Pool size should be 0-2 as everything is idle, was " + exec.getPoolSize(),
|
|
||||||
exec.getPoolSize() <= 2
|
|
||||||
);
|
|
||||||
|
|
||||||
SleepUntilAllWake.reset();
|
|
||||||
|
|
||||||
// Add 2 new jobs, will stay/ go to at 2 threads
|
|
||||||
assertEquals(0, exec.getQueue().size());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
|
|
||||||
// Let the idle threads grab them, then check
|
|
||||||
Thread.sleep(20);
|
|
||||||
assertEquals(2, exec.getPoolSize());
|
|
||||||
assertEquals(0, exec.getQueue().size());
|
|
||||||
|
|
||||||
// 3 more, still at 2 threads
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
assertEquals(2, exec.getPoolSize());
|
|
||||||
assertEquals(3, exec.getQueue().size());
|
|
||||||
|
|
||||||
// And again wait for it all
|
|
||||||
SleepUntilAllWake.wakeAll();
|
|
||||||
Thread.sleep(100);
|
|
||||||
assertEquals(2, exec.getPoolSize());
|
|
||||||
|
|
||||||
|
|
||||||
// Now decrease the overall pool size
|
|
||||||
// Will rise and fall to there now
|
|
||||||
exec.setCorePoolSize(1);
|
|
||||||
|
|
||||||
// Run a quick job, to ensure that the
|
|
||||||
// "can I kill one yet" logic is applied
|
|
||||||
SleepUntilAllWake.reset();
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
SleepUntilAllWake.wakeAll();
|
|
||||||
|
|
||||||
Thread.sleep(100);
|
|
||||||
assertEquals(1, exec.getPoolSize());
|
|
||||||
assertEquals(0, exec.getQueue().size());
|
|
||||||
|
|
||||||
SleepUntilAllWake.reset();
|
|
||||||
|
|
||||||
|
|
||||||
// Push enough on to go up to 4 active threads
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
exec.execute(new SleepUntilAllWake());
|
|
||||||
|
|
||||||
Thread.sleep(20); // Let the new threads spin up
|
|
||||||
assertEquals(4, exec.getPoolSize());
|
|
||||||
assertEquals(6, exec.getQueue().size());
|
|
||||||
|
|
||||||
// Wait for them all to finish, should drop back to 1 now
|
|
||||||
// (Or zero, if your JVM can't read the specification...)
|
|
||||||
SleepUntilAllWake.wakeAll();
|
|
||||||
Thread.sleep(100);
|
|
||||||
assertTrue(
|
|
||||||
"Pool size should be 0 or 1 as everything is idle, was " + exec.getPoolSize(),
|
|
||||||
exec.getPoolSize() >= 0
|
|
||||||
);
|
|
||||||
assertTrue(
|
|
||||||
"Pool size should be 0 or 1 as everything is idle, was " + exec.getPoolSize(),
|
|
||||||
exec.getPoolSize() <= 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DynamicallySizedThreadPoolExecutor createInstance(int corePoolSize, int maximumPoolSize, int keepAliveTime)
|
private DynamicallySizedThreadPoolExecutor createInstance(int corePoolSize, int maximumPoolSize, int keepAliveTime)
|
||||||
{
|
{
|
||||||
// We need a thread factory
|
// We need a thread factory
|
||||||
@@ -291,6 +165,11 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void waitForPoolSizeEquals(DynamicallySizedThreadPoolExecutor exec, int expectedSize)
|
||||||
|
{
|
||||||
|
await().atMost(MAX_WAIT_TIMEOUT).until(() -> exec.getPoolSize() == expectedSize);
|
||||||
|
}
|
||||||
|
|
||||||
public static class SleepUntilAllWake implements Runnable
|
public static class SleepUntilAllWake implements Runnable
|
||||||
{
|
{
|
||||||
private static ConcurrentMap<String, Thread> sleeping = new ConcurrentHashMap<String, Thread>();
|
private static ConcurrentMap<String, Thread> sleeping = new ConcurrentHashMap<String, Thread>();
|
||||||
@@ -299,17 +178,18 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
if(allAwake) return;
|
if (allAwake)
|
||||||
|
return;
|
||||||
|
|
||||||
// Track us, and wait for the bang
|
// Track us, and wait for the bang
|
||||||
logger.debug("Adding thread: " + Thread.currentThread().getName());
|
logger.debug("Adding thread: " + Thread.currentThread().getName());
|
||||||
sleeping.put(Thread.currentThread().getName(), Thread.currentThread());
|
sleeping.put(Thread.currentThread().getName(), Thread.currentThread());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(30*1000);
|
Thread.sleep(30 * 1000);
|
||||||
System.err.println("Warning - Thread finished sleeping without wake!");
|
System.err.println("Warning - Thread finished sleeping without wake!");
|
||||||
}
|
}
|
||||||
catch(InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
logger.debug("Interrupted thread: " + Thread.currentThread().getName());
|
logger.debug("Interrupted thread: " + Thread.currentThread().getName());
|
||||||
}
|
}
|
||||||
@@ -318,12 +198,13 @@ public class DynamicallySizedThreadPoolExecutorTest extends TestCase
|
|||||||
public static void wakeAll()
|
public static void wakeAll()
|
||||||
{
|
{
|
||||||
allAwake = true;
|
allAwake = true;
|
||||||
for(Entry<String, Thread> t : sleeping.entrySet())
|
for (Entry<String, Thread> t : sleeping.entrySet())
|
||||||
{
|
{
|
||||||
logger.debug("Interrupting thread: " + t.getKey());
|
logger.debug("Interrupting thread: " + t.getKey());
|
||||||
t.getValue().interrupt();
|
t.getValue().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reset()
|
public static void reset()
|
||||||
{
|
{
|
||||||
logger.debug("Resetting.");
|
logger.debug("Resetting.");
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2023 Alfresco Software Limited.
|
* Copyright (C) 2005-2025 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -20,13 +20,11 @@ package org.alfresco.util.transaction;
|
|||||||
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import jakarta.transaction.RollbackException;
|
import jakarta.transaction.RollbackException;
|
||||||
import jakarta.transaction.Status;
|
import jakarta.transaction.Status;
|
||||||
import jakarta.transaction.UserTransaction;
|
import jakarta.transaction.UserTransaction;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.springframework.transaction.CannotCreateTransactionException;
|
import org.springframework.transaction.CannotCreateTransactionException;
|
||||||
import org.springframework.transaction.NoTransactionException;
|
import org.springframework.transaction.NoTransactionException;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
@@ -35,9 +33,8 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
|
|||||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.util.transaction.SpringAwareUserTransaction
|
|
||||||
*
|
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
|
* @see org.alfresco.util.transaction.SpringAwareUserTransaction
|
||||||
*/
|
*/
|
||||||
public class SpringAwareUserTransactionTest extends TestCase
|
public class SpringAwareUserTransactionTest extends TestCase
|
||||||
{
|
{
|
||||||
@@ -245,58 +242,6 @@ public class SpringAwareUserTransactionTest extends TestCase
|
|||||||
checkNoStatusOnThread();
|
checkNoStatusOnThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for leaked transactions (no guarantee it will succeed due to reliance
|
|
||||||
* on garbage collector), so disabled by default.
|
|
||||||
*
|
|
||||||
* Also, if it succeeds, transaction call stack tracing will be enabled
|
|
||||||
* potentially hitting the performance of all subsequent tests.
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void xtestLeakedTransactionLogging() throws Exception
|
|
||||||
{
|
|
||||||
assertFalse(SpringAwareUserTransaction.isCallStackTraced());
|
|
||||||
|
|
||||||
TrxThread t1 = new TrxThread();
|
|
||||||
t1.start();
|
|
||||||
System.gc();
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
TrxThread t2 = new TrxThread();
|
|
||||||
t2.start();
|
|
||||||
System.gc();
|
|
||||||
Thread.sleep(1000);
|
|
||||||
|
|
||||||
assertTrue(SpringAwareUserTransaction.isCallStackTraced());
|
|
||||||
|
|
||||||
TrxThread t3 = new TrxThread();
|
|
||||||
t3.start();
|
|
||||||
System.gc();
|
|
||||||
Thread.sleep(3000);
|
|
||||||
System.gc();
|
|
||||||
Thread.sleep(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TrxThread extends Thread
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
getTrx();
|
|
||||||
}
|
|
||||||
catch (Exception e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getTrx() throws Exception
|
|
||||||
{
|
|
||||||
UserTransaction txn = getTxn();
|
|
||||||
txn.begin();
|
|
||||||
txn = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testConnectionPoolException() throws Exception
|
public void testConnectionPoolException() throws Exception
|
||||||
{
|
{
|
||||||
testNoTxnStatus();
|
testNoTxnStatus();
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -26,7 +26,12 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.action;
|
package org.alfresco.repo.action;
|
||||||
|
|
||||||
|
import static java.time.Duration.ofSeconds;
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -38,6 +43,13 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.executer.ActionExecuter;
|
import org.alfresco.repo.action.executer.ActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.ContentMetadataExtracter;
|
import org.alfresco.repo.action.executer.ContentMetadataExtracter;
|
||||||
@@ -64,12 +76,6 @@ import org.alfresco.util.test.junitrules.TemporaryNodes;
|
|||||||
import org.alfresco.util.test.junitrules.TemporarySites;
|
import org.alfresco.util.test.junitrules.TemporarySites;
|
||||||
import org.alfresco.util.test.junitrules.TemporarySites.TestSiteAndMemberInfo;
|
import org.alfresco.util.test.junitrules.TemporarySites.TestSiteAndMemberInfo;
|
||||||
import org.alfresco.util.test.junitrules.WellKnownNodes;
|
import org.alfresco.util.test.junitrules.WellKnownNodes;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
@@ -77,13 +83,13 @@ import org.junit.Test;
|
|||||||
*/
|
*/
|
||||||
public class ActionServiceImpl2Test
|
public class ActionServiceImpl2Test
|
||||||
{
|
{
|
||||||
|
private static final int MAX_WAIT_TIMEOUT = 10;
|
||||||
// Rule to initialise the default Alfresco spring configuration
|
// Rule to initialise the default Alfresco spring configuration
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
|
public static ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This JUnit rule will allow us to create Share sites and users and have
|
* This JUnit rule will allow us to create Share sites and users and have them automatically cleaned up for us.
|
||||||
* them automatically cleaned up for us.
|
|
||||||
*/
|
*/
|
||||||
@Rule
|
@Rule
|
||||||
public TemporarySites temporarySites = new TemporarySites(APP_CONTEXT_INIT);
|
public TemporarySites temporarySites = new TemporarySites(APP_CONTEXT_INIT);
|
||||||
@@ -107,8 +113,6 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
private NodeRef testNode;
|
private NodeRef testNode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initStaticData() throws Exception
|
public static void initStaticData() throws Exception
|
||||||
{
|
{
|
||||||
@@ -132,8 +136,7 @@ public class ActionServiceImpl2Test
|
|||||||
SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName());
|
SiteVisibility.PUBLIC, AuthenticationUtil.getAdminUserName());
|
||||||
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
testNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
testNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
// get the Document Library NodeRef
|
// get the Document Library NodeRef
|
||||||
@@ -150,8 +153,7 @@ public class ActionServiceImpl2Test
|
|||||||
@Test
|
@Test
|
||||||
public void testIncrementCounterOnDeletedNode() throws Exception
|
public void testIncrementCounterOnDeletedNode() throws Exception
|
||||||
{
|
{
|
||||||
final NodeRef deletedNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
final NodeRef deletedNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
// get the Document Library NodeRef
|
// get the Document Library NodeRef
|
||||||
@@ -165,8 +167,7 @@ public class ActionServiceImpl2Test
|
|||||||
});
|
});
|
||||||
|
|
||||||
// before the fix that would thrown an error
|
// before the fix that would thrown an error
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
|
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
|
||||||
@@ -182,8 +183,7 @@ public class ActionServiceImpl2Test
|
|||||||
{
|
{
|
||||||
// Set authentication to SiteManager.
|
// Set authentication to SiteManager.
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// add the cm:countable aspect and set the value to 1
|
// add the cm:countable aspect and set the value to 1
|
||||||
@@ -200,8 +200,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteConsumer.
|
// Set authentication to SiteConsumer.
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
|
Action incrementAction = actionService.createAction(CounterIncrementActionExecuter.NAME);
|
||||||
@@ -217,7 +216,7 @@ public class ActionServiceImpl2Test
|
|||||||
assertEquals(2, afterIncrement);
|
assertEquals(2, afterIncrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test//(expected = AccessDeniedException.class)
|
@Test // (expected = AccessDeniedException.class)
|
||||||
public void testTransform() throws Exception
|
public void testTransform() throws Exception
|
||||||
{
|
{
|
||||||
final File file = loadAndAddQuickFileAsManager(testNode, "quick.txt", MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
final File file = loadAndAddQuickFileAsManager(testNode, "quick.txt", MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
@@ -225,8 +224,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteConsumer.
|
// Set authentication to SiteConsumer.
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
Action action = actionService.createAction(TransformActionExecuter.NAME);
|
Action action = actionService.createAction(TransformActionExecuter.NAME);
|
||||||
@@ -269,8 +267,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteConsumer
|
// Set authentication to SiteConsumer
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Create the action
|
// Create the action
|
||||||
@@ -295,8 +292,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteManager
|
// Set authentication to SiteManager
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Create the action
|
// Create the action
|
||||||
@@ -312,16 +308,15 @@ public class ActionServiceImpl2Test
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Execute script not in Data Dictionary > Scripts
|
// Execute script not in Data Dictionary > Scripts
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
||||||
NodeRef companyHomeRef = wellKnownNodes.getCompanyHome();
|
NodeRef companyHomeRef = wellKnownNodes.getCompanyHome();
|
||||||
NodeRef sharedFolderRef = nodeService.getChildByName(companyHomeRef, ContentModel.ASSOC_CONTAINS,
|
NodeRef sharedFolderRef = nodeService.getChildByName(companyHomeRef, ContentModel.ASSOC_CONTAINS,
|
||||||
"Shared");
|
"Shared");
|
||||||
final NodeRef invalidScriptRef = addTempScript("changeFileNameTest.js",
|
final NodeRef invalidScriptRef = addTempScript("changeFileNameTest.js",
|
||||||
"document.properties.name = \"Invalid_Change.pdf\";\ndocument.save();",sharedFolderRef);
|
"document.properties.name = \"Invalid_Change.pdf\";\ndocument.save();", sharedFolderRef);
|
||||||
assertNotNull("Failed to add the test script.", scriptToBeExecuted);
|
assertNotNull("Failed to add the test script.", scriptToBeExecuted);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Create the action
|
// Create the action
|
||||||
@@ -349,8 +344,7 @@ public class ActionServiceImpl2Test
|
|||||||
public void testActionResult() throws Exception
|
public void testActionResult() throws Exception
|
||||||
{
|
{
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -389,8 +383,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteConsumer
|
// Set authentication to SiteConsumer
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteConsumer);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Create the action
|
// Create the action
|
||||||
@@ -412,8 +405,7 @@ public class ActionServiceImpl2Test
|
|||||||
|
|
||||||
// Set authentication to SiteCollaborator
|
// Set authentication to SiteCollaborator
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteCollaborator);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteCollaborator);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Create the action
|
// Create the action
|
||||||
@@ -424,24 +416,23 @@ public class ActionServiceImpl2Test
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Thread.sleep(3000); // Need to wait for the async extract
|
// Need to wait for the async extract
|
||||||
|
await().atMost(ofSeconds(MAX_WAIT_TIMEOUT))
|
||||||
|
.until(() -> nonNull(getProperty(testNode, ContentModel.PROP_DESCRIPTION)));
|
||||||
|
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
assertThat(getProperty(testNode, ContentModel.PROP_DESCRIPTION))
|
||||||
{
|
.isEqualTo("Pangram, fox, dog, Gym class featuring a brown fox and lazy dog");
|
||||||
public Void execute() throws Throwable
|
|
||||||
{
|
|
||||||
assertEquals("Pangram, fox, dog, Gym class featuring a brown fox and lazy dog",
|
|
||||||
nodeService.getProperty(testNode, ContentModel.PROP_DESCRIPTION));
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
private Serializable getProperty(NodeRef nodeRef, QName propertyName)
|
||||||
|
{
|
||||||
|
return transactionHelper.doInTransaction(() -> nodeService.getProperty(nodeRef, propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeRef addTempScript(final String scriptFileName, final String javaScript, final NodeRef parentRef)
|
private NodeRef addTempScript(final String scriptFileName, final String javaScript, final NodeRef parentRef)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -466,8 +457,7 @@ public class ActionServiceImpl2Test
|
|||||||
private NodeRef addTempScript(final String scriptFileName, final String javaScript)
|
private NodeRef addTempScript(final String scriptFileName, final String javaScript)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
return transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -490,12 +480,14 @@ public class ActionServiceImpl2Test
|
|||||||
{
|
{
|
||||||
final File file = AbstractContentTransformerTest.loadNamedQuickTestFile(quickFileName);
|
final File file = AbstractContentTransformerTest.loadNamedQuickTestFile(quickFileName);
|
||||||
|
|
||||||
if (file == null) { return null; }
|
if (file == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Set authentication to SiteManager and add a file
|
// Set authentication to SiteManager and add a file
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
AuthenticationUtil.setFullyAuthenticatedUser(testSiteAndMemberInfo.siteManager);
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, quickFileName);
|
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, quickFileName);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,28 +25,38 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.action;
|
package org.alfresco.repo.action;
|
||||||
|
|
||||||
|
import static java.time.Duration.ofMillis;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.transaction.TestTransaction;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
|
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
|
||||||
import org.alfresco.repo.action.executer.ActionExecuter;
|
|
||||||
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||||
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
|
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CheckInActionExecuter;
|
import org.alfresco.repo.action.executer.CheckInActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
|
import org.alfresco.repo.action.executer.CheckOutActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.MoveActionExecuter;
|
import org.alfresco.repo.action.executer.MoveActionExecuter;
|
||||||
import org.alfresco.repo.action.executer.ScriptActionExecuter;
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
@@ -65,27 +75,12 @@ import org.alfresco.service.cmr.action.CompositeActionCondition;
|
|||||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||||
import org.alfresco.service.cmr.repository.ContentData;
|
import org.alfresco.service.cmr.repository.ContentData;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
|
||||||
import org.alfresco.test_category.BaseSpringTestsCategory;
|
import org.alfresco.test_category.BaseSpringTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
|
||||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.PropertyMap;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.transaction.TestTransaction;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action service test
|
* Action service test
|
||||||
@@ -109,7 +104,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
this.transactionHelper = (RetryingTransactionHelper)this.applicationContext.getBean("retryingTransactionHelper");
|
this.transactionHelper = (RetryingTransactionHelper) this.applicationContext.getBean("retryingTransactionHelper");
|
||||||
|
|
||||||
// Create the node used for tests
|
// Create the node used for tests
|
||||||
this.nodeRef = this.nodeService.createNode(
|
this.nodeRef = this.nodeService.createNode(
|
||||||
@@ -183,7 +178,6 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getActionConditionDefinitions
|
* Test getActionConditionDefinitions
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetActionConditionDefinitions()
|
public void testGetActionConditionDefinitions()
|
||||||
@@ -440,8 +434,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test saving an action with no conditions. Includes testing storage and retrieval
|
* Test saving an action with no conditions. Includes testing storage and retrieval of compensating actions.
|
||||||
* of compensating actions.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSaveActionNoCondition()
|
public void testSaveActionNoCondition()
|
||||||
@@ -522,7 +515,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
Action savedAction4 = this.actionService.getAction(this.nodeRef, actionId);
|
Action savedAction4 = this.actionService.getAction(this.nodeRef, actionId);
|
||||||
assertNull(savedAction4.getCompensatingAction());
|
assertNull(savedAction4.getCompensatingAction());
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -541,7 +534,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
action.setExecuteAsynchronously(true);
|
action.setExecuteAsynchronously(true);
|
||||||
|
|
||||||
// Check the owning node ref
|
// Check the owning node ref
|
||||||
//assertNull(action.getOwningNodeRef());
|
// assertNull(action.getOwningNodeRef());
|
||||||
|
|
||||||
// Save the action
|
// Save the action
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
@@ -640,7 +633,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -659,7 +652,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, compositeAction);
|
this.actionService.saveAction(this.nodeRef, compositeAction);
|
||||||
assertEquals(1, this.actionService.getActions(this.nodeRef).size());
|
assertEquals(1, this.actionService.getActions(this.nodeRef).size());
|
||||||
CompositeAction savedCompositeAction = (CompositeAction)this.actionService.getAction(this.nodeRef, actionId);
|
CompositeAction savedCompositeAction = (CompositeAction) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
// Check the saved composite action
|
// Check the saved composite action
|
||||||
assertEquals(2, savedCompositeAction.getActions().size());
|
assertEquals(2, savedCompositeAction.getActions().size());
|
||||||
@@ -687,7 +680,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, compositeAction);
|
this.actionService.saveAction(this.nodeRef, compositeAction);
|
||||||
assertEquals(1, this.actionService.getActions(this.nodeRef).size());
|
assertEquals(1, this.actionService.getActions(this.nodeRef).size());
|
||||||
CompositeAction savedCompositeAction2 = (CompositeAction)this.actionService.getAction(this.nodeRef, actionId);
|
CompositeAction savedCompositeAction2 = (CompositeAction) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
assertEquals(2, savedCompositeAction2.getActions().size());
|
assertEquals(2, savedCompositeAction2.getActions().size());
|
||||||
for (Action action : savedCompositeAction2.getActions())
|
for (Action action : savedCompositeAction2.getActions())
|
||||||
@@ -780,7 +773,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
action.addAction(action2);
|
action.addAction(action2);
|
||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
CompositeAction savedAction = (CompositeAction)this.actionService.getAction(this.nodeRef, actionId);
|
CompositeAction savedAction = (CompositeAction) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
// Check that the conditions have been retrieved in the correct order
|
// Check that the conditions have been retrieved in the correct order
|
||||||
assertNotNull(savedAction);
|
assertNotNull(savedAction);
|
||||||
@@ -796,7 +789,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
savedAction.addAction(action4);
|
savedAction.addAction(action4);
|
||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, savedAction);
|
this.actionService.saveAction(this.nodeRef, savedAction);
|
||||||
CompositeAction savedAction2 = (CompositeAction)this.actionService.getAction(this.nodeRef, actionId);
|
CompositeAction savedAction2 = (CompositeAction) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
// Check that the conditions are still in the correct order
|
// Check that the conditions are still in the correct order
|
||||||
assertNotNull(savedAction2);
|
assertNotNull(savedAction2);
|
||||||
@@ -805,90 +798,9 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
assertEquals(action4, savedAction2.getAction(2));
|
assertEquals(action4, savedAction2.getAction(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** ===================================================================================
|
|
||||||
* Test asynchronous actions
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test checks that a series of "equivalent" actions submitted for asynchronous execution
|
* =================================================================================== Test asynchronous actions
|
||||||
* will be correctly filtered so that no 2 equivalent actions are executed at the same time.
|
|
||||||
*/
|
*/
|
||||||
public void offtestAsyncLongRunningActionsFilter()
|
|
||||||
{
|
|
||||||
TestTransaction.flagForCommit();
|
|
||||||
TestTransaction.end();
|
|
||||||
|
|
||||||
final SleepActionExecuter sleepAction = (SleepActionExecuter)applicationContext.getBean("sleep-action");
|
|
||||||
assertNotNull(sleepAction);
|
|
||||||
sleepAction.setSleepMs(10);
|
|
||||||
|
|
||||||
final int actionSubmissonCount = 4; // Rather arbitrary count.
|
|
||||||
for (int i = 0; i < actionSubmissonCount; i ++)
|
|
||||||
{
|
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
|
||||||
{
|
|
||||||
Action action = actionService.createAction(SleepActionExecuter.NAME);
|
|
||||||
action.setExecuteAsynchronously(true);
|
|
||||||
|
|
||||||
actionService.executeAction(action, nodeRef);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait long enough for previous action(s) to have executed and then submit another
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(sleepAction.getSleepMs() * actionSubmissonCount + 1000); // Enough time for all actions and an extra second for luck.
|
|
||||||
}
|
|
||||||
catch (InterruptedException ignored)
|
|
||||||
{
|
|
||||||
// intentionally empty
|
|
||||||
}
|
|
||||||
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
|
||||||
{
|
|
||||||
Action action = actionService.createAction(SleepActionExecuter.NAME);
|
|
||||||
action.setExecuteAsynchronously(true);
|
|
||||||
|
|
||||||
actionService.executeAction(action, nodeRef);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(sleepAction.getSleepMs() + 2000); // Enough time for latest action and an extra 2 seconds for luck.
|
|
||||||
}
|
|
||||||
catch (InterruptedException ignored)
|
|
||||||
{
|
|
||||||
// intentionally empty
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int sleepTime = 0; // Do not sleep during execution as the Action itself sleeps.
|
|
||||||
int maxTries = 1;
|
|
||||||
postAsyncActionTest(
|
|
||||||
this.transactionService,
|
|
||||||
sleepTime,
|
|
||||||
maxTries,
|
|
||||||
new AsyncTest()
|
|
||||||
{
|
|
||||||
public String executeTest()
|
|
||||||
{
|
|
||||||
final int expectedResult = 2;
|
|
||||||
int actualResult = sleepAction.getTimesExecuted();
|
|
||||||
return actualResult == expectedResult ? null : "Expected timesExecuted " + expectedResult + " was " + actualResult;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test asynchronous execute action
|
* Test asynchronous execute action
|
||||||
@@ -907,25 +819,15 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
TestTransaction.flagForCommit();
|
TestTransaction.flagForCommit();
|
||||||
TestTransaction.end();
|
TestTransaction.end();
|
||||||
|
|
||||||
final NodeService finalNodeService = this.nodeService;
|
|
||||||
final NodeRef finalNodeRef = this.nodeRef;
|
final NodeRef finalNodeRef = this.nodeRef;
|
||||||
|
|
||||||
postAsyncActionTest(
|
await().atMost(MAX_ASYNC_TIMEOUT).until(() -> nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_CLASSIFIABLE));
|
||||||
this.transactionService,
|
|
||||||
1000l,
|
assertThat(nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_CLASSIFIABLE))
|
||||||
10,
|
.as("Expected aspect classifiable")
|
||||||
new AsyncTest()
|
.isTrue();
|
||||||
{
|
|
||||||
public String executeTest()
|
|
||||||
{
|
|
||||||
boolean result = finalNodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_CLASSIFIABLE);
|
|
||||||
return result ? null : "Expected aspect Classifiable";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test async composite action execution
|
* Test async composite action execution
|
||||||
*/
|
*/
|
||||||
@@ -950,97 +852,17 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
TestTransaction.flagForCommit();
|
TestTransaction.flagForCommit();
|
||||||
TestTransaction.end();
|
TestTransaction.end();
|
||||||
|
|
||||||
final NodeService finalNodeService = this.nodeService;
|
|
||||||
final NodeRef finalNodeRef = this.nodeRef;
|
final NodeRef finalNodeRef = this.nodeRef;
|
||||||
|
|
||||||
postAsyncActionTest(
|
await().atMost(MAX_ASYNC_TIMEOUT).until(() -> nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
this.transactionService,
|
await().atMost(MAX_ASYNC_TIMEOUT).until(() -> nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_LOCKABLE));
|
||||||
1000,
|
|
||||||
10,
|
|
||||||
new AsyncTest()
|
|
||||||
{
|
|
||||||
public String executeTest()
|
|
||||||
{
|
|
||||||
boolean result = finalNodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_VERSIONABLE) &&
|
|
||||||
finalNodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_LOCKABLE);
|
|
||||||
return result ? null : "Expected aspects Versionable & Lockable";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void xtestAsyncLoadTest()
|
assertThat(nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_VERSIONABLE))
|
||||||
{
|
.as("Expected aspect versionable")
|
||||||
// TODO this is very weak .. how do we improve this ???
|
.isTrue();
|
||||||
|
assertThat(nodeService.hasAspect(finalNodeRef, ContentModel.ASPECT_LOCKABLE))
|
||||||
Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME);
|
.as("Expected aspect lockable")
|
||||||
action.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
|
.isTrue();
|
||||||
action.setExecuteAsynchronously(true);
|
|
||||||
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
this.actionService.executeAction(action, this.nodeRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestTransaction.flagForCommit();
|
|
||||||
TestTransaction.end();
|
|
||||||
|
|
||||||
// TODO how do we assess whether the large number of actions stacked cause a problem ??
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param sleepTime
|
|
||||||
* @param maxTries
|
|
||||||
* @param test
|
|
||||||
*/
|
|
||||||
public static void postAsyncActionTest(
|
|
||||||
TransactionService transactionService,
|
|
||||||
final long sleepTime,
|
|
||||||
final int maxTries,
|
|
||||||
final AsyncTest test)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int tries = 0;
|
|
||||||
String errorMsg = null;
|
|
||||||
while (errorMsg == null && tries < maxTries)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Increment the tries counter
|
|
||||||
tries++;
|
|
||||||
|
|
||||||
// Sleep for a bit
|
|
||||||
Thread.sleep(sleepTime);
|
|
||||||
|
|
||||||
errorMsg = (transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
||||||
new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute()
|
|
||||||
{
|
|
||||||
// See if the action has been performed
|
|
||||||
String done = test.executeTest();
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
catch (InterruptedException e)
|
|
||||||
{
|
|
||||||
// Do nothing
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMsg != null)
|
|
||||||
{
|
|
||||||
throw new RuntimeException("Asynchronous action was not executed. " + errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable exception)
|
|
||||||
{
|
|
||||||
exception.printStackTrace();
|
|
||||||
fail("An exception was encountered whilst checking the async action was executed: " + exception.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1049,14 +871,13 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
public interface AsyncTest
|
public interface AsyncTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return <code>null</code> if the test succeeded, else an error message for use in JUnit report.
|
* @return <code>null</code> if the test succeeded, else an error message for use in JUnit report.
|
||||||
*/
|
*/
|
||||||
String executeTest();
|
String executeTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ===================================================================================
|
/**
|
||||||
* Test failure behaviour
|
* =================================================================================== Test failure behaviour
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1128,7 +949,6 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
compensatingAction2.setTitle("title");
|
compensatingAction2.setTitle("title");
|
||||||
nonfatalAction.setCompensatingAction(compensatingAction2);
|
nonfatalAction.setCompensatingAction(compensatingAction2);
|
||||||
|
|
||||||
|
|
||||||
// Set the actions to execute asynchronously
|
// Set the actions to execute asynchronously
|
||||||
fatalAction.setExecuteAsynchronously(true);
|
fatalAction.setExecuteAsynchronously(true);
|
||||||
nonfatalAction.setExecuteAsynchronously(true);
|
nonfatalAction.setExecuteAsynchronously(true);
|
||||||
@@ -1139,38 +959,21 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
TestTransaction.flagForCommit();
|
TestTransaction.flagForCommit();
|
||||||
TestTransaction.end();
|
TestTransaction.end();
|
||||||
|
|
||||||
postAsyncActionTest(
|
await().atMost(MAX_ASYNC_TIMEOUT).until(() -> nodeService.hasAspect(nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
|
||||||
this.transactionService,
|
await().pollDelay(ofMillis(500)).atMost(MAX_ASYNC_TIMEOUT).until(() -> !nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY));
|
||||||
1000,
|
|
||||||
10,
|
|
||||||
new AsyncTest()
|
|
||||||
{
|
|
||||||
public String executeTest()
|
|
||||||
{
|
|
||||||
boolean fatalCompensatingActionRun = ActionServiceImplTest.this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_CLASSIFIABLE);
|
|
||||||
|
|
||||||
boolean nonFatalCompensatingActionRun = ActionServiceImplTest.this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY);
|
assertThat(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_CLASSIFIABLE))
|
||||||
|
.as("Expected aspect Classifiable")
|
||||||
StringBuilder result = new StringBuilder();
|
.isTrue();
|
||||||
if (!fatalCompensatingActionRun)
|
assertThat(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY))
|
||||||
{
|
.as("Did not expect aspect Temporary")
|
||||||
result.append("Expected aspect Classifiable.");
|
.isFalse();
|
||||||
}
|
|
||||||
if (nonFatalCompensatingActionRun)
|
|
||||||
{
|
|
||||||
result.append(" Did not expect aspect Temporary");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( !fatalCompensatingActionRun || nonFatalCompensatingActionRun ? result.toString() : null);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Modify the compensating action so that it will also fail
|
// Modify the compensating action so that it will also fail
|
||||||
compensatingAction.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, QName.createQName("{test}badAspect"));
|
compensatingAction.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, QName.createQName("{test}badAspect"));
|
||||||
|
|
||||||
this.transactionService.getRetryingTransactionHelper().doInTransaction(
|
this.transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||||
new RetryingTransactionCallback<Object>()
|
new RetryingTransactionCallback<Object>() {
|
||||||
{
|
|
||||||
public Object execute()
|
public Object execute()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1198,7 +1001,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
{
|
{
|
||||||
String userName = "bob" + GUID.generate();
|
String userName = "bob" + GUID.generate();
|
||||||
createUser(userName);
|
createUser(userName);
|
||||||
PermissionService permissionService = (PermissionService)applicationContext.getBean("PermissionService");
|
PermissionService permissionService = (PermissionService) applicationContext.getBean("PermissionService");
|
||||||
permissionService.setPermission(rootNodeRef, userName, PermissionService.COORDINATOR, true);
|
permissionService.setPermission(rootNodeRef, userName, PermissionService.COORDINATOR, true);
|
||||||
|
|
||||||
AuthenticationUtil.setRunAsUser(userName);
|
AuthenticationUtil.setRunAsUser(userName);
|
||||||
@@ -1209,7 +1012,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
QName.createQName("{test}myTestNode" + GUID.generate()),
|
QName.createQName("{test}myTestNode" + GUID.generate()),
|
||||||
ContentModel.TYPE_CONTENT).getChildRef();
|
ContentModel.TYPE_CONTENT).getChildRef();
|
||||||
|
|
||||||
CheckOutCheckInService coci = (CheckOutCheckInService)applicationContext.getBean("CheckoutCheckinService");
|
CheckOutCheckInService coci = (CheckOutCheckInService) applicationContext.getBean("CheckoutCheckinService");
|
||||||
NodeRef workingcopy = coci.checkout(myNodeRef);
|
NodeRef workingcopy = coci.checkout(myNodeRef);
|
||||||
assertNotNull(workingcopy);
|
assertNotNull(workingcopy);
|
||||||
|
|
||||||
@@ -1229,12 +1032,11 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that we can read, save, load etc the various
|
* Tests that we can read, save, load etc the various execution related details such as started at, ended at, status and exception
|
||||||
* execution related details such as started at,
|
|
||||||
* ended at, status and exception
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testExecutionTrackingDetails() {
|
public void testExecutionTrackingDetails()
|
||||||
|
{
|
||||||
Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME);
|
Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME);
|
||||||
String actionId = action.getId();
|
String actionId = action.getId();
|
||||||
|
|
||||||
@@ -1243,52 +1045,48 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
assertNull(action.getExecutionFailureMessage());
|
assertNull(action.getExecutionFailureMessage());
|
||||||
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
||||||
|
|
||||||
|
|
||||||
// Save and load, details shouldn't have changed
|
// Save and load, details shouldn't have changed
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
action = (Action)this.actionService.getAction(this.nodeRef, actionId);
|
action = (Action) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
assertNull(action.getExecutionStartDate());
|
assertNull(action.getExecutionStartDate());
|
||||||
assertNull(action.getExecutionEndDate());
|
assertNull(action.getExecutionEndDate());
|
||||||
assertNull(action.getExecutionFailureMessage());
|
assertNull(action.getExecutionFailureMessage());
|
||||||
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
||||||
|
|
||||||
|
|
||||||
// Set some details, ensure they survive a save/load
|
// Set some details, ensure they survive a save/load
|
||||||
((ActionImpl)action).setExecutionStatus(ActionStatus.Running);
|
((ActionImpl) action).setExecutionStatus(ActionStatus.Running);
|
||||||
((ActionImpl)action).setExecutionStartDate(new Date(12345));
|
((ActionImpl) action).setExecutionStartDate(new Date(12345));
|
||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
action = (Action)this.actionService.getAction(this.nodeRef, actionId);
|
action = (Action) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
||||||
assertEquals(12345, action.getExecutionStartDate().getTime());
|
assertEquals(12345, action.getExecutionStartDate().getTime());
|
||||||
assertNull(action.getExecutionEndDate());
|
assertNull(action.getExecutionEndDate());
|
||||||
assertNull(action.getExecutionFailureMessage());
|
assertNull(action.getExecutionFailureMessage());
|
||||||
|
|
||||||
|
|
||||||
// Set the rest, and change some, ensure they survive a save/load
|
// Set the rest, and change some, ensure they survive a save/load
|
||||||
((ActionImpl)action).setExecutionStatus(ActionStatus.Failed);
|
((ActionImpl) action).setExecutionStatus(ActionStatus.Failed);
|
||||||
((ActionImpl)action).setExecutionStartDate(new Date(123450));
|
((ActionImpl) action).setExecutionStartDate(new Date(123450));
|
||||||
((ActionImpl)action).setExecutionEndDate(new Date(123455));
|
((ActionImpl) action).setExecutionEndDate(new Date(123455));
|
||||||
((ActionImpl)action).setExecutionFailureMessage("Testing");
|
((ActionImpl) action).setExecutionFailureMessage("Testing");
|
||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
action = (Action)this.actionService.getAction(this.nodeRef, actionId);
|
action = (Action) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
|
assertEquals(ActionStatus.Failed, action.getExecutionStatus());
|
||||||
assertEquals(123450, action.getExecutionStartDate().getTime());
|
assertEquals(123450, action.getExecutionStartDate().getTime());
|
||||||
assertEquals(123455, action.getExecutionEndDate().getTime());
|
assertEquals(123455, action.getExecutionEndDate().getTime());
|
||||||
assertEquals("Testing", action.getExecutionFailureMessage());
|
assertEquals("Testing", action.getExecutionFailureMessage());
|
||||||
|
|
||||||
|
|
||||||
// Unset a few, ensure they survive a save/load
|
// Unset a few, ensure they survive a save/load
|
||||||
((ActionImpl)action).setExecutionStatus(null);
|
((ActionImpl) action).setExecutionStatus(null);
|
||||||
((ActionImpl)action).setExecutionStartDate(new Date(123450));
|
((ActionImpl) action).setExecutionStartDate(new Date(123450));
|
||||||
((ActionImpl)action).setExecutionFailureMessage(null);
|
((ActionImpl) action).setExecutionFailureMessage(null);
|
||||||
|
|
||||||
this.actionService.saveAction(this.nodeRef, action);
|
this.actionService.saveAction(this.nodeRef, action);
|
||||||
action = (Action)this.actionService.getAction(this.nodeRef, actionId);
|
action = (Action) this.actionService.getAction(this.nodeRef, actionId);
|
||||||
|
|
||||||
assertEquals(ActionStatus.New, action.getExecutionStatus()); // Default
|
assertEquals(ActionStatus.New, action.getExecutionStatus()); // Default
|
||||||
assertEquals(123450, action.getExecutionStartDate().getTime());
|
assertEquals(123450, action.getExecutionStartDate().getTime());
|
||||||
@@ -1299,10 +1097,11 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
/**
|
/**
|
||||||
* This method returns an {@link Action} which will fail when executed.
|
* This method returns an {@link Action} which will fail when executed.
|
||||||
*
|
*
|
||||||
* @param isFatal if <code>false</code> this will give an action which throws
|
* @param isFatal
|
||||||
* a {@link ActionServiceTransientException non-fatal action exception}.
|
* if <code>false</code> this will give an action which throws a {@link ActionServiceTransientException non-fatal action exception}.
|
||||||
*/
|
*/
|
||||||
protected Action createFailingMoveAction(boolean isFatal) {
|
protected Action createFailingMoveAction(boolean isFatal)
|
||||||
|
{
|
||||||
Action failingAction;
|
Action failingAction;
|
||||||
if (isFatal)
|
if (isFatal)
|
||||||
{
|
{
|
||||||
@@ -1320,10 +1119,13 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
return failingAction;
|
return failingAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Action createFailingSleepAction(String id, boolean isFatal) throws Exception {
|
protected Action createFailingSleepAction(String id, boolean isFatal) throws Exception
|
||||||
|
{
|
||||||
return createFailingSleepAction(id, isFatal, this.actionService);
|
return createFailingSleepAction(id, isFatal, this.actionService);
|
||||||
}
|
}
|
||||||
protected static Action createFailingSleepAction(String id, boolean isFatal, ActionService actionService) throws Exception {
|
|
||||||
|
protected static Action createFailingSleepAction(String id, boolean isFatal, ActionService actionService) throws Exception
|
||||||
|
{
|
||||||
Action failingAction = createWorkingSleepAction(id, actionService);
|
Action failingAction = createWorkingSleepAction(id, actionService);
|
||||||
failingAction.setParameterValue(SleepActionExecuter.GO_BANG, Boolean.TRUE);
|
failingAction.setParameterValue(SleepActionExecuter.GO_BANG, Boolean.TRUE);
|
||||||
failingAction.setParameterValue(SleepActionExecuter.FAIL_FATALLY, Boolean.valueOf(isFatal));
|
failingAction.setParameterValue(SleepActionExecuter.FAIL_FATALLY, Boolean.valueOf(isFatal));
|
||||||
@@ -1334,15 +1136,17 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
{
|
{
|
||||||
return createWorkingSleepAction(null);
|
return createWorkingSleepAction(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Action createWorkingSleepAction(String id) throws Exception
|
protected Action createWorkingSleepAction(String id) throws Exception
|
||||||
{
|
{
|
||||||
return createWorkingSleepAction(id, this.actionService);
|
return createWorkingSleepAction(id, this.actionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Action createWorkingSleepAction(String id, ActionService actionService) throws Exception
|
protected static Action createWorkingSleepAction(String id, ActionService actionService) throws Exception
|
||||||
{
|
{
|
||||||
Action workingAction = new CancellableSleepAction(actionService.createAction(SleepActionExecuter.NAME));
|
Action workingAction = new CancellableSleepAction(actionService.createAction(SleepActionExecuter.NAME));
|
||||||
workingAction.setTrackStatus(Boolean.TRUE);
|
workingAction.setTrackStatus(Boolean.TRUE);
|
||||||
if(id != null)
|
if (id != null)
|
||||||
{
|
{
|
||||||
Field idF = ParameterizedItemImpl.class.getDeclaredField("id");
|
Field idF = ParameterizedItemImpl.class.getDeclaredField("id");
|
||||||
idF.setAccessible(true);
|
idF.setAccessible(true);
|
||||||
@@ -1380,9 +1184,21 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
private Thread executingThread;
|
private Thread executingThread;
|
||||||
|
|
||||||
private int timesExecuted = 0;
|
private int timesExecuted = 0;
|
||||||
private void incrementTimesExecutedCount() {timesExecuted++;}
|
|
||||||
public int getTimesExecuted() {return timesExecuted;}
|
private void incrementTimesExecutedCount()
|
||||||
public void resetTimesExecuted() {timesExecuted=0;}
|
{
|
||||||
|
timesExecuted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTimesExecuted()
|
||||||
|
{
|
||||||
|
return timesExecuted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetTimesExecuted()
|
||||||
|
{
|
||||||
|
timesExecuted = 0;
|
||||||
|
}
|
||||||
|
|
||||||
private ActionTrackingService actionTrackingService;
|
private ActionTrackingService actionTrackingService;
|
||||||
|
|
||||||
@@ -1427,9 +1243,10 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
|
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
|
||||||
|
{
|
||||||
executingThread = Thread.currentThread();
|
executingThread = Thread.currentThread();
|
||||||
//System.err.println("Sleeping for " + sleepMs + " for " + action);
|
// System.err.println("Sleeping for " + sleepMs + " for " + action);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1444,8 +1261,8 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
incrementTimesExecutedCount();
|
incrementTimesExecutedCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean fail = (Boolean)action.getParameterValue(GO_BANG);
|
Boolean fail = (Boolean) action.getParameterValue(GO_BANG);
|
||||||
Boolean failFatally = (Boolean)action.getParameterValue(FAIL_FATALLY);
|
Boolean failFatally = (Boolean) action.getParameterValue(FAIL_FATALLY);
|
||||||
if (fail != null && fail)
|
if (fail != null && fail)
|
||||||
{
|
{
|
||||||
// this should fail
|
// this should fail
|
||||||
@@ -1461,11 +1278,11 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(action instanceof CancellableSleepAction)
|
if (action instanceof CancellableSleepAction)
|
||||||
{
|
{
|
||||||
CancellableSleepAction ca = (CancellableSleepAction)action;
|
CancellableSleepAction ca = (CancellableSleepAction) action;
|
||||||
boolean cancelled = actionTrackingService.isCancellationRequested(ca);
|
boolean cancelled = actionTrackingService.isCancellationRequested(ca);
|
||||||
if(cancelled)
|
if (cancelled)
|
||||||
throw new ActionCancelledException(ca);
|
throw new ActionCancelledException(ca);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1499,19 +1316,20 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void addParameterDefinitions(List<ParameterDefinition> paramList)
|
@Override
|
||||||
|
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
|
||||||
{
|
{
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
|
@Override
|
||||||
|
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
|
||||||
|
{
|
||||||
// this action always fails with a non-fatal exception.
|
// this action always fails with a non-fatal exception.
|
||||||
throw new ActionServiceTransientException("action failed intentionally in " + TransientFailActionExecuter.class.getSimpleName());
|
throw new ActionServiceTransientException("action failed intentionally in " + TransientFailActionExecuter.class.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected static class CancellableSleepAction extends ActionImpl implements CancellableAction
|
protected static class CancellableSleepAction extends ActionImpl implements CancellableAction
|
||||||
{
|
{
|
||||||
public CancellableSleepAction(Action action)
|
public CancellableSleepAction(Action action)
|
||||||
@@ -1525,7 +1343,6 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
{
|
{
|
||||||
assertTrue(
|
assertTrue(
|
||||||
before.toString() + " not before " + after.toString(),
|
before.toString() + " not before " + after.toString(),
|
||||||
before.getTime() <= after.getTime()
|
before.getTime() <= after.getTime());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,15 +25,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.action;
|
package org.alfresco.repo.action;
|
||||||
|
|
||||||
import static org.alfresco.repo.action.ActionServiceImplTest.assertBefore;
|
import static java.util.Objects.isNull;
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import jakarta.transaction.UserTransaction;
|
import jakarta.transaction.UserTransaction;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ActionServiceImplTest.CancellableSleepAction;
|
import org.alfresco.repo.action.ActionServiceImplTest.CancellableSleepAction;
|
||||||
import org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter;
|
import org.alfresco.repo.action.ActionServiceImplTest.SleepActionExecuter;
|
||||||
@@ -65,22 +74,17 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action tracking service tests. These mostly need
|
* Action tracking service tests. These mostly need careful control over the transactions they use.
|
||||||
* careful control over the transactions they use.
|
|
||||||
*
|
*
|
||||||
* @author Nick Burch
|
* @author Nick Burch
|
||||||
*/
|
*/
|
||||||
@Category(OwnJVMTestsCategory.class)
|
@Category(OwnJVMTestsCategory.class)
|
||||||
public class ActionTrackingServiceImplTest extends TestCase
|
public class ActionTrackingServiceImplTest extends TestCase
|
||||||
{
|
{
|
||||||
private static ConfigurableApplicationContext ctx =
|
private static final Duration MAX_WAIT_TIMEOUT = Duration.ofSeconds(10);
|
||||||
(ConfigurableApplicationContext)ApplicationContextHelper.getApplicationContext();
|
private static ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) ApplicationContextHelper.getApplicationContext();
|
||||||
|
|
||||||
private StoreRef storeRef;
|
private StoreRef storeRef;
|
||||||
private NodeRef rootNodeRef;
|
private NodeRef rootNodeRef;
|
||||||
@@ -112,13 +116,13 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab our beans
|
// Grab our beans
|
||||||
this.nodeService = (NodeService)ctx.getBean("nodeService");
|
this.nodeService = (NodeService) ctx.getBean("nodeService");
|
||||||
this.scriptService = (ScriptService)ctx.getBean("scriptService");
|
this.scriptService = (ScriptService) ctx.getBean("scriptService");
|
||||||
this.actionService = (ActionService)ctx.getBean("actionService");
|
this.actionService = (ActionService) ctx.getBean("actionService");
|
||||||
this.runtimeActionService = (RuntimeActionService)ctx.getBean("actionService");
|
this.runtimeActionService = (RuntimeActionService) ctx.getBean("actionService");
|
||||||
this.actionTrackingService = (ActionTrackingService)ctx.getBean("actionTrackingService");
|
this.actionTrackingService = (ActionTrackingService) ctx.getBean("actionTrackingService");
|
||||||
this.transactionService = (TransactionService)ctx.getBean("transactionService");
|
this.transactionService = (TransactionService) ctx.getBean("transactionService");
|
||||||
this.executingActionsCache = (SimpleCache<String, ExecutionDetails>)ctx.getBean("executingActionsCache");
|
this.executingActionsCache = (SimpleCache<String, ExecutionDetails>) ctx.getBean("executingActionsCache");
|
||||||
|
|
||||||
AuthenticationUtil.setRunAsUserSystem();
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
|
|
||||||
@@ -152,24 +156,23 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
|
|
||||||
// Reset the execution instance IDs, so we
|
// Reset the execution instance IDs, so we
|
||||||
// can predict what they'll be
|
// can predict what they'll be
|
||||||
((ActionTrackingServiceImpl)actionTrackingService).resetNextExecutionId();
|
((ActionTrackingServiceImpl) actionTrackingService).resetNextExecutionId();
|
||||||
|
|
||||||
// Register the test executor, if needed
|
// Register the test executor, if needed
|
||||||
SleepActionExecuter.registerIfNeeded(ctx);
|
SleepActionExecuter.registerIfNeeded(ctx);
|
||||||
|
|
||||||
// We want to know when async actions occur
|
// We want to know when async actions occur
|
||||||
asyncOccurs = new AsyncOccurs();
|
asyncOccurs = new AsyncOccurs();
|
||||||
((PolicyComponent)ctx.getBean("policyComponent")).bindClassBehaviour(
|
((PolicyComponent) ctx.getBean("policyComponent")).bindClassBehaviour(
|
||||||
AsynchronousActionExecutionQueuePolicies.OnAsyncActionExecute.QNAME,
|
AsynchronousActionExecutionQueuePolicies.OnAsyncActionExecute.QNAME,
|
||||||
ActionModel.TYPE_ACTION,
|
ActionModel.TYPE_ACTION,
|
||||||
new JavaBehaviour(asyncOccurs, "onAsyncActionExecute", NotificationFrequency.EVERY_EVENT)
|
new JavaBehaviour(asyncOccurs, "onAsyncActionExecute", NotificationFrequency.EVERY_EVENT));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creating cache keys */
|
/** Creating cache keys */
|
||||||
public void testCreateCacheKeys() throws Exception
|
public void testCreateCacheKeys() throws Exception
|
||||||
{
|
{
|
||||||
ActionImpl action = (ActionImpl)createWorkingSleepAction("1234");
|
ActionImpl action = (ActionImpl) createWorkingSleepAction("1234");
|
||||||
assertEquals("sleep-action", action.getActionDefinitionName());
|
assertEquals("sleep-action", action.getActionDefinitionName());
|
||||||
assertEquals("1234", action.getId());
|
assertEquals("1234", action.getId());
|
||||||
assertEquals(-1, action.getExecutionInstance());
|
assertEquals(-1, action.getExecutionInstance());
|
||||||
@@ -192,7 +195,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
{
|
{
|
||||||
// Create an action with a known execution instance
|
// Create an action with a known execution instance
|
||||||
Action action = createWorkingSleepAction("1234");
|
Action action = createWorkingSleepAction("1234");
|
||||||
((ActionImpl)action).setExecutionInstance(1);
|
((ActionImpl) action).setExecutionInstance(1);
|
||||||
|
|
||||||
// Create the ExecutionSummary from an action
|
// Create the ExecutionSummary from an action
|
||||||
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -228,7 +231,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
/** Running an action gives it an execution ID */
|
/** Running an action gives it an execution ID */
|
||||||
public void testExecutionInstanceAssignment() throws Exception
|
public void testExecutionInstanceAssignment() throws Exception
|
||||||
{
|
{
|
||||||
ActionImpl action = (ActionImpl)createWorkingSleepAction("1234");
|
ActionImpl action = (ActionImpl) createWorkingSleepAction("1234");
|
||||||
assertEquals(-1, action.getExecutionInstance());
|
assertEquals(-1, action.getExecutionInstance());
|
||||||
|
|
||||||
// Have it run, will get the ID of 1
|
// Have it run, will get the ID of 1
|
||||||
@@ -245,8 +248,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The correct things happen with the cache
|
* The correct things happen with the cache when you mark things as working / failed / etc
|
||||||
* when you mark things as working / failed / etc
|
|
||||||
*/
|
*/
|
||||||
public void testInOutCache() throws Exception
|
public void testInOutCache() throws Exception
|
||||||
{
|
{
|
||||||
@@ -256,7 +258,6 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertEquals(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Can complete or fail, won't be there
|
// Can complete or fail, won't be there
|
||||||
actionTrackingService.recordActionComplete(action);
|
actionTrackingService.recordActionComplete(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -269,7 +270,6 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals("Testing", action.getExecutionFailureMessage());
|
assertEquals("Testing", action.getExecutionFailureMessage());
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertEquals(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Pending will add it, but with no start date
|
// Pending will add it, but with no start date
|
||||||
actionTrackingService.recordActionPending(action);
|
actionTrackingService.recordActionPending(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -285,7 +285,6 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(null, d.getPersistedActionRef());
|
assertEquals(null, d.getPersistedActionRef());
|
||||||
assertNull(null, d.getStartedAt());
|
assertNull(null, d.getStartedAt());
|
||||||
|
|
||||||
|
|
||||||
// Run it, will be updated in the cache
|
// Run it, will be updated in the cache
|
||||||
actionTrackingService.recordActionExecuting(action);
|
actionTrackingService.recordActionExecuting(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -301,7 +300,6 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(null, d.getPersistedActionRef());
|
assertEquals(null, d.getPersistedActionRef());
|
||||||
assertNotNull(null, d.getStartedAt());
|
assertNotNull(null, d.getStartedAt());
|
||||||
|
|
||||||
|
|
||||||
// Completion removes it
|
// Completion removes it
|
||||||
actionTrackingService.recordActionComplete(action);
|
actionTrackingService.recordActionComplete(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -319,17 +317,16 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals("Testing", action.getExecutionFailureMessage());
|
assertEquals("Testing", action.getExecutionFailureMessage());
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertEquals(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// If run from new, i.e. not via pending, goes into the cache
|
// If run from new, i.e. not via pending, goes into the cache
|
||||||
((ActionImpl)action).setExecutionStatus(ActionStatus.New);
|
((ActionImpl) action).setExecutionStatus(ActionStatus.New);
|
||||||
((ActionImpl)action).setExecutionStartDate(null);
|
((ActionImpl) action).setExecutionStartDate(null);
|
||||||
((ActionImpl)action).setExecutionEndDate(null);
|
((ActionImpl) action).setExecutionEndDate(null);
|
||||||
((ActionImpl)action).setExecutionFailureMessage(null);
|
((ActionImpl) action).setExecutionFailureMessage(null);
|
||||||
((ActionImpl)action).setExecutionInstance(-1);
|
((ActionImpl) action).setExecutionInstance(-1);
|
||||||
|
|
||||||
actionTrackingService.recordActionExecuting(action);
|
actionTrackingService.recordActionExecuting(action);
|
||||||
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
||||||
assertTrue( ((ActionImpl)action).getExecutionInstance() != -1 );
|
assertTrue(((ActionImpl) action).getExecutionInstance() != -1);
|
||||||
|
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
assertNotNull(null, executingActionsCache.get(key));
|
assertNotNull(null, executingActionsCache.get(key));
|
||||||
@@ -343,8 +340,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
/** Working actions go into the cache, then out */
|
/** Working actions go into the cache, then out */
|
||||||
public void testWorkingActions() throws Exception
|
public void testWorkingActions() throws Exception
|
||||||
{
|
{
|
||||||
final SleepActionExecuter sleepActionExec =
|
final SleepActionExecuter sleepActionExec = (SleepActionExecuter) ctx.getBean(SleepActionExecuter.NAME);
|
||||||
(SleepActionExecuter)ctx.getBean(SleepActionExecuter.NAME);
|
|
||||||
sleepActionExec.resetTimesExecuted();
|
sleepActionExec.resetTimesExecuted();
|
||||||
sleepActionExec.setSleepMs(10000);
|
sleepActionExec.setSleepMs(10000);
|
||||||
|
|
||||||
@@ -362,17 +358,15 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
|
|
||||||
this.actionService.executeAction(action, this.nodeRef, false, true);
|
this.actionService.executeAction(action, this.nodeRef, false, true);
|
||||||
|
|
||||||
|
|
||||||
// End the transaction. Should allow the async action
|
// End the transaction. Should allow the async action
|
||||||
// to start up, and begin sleeping
|
// to start up, and begin sleeping
|
||||||
txn.commit();
|
txn.commit();
|
||||||
Thread.sleep(150);
|
waitUntilActionHasStarted(action);
|
||||||
|
|
||||||
// The action should now be running
|
// The action should now be running
|
||||||
// It will have got an execution instance id, so a new key
|
// It will have got an execution instance id, so a new key
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
|
|
||||||
|
|
||||||
// Check it's in the cache
|
// Check it's in the cache
|
||||||
System.out.println("Checking the cache for " + key);
|
System.out.println("Checking the cache for " + key);
|
||||||
assertNotNull(executingActionsCache.get(key));
|
assertNotNull(executingActionsCache.get(key));
|
||||||
@@ -386,12 +380,10 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(null, d.getPersistedActionRef());
|
assertEquals(null, d.getPersistedActionRef());
|
||||||
assertNotNull(null, d.getStartedAt());
|
assertNotNull(null, d.getStartedAt());
|
||||||
|
|
||||||
|
|
||||||
// Tell it to stop sleeping
|
// Tell it to stop sleeping
|
||||||
// Then wait for it to finish
|
// Then wait for it to finish
|
||||||
asyncOccurs.awaitExecution(null, sleepActionExec.getExecutingThread(), action.getActionDefinitionName());
|
asyncOccurs.awaitExecution(null, sleepActionExec.getExecutingThread(), action.getActionDefinitionName());
|
||||||
|
|
||||||
|
|
||||||
// Ensure it went away again
|
// Ensure it went away again
|
||||||
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
|
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertEquals(null, executingActionsCache.get(key));
|
||||||
@@ -432,18 +424,18 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertNull(action.getExecutionFailureMessage());
|
assertNull(action.getExecutionFailureMessage());
|
||||||
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
||||||
|
|
||||||
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
var beforeExecKey = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertNull(executingActionsCache.get(beforeExecKey));
|
||||||
|
|
||||||
this.actionService.executeAction(action, this.nodeRef, false, true);
|
this.actionService.executeAction(action, this.nodeRef, false, true);
|
||||||
|
|
||||||
// End the transaction. Should allow the async action
|
// End the transaction. Should allow the async action
|
||||||
// to be started, and move into its sleeping phase
|
// to be started, and move into its sleeping phase
|
||||||
txn.commit();
|
txn.commit();
|
||||||
Thread.sleep(150);
|
waitUntilActionHasStarted(action);
|
||||||
|
|
||||||
// Will get an execution instance id, so a new key
|
// Will get an execution instance id, so a new key
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
var key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
|
|
||||||
// Check it's in the cache
|
// Check it's in the cache
|
||||||
System.out.println("Checking the cache for " + key);
|
System.out.println("Checking the cache for " + key);
|
||||||
@@ -455,40 +447,22 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals("sleep-action", d.getActionType());
|
assertEquals("sleep-action", d.getActionType());
|
||||||
assertEquals(actionId, d.getActionId());
|
assertEquals(actionId, d.getActionId());
|
||||||
assertEquals(1, d.getExecutionInstance());
|
assertEquals(1, d.getExecutionInstance());
|
||||||
assertEquals(null, d.getPersistedActionRef());
|
assertNull(d.getPersistedActionRef());
|
||||||
|
|
||||||
// let's be more resilient and try a number of times with a delay
|
// let's be more resilient and try a number of times with a delay
|
||||||
long start = System.currentTimeMillis();
|
await().atMost(MAX_WAIT_TIMEOUT).until(() -> nonNull(d.getStartedAt()));
|
||||||
int sleepTime = 1000; // 1s
|
assertNotNull("Started at time is null, the action has not yet started after 10s", d.getStartedAt());
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
if (d.getStartedAt() == null)
|
|
||||||
{
|
|
||||||
Thread.sleep(sleepTime);
|
|
||||||
sleepTime += 100; // increase by 100ms
|
|
||||||
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
|
// Tell it to stop sleeping
|
||||||
// Then wait for it to finish and go bang
|
// Then wait for it to finish and go bang
|
||||||
// (Need to do it by hand, as it won't fire the complete policy
|
// (Need to do it by hand, as it won't fire the complete policy
|
||||||
// as the action has failed)
|
// as the action has failed)
|
||||||
sleepActionExec.getExecutingThread().interrupt();
|
sleepActionExec.getExecutingThread().interrupt();
|
||||||
Thread.sleep(150);
|
await().atMost(MAX_WAIT_TIMEOUT).until(() -> isNull(executingActionsCache.get(key)));
|
||||||
|
|
||||||
// Ensure it went away again
|
// Ensure it went away again
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertNull(executingActionsCache.get(key));
|
||||||
|
assertNull(actionTrackingService.getExecutionDetails(s));
|
||||||
d = actionTrackingService.getExecutionDetails(s);
|
|
||||||
assertEquals(null, d);
|
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
@@ -501,8 +475,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
assertEquals(ActionStatus.New, action.getExecutionStatus());
|
||||||
|
|
||||||
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
String key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertNull(executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Ask for it to be pending, will go in
|
// Ask for it to be pending, will go in
|
||||||
actionTrackingService.recordActionPending(action);
|
actionTrackingService.recordActionPending(action);
|
||||||
@@ -516,9 +489,8 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals("sleep-action", d.getActionType());
|
assertEquals("sleep-action", d.getActionType());
|
||||||
assertEquals("1234", d.getActionId());
|
assertEquals("1234", d.getActionId());
|
||||||
assertEquals(1, d.getExecutionInstance());
|
assertEquals(1, d.getExecutionInstance());
|
||||||
assertEquals(null, d.getPersistedActionRef());
|
assertNull(d.getPersistedActionRef());
|
||||||
assertNull(null, d.getStartedAt());
|
assertNull(d.getStartedAt());
|
||||||
|
|
||||||
|
|
||||||
// Run it, will stay
|
// Run it, will stay
|
||||||
actionTrackingService.recordActionExecuting(action);
|
actionTrackingService.recordActionExecuting(action);
|
||||||
@@ -535,14 +507,12 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(null, d.getPersistedActionRef());
|
assertEquals(null, d.getPersistedActionRef());
|
||||||
assertNotNull(d.getStartedAt());
|
assertNotNull(d.getStartedAt());
|
||||||
|
|
||||||
|
|
||||||
// Finish, goes
|
// Finish, goes
|
||||||
actionTrackingService.recordActionComplete(action);
|
actionTrackingService.recordActionComplete(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
|
assertEquals(ActionStatus.Completed, action.getExecutionStatus());
|
||||||
assertEquals(null, executingActionsCache.get(key));
|
assertEquals(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Put another pending one in
|
// Put another pending one in
|
||||||
action = createWorkingSleepAction("1234");
|
action = createWorkingSleepAction("1234");
|
||||||
actionTrackingService.recordActionPending(action);
|
actionTrackingService.recordActionPending(action);
|
||||||
@@ -550,22 +520,19 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
|
assertEquals(ActionStatus.Pending, action.getExecutionStatus());
|
||||||
assertNotNull(null, executingActionsCache.get(key));
|
assertNotNull(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Remove it by hand
|
// Remove it by hand
|
||||||
executingActionsCache.remove(key);
|
executingActionsCache.remove(key);
|
||||||
assertNull(null, executingActionsCache.get(key));
|
assertNull(null, executingActionsCache.get(key));
|
||||||
int instanceId = ((ActionImpl)action).getExecutionInstance();
|
int instanceId = ((ActionImpl) action).getExecutionInstance();
|
||||||
|
|
||||||
|
|
||||||
// Run it, will go back in again, ID unchanged
|
// Run it, will go back in again, ID unchanged
|
||||||
actionTrackingService.recordActionExecuting(action);
|
actionTrackingService.recordActionExecuting(action);
|
||||||
assertEquals(key, ActionTrackingServiceImpl.generateCacheKey(action));
|
assertEquals(key, ActionTrackingServiceImpl.generateCacheKey(action));
|
||||||
assertEquals(instanceId, ((ActionImpl)action).getExecutionInstance());
|
assertEquals(instanceId, ((ActionImpl) action).getExecutionInstance());
|
||||||
|
|
||||||
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
assertEquals(ActionStatus.Running, action.getExecutionStatus());
|
||||||
assertNotNull(null, executingActionsCache.get(key));
|
assertNotNull(null, executingActionsCache.get(key));
|
||||||
|
|
||||||
|
|
||||||
// Finish, will go again
|
// Finish, will go again
|
||||||
actionTrackingService.recordActionComplete(action);
|
actionTrackingService.recordActionComplete(action);
|
||||||
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
key = ActionTrackingServiceImpl.generateCacheKey(action);
|
||||||
@@ -663,7 +630,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
actionTrackingService.recordActionComplete(moveAction);
|
actionTrackingService.recordActionComplete(moveAction);
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
Thread.sleep(50);
|
await().atMost(MAX_WAIT_TIMEOUT).until(() -> actionTrackingService.getAllExecutingActions(), n -> CollectionUtils.size(n) == 2);
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
assertEquals(2, actionTrackingService.getAllExecutingActions().size());
|
assertEquals(2, actionTrackingService.getAllExecutingActions().size());
|
||||||
@@ -728,7 +695,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
// End the transaction. Should allow the async action
|
// End the transaction. Should allow the async action
|
||||||
// to be started
|
// to be started
|
||||||
txn.commit();
|
txn.commit();
|
||||||
Thread.sleep(150);
|
waitUntilActionHasStarted(sleepAction3);
|
||||||
|
|
||||||
// Get the updated key, and check
|
// Get the updated key, and check
|
||||||
key3 = ActionTrackingServiceImpl.generateCacheKey(sleepAction3);
|
key3 = ActionTrackingServiceImpl.generateCacheKey(sleepAction3);
|
||||||
@@ -747,7 +714,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
// Have it finish sleeping, will have been cancelled
|
// Have it finish sleeping, will have been cancelled
|
||||||
// (Can't use the policy, as cancel is counted as a failure)
|
// (Can't use the policy, as cancel is counted as a failure)
|
||||||
sleepActionExec.getExecutingThread().interrupt();
|
sleepActionExec.getExecutingThread().interrupt();
|
||||||
Thread.sleep(150);
|
await().atMost(MAX_WAIT_TIMEOUT).until(sleepAction3::getExecutionStatus, ActionStatus.Cancelled::equals);
|
||||||
|
|
||||||
// Ensure the proper cancelled tracking
|
// Ensure the proper cancelled tracking
|
||||||
assertEquals(ActionStatus.Cancelled, sleepAction3.getExecutionStatus());
|
assertEquals(ActionStatus.Cancelled, sleepAction3.getExecutionStatus());
|
||||||
@@ -756,321 +723,6 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
|
|
||||||
// =================================================================== //
|
// =================================================================== //
|
||||||
|
|
||||||
/**
|
|
||||||
* 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());
|
|
||||||
Thread.sleep(250); // Need to allow the post-commit update to the stored node
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testJavascriptAPI() throws Exception
|
public void testJavascriptAPI() throws Exception
|
||||||
{
|
{
|
||||||
// We need a background action to sleep for long enough for
|
// We need a background action to sleep for long enough for
|
||||||
@@ -1168,8 +820,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1188,8 +839,7 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param isFatal
|
* @param isFatal
|
||||||
* <tt>true</tt> means the sleep action will fail with a RuntimeException, <tt>false</tt> means it will
|
* <tt>true</tt> means the sleep action will fail with a RuntimeException, <tt>false</tt> means it will fail with a {@link ActionServiceTransientException}.
|
||||||
* fail with a {@link ActionServiceTransientException}.
|
|
||||||
*/
|
*/
|
||||||
private Action createFailingSleepAction(String id, boolean isFatal) throws Exception
|
private Action createFailingSleepAction(String id, boolean isFatal) throws Exception
|
||||||
{
|
{
|
||||||
@@ -1200,4 +850,9 @@ public class ActionTrackingServiceImplTest extends TestCase
|
|||||||
{
|
{
|
||||||
return ActionServiceImplTest.createWorkingSleepAction(id, actionService);
|
return ActionServiceImplTest.createWorkingSleepAction(id, actionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void waitUntilActionHasStarted(Action action)
|
||||||
|
{
|
||||||
|
await().atMost(MAX_WAIT_TIMEOUT).until(action::getExecutionStartDate, Objects::nonNull);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -26,10 +26,16 @@
|
|||||||
package org.alfresco.repo.action.evaluator;
|
package org.alfresco.repo.action.evaluator;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ActionConditionImpl;
|
import org.alfresco.repo.action.ActionConditionImpl;
|
||||||
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
|
import org.alfresco.repo.action.evaluator.compare.ComparePropertyValueOperation;
|
||||||
@@ -54,10 +60,6 @@ import org.alfresco.service.namespace.NamespaceService;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.BaseSpringTest;
|
import org.alfresco.util.BaseSpringTest;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare property value evaluator test
|
* Compare property value evaluator test
|
||||||
@@ -99,9 +101,9 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
// Need to create model to contain our custom type
|
// Need to create model to contain our custom type
|
||||||
createTestModel();
|
createTestModel();
|
||||||
|
|
||||||
this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
|
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
|
||||||
this.contentService = (ContentService)this.applicationContext.getBean("contentService");
|
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
|
||||||
actionService = (ActionService)applicationContext.getBean("actionService");
|
actionService = (ActionService) applicationContext.getBean("actionService");
|
||||||
|
|
||||||
// Create the store and get the root node
|
// Create the store and get the root node
|
||||||
this.testStoreRef = this.nodeService.createStore(
|
this.testStoreRef = this.nodeService.createStore(
|
||||||
@@ -111,11 +113,10 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
|
|
||||||
this.nodeValue = this.rootNodeRef;
|
this.nodeValue = this.rootNodeRef;
|
||||||
|
|
||||||
this.beforeDateValue = new Date();
|
var now = Instant.now();
|
||||||
Thread.sleep(2000);
|
this.beforeDateValue = Date.from(now.minusSeconds(4));
|
||||||
this.dateValue = new Date();
|
this.dateValue = Date.from(now.minusSeconds(2));
|
||||||
Thread.sleep(2000);
|
this.afterDateValue = Date.from(now);
|
||||||
this.afterDateValue = new Date();
|
|
||||||
|
|
||||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||||
props.put(PROP_TEXT, TEXT_VALUE);
|
props.put(PROP_TEXT, TEXT_VALUE);
|
||||||
@@ -132,7 +133,7 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
TEST_TYPE_QNAME,
|
TEST_TYPE_QNAME,
|
||||||
props).getChildRef();
|
props).getChildRef();
|
||||||
|
|
||||||
this.evaluator = (ComparePropertyValueEvaluator)this.applicationContext.getBean(ComparePropertyValueEvaluator.NAME);
|
this.evaluator = (ComparePropertyValueEvaluator) this.applicationContext.getBean(ComparePropertyValueEvaluator.NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -226,11 +227,34 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
// Ensure other operators are invalid
|
// Ensure other operators are invalid
|
||||||
|
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,11 +333,34 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
// Ensure other operators are invalid
|
// Ensure other operators are invalid
|
||||||
|
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -388,13 +435,43 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
// Ensure other operators are invalid
|
// Ensure other operators are invalid
|
||||||
|
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {exception.printStackTrace();};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,19 +524,70 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
// Ensure other operators are invalid
|
// Ensure other operators are invalid
|
||||||
|
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.BEGINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) { exception.printStackTrace();};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.ENDS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.CONTAINS.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.GREATER_THAN_EQUAL.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_OPERATION, ComparePropertyValueOperation.LESS_THAN_EQUAL.toString());
|
||||||
try { this.evaluator.evaluate(condition, this.nodeRef); fail("An exception should have been raised here."); } catch (ActionServiceException exception) {};
|
try
|
||||||
|
{
|
||||||
|
this.evaluator.evaluate(condition, this.nodeRef);
|
||||||
|
fail("An exception should have been raised here.");
|
||||||
|
}
|
||||||
|
catch (ActionServiceException exception)
|
||||||
|
{}
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +627,6 @@ public class ComparePropertyValueEvaluatorTest extends BaseSpringTest
|
|||||||
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_VALUE, 2);
|
condition.setParameterValue(ComparePropertyValueEvaluator.PARAM_VALUE, 2);
|
||||||
assertFalse(this.evaluator.evaluate(condition, this.nodeRef));
|
assertFalse(this.evaluator.evaluate(condition, this.nodeRef));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -23,26 +23,23 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* Copyright (C) 2005 Jesper Steen M<>ller
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.repo.action.executer;
|
package org.alfresco.repo.action.executer;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.test.context.transaction.TestTransaction;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ActionImpl;
|
import org.alfresco.repo.action.ActionImpl;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
@@ -63,17 +60,6 @@ import org.alfresco.service.transaction.TransactionService;
|
|||||||
import org.alfresco.test_category.BaseSpringTestsCategory;
|
import org.alfresco.test_category.BaseSpringTestsCategory;
|
||||||
import org.alfresco.util.BaseSpringTest;
|
import org.alfresco.util.BaseSpringTest;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.test.context.transaction.TestTransaction;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of the ActionExecuter for extracting metadata.
|
* Test of the ActionExecuter for extracting metadata.
|
||||||
@@ -108,7 +94,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
registry = (MetadataExtracterRegistry) applicationContext.getBean("metadataExtracterRegistry");
|
registry = (MetadataExtracterRegistry) applicationContext.getBean("metadataExtracterRegistry");
|
||||||
transactionService = (TransactionService) this.applicationContext.getBean("transactionService");
|
transactionService = (TransactionService) this.applicationContext.getBean("transactionService");
|
||||||
|
|
||||||
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
|
AuthenticationComponent authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
|
||||||
authenticationComponent.setSystemUserAsCurrentUser();
|
authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
// Create the store and get the root node
|
// Create the store and get the root node
|
||||||
@@ -154,8 +140,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
TestTransaction.end();
|
TestTransaction.end();
|
||||||
|
|
||||||
// Execute the action
|
// Execute the action
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
|
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
|
||||||
@@ -164,11 +149,13 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Thread.sleep(3000); // Need to wait for the async extract
|
// Need to wait for the async extract
|
||||||
|
await().pollInSameThread()
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT)
|
||||||
|
.until(() -> nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION), Objects::nonNull);
|
||||||
|
|
||||||
// Check that the properties have been set
|
// Check that the properties have been set
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
assertEquals(QUICK_TITLE, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
|
assertEquals(QUICK_TITLE, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
|
||||||
@@ -181,6 +168,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
|
|
||||||
private static final QName PROP_UNKNOWN_1 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown1");
|
private static final QName PROP_UNKNOWN_1 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown1");
|
||||||
private static final QName PROP_UNKNOWN_2 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown2");
|
private static final QName PROP_UNKNOWN_2 = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "unkown2");
|
||||||
|
|
||||||
private static class TestUnknownMetadataExtracter extends AbstractMappingMetadataExtracter
|
private static class TestUnknownMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||||
{
|
{
|
||||||
public TestUnknownMetadataExtracter()
|
public TestUnknownMetadataExtracter()
|
||||||
@@ -190,12 +178,14 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
mappingProperties.put("unknown2", PROP_UNKNOWN_2.toString());
|
mappingProperties.put("unknown2", PROP_UNKNOWN_2.toString());
|
||||||
setMappingProperties(mappingProperties);
|
setMappingProperties(mappingProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Set<QName>> getDefaultMapping()
|
protected Map<String, Set<QName>> getDefaultMapping()
|
||||||
{
|
{
|
||||||
// No need to give anything back as we have explicitly set the mapping already
|
// No need to give anything back as we have explicitly set the mapping already
|
||||||
return new HashMap<String, Set<QName>>(0);
|
return new HashMap<String, Set<QName>>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(String sourceMimetype)
|
public boolean isSupported(String sourceMimetype)
|
||||||
{
|
{
|
||||||
@@ -242,12 +232,14 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
mappingProperties.put("description", ContentModel.PROP_DESCRIPTION.toString());
|
mappingProperties.put("description", ContentModel.PROP_DESCRIPTION.toString());
|
||||||
setMappingProperties(mappingProperties);
|
setMappingProperties(mappingProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Set<QName>> getDefaultMapping()
|
protected Map<String, Set<QName>> getDefaultMapping()
|
||||||
{
|
{
|
||||||
// No need to give anything back as we have explicitly set the mapping already
|
// No need to give anything back as we have explicitly set the mapping already
|
||||||
return new HashMap<String, Set<QName>>(0);
|
return new HashMap<String, Set<QName>>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(String sourceMimetype)
|
public boolean isSupported(String sourceMimetype)
|
||||||
{
|
{
|
||||||
@@ -264,9 +256,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that missing raw values result in node properties being removed
|
* Ensure that missing raw values result in node properties being removed when running with {@link ContentMetadataExtracter#setCarryAspectProperties(boolean)} set to <tt>false</tt>.
|
||||||
* when running with {@link ContentMetadataExtracter#setCarryAspectProperties(boolean)}
|
|
||||||
* set to <tt>false</tt>.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNullExtractedValues_ALF1823()
|
public void testNullExtractedValues_ALF1823()
|
||||||
@@ -335,8 +325,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
TestTransaction.end();
|
TestTransaction.end();
|
||||||
|
|
||||||
// Execute the action
|
// Execute the action
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
|
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
|
||||||
@@ -345,11 +334,13 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Thread.sleep(3000); // Need to wait for the async extract
|
// Need to wait for the async extract
|
||||||
|
await().pollInSameThread()
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT)
|
||||||
|
.until(() -> nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION), Objects::nonNull);
|
||||||
|
|
||||||
// Check that the properties have been preserved, but that description has been set
|
// Check that the properties have been preserved, but that description has been set
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
|
||||||
{
|
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
{
|
{
|
||||||
assertEquals(myTitle, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
|
assertEquals(myTitle, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,16 +25,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.content.caching.cleanup;
|
package org.alfresco.repo.content.caching.cleanup;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
import org.alfresco.repo.content.caching.CacheFileProps;
|
import org.alfresco.repo.content.caching.CacheFileProps;
|
||||||
import org.alfresco.repo.content.caching.CachingContentStore;
|
import org.alfresco.repo.content.caching.CachingContentStore;
|
||||||
import org.alfresco.repo.content.caching.ContentCacheImpl;
|
import org.alfresco.repo.content.caching.ContentCacheImpl;
|
||||||
@@ -43,12 +54,6 @@ import org.alfresco.service.cmr.repository.ContentReader;
|
|||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.testing.category.LuceneTests;
|
import org.alfresco.util.testing.category.LuceneTests;
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the CachedContentCleanupJob
|
* Tests for the CachedContentCleanupJob
|
||||||
@@ -58,22 +63,29 @@ import org.springframework.context.ApplicationContext;
|
|||||||
@Category(LuceneTests.class)
|
@Category(LuceneTests.class)
|
||||||
public class CachedContentCleanupJobTest
|
public class CachedContentCleanupJobTest
|
||||||
{
|
{
|
||||||
private enum UrlSource { PROPS_FILE, REVERSE_CACHE_LOOKUP, NOT_PRESENT };
|
|
||||||
|
private static final Duration MAX_WAIT_TIMEOUT = Duration.ofSeconds(10);
|
||||||
|
|
||||||
|
private enum UrlSource
|
||||||
|
{
|
||||||
|
PROPS_FILE, REVERSE_CACHE_LOOKUP, NOT_PRESENT
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
private static ApplicationContext ctx;
|
private static ApplicationContext ctx;
|
||||||
private CachingContentStore cachingStore;
|
private CachingContentStore cachingStore;
|
||||||
private ContentCacheImpl cache;
|
private ContentCacheImpl cache;
|
||||||
private File cacheRoot;
|
private File cacheRoot;
|
||||||
private CachedContentCleaner cleaner;
|
private CachedContentCleaner cleaner;
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass()
|
public static void beforeClass()
|
||||||
{
|
{
|
||||||
String cleanerConf = "classpath:cachingstore/test-cleaner-context.xml";
|
String cleanerConf = "classpath:cachingstore/test-cleaner-context.xml";
|
||||||
ctx = ApplicationContextHelper.getApplicationContext(new String[] { cleanerConf });
|
ctx = ApplicationContextHelper.getApplicationContext(new String[]{cleanerConf});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws IOException
|
public void setUp() throws IOException
|
||||||
{
|
{
|
||||||
@@ -89,7 +101,6 @@ public class CachedContentCleanupJobTest
|
|||||||
FileUtils.cleanDirectory(cacheRoot);
|
FileUtils.cleanDirectory(cacheRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void filesNotInCacheAreDeleted() throws InterruptedException
|
public void filesNotInCacheAreDeleted() throws InterruptedException
|
||||||
{
|
{
|
||||||
@@ -112,11 +123,9 @@ public class CachedContentCleanupJobTest
|
|||||||
// Run cleaner
|
// Run cleaner
|
||||||
cleaner.execute();
|
cleaner.execute();
|
||||||
|
|
||||||
Thread.sleep(400);
|
await().pollDelay(Duration.ofMillis(100))
|
||||||
while (cleaner.isRunning())
|
.atMost(MAX_WAIT_TIMEOUT)
|
||||||
{
|
.until(() -> !cleaner.isRunning());
|
||||||
Thread.sleep(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check all files deleted
|
// check all files deleted
|
||||||
for (File file : files)
|
for (File file : files)
|
||||||
@@ -128,7 +137,6 @@ public class CachedContentCleanupJobTest
|
|||||||
assertEquals("Incorrect total size of files deleted", totalSize, cleaner.getSizeFilesDeleted());
|
assertEquals("Incorrect total size of files deleted", totalSize, cleaner.getSizeFilesDeleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void filesNewerThanMinFileAgeMillisAreNotDeleted() throws InterruptedException
|
public void filesNewerThanMinFileAgeMillisAreNotDeleted() throws InterruptedException
|
||||||
{
|
{
|
||||||
@@ -154,16 +162,13 @@ public class CachedContentCleanupJobTest
|
|||||||
newFilesTotalSize += newFiles[i].length();
|
newFilesTotalSize += newFiles[i].length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The cleaner must finish before any of the newFiles are older than minFileAge. If the files are too
|
// The cleaner must finish before any of the newFiles are older than minFileAge. If the files are too
|
||||||
// old the test will fail and it will be necessary to rethink how to test this.
|
// old the test will fail and it will be necessary to rethink how to test this.
|
||||||
cleaner.execute();
|
cleaner.execute();
|
||||||
|
|
||||||
Thread.sleep(400);
|
await().pollDelay(Duration.ofMillis(100))
|
||||||
while (cleaner.isRunning())
|
.atMost(MAX_WAIT_TIMEOUT)
|
||||||
{
|
.until(() -> !cleaner.isRunning());
|
||||||
Thread.sleep(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cleaner.getDurationMillis() > minFileAge)
|
if (cleaner.getDurationMillis() > minFileAge)
|
||||||
{
|
{
|
||||||
@@ -224,14 +229,13 @@ public class CachedContentCleanupJobTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// How many were definitely deleted?
|
// How many were definitely deleted?
|
||||||
assertEquals("Wrong number of files deleted", 7 , numDeleted);
|
assertEquals("Wrong number of files deleted", 7, numDeleted);
|
||||||
|
|
||||||
// The cleaner should have recorded the correct number of deletions
|
// The cleaner should have recorded the correct number of deletions
|
||||||
assertEquals("Incorrect number of deleted files", 7, cleaner.getNumFilesDeleted());
|
assertEquals("Incorrect number of deleted files", 7, cleaner.getNumFilesDeleted());
|
||||||
assertEquals("Incorrect total size of files deleted", sevenFilesSize, cleaner.getSizeFilesDeleted());
|
assertEquals("Incorrect total size of files deleted", sevenFilesSize, cleaner.getSizeFilesDeleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void standardCleanAfterAggressiveFinished() throws InterruptedException
|
public void standardCleanAfterAggressiveFinished() throws InterruptedException
|
||||||
{
|
{
|
||||||
@@ -239,7 +243,6 @@ public class CachedContentCleanupJobTest
|
|||||||
final int numFiles = 30;
|
final int numFiles = 30;
|
||||||
File[] files = new File[numFiles];
|
File[] files = new File[numFiles];
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < numFiles; i++)
|
for (int i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
Calendar calendar = new GregorianCalendar(2010, 11, 2, 17, i);
|
Calendar calendar = new GregorianCalendar(2010, 11, 2, 17, i);
|
||||||
@@ -286,7 +289,7 @@ public class CachedContentCleanupJobTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals("Incorrect number of deleted files", 11, cleaner.getNumFilesDeleted());
|
assertEquals("Incorrect number of deleted files", 11, cleaner.getNumFilesDeleted());
|
||||||
assertEquals("Incorrect total size of files deleted", (11*fileSize), cleaner.getSizeFilesDeleted());
|
assertEquals("Incorrect total size of files deleted", (11 * fileSize), cleaner.getSizeFilesDeleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -343,7 +346,6 @@ public class CachedContentCleanupJobTest
|
|||||||
checkFilesDeleted(file);
|
checkFilesDeleted(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkFilesDeleted(File file)
|
private void checkFilesDeleted(File file)
|
||||||
{
|
{
|
||||||
assertFalse("File should have been deleted: " + file, file.exists());
|
assertFalse("File should have been deleted: " + file, file.exists());
|
||||||
@@ -351,7 +353,6 @@ public class CachedContentCleanupJobTest
|
|||||||
assertFalse("Properties file should have been deleted, cache file: " + file, props.exists());
|
assertFalse("Properties file should have been deleted, cache file: " + file, props.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkWatchCountForCacheFile(File file, Integer expectedWatchCount)
|
private void checkWatchCountForCacheFile(File file, Integer expectedWatchCount)
|
||||||
{
|
{
|
||||||
assertTrue("File should still exist: " + file, file.exists());
|
assertTrue("File should still exist: " + file, file.exists());
|
||||||
@@ -360,7 +361,6 @@ public class CachedContentCleanupJobTest
|
|||||||
assertEquals("File should contain correct deleteWatchCount", expectedWatchCount, props.getDeleteWatchCount());
|
assertEquals("File should contain correct deleteWatchCount", expectedWatchCount, props.getDeleteWatchCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void filesInCacheAreNotDeleted() throws InterruptedException
|
public void filesInCacheAreNotDeleted() throws InterruptedException
|
||||||
{
|
{
|
||||||
@@ -397,7 +397,7 @@ public class CachedContentCleanupJobTest
|
|||||||
return createCacheFile(calendar, urlSource, putInCache);
|
return createCacheFile(calendar, urlSource, putInCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
private File createCacheFile(Calendar calendar, /*int year, int month, int day, int hour, int minute,*/
|
private File createCacheFile(Calendar calendar, /* int year, int month, int day, int hour, int minute, */
|
||||||
UrlSource urlSource, boolean putInCache)
|
UrlSource urlSource, boolean putInCache)
|
||||||
{
|
{
|
||||||
File file = new File(cacheRoot, createNewCacheFilePath(calendar));
|
File file = new File(cacheRoot, createNewCacheFilePath(calendar));
|
||||||
@@ -410,7 +410,7 @@ public class CachedContentCleanupJobTest
|
|||||||
cache.putIntoLookup(Key.forUrl(contentUrl), file.getAbsolutePath());
|
cache.putIntoLookup(Key.forUrl(contentUrl), file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(urlSource)
|
switch (urlSource)
|
||||||
{
|
{
|
||||||
case NOT_PRESENT:
|
case NOT_PRESENT:
|
||||||
// cache won't be able to determine original content URL for the file
|
// cache won't be able to determine original content URL for the file
|
||||||
@@ -429,12 +429,11 @@ public class CachedContentCleanupJobTest
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mimick functionality of ContentCacheImpl.createNewCacheFilePath()
|
* Mimick functionality of ContentCacheImpl.createNewCacheFilePath() but allowing a specific date (rather than 'now') to be used.
|
||||||
* but allowing a specific date (rather than 'now') to be used.
|
|
||||||
*
|
*
|
||||||
* @param calendar Calendar
|
* @param calendar
|
||||||
|
* Calendar
|
||||||
* @return Path to use for cache file.
|
* @return Path to use for cache file.
|
||||||
*/
|
*/
|
||||||
private String createNewCacheFilePath(Calendar calendar)
|
private String createNewCacheFilePath(Calendar calendar)
|
||||||
@@ -455,13 +454,11 @@ public class CachedContentCleanupJobTest
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String makeContentUrl()
|
private String makeContentUrl()
|
||||||
{
|
{
|
||||||
return "protocol://some/made/up/url/" + GUID.generate();
|
return "protocol://some/made/up/url/" + GUID.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeSampleContent(File file)
|
private void writeSampleContent(File file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,10 +25,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.lock;
|
package org.alfresco.repo.lock;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.secure;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.node.archive.NodeArchiveService;
|
import org.alfresco.repo.node.archive.NodeArchiveService;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
@@ -48,10 +57,6 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
import org.alfresco.util.BaseSpringTest;
|
import org.alfresco.util.BaseSpringTest;
|
||||||
import org.alfresco.util.TestWithUserUtils;
|
import org.alfresco.util.TestWithUserUtils;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LockBehaviourImpl Unit Test.
|
* LockBehaviourImpl Unit Test.
|
||||||
@@ -109,7 +114,7 @@ public class LockBehaviourImplTest extends BaseSpringTest
|
|||||||
/**
|
/**
|
||||||
* User details
|
* User details
|
||||||
*/
|
*/
|
||||||
private static final String PWD = "password";
|
private static final String PWD = secure().nextAlphabetic(10);
|
||||||
private static final String GOOD_USER_NAME = "goodUser";
|
private static final String GOOD_USER_NAME = "goodUser";
|
||||||
private static final String BAD_USER_NAME = "badUser";
|
private static final String BAD_USER_NAME = "badUser";
|
||||||
private static final String BAD_USER_WITH_ALL_PERMS_NAME = "badUserOwns";
|
private static final String BAD_USER_WITH_ALL_PERMS_NAME = "badUserOwns";
|
||||||
@@ -119,16 +124,16 @@ public class LockBehaviourImplTest extends BaseSpringTest
|
|||||||
@Before
|
@Before
|
||||||
public void before() throws Exception
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
this.nodeService = (NodeService)applicationContext.getBean("dbNodeService");
|
this.nodeService = (NodeService) applicationContext.getBean("dbNodeService");
|
||||||
this.lockService = (LockService)applicationContext.getBean("lockService");
|
this.lockService = (LockService) applicationContext.getBean("lockService");
|
||||||
this.versionService = (VersionService)applicationContext.getBean("versionService");
|
this.versionService = (VersionService) applicationContext.getBean("versionService");
|
||||||
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("authenticationService");
|
this.authenticationService = (MutableAuthenticationService) applicationContext.getBean("authenticationService");
|
||||||
this.permissionService = (PermissionService)applicationContext.getBean("permissionService");
|
this.permissionService = (PermissionService) applicationContext.getBean("permissionService");
|
||||||
this.copyService = (CopyService)applicationContext.getBean("copyService");
|
this.copyService = (CopyService) applicationContext.getBean("copyService");
|
||||||
this.nodeArchiveService = (NodeArchiveService)applicationContext.getBean("nodeArchiveService");
|
this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");
|
||||||
|
|
||||||
// Set the authentication
|
// Set the authentication
|
||||||
AuthenticationComponent authComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
|
AuthenticationComponent authComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
|
||||||
authComponent.setSystemUserAsCurrentUser();
|
authComponent.setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
// Create the node properties
|
// Create the node properties
|
||||||
@@ -292,7 +297,10 @@ public class LockBehaviourImplTest extends BaseSpringTest
|
|||||||
assertTrue(lockService.isLocked(nodeRef));
|
assertTrue(lockService.isLocked(nodeRef));
|
||||||
assertTrue(lockService.isLockedAndReadOnly(nodeRef));
|
assertTrue(lockService.isLockedAndReadOnly(nodeRef));
|
||||||
|
|
||||||
try {Thread.sleep(2*1000); } catch (Exception e) {};
|
await().pollInSameThread()
|
||||||
|
.pollDelay(Duration.ofMillis(500))
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT)
|
||||||
|
.until(() -> !lockService.isLocked(nodeRef));
|
||||||
|
|
||||||
// Should now have expired so the node should no longer appear to be locked
|
// Should now have expired so the node should no longer appear to be locked
|
||||||
this.lockService.checkForLock(this.nodeRef);
|
this.lockService.checkForLock(this.nodeRef);
|
||||||
@@ -372,7 +380,6 @@ public class LockBehaviourImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the node service lock behaviour is as we expect
|
* Test that the node service lock behaviour is as we expect
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void testNodeServiceLockBehaviour()
|
public void testNodeServiceLockBehaviour()
|
||||||
@@ -422,9 +429,8 @@ public class LockBehaviourImplTest extends BaseSpringTest
|
|||||||
ContentModel.TYPE_CONTAINER);
|
ContentModel.TYPE_CONTAINER);
|
||||||
fail("The parent is locked so a new child should not have been created.");
|
fail("The parent is locked so a new child should not have been created.");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException exception)
|
catch (NodeLockedException exception)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO various other tests along these lines ...
|
// TODO various other tests along these lines ...
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,16 +25,25 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.lock;
|
package org.alfresco.repo.lock;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.secure;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.test.context.transaction.TestTransaction;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.lock.mem.Lifetime;
|
import org.alfresco.repo.lock.mem.Lifetime;
|
||||||
import org.alfresco.repo.lock.mem.LockState;
|
import org.alfresco.repo.lock.mem.LockState;
|
||||||
@@ -66,11 +75,6 @@ import org.alfresco.test_category.BaseSpringTestsCategory;
|
|||||||
import org.alfresco.util.BaseSpringTest;
|
import org.alfresco.util.BaseSpringTest;
|
||||||
import org.alfresco.util.TestWithUserUtils;
|
import org.alfresco.util.TestWithUserUtils;
|
||||||
import org.alfresco.util.testing.category.RedundantTests;
|
import org.alfresco.util.testing.category.RedundantTests;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.test.context.transaction.TestTransaction;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple lock service test
|
* Simple lock service test
|
||||||
@@ -100,14 +104,13 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
private static final String GOOD_USER_NAME = "goodUser";
|
private static final String GOOD_USER_NAME = "goodUser";
|
||||||
private static final String BAD_USER_NAME = "badUser";
|
private static final String BAD_USER_NAME = "badUser";
|
||||||
private static final String PWD = "password";
|
private static final String PWD = secure().nextAlphabetic(10);
|
||||||
|
|
||||||
NodeRef rootNodeRef;
|
NodeRef rootNodeRef;
|
||||||
private StoreRef storeRef;
|
private StoreRef storeRef;
|
||||||
|
|
||||||
private PolicyComponent policyComponent;
|
private PolicyComponent policyComponent;
|
||||||
|
|
||||||
|
|
||||||
public class LockServicePoliciesImpl implements LockServicePolicies.BeforeLock,
|
public class LockServicePoliciesImpl implements LockServicePolicies.BeforeLock,
|
||||||
LockServicePolicies.BeforeUnlock
|
LockServicePolicies.BeforeUnlock
|
||||||
{
|
{
|
||||||
@@ -131,24 +134,23 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
this.nodeService = (NodeService)applicationContext.getBean("dbNodeService");
|
this.nodeService = (NodeService) applicationContext.getBean("dbNodeService");
|
||||||
this.lockService = (LockService)applicationContext.getBean("lockService");
|
this.lockService = (LockService) applicationContext.getBean("lockService");
|
||||||
|
|
||||||
this.securedLockService = (LockService)applicationContext.getBean("LockService");
|
this.securedLockService = (LockService) applicationContext.getBean("LockService");
|
||||||
PermissionService permissionService = (PermissionService) applicationContext.getBean("PermissionService");
|
PermissionService permissionService = (PermissionService) applicationContext.getBean("PermissionService");
|
||||||
|
|
||||||
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("authenticationService");
|
this.authenticationService = (MutableAuthenticationService) applicationContext.getBean("authenticationService");
|
||||||
CheckOutCheckInService cociService = (CheckOutCheckInService) applicationContext.getBean(
|
CheckOutCheckInService cociService = (CheckOutCheckInService) applicationContext.getBean(
|
||||||
"checkOutCheckInService");
|
"checkOutCheckInService");
|
||||||
|
|
||||||
this.policyComponent = (PolicyComponent)applicationContext.getBean("policyComponent");
|
this.policyComponent = (PolicyComponent) applicationContext.getBean("policyComponent");
|
||||||
|
|
||||||
// Set the authentication
|
// Set the authentication
|
||||||
AuthenticationComponent authComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
|
AuthenticationComponent authComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
|
||||||
authComponent.setSystemUserAsCurrentUser();
|
authComponent.setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
// Create the node properties
|
// Create the node properties
|
||||||
@@ -216,7 +218,6 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
assertTrue("checkedOutNode should have checked out aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_CHECKED_OUT));
|
assertTrue("checkedOutNode should have checked out aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_CHECKED_OUT));
|
||||||
assertTrue("checkedOutNode should have lockable aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_LOCKABLE));
|
assertTrue("checkedOutNode should have lockable aspect", nodeService.hasAspect(checkedOutNode, ContentModel.ASPECT_LOCKABLE));
|
||||||
|
|
||||||
|
|
||||||
// Create the users
|
// Create the users
|
||||||
TestWithUserUtils.createUser(GOOD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
|
TestWithUserUtils.createUser(GOOD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
|
||||||
TestWithUserUtils.createUser(BAD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
|
TestWithUserUtils.createUser(BAD_USER_NAME, PWD, rootNodeRef, this.nodeService, this.authenticationService);
|
||||||
@@ -236,12 +237,10 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
{
|
{
|
||||||
LockServicePoliciesImpl mockedLockServicePoliciesImpl = mock(LockServicePoliciesImpl.class);
|
LockServicePoliciesImpl mockedLockServicePoliciesImpl = mock(LockServicePoliciesImpl.class);
|
||||||
|
|
||||||
BehaviourDefinition<ClassBehaviourBinding> lockDef =
|
BehaviourDefinition<ClassBehaviourBinding> lockDef = this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeLock.QNAME, ContentModel.TYPE_BASE,
|
||||||
this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeLock.QNAME, ContentModel.TYPE_BASE,
|
|
||||||
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeLock"));
|
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeLock"));
|
||||||
|
|
||||||
BehaviourDefinition<ClassBehaviourBinding> unlockDef =
|
BehaviourDefinition<ClassBehaviourBinding> unlockDef = this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeUnlock.QNAME, ContentModel.TYPE_BASE,
|
||||||
this.policyComponent.bindClassBehaviour(LockServicePolicies.BeforeUnlock.QNAME, ContentModel.TYPE_BASE,
|
|
||||||
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeUnlock"));
|
new JavaBehaviour(mockedLockServicePoliciesImpl, "beforeUnlock"));
|
||||||
|
|
||||||
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK);
|
this.lockService.lock(this.parentNode, LockType.WRITE_LOCK);
|
||||||
@@ -305,7 +304,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
catch (UnableToAquireLockException exception)
|
catch (UnableToAquireLockException exception)
|
||||||
{
|
{
|
||||||
if(logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug(exception.getMessage());
|
logger.debug(exception.getMessage());
|
||||||
}
|
}
|
||||||
@@ -443,8 +442,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
{
|
{
|
||||||
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, authenticationService);
|
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, authenticationService);
|
||||||
|
|
||||||
IndexerAndSearcher indexerAndSearcher = (IndexerAndSearcher)
|
IndexerAndSearcher indexerAndSearcher = (IndexerAndSearcher) applicationContext.getBean("indexerAndSearcherFactory");
|
||||||
applicationContext.getBean("indexerAndSearcherFactory");
|
|
||||||
SearcherComponent searcher = new SearcherComponent();
|
SearcherComponent searcher = new SearcherComponent();
|
||||||
searcher.setIndexerAndSearcherFactory(indexerAndSearcher);
|
searcher.setIndexerAndSearcherFactory(indexerAndSearcher);
|
||||||
|
|
||||||
@@ -498,7 +496,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -510,7 +508,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -525,7 +523,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -537,7 +535,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -545,11 +543,11 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
/* addAspect test */
|
/* addAspect test */
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fullNodeService.addAspect(noAspectNode, ContentModel.ASPECT_AUTHOR , null);
|
fullNodeService.addAspect(noAspectNode, ContentModel.ASPECT_AUTHOR, null);
|
||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -561,7 +559,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -573,7 +571,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
|
|
||||||
fail("node should be locked");
|
fail("node should be locked");
|
||||||
}
|
}
|
||||||
catch(NodeLockedException e)
|
catch (NodeLockedException e)
|
||||||
{
|
{
|
||||||
// it's ok - node supposed to be locked
|
// it's ok - node supposed to be locked
|
||||||
}
|
}
|
||||||
@@ -611,8 +609,10 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
assertEquals("retrieved lock lifetime should be ephemeral", Lifetime.EPHEMERAL, lockState.getLifetime());
|
assertEquals("retrieved lock lifetime should be ephemeral", Lifetime.EPHEMERAL, lockState.getLifetime());
|
||||||
assertNotNull("retrieved expire date should not be null", lockState.getExpires());
|
assertNotNull("retrieved expire date should not be null", lockState.getExpires());
|
||||||
|
|
||||||
// Wait for 2 seconds to give the ephemeral lock time to expire
|
// Wait to give the ephemeral lock time to expire
|
||||||
try {Thread.sleep(2*1000);} catch (Exception exception){}
|
await().pollInSameThread()
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT)
|
||||||
|
.until(() -> !securedLockService.isLocked(noAspectNode));
|
||||||
|
|
||||||
assertFalse("noAspectNode should not be locked", securedLockService.isLocked(noAspectNode));
|
assertFalse("noAspectNode should not be locked", securedLockService.isLocked(noAspectNode));
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
{
|
{
|
||||||
this.lockService.unlock(this.parentNode);
|
this.lockService.unlock(this.parentNode);
|
||||||
// This will pass in the open workd
|
// This will pass in the open workd
|
||||||
//fail("A user cannot unlock a node that is currently lock by another user.");
|
// fail("A user cannot unlock a node that is currently lock by another user.");
|
||||||
}
|
}
|
||||||
catch (UnableToReleaseLockException exception)
|
catch (UnableToReleaseLockException exception)
|
||||||
{
|
{
|
||||||
@@ -947,8 +947,10 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
|
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
|
||||||
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
|
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
|
||||||
|
|
||||||
// Wait for 2 second before re-testing the status
|
// Wait for lock to expire before re-testing the status
|
||||||
try {Thread.sleep(2*1000);} catch (Exception exception){}
|
await().pollInSameThread()
|
||||||
|
.pollDelay(Duration.ofMillis(500))
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT).until(() -> lockService.getLockStatus(parentNode), LockStatus.LOCK_EXPIRED::equals);
|
||||||
|
|
||||||
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
||||||
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
|
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
|
||||||
@@ -981,8 +983,11 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
|
assertEquals("lock status should be locked", LockStatus.LOCKED, this.lockService.getLockStatus(this.parentNode));
|
||||||
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
|
assertTrue("parent node should be locked", lockService.isLocked(parentNode));
|
||||||
|
|
||||||
// Wait for 2 second before re-testing the status
|
// Wait for lock to expire before re-testing the status
|
||||||
try {Thread.sleep(2*1000);} catch (Exception exception){}
|
await().pollInSameThread()
|
||||||
|
.pollDelay(Duration.ofMillis(500))
|
||||||
|
.atMost(MAX_ASYNC_TIMEOUT)
|
||||||
|
.until(() -> lockService.getLockStatus(parentNode), LockStatus.LOCK_EXPIRED::equals);
|
||||||
|
|
||||||
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
||||||
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
|
assertEquals("lock status should be expired", LockStatus.LOCK_EXPIRED, this.lockService.getLockStatus(this.parentNode));
|
||||||
@@ -997,7 +1002,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
public void testEphemeralExpiryThreshold()
|
public void testEphemeralExpiryThreshold()
|
||||||
{
|
{
|
||||||
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
||||||
final int origThresh = ((LockServiceImpl)lockService).getEphemeralExpiryThreshold();
|
final int origThresh = ((LockServiceImpl) lockService).getEphemeralExpiryThreshold();
|
||||||
// Check the default situation is that the threshold does not apply.
|
// Check the default situation is that the threshold does not apply.
|
||||||
assertEquals("threshold should not apply", LockServiceImpl.MAX_EPHEMERAL_LOCK_SECONDS, origThresh);
|
assertEquals("threshold should not apply", LockServiceImpl.MAX_EPHEMERAL_LOCK_SECONDS, origThresh);
|
||||||
try
|
try
|
||||||
@@ -1034,35 +1039,27 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
private void checkLifetimeForExpiry(Lifetime expectedLifetime, int expirySecs, Lifetime requestedLifetime)
|
private void checkLifetimeForExpiry(Lifetime expectedLifetime, int expirySecs, Lifetime requestedLifetime)
|
||||||
{
|
{
|
||||||
lockService.unlock(parentNode);
|
lockService.unlock(parentNode);
|
||||||
assertNotEquals("lock status should not be locked", LockStatus.LOCKED ,lockService.getLockStatus(parentNode));
|
assertNotEquals("lock status should not be locked", LockStatus.LOCKED, lockService.getLockStatus(parentNode));
|
||||||
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, requestedLifetime);
|
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, requestedLifetime);
|
||||||
LockState lock = lockService.getLockState(parentNode);
|
LockState lock = lockService.getLockState(parentNode);
|
||||||
assertEquals("lock lifetime should be the same", expectedLifetime, lock.getLifetime());
|
assertEquals("lock lifetime should be the same", expectedLifetime, lock.getLifetime());
|
||||||
|
|
||||||
// Check that for any timeouts we test, a request for a persistent lock always yields a persistent lock.
|
// Check that for any timeouts we test, a request for a persistent lock always yields a persistent lock.
|
||||||
lockService.unlock(parentNode);
|
lockService.unlock(parentNode);
|
||||||
assertNotEquals("lock status should not be locked", LockStatus.LOCKED ,lockService.getLockStatus(parentNode));
|
assertNotEquals("lock status should not be locked", LockStatus.LOCKED, lockService.getLockStatus(parentNode));
|
||||||
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, Lifetime.PERSISTENT);
|
lockService.lock(parentNode, LockType.WRITE_LOCK, expirySecs, Lifetime.PERSISTENT);
|
||||||
lock = lockService.getLockState(parentNode);
|
lock = lockService.getLockState(parentNode);
|
||||||
assertEquals("lock lifetime should be persistent", Lifetime.PERSISTENT, lock.getLifetime());
|
assertEquals("lock lifetime should be persistent", Lifetime.PERSISTENT, lock.getLifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test to validate the behaviour of creating children of locked nodes.
|
* Unit test to validate the behaviour of creating children of locked nodes. No lock - can create children READ_ONLY_LOCK - can't create children WRITE_LOCK - owner can create children non owner can't create children NODE_LOCK non owner can create children owner can create children
|
||||||
* No lock - can create children
|
|
||||||
* READ_ONLY_LOCK - can't create children
|
|
||||||
* WRITE_LOCK - owner can create children
|
|
||||||
* non owner can't create children
|
|
||||||
* NODE_LOCK non owner can create children
|
|
||||||
* owner can create children
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCreateChildrenOfLockedNodes() throws Exception
|
public void testCreateChildrenOfLockedNodes() throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/* Check we can create a child of an unlocked node. */
|
||||||
* Check we can create a child of an unlocked node.
|
|
||||||
*/
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"parent node should not be locked",
|
"parent node should not be locked",
|
||||||
LockStatus.NO_LOCK,
|
LockStatus.NO_LOCK,
|
||||||
@@ -1163,8 +1160,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
TestWithUserUtils.authenticateUser(GOOD_USER_NAME, PWD, rootNodeRef, this.authenticationService);
|
||||||
|
|
||||||
/* create node */
|
/* create node */
|
||||||
final NodeRef testNode =
|
final NodeRef testNode = this.nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{}testNode"), ContentModel.TYPE_CONTAINER).getChildRef();
|
||||||
this.nodeService.createNode(parentNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{}testNode"), ContentModel.TYPE_CONTAINER).getChildRef();
|
|
||||||
|
|
||||||
// lock it as GOOD user
|
// lock it as GOOD user
|
||||||
this.securedLockService.lock(testNode, LockType.WRITE_LOCK, 2 * 86400, lt, null);
|
this.securedLockService.lock(testNode, LockType.WRITE_LOCK, 2 * 86400, lt, null);
|
||||||
@@ -1189,7 +1185,7 @@ public class LockServiceImplTest extends BaseSpringTest
|
|||||||
this.securedLockService.unlock(testNode);
|
this.securedLockService.unlock(testNode);
|
||||||
fail("BAD user shouldn't be able to unlock " + lt + " lock");
|
fail("BAD user shouldn't be able to unlock " + lt + " lock");
|
||||||
}
|
}
|
||||||
catch(AccessDeniedException e)
|
catch (AccessDeniedException e)
|
||||||
{
|
{
|
||||||
// expected exception
|
// expected exception
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,26 +25,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rule;
|
package org.alfresco.repo.rule;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import jakarta.mail.internet.MimeMessage;
|
||||||
import jakarta.transaction.UserTransaction;
|
import jakarta.transaction.UserTransaction;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.util.StopWatch;
|
||||||
|
|
||||||
import org.alfresco.model.ApplicationModel;
|
import org.alfresco.model.ApplicationModel;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ActionServiceImplTest;
|
|
||||||
import org.alfresco.repo.action.ActionServiceImplTest.AsyncTest;
|
|
||||||
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
|
||||||
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
|
||||||
@@ -100,9 +104,6 @@ import org.alfresco.service.transaction.TransactionService;
|
|||||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.util.StopWatch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
@@ -160,23 +161,22 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
protected void setUp() throws Exception
|
protected void setUp() throws Exception
|
||||||
{
|
{
|
||||||
// Get the required services
|
// Get the required services
|
||||||
this.serviceRegistry = (ServiceRegistry)applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
this.serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||||
this.nodeService = serviceRegistry.getNodeService();
|
this.nodeService = serviceRegistry.getNodeService();
|
||||||
this.ruleService = serviceRegistry.getRuleService();
|
this.ruleService = serviceRegistry.getRuleService();
|
||||||
this.cociService = serviceRegistry.getCheckOutCheckInService();
|
this.cociService = serviceRegistry.getCheckOutCheckInService();
|
||||||
this.lockService = serviceRegistry.getLockService();
|
this.lockService = serviceRegistry.getLockService();
|
||||||
this.copyService = serviceRegistry.getCopyService();
|
this.copyService = serviceRegistry.getCopyService();
|
||||||
this.contentService = serviceRegistry.getContentService();
|
this.contentService = serviceRegistry.getContentService();
|
||||||
this.dictionaryDAO = (DictionaryDAO)applicationContext.getBean("dictionaryDAO");
|
this.dictionaryDAO = (DictionaryDAO) applicationContext.getBean("dictionaryDAO");
|
||||||
this.actionService = serviceRegistry.getActionService();
|
this.actionService = serviceRegistry.getActionService();
|
||||||
this.transactionService = serviceRegistry.getTransactionService();
|
this.transactionService = serviceRegistry.getTransactionService();
|
||||||
this.authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
|
this.authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
|
||||||
this.fileFolderService = serviceRegistry.getFileFolderService();
|
this.fileFolderService = serviceRegistry.getFileFolderService();
|
||||||
|
|
||||||
//authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
// authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||||
//authenticationComponent.setSystemUserAsCurrentUser();
|
// authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
RetryingTransactionCallback<Object> setUserCallback = new RetryingTransactionCallback<Object>()
|
RetryingTransactionCallback<Object> setUserCallback = new RetryingTransactionCallback<Object>() {
|
||||||
{
|
|
||||||
public Object execute() throws Exception
|
public Object execute() throws Exception
|
||||||
{
|
{
|
||||||
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
|
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
|
||||||
@@ -260,11 +260,10 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* Check async rule execution
|
* Check async rule execution
|
||||||
*/
|
*/
|
||||||
public void testAsyncRuleExecution()
|
public void testAsyncRuleExecution() throws InterruptedException
|
||||||
{
|
{
|
||||||
final NodeRef newNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(
|
final NodeRef newNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||||
new RetryingTransactionCallback<NodeRef>()
|
new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute()
|
public NodeRef execute()
|
||||||
{
|
{
|
||||||
RuleServiceCoverageTest.this.nodeService.addAspect(
|
RuleServiceCoverageTest.this.nodeService.addAspect(
|
||||||
@@ -297,34 +296,20 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ActionServiceImplTest.postAsyncActionTest(
|
await().pollInSameThread()
|
||||||
this.transactionService,
|
.pollDelay(Duration.ofMillis(50))
|
||||||
5000,
|
.until(() -> nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
12,
|
assertThat(nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE))
|
||||||
new AsyncTest()
|
.as("Expected aspect Versionable")
|
||||||
{
|
.isTrue();
|
||||||
public String executeTest()
|
|
||||||
{
|
|
||||||
boolean result = RuleServiceCoverageTest.this.nodeService.hasAspect(
|
|
||||||
newNodeRef,
|
|
||||||
ContentModel.ASPECT_VERSIONABLE);
|
|
||||||
return result ? null : "Expected aspect Versionable";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check compensating action execution
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard rule coverage tests
|
* Standard rule coverage tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: add-features( aspect-name = versionable)
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: add-features(
|
|
||||||
* aspect-name = versionable)
|
|
||||||
*/
|
*/
|
||||||
public void testAddFeaturesAction()
|
public void testAddFeaturesAction()
|
||||||
{
|
{
|
||||||
@@ -357,7 +342,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
params2.put(ApplicationModel.PROP_APPROVE_MOVE.toString(), false);
|
params2.put(ApplicationModel.PROP_APPROVE_MOVE.toString(), false);
|
||||||
|
|
||||||
// Test that rule can be updated and execute correctly
|
// Test that rule can be updated and execute correctly
|
||||||
//rule.removeAllActions();
|
// rule.removeAllActions();
|
||||||
Action action2 = this.actionService.createAction(AddFeaturesActionExecuter.NAME, params2);
|
Action action2 = this.actionService.createAction(AddFeaturesActionExecuter.NAME, params2);
|
||||||
rule.setAction(action2);
|
rule.setAction(action2);
|
||||||
this.ruleService.saveRule(this.nodeRef, rule);
|
this.ruleService.saveRule(this.nodeRef, rule);
|
||||||
@@ -378,7 +363,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
public void testCheckThatModifyNameDoesNotTriggerInboundRule() throws Exception
|
public void testCheckThatModifyNameDoesNotTriggerInboundRule() throws Exception
|
||||||
{
|
{
|
||||||
//this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null);
|
// this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null);
|
||||||
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
||||||
folderProps.put(ContentModel.PROP_NAME, "myTestFolder");
|
folderProps.put(ContentModel.PROP_NAME, "myTestFolder");
|
||||||
NodeRef folder = this.nodeService.createNode(
|
NodeRef folder = this.nodeService.createNode(
|
||||||
@@ -408,7 +393,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myTestDocument.txt"),
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myTestDocument.txt"),
|
||||||
ContentModel.TYPE_CONTENT,
|
ContentModel.TYPE_CONTENT,
|
||||||
contentProps).getChildRef();
|
contentProps).getChildRef();
|
||||||
//addContentToNode(newNodeRef);
|
// addContentToNode(newNodeRef);
|
||||||
nodeService.removeAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE);
|
nodeService.removeAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE);
|
||||||
assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
@@ -452,7 +437,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
public void testCheckThatChildRuleFiresOnMove() throws Exception
|
public void testCheckThatChildRuleFiresOnMove() throws Exception
|
||||||
{
|
{
|
||||||
//ALF-9415 test
|
// ALF-9415 test
|
||||||
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
||||||
folderProps.put(ContentModel.PROP_NAME, "myTestFolder");
|
folderProps.put(ContentModel.PROP_NAME, "myTestFolder");
|
||||||
NodeRef folder = this.nodeService.createNode(
|
NodeRef folder = this.nodeService.createNode(
|
||||||
@@ -491,9 +476,11 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* ALF-4926: Incorrect behavior of update and move rule for the same folder
|
* ALF-4926: Incorrect behavior of update and move rule for the same folder
|
||||||
* <p/>
|
* <p/>
|
||||||
* Two rules:<br/><ul>
|
* Two rules:<br/>
|
||||||
|
* <ul>
|
||||||
* <li>When items are deleted, copy to another folder.</li>
|
* <li>When items are deleted, copy to another folder.</li>
|
||||||
* <li>In addition, when items are updated, add an aspect (or any other rule).</li></ul>
|
* <li>In addition, when items are updated, add an aspect (or any other rule).</li>
|
||||||
|
* </ul>
|
||||||
* Ensure that the first copy does not result in rules being fired on the target.
|
* Ensure that the first copy does not result in rules being fired on the target.
|
||||||
*/
|
*/
|
||||||
public void testUpdateAndMoveRuleOnSameFolder() throws Exception
|
public void testUpdateAndMoveRuleOnSameFolder() throws Exception
|
||||||
@@ -712,7 +699,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertTrue(this.nodeService.hasAspect(childAssoc.getChildRef(), ContentModel.ASPECT_TEMPLATABLE));
|
assertTrue(this.nodeService.hasAspect(childAssoc.getChildRef(), ContentModel.ASPECT_TEMPLATABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<QName, Serializable> getContentProperties()
|
private Map<QName, Serializable> getContentProperties()
|
||||||
@@ -723,10 +710,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition action: simple-workflow
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition
|
|
||||||
* action: simple-workflow
|
|
||||||
*/
|
*/
|
||||||
public void testSimpleWorkflowAction()
|
public void testSimpleWorkflowAction()
|
||||||
{
|
{
|
||||||
@@ -760,20 +744,17 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW));
|
assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW));
|
||||||
assertEquals("approveStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_STEP));
|
assertEquals("approveStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_STEP));
|
||||||
assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_FOLDER));
|
assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_FOLDER));
|
||||||
assertTrue(((Boolean)this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_MOVE)).booleanValue());
|
assertTrue(((Boolean) this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_MOVE)).booleanValue());
|
||||||
assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW));
|
assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW));
|
||||||
assertEquals("rejectStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_STEP));
|
assertEquals("rejectStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_STEP));
|
||||||
assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_FOLDER));
|
assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_FOLDER));
|
||||||
assertFalse(((Boolean)this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_MOVE)).booleanValue());
|
assertFalse(((Boolean) this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_MOVE)).booleanValue());
|
||||||
|
|
||||||
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: in-category action: add-feature
|
||||||
* rule type: inbound
|
|
||||||
* condition: in-category
|
|
||||||
* action: add-feature
|
|
||||||
*/
|
*/
|
||||||
public void testInCategoryCondition()
|
public void testInCategoryCondition()
|
||||||
{
|
{
|
||||||
@@ -809,8 +790,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertFalse(this.nodeService.hasAspect(newNodeRef2, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRef2, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
// Check rule gets fired when node contains category value
|
// Check rule gets fired when node contains category value
|
||||||
RetryingTransactionCallback<NodeRef> callback1 = new RetryingTransactionCallback<NodeRef>()
|
RetryingTransactionCallback<NodeRef> callback1 = new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
NodeRef newNodeRef = nodeService.createNode(
|
NodeRef newNodeRef = nodeService.createNode(
|
||||||
@@ -830,8 +810,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
// Check rule does not get fired when the node has the incorrect category value
|
// Check rule does not get fired when the node has the incorrect category value
|
||||||
RetryingTransactionCallback<NodeRef> callback3 = new RetryingTransactionCallback<NodeRef>()
|
RetryingTransactionCallback<NodeRef> callback3 = new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
NodeRef newNodeRef3 = nodeService.createNode(
|
NodeRef newNodeRef3 = nodeService.createNode(
|
||||||
@@ -850,7 +829,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
NodeRef newNodeRef3 = transactionService.getRetryingTransactionHelper().doInTransaction(callback3);
|
NodeRef newNodeRef3 = transactionService.getRetryingTransactionHelper().doInTransaction(callback3);
|
||||||
assertFalse(this.nodeService.hasAspect(newNodeRef3, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRef3, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -859,10 +838,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition action: link-category
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition
|
|
||||||
* action: link-category
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testLinkCategoryAction()
|
public void testLinkCategoryAction()
|
||||||
@@ -903,14 +879,11 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertNotNull(setValue);
|
assertNotNull(setValue);
|
||||||
assertEquals(1, setValue.size());
|
assertEquals(1, setValue.size());
|
||||||
assertEquals(this.catROne, setValue.toArray()[0]);
|
assertEquals(this.catROne, setValue.toArray()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition action: mail
|
||||||
* rule type: inbound
|
*
|
||||||
* condition: no-condition
|
|
||||||
* action: mail
|
|
||||||
* @throws MessagingException
|
* @throws MessagingException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@@ -987,7 +960,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
makeNameProperty(illegalName)).getChildRef();
|
makeNameProperty(illegalName)).getChildRef();
|
||||||
fail("createNode() should have failed.");
|
fail("createNode() should have failed.");
|
||||||
}
|
}
|
||||||
catch(IntegrityException e)
|
catch (IntegrityException e)
|
||||||
{
|
{
|
||||||
// Expected exception.
|
// Expected exception.
|
||||||
// An email should NOT appear in the recipients email
|
// An email should NOT appear in the recipients email
|
||||||
@@ -1005,10 +978,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: copy()
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: copy()
|
|
||||||
*/
|
*/
|
||||||
public void testCopyAction()
|
public void testCopyAction()
|
||||||
{
|
{
|
||||||
@@ -1034,7 +1004,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
getContentProperties()).getChildRef();
|
getContentProperties()).getChildRef();
|
||||||
addContentToNode(newNodeRef);
|
addContentToNode(newNodeRef);
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
|
|
||||||
// Check that the created node is still there
|
// Check that the created node is still there
|
||||||
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
||||||
@@ -1066,10 +1036,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: transform()
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: transform()
|
|
||||||
*/
|
*/
|
||||||
public void testTransformAction() throws Throwable
|
public void testTransformAction() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1091,7 +1058,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
UserTransaction tx = transactionService.getUserTransaction();
|
UserTransaction tx = transactionService.getUserTransaction();
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Map<QName, Serializable> props =new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||||
props.put(ContentModel.PROP_NAME, "test.xls");
|
props.put(ContentModel.PROP_NAME, "test.xls");
|
||||||
|
|
||||||
// Create the node at the root
|
// Create the node at the root
|
||||||
@@ -1110,9 +1077,9 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
tx.commit();
|
tx.commit();
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
|
|
||||||
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
|
AuthenticationComponent authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
|
||||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||||
|
|
||||||
// Check that the created node is still there
|
// Check that the created node is still there
|
||||||
@@ -1142,7 +1109,6 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test image transformation
|
* Test image transformation
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void testImageTransformAction() throws Throwable
|
public void testImageTransformAction() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1165,7 +1131,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
UserTransaction tx = transactionService.getUserTransaction();
|
UserTransaction tx = transactionService.getUserTransaction();
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Map<QName, Serializable> props =new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||||
props.put(ContentModel.PROP_NAME, "test.gif");
|
props.put(ContentModel.PROP_NAME, "test.gif");
|
||||||
|
|
||||||
// Create the node at the root
|
// Create the node at the root
|
||||||
@@ -1184,7 +1150,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
tx.commit();
|
tx.commit();
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
|
|
||||||
// Check that the created node is still there
|
// Check that the created node is still there
|
||||||
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
||||||
@@ -1208,10 +1174,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: move()
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: move()
|
|
||||||
*/
|
*/
|
||||||
public void testMoveAction()
|
public void testMoveAction()
|
||||||
{
|
{
|
||||||
@@ -1235,7 +1198,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
getContentProperties()).getChildRef();
|
getContentProperties()).getChildRef();
|
||||||
addContentToNode(newNodeRef);
|
addContentToNode(newNodeRef);
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
|
|
||||||
// Check that the created node has been moved
|
// Check that the created node has been moved
|
||||||
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
List<ChildAssociationRef> origRefs = this.nodeService.getChildAssocs(
|
||||||
@@ -1255,10 +1218,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: checkout()
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: checkout()
|
|
||||||
*/
|
*/
|
||||||
public void testCheckOutAction()
|
public void testCheckOutAction()
|
||||||
{
|
{
|
||||||
@@ -1293,7 +1253,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
throw new RuntimeException(exception);
|
throw new RuntimeException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
|
|
||||||
// Check that the new node has been checked out
|
// Check that the new node has been checked out
|
||||||
List<ChildAssociationRef> children = this.nodeService.getChildAssocs(this.nodeRef);
|
List<ChildAssociationRef> children = this.nodeService.getChildAssocs(this.nodeRef);
|
||||||
@@ -1318,10 +1278,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: no-condition() action: checkin()
|
||||||
* rule type: inbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: checkin()
|
|
||||||
*/
|
*/
|
||||||
public void testCheckInAction()
|
public void testCheckInAction()
|
||||||
{
|
{
|
||||||
@@ -1338,8 +1295,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
this.ruleService.saveRule(this.nodeRef, rule);
|
this.ruleService.saveRule(this.nodeRef, rule);
|
||||||
|
|
||||||
List<NodeRef> list = transactionService.getRetryingTransactionHelper().doInTransaction(
|
List<NodeRef> list = transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||||
new RetryingTransactionCallback<List<NodeRef>>()
|
new RetryingTransactionCallback<List<NodeRef>>() {
|
||||||
{
|
|
||||||
public List<NodeRef> execute()
|
public List<NodeRef> execute()
|
||||||
{
|
{
|
||||||
// Create a new node and check-it out
|
// Create a new node and check-it out
|
||||||
@@ -1372,7 +1328,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
// Check that the origional is no longer locked
|
// Check that the origional is no longer locked
|
||||||
assertEquals(LockStatus.NO_LOCK, this.lockService.getLockStatus(list.get(0)));
|
assertEquals(LockStatus.NO_LOCK, this.lockService.getLockStatus(list.get(0)));
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1392,8 +1348,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
this.ruleService.saveRule(this.nodeRef, rule);
|
this.ruleService.saveRule(this.nodeRef, rule);
|
||||||
|
|
||||||
RetryingTransactionCallback<NodeRef> noRulesWork = new RetryingTransactionCallback<NodeRef>()
|
RetryingTransactionCallback<NodeRef> noRulesWork = new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1412,8 +1367,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
NodeRef newNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(noRulesWork);
|
NodeRef newNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(noRulesWork);
|
||||||
assertFalse(nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
RetryingTransactionCallback<NodeRef> withRulesWork = new RetryingTransactionCallback<NodeRef>()
|
RetryingTransactionCallback<NodeRef> withRulesWork = new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1436,7 +1390,8 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
* <p>
|
* <p>
|
||||||
* Used to trigger rules of type of incomming.
|
* Used to trigger rules of type of incomming.
|
||||||
*
|
*
|
||||||
* @param nodeRef the node reference
|
* @param nodeRef
|
||||||
|
* the node reference
|
||||||
*/
|
*/
|
||||||
private void addContentToNode(NodeRef nodeRef)
|
private void addContentToNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
@@ -1488,13 +1443,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: inbound condition: match-text( text = .doc, operation = CONTAINS) action: add-features( aspect-name = versionable)
|
||||||
* rule type: inbound
|
|
||||||
* condition: match-text(
|
|
||||||
* text = .doc,
|
|
||||||
* operation = CONTAINS)
|
|
||||||
* action: add-features(
|
|
||||||
* aspect-name = versionable)
|
|
||||||
*/
|
*/
|
||||||
public void testContainsTextCondition()
|
public void testContainsTextCondition()
|
||||||
{
|
{
|
||||||
@@ -1526,15 +1475,15 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
props1).getChildRef();
|
props1).getChildRef();
|
||||||
addContentToNode(newNodeRef);
|
addContentToNode(newNodeRef);
|
||||||
|
|
||||||
//Map<QName, Serializable> map = this.nodeService.getProperties(newNodeRef);
|
// Map<QName, Serializable> map = this.nodeService.getProperties(newNodeRef);
|
||||||
//String value = (String)this.nodeService.getProperty(newNodeRef, ContentModel.PROP_NAME);
|
// String value = (String)this.nodeService.getProperty(newNodeRef, ContentModel.PROP_NAME);
|
||||||
|
|
||||||
assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
// Test condition success
|
// Test condition success
|
||||||
Map<QName, Serializable> props2 = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> props2 = new HashMap<QName, Serializable>();
|
||||||
props2.put(ContentModel.PROP_NAME, "bobbins.doc");
|
props2.put(ContentModel.PROP_NAME, "bobbins.doc");
|
||||||
//props2.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
// props2.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
||||||
NodeRef newNodeRef2 = this.nodeService.createNode(
|
NodeRef newNodeRef2 = this.nodeService.createNode(
|
||||||
this.nodeRef,
|
this.nodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1571,7 +1520,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
this.ruleService.saveRule(this.nodeRef, rule);
|
this.ruleService.saveRule(this.nodeRef, rule);
|
||||||
Map<QName, Serializable> propsx = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> propsx = new HashMap<QName, Serializable>();
|
||||||
propsx.put(ContentModel.PROP_NAME, "mybobbins.doc");
|
propsx.put(ContentModel.PROP_NAME, "mybobbins.doc");
|
||||||
//propsx.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
// propsx.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
||||||
NodeRef newNodeRefx = this.nodeService.createNode(
|
NodeRef newNodeRefx = this.nodeService.createNode(
|
||||||
this.nodeRef,
|
this.nodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1582,7 +1531,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertFalse(this.nodeService.hasAspect(newNodeRefx, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRefx, ContentModel.ASPECT_VERSIONABLE));
|
||||||
Map<QName, Serializable> propsy = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> propsy = new HashMap<QName, Serializable>();
|
||||||
propsy.put(ContentModel.PROP_NAME, "bobbins.doc");
|
propsy.put(ContentModel.PROP_NAME, "bobbins.doc");
|
||||||
//propsy.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
// propsy.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
||||||
NodeRef newNodeRefy = this.nodeService.createNode(
|
NodeRef newNodeRefy = this.nodeService.createNode(
|
||||||
this.nodeRef,
|
this.nodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1614,7 +1563,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertFalse(this.nodeService.hasAspect(newNodeRefa, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(newNodeRefa, ContentModel.ASPECT_VERSIONABLE));
|
||||||
Map<QName, Serializable> propsb = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> propsb = new HashMap<QName, Serializable>();
|
||||||
propsb.put(ContentModel.PROP_NAME, "bobbins.doc");
|
propsb.put(ContentModel.PROP_NAME, "bobbins.doc");
|
||||||
//propsb.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
// propsb.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
|
||||||
NodeRef newNodeRefb = this.nodeService.createNode(
|
NodeRef newNodeRefb = this.nodeService.createNode(
|
||||||
this.nodeRef,
|
this.nodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1659,8 +1608,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
// ALF-14744 / MNT-187: Create a content node - this time with 'empty content' in the same transaction
|
// ALF-14744 / MNT-187: Create a content node - this time with 'empty content' in the same transaction
|
||||||
contentNodeRef = this.transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
contentNodeRef = this.transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1682,8 +1630,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
// ALF-14744 / MNT-187: Create a content node - this time with the 'no content' aspect in the same transaction
|
// ALF-14744 / MNT-187: Create a content node - this time with the 'no content' aspect in the same transaction
|
||||||
contentNodeRef = this.transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
contentNodeRef = this.transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public NodeRef execute() throws Throwable
|
public NodeRef execute() throws Throwable
|
||||||
{
|
{
|
||||||
@@ -1781,8 +1728,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
this.nodeService.setProperty(nodeRef2, ContentModel.PROP_NAME, "testName2");
|
this.nodeService.setProperty(nodeRef2, ContentModel.PROP_NAME, "testName2");
|
||||||
assertTrue(this.nodeService.hasAspect(nodeRef2, ContentModel.ASPECT_VERSIONABLE));
|
assertTrue(this.nodeService.hasAspect(nodeRef2, ContentModel.ASPECT_VERSIONABLE));
|
||||||
|
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>() {
|
||||||
{
|
|
||||||
public Object execute() throws Exception
|
public Object execute() throws Exception
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||||
@@ -1804,7 +1750,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
public void testAssociationUpdateRule()
|
public void testAssociationUpdateRule()
|
||||||
{
|
{
|
||||||
//ALF-9661 test
|
// ALF-9661 test
|
||||||
NodeRef sourceFolder = this.nodeService.createNode(
|
NodeRef sourceFolder = this.nodeService.createNode(
|
||||||
this.rootNodeRef,
|
this.rootNodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1812,7 +1758,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
ContentModel.TYPE_FOLDER).getChildRef();
|
ContentModel.TYPE_FOLDER).getChildRef();
|
||||||
Map<String, Serializable> params = new HashMap<String, Serializable>(1);
|
Map<String, Serializable> params = new HashMap<String, Serializable>(1);
|
||||||
params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE);
|
params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE);
|
||||||
//create a rule that adds an aspect after a property is updated
|
// create a rule that adds an aspect after a property is updated
|
||||||
Rule rule = createRule(
|
Rule rule = createRule(
|
||||||
RuleType.UPDATE,
|
RuleType.UPDATE,
|
||||||
AddFeaturesActionExecuter.NAME,
|
AddFeaturesActionExecuter.NAME,
|
||||||
@@ -1821,7 +1767,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
null);
|
null);
|
||||||
|
|
||||||
this.ruleService.saveRule(sourceFolder, rule);
|
this.ruleService.saveRule(sourceFolder, rule);
|
||||||
//create folders
|
// create folders
|
||||||
NodeRef testNodeOneRef = this.nodeService.createNode(
|
NodeRef testNodeOneRef = this.nodeService.createNode(
|
||||||
sourceFolder,
|
sourceFolder,
|
||||||
ContentModel.ASSOC_CONTAINS,
|
ContentModel.ASSOC_CONTAINS,
|
||||||
@@ -1837,21 +1783,17 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
ContentModel.TYPE_CONTENT,
|
ContentModel.TYPE_CONTENT,
|
||||||
getContentProperties()).getChildRef();
|
getContentProperties()).getChildRef();
|
||||||
addContentToNode(testNodeTwoRef);
|
addContentToNode(testNodeTwoRef);
|
||||||
//there is no aspect
|
// there is no aspect
|
||||||
assertFalse(this.nodeService.hasAspect(testNodeOneRef, ContentModel.ASPECT_VERSIONABLE));
|
assertFalse(this.nodeService.hasAspect(testNodeOneRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
//create an association
|
// create an association
|
||||||
this.nodeService.addAspect(testNodeOneRef, ContentModel.ASPECT_REFERENCING, null);
|
this.nodeService.addAspect(testNodeOneRef, ContentModel.ASPECT_REFERENCING, null);
|
||||||
this.nodeService.createAssociation(testNodeOneRef, testNodeTwoRef, ContentModel.ASSOC_REFERENCES);
|
this.nodeService.createAssociation(testNodeOneRef, testNodeTwoRef, ContentModel.ASSOC_REFERENCES);
|
||||||
//there should be the versionable aspect added
|
// there should be the versionable aspect added
|
||||||
assertTrue(this.nodeService.hasAspect(testNodeOneRef, ContentModel.ASPECT_VERSIONABLE));
|
assertTrue(this.nodeService.hasAspect(testNodeOneRef, ContentModel.ASPECT_VERSIONABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test:
|
* Test: rule type: outbound condition: no-condition() action: add-features( aspect-name = versionable)
|
||||||
* rule type: outbound
|
|
||||||
* condition: no-condition()
|
|
||||||
* action: add-features(
|
|
||||||
* aspect-name = versionable)
|
|
||||||
*/
|
*/
|
||||||
public void testOutboundRuleType()
|
public void testOutboundRuleType()
|
||||||
{
|
{
|
||||||
@@ -1887,7 +1829,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
// Check the deletion of a node
|
// Check the deletion of a node
|
||||||
|
|
||||||
//System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
// System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef));
|
||||||
NodeRef newNodeRef2 = this.nodeService.createNode(
|
NodeRef newNodeRef2 = this.nodeService.createNode(
|
||||||
this.nodeRef,
|
this.nodeRef,
|
||||||
ContentModel.ASSOC_CHILDREN,
|
ContentModel.ASSOC_CHILDREN,
|
||||||
@@ -1898,7 +1840,6 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performance guideline test
|
* Performance guideline test
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void xtestPerformanceOfRuleExecution()
|
public void xtestPerformanceOfRuleExecution()
|
||||||
{
|
{
|
||||||
@@ -1999,7 +1940,7 @@ public class RuleServiceCoverageTest extends TestCase
|
|||||||
UserTransaction tx = transactionService.getUserTransaction();
|
UserTransaction tx = transactionService.getUserTransaction();
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Map<QName, Serializable> props =new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||||
props.put(ContentModel.PROP_NAME, "test.xls");
|
props.put(ContentModel.PROP_NAME, "test.xls");
|
||||||
|
|
||||||
// Create the node at the root
|
// Create the node at the root
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 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
|
||||||
@@ -25,6 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.util;
|
package org.alfresco.util;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -38,10 +40,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
/**
|
/**
|
||||||
* Base test class providing Hibernate sessions.
|
* Base test class providing Hibernate sessions.
|
||||||
* <p>
|
* <p>
|
||||||
* By default this is auto-wired by type. If a this is going to
|
* By default this is auto-wired by type. If a this is going to result in a conlict the use auto-wire by name. This can be done by setting populateProtectedVariables to true in the constructor and then adding protected members with the same name as the bean you require.
|
||||||
* result in a conlict the use auto-wire by name. This can be done by
|
|
||||||
* setting populateProtectedVariables to true in the constructor and
|
|
||||||
* then adding protected members with the same name as the bean you require.
|
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
*/
|
*/
|
||||||
@@ -50,6 +49,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
@ContextCustomizerFactories(factories = {}, mergeMode = ContextCustomizerFactories.MergeMode.REPLACE_DEFAULTS)
|
@ContextCustomizerFactories(factories = {}, mergeMode = ContextCustomizerFactories.MergeMode.REPLACE_DEFAULTS)
|
||||||
public abstract class BaseSpringTest extends TestCase
|
public abstract class BaseSpringTest extends TestCase
|
||||||
{
|
{
|
||||||
|
protected static final Duration MAX_ASYNC_TIMEOUT = Duration.ofSeconds(10);
|
||||||
public Log logger = LogFactory.getLog(getClass().getName());
|
public Log logger = LogFactory.getLog(getClass().getName());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
Reference in New Issue
Block a user