Merged V2.2 to HEAD

10953: Merged V2.1 to V2.2
      10904: AVM - add test suite wrapper, update existing tests to purge test stores (rather than all stores)
      10909: AVM - unit test updates only (exposed further tests via test suite)
      10947: AVM - unit test update only (extra checks)
   10969: Merged V2.1 to V2.2 (cont)
      10904: AVM - add test suite wrapper, update existing tests to purge test stores (rather than all stores)
   11054: Fixed blind failures in AVM unit tests
   11064: AVM - unit test error handling
   11068: Temporarily remove AvmTestSuite from the build
   11074: AVM - unit tests - added error stack on concurrency tests (to show failure in build output), removed 1 hour freeze, put back AVM test suite
   11218: Merged V2.1 to V2.2
      11217: AVM - unit test fix ("n must be positive")


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11224 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-10-07 00:57:23 +00:00
parent 2f2af720da
commit 5407e7ff37
13 changed files with 675 additions and 289 deletions

View File

@@ -36,23 +36,60 @@ import org.alfresco.repo.avm.util.BulkLoader;
*/ */
public class AVMCrawlTestP extends AVMServiceTestBase public class AVMCrawlTestP extends AVMServiceTestBase
{ {
/** public void testCrawlA()
* Do the crawl test. {
*/ testCrawl(1,
public void testCrawl() "source/java/org/alfresco/repo/avm/actions", // relative from .../repository
1,
30000); // 30 secs
}
public void testCrawlB()
{
testCrawl(2,
"source/java/org/alfresco/repo/avm", // relative from .../repository
2,
30000); // 30 secs
}
/*
public void xtestCrawlZ()
{
testCrawl(8,
"source", // relative from .../repository
2,
28800000); // 8 hours
}
*/
/**
* Do the crawl test
*
* @param n Number of threads
* @param fsPath The path in the filesystem to load (tree of stuff) from
* @param m How many multiples of content to start with
* @param runTime Min run time (in msecs)
*/
private void testCrawl(int n, String fsPath, int m, long runTime)
{ {
int n = 8; // Number of Threads.
int m = 2; // How many multiples of content to start with.
try try
{ {
long runTime = 28800000; // 8 Hours. . if (m < 1)
fService.purgeStore("main"); {
fail("Must have at least one 1 copy of content");
}
if (fService.getStore("main") != null)
{
fService.purgeStore("main");
}
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
for (int i = 0; i < m; i++) for (int i = 0; i < m; i++)
{ {
fService.createStore("d" + i); fService.createStore("d" + i);
loader.recursiveLoad("source", "d" + i + ":/"); loader.recursiveLoad(fsPath, "d" + i + ":/");
fService.createSnapshot("d" + i, null, null); fService.createSnapshot("d" + i, null, null);
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@@ -89,7 +126,8 @@ public class AVMCrawlTestP extends AVMServiceTestBase
// Do nothing. // Do nothing.
} }
} }
fail(); //fail();
System.err.println("Crawler error");
} }
} }
} }
@@ -119,18 +157,40 @@ public class AVMCrawlTestP extends AVMServiceTestBase
} }
} }
long ops = 0L; long ops = 0L;
int errorCnt = 0;
for (AVMCrawler crawler : crawlers) for (AVMCrawler crawler : crawlers)
{ {
ops += crawler.getOpCount(); ops += crawler.getOpCount();
errorCnt += (crawler.getError() ? 1 : 0);
} }
long time = System.currentTimeMillis() - startTime; long time = System.currentTimeMillis() - startTime;
System.out.println("Ops/Sec: " + (ops * 1000L / time)); System.out.println("Ops/Sec: " + (ops * 1000L / time));
if (errorCnt > 0)
{
StringBuffer errorStack = new StringBuffer();
errorStack.append("Crawler errors: ").append(errorCnt).append(" out of ").append(crawlers.size()).append(" are in error state");
for (AVMCrawler crawler : crawlers)
{
if (crawler.getError())
{
errorStack.append("\n\n").append(crawler.getErrorStackTrace());
}
}
fail(errorStack.toString());
}
} }
finally finally
{ {
for (int i = 0; i < m; i++) for (int i = 0; i < m; i++)
{ {
if (fService.getStore("d" + i) != null) { fService.purgeStore("d" + i); } if (fService.getStore("d" + i) != null)
{
fService.purgeStore("d" + i);
}
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -27,6 +27,8 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -64,6 +66,7 @@ class AVMCrawler implements Runnable
* Whether an error has occurred. * Whether an error has occurred.
*/ */
private boolean fError; private boolean fError;
private String fErrorStackTrace = null;
/** /**
* Random number generator. * Random number generator.
@@ -99,6 +102,14 @@ class AVMCrawler implements Runnable
return fError; return fError;
} }
/**
* Get error stack trace
*/
public String getErrorStackTrace()
{
return fErrorStackTrace;
}
/** /**
* Implementation of run. * Implementation of run.
*/ */
@@ -111,9 +122,16 @@ class AVMCrawler implements Runnable
doCrawl(); doCrawl();
} }
} }
catch (Exception e) catch (Throwable t)
{ {
t.printStackTrace();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
fError = true; fError = true;
fErrorStackTrace = sw.toString();
} }
} }
@@ -126,6 +144,13 @@ class AVMCrawler implements Runnable
{ {
List<AVMStoreDescriptor> reps = fService.getStores(); List<AVMStoreDescriptor> reps = fService.getStores();
fOpCount++; fOpCount++;
if (reps.size() == 0)
{
System.out.println("No AVM stores");
return;
}
AVMStoreDescriptor repDesc = reps.get(fRandom.nextInt(reps.size())); AVMStoreDescriptor repDesc = reps.get(fRandom.nextInt(reps.size()));
Map<String, AVMNodeDescriptor> rootListing = fService.getDirectoryListing(-1, repDesc.getName() + ":/"); Map<String, AVMNodeDescriptor> rootListing = fService.getDirectoryListing(-1, repDesc.getName() + ":/");
fOpCount++; fOpCount++;
@@ -138,101 +163,110 @@ class AVMCrawler implements Runnable
dirs.add(desc); dirs.add(desc);
} }
} }
AVMNodeDescriptor dir = dirs.get(fRandom.nextInt(dirs.size()));
int depth = 1; if (dirs.size() == 0)
while (dir != null)
{ {
Map<String, AVMNodeDescriptor> listing = fService.getDirectoryListing(-1, dir.getPath()); System.out.println("No dirs in root: "+repDesc.getName() + ":/");
fOpCount++; }
List<AVMNodeDescriptor> files = new ArrayList<AVMNodeDescriptor>(); else
dirs = new ArrayList<AVMNodeDescriptor>(); {
for (AVMNodeDescriptor desc : listing.values()) AVMNodeDescriptor dir = dirs.get(fRandom.nextInt(dirs.size()));
int depth = 1;
while (dir != null)
{ {
if (desc.isDirectory()) Map<String, AVMNodeDescriptor> listing = fService.getDirectoryListing(-1, dir.getPath());
fOpCount++;
List<AVMNodeDescriptor> files = new ArrayList<AVMNodeDescriptor>();
dirs = new ArrayList<AVMNodeDescriptor>();
for (AVMNodeDescriptor desc : listing.values())
{ {
dirs.add(desc); if (desc.isDirectory())
{
dirs.add(desc);
}
else
{
files.add(desc);
}
} }
else // Read some files if there are any.
if (files.size() > 0)
{ {
files.add(desc); for (int i = 0; i < 6; i++)
{
BufferedReader
reader = new BufferedReader
(new InputStreamReader
(fService.getFileInputStream(-1, files.get(fRandom.nextInt(files.size())).getPath())));
fOpCount++;
String line = reader.readLine();
System.out.println(line);
reader.close();
}
// Modify some files.
for (int i = 0; i < 2; i++)
{
String path = files.get(fRandom.nextInt(files.size())).getPath();
System.out.println("Modifying: " + path);
PrintStream out = new PrintStream(fService.getFileOutputStream(path));
out.println("I am " + path);
out.close();
fOpCount++;
}
} }
} if (fRandom.nextInt(depth) < depth - 1)
// Read some files if there are any.
if (files.size() > 0)
{
for (int i = 0; i < 6; i++)
{ {
BufferedReader // Create some files.
reader = new BufferedReader for (int i = 0; i < 1; i++)
(new InputStreamReader {
(fService.getFileInputStream(-1, files.get(fRandom.nextInt(files.size())).getPath()))); String name = randomName();
fOpCount++; if (listing.containsKey(name))
String line = reader.readLine(); {
System.out.println(line); break;
reader.close(); }
System.out.println("Creating File: " + name);
fService.createFile(dir.getPath(), name,
new ByteArrayInputStream(("I am " + name).getBytes()));
fOpCount++;
}
} }
// Modify some files. // 1 in 100 times create a directory.
for (int i = 0; i < 2; i++) if (fRandom.nextInt(100) == 0)
{
String path = files.get(fRandom.nextInt(files.size())).getPath();
System.out.println("Modifying: " + path);
PrintStream out = new PrintStream(fService.getFileOutputStream(path));
out.println("I am " + path);
out.close();
fOpCount++;
}
}
if (fRandom.nextInt(depth) < depth - 1)
{
// Create some files.
for (int i = 0; i < 1; i++)
{ {
String name = randomName(); String name = randomName();
if (listing.containsKey(name)) if (listing.containsKey(name))
{ {
break; break;
} }
System.out.println("Creating File: " + name); System.out.println("Creating Directory: " + name);
fService.createFile(dir.getPath(), name, fService.createDirectory(dir.getPath(), name);
new ByteArrayInputStream(("I am " + name).getBytes()));
fOpCount++; fOpCount++;
} }
} if (listing.size() > 0)
// 1 in 100 times create a directory.
if (fRandom.nextInt(100) == 0)
{
String name = randomName();
if (listing.containsKey(name))
{ {
break; // 1 in 100 times remove something
if (fRandom.nextInt(100) == 0)
{
List<String> names = new ArrayList<String>(listing.keySet());
String name = names.get(fRandom.nextInt(names.size()));
System.out.println("Removing: " + name);
fService.removeNode(dir.getPath(),
name);
fOpCount++;
}
} }
System.out.println("Creating Directory: " + name); if (dirs.size() > 0)
fService.createDirectory(dir.getPath(), name);
fOpCount++;
}
if (listing.size() > 0)
{
// 1 in 100 times remove something
if (fRandom.nextInt(100) == 0)
{ {
List<String> names = new ArrayList<String>(listing.keySet()); dir = dirs.get(fRandom.nextInt(dirs.size()));
String name = names.get(fRandom.nextInt(names.size()));
System.out.println("Removing: " + name);
fService.removeNode(dir.getPath(),
name);
fOpCount++;
} }
else
{
dir = null;
}
depth++;
} }
if (dirs.size() > 0)
{
dir = dirs.get(fRandom.nextInt(dirs.size()));
}
else
{
dir = null;
}
depth++;
} }
if (fRandom.nextInt(16) == 0) if (fRandom.nextInt(16) == 0)
{ {
System.out.println("Snapshotting: " + repDesc.getName()); System.out.println("Snapshotting: " + repDesc.getName());

View File

@@ -34,14 +34,40 @@ import org.alfresco.repo.avm.util.BulkReader;
*/ */
public class AVMScaleTestP extends AVMServiceTestBase public class AVMScaleTestP extends AVMServiceTestBase
{ {
public void testScaling() public void testScaleA()
{
testScaling(1,
"source/java/org/alfresco/repo/avm/actions", // relative from .../repository
1);
}
public void testScaleB()
{
testScaling(2,
"source/java/org/alfresco/repo/avm", // relative from .../repository
2);
}
/*
public void xtestScaleZ()
{
testScaling(250,
"/Users/britt/hibernate-3.1",
10);
}
*/
/**
* Do the scale test
*
* @param n Number of bulkloads to do
* @param fsPath The path in the filesystem to load (tree of stuff) from
* @param futzCount The number of post snapshot modifications to make after each load
*/
private void testScaling(int n, String fsPath, int futzCount)
{ {
int n = 250; // The number of BulkLoads to do.
try try
{ {
int futzCount = 10; // The number of post snapshot modifications to make after each load.
String load = "config/alfresco"; // The tree of stuff to load.
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
loader.setPropertyCount(50); loader.setPropertyCount(50);
@@ -52,7 +78,7 @@ public class AVMScaleTestP extends AVMServiceTestBase
{ {
System.out.println("Round " + (i + 1)); System.out.println("Round " + (i + 1));
fService.createStore("store" + i); fService.createStore("store" + i);
loader.recursiveLoad(load, "store" + i + ":/"); loader.recursiveLoad(fsPath, "store" + i + ":/");
fService.createSnapshot("store" + i, null, null); fService.createSnapshot("store" + i, null, null);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
System.out.println("Load Time: " + (now - lastTime) + "ms"); System.out.println("Load Time: " + (now - lastTime) + "ms");
@@ -68,7 +94,10 @@ public class AVMScaleTestP extends AVMServiceTestBase
{ {
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
if (fService.getStore("store" + i) != null) { fService.purgeStore("store" + i); } if (fService.getStore("store" + i) != null)
{
fService.purgeStore("store" + i);
}
} }
} }
} }

View File

@@ -45,11 +45,12 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.remote.AVMRemote; import org.alfresco.service.cmr.remote.AVMRemote;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.NameMatcher; import org.alfresco.util.NameMatcher;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
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 org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.context.ApplicationContext;
/** /**
* Local unit tests of AVM (AVMSyncService & AVMService) * Local unit tests of AVM (AVMSyncService & AVMService)
@@ -71,7 +72,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* The application context. * The application context.
*/ */
protected static FileSystemXmlApplicationContext fContext; protected static ApplicationContext fContext;
protected static NameMatcher excluder; protected static NameMatcher excluder;
@@ -81,7 +82,7 @@ public class AVMServiceLocalTest extends TestCase
if (fContext == null) if (fContext == null)
{ {
// local (embedded) test setup // local (embedded) test setup
fContext = new FileSystemXmlApplicationContext("config/alfresco/application-context.xml"); fContext = ApplicationContextHelper.getApplicationContext();
fService = (AVMRemote)fContext.getBean("avmRemote"); fService = (AVMRemote)fContext.getBean("avmRemote");
fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService"); fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
excluder = (NameMatcher) fContext.getBean("globalPathExcluder"); excluder = (NameMatcher) fContext.getBean("globalPathExcluder");
@@ -122,7 +123,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
fail(); throw e;
} }
finally finally
{ {
@@ -133,7 +134,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* Do a simple hello world test. * Do a simple hello world test.
*/ */
public void testSimple() public void testSimple() throws Throwable
{ {
try try
{ {
@@ -147,7 +148,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
@@ -168,7 +169,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* Test reading and writing. * Test reading and writing.
*/ */
public void testReadWrite() public void testReadWrite() throws Throwable
{ {
try try
{ {
@@ -195,7 +196,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
finally finally
{ {
@@ -206,7 +207,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* Another test of reading. * Another test of reading.
*/ */
public void testRead() public void testRead() throws Throwable
{ {
try try
{ {
@@ -231,7 +232,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
finally finally
{ {
@@ -242,7 +243,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* Test a call that should return null; * Test a call that should return null;
*/ */
public void testErrorState() public void testErrorState() throws Throwable
{ {
try try
{ {
@@ -251,7 +252,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
@@ -259,7 +260,7 @@ public class AVMServiceLocalTest extends TestCase
/** /**
* Test update to branch * Test update to branch
*/ */
public void testSimpleUpdateBR() public void testSimpleUpdateBR() throws Throwable
{ {
try try
{ {
@@ -287,7 +288,7 @@ public class AVMServiceLocalTest extends TestCase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
fail(); throw e;
} }
finally finally
{ {

View File

@@ -34,7 +34,7 @@ public class AVMServicePerfTest extends AVMServiceTestBase
/** /**
* Test adding 100 files to each directory. * Test adding 100 files to each directory.
*/ */
public void testAdd100a() public void testAdd100a() throws Throwable
{ {
try try
{ {
@@ -59,14 +59,14 @@ public class AVMServicePerfTest extends AVMServiceTestBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
/** /**
* Test adding 100 files to each directory. * Test adding 100 files to each directory.
*/ */
public void testAdd100b() public void testAdd100b() throws Throwable
{ {
try try
{ {
@@ -91,14 +91,14 @@ public class AVMServicePerfTest extends AVMServiceTestBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
/** /**
* Test adding 100 files to each directory. * Test adding 100 files to each directory.
*/ */
public void testAdd100c() public void testAdd100c() throws Throwable
{ {
try try
{ {
@@ -123,14 +123,14 @@ public class AVMServicePerfTest extends AVMServiceTestBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
/** /**
* Test adding 100 files to each directory. * Test adding 100 files to each directory.
*/ */
public void testAdd100d() public void testAdd100d() throws Throwable
{ {
try try
{ {
@@ -155,7 +155,7 @@ public class AVMServicePerfTest extends AVMServiceTestBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
} }

View File

@@ -164,7 +164,7 @@ public class AVMServiceTest extends AVMServiceTestBase
} }
public void testPathEncoding() public void testPathEncoding() throws Throwable
{ {
try try
{ {
@@ -202,7 +202,7 @@ public class AVMServiceTest extends AVMServiceTestBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
fail(); throw e;
} }
} }

View File

@@ -47,7 +47,6 @@ import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/** /**
* Base class for AVMService tests. * Base class for AVMService tests.
@@ -87,6 +86,11 @@ public class AVMServiceTestBase extends TestCase
protected static AVMLockingService fLockingService; protected static AVMLockingService fLockingService;
public void testSetup()
{
// NOOP
}
/** /**
* Setup for AVM tests. Note that we set the polling * Setup for AVM tests. Note that we set the polling
* interval for the reaper to 4 seconds so that tests will * interval for the reaper to 4 seconds so that tests will

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -34,22 +34,85 @@ import org.alfresco.repo.avm.util.BulkLoader;
*/ */
public class AVMStressTestP extends AVMServiceTestBase public class AVMStressTestP extends AVMServiceTestBase
{ {
public void testStressA() throws Throwable
{
testNThreads( 1, // nThreads
"source/java/org/alfresco/repo/avm/actions", // relative dir to load from (.../repository)
1, // nCopies
1, // create file
1, // create dir
0, // rename
0, // create layered dir
0, // create layered file
0, // remove node
0, // modify file
50, // read file
0, // snapshot
100); // # ops (for each thread)
}
public void testStressB() throws Throwable
{
testNThreads( 2, // nThreads
"source/java/org/alfresco/repo/avm", // relative dir to load from (.../repository)
1, // nCopies
10, // create file
2, // create dir
2, // rename
0, // create layered dir // TODO pending ETWOTWO-715 (is 2 in 2.1.x)
0, // create layered file // TODO pending ETWOTWO-715 (is 2 in 2.1.x)
5, // remove node
10, // modify file
50, // read file
5, // snapshot
200); // # ops (for each thread)
}
/*
public void xtestStressZ()
{
testNThreads( 4, // nThreads
"source", // relative dir to load from (.../repository)
8, // nCopies
400, // create file
20, // create dir
5, // rename
5, // create layered dir
5, // create layered file
10, // remove node
20, // modify file
3200, // read file
10, // snapshot
40000); // # ops
}
*/
/** /**
* Test N threads * Test N threads
*/ */
public void testNThreads() private void testNThreads(int nThreads,
String fsPath,
int nCopies,
int createFile,
int createDir,
int rename,
int createLayeredDir,
int createLayeredFile,
int removeNode,
int modifyFile,
int readFile,
int snapshot,
int opCount) throws Throwable
{ {
try try
{ {
int nCopies = 8;
int nThreads = 4;
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for (int i = 0; i < nCopies; i++) for (int i = 0; i < nCopies; i++)
{ {
fService.createDirectory("main:/", "" + i); fService.createDirectory("main:/", "" + i);
loader.recursiveLoad("source", "main:/" + i); loader.recursiveLoad(fsPath, "main:/" + i);
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
} }
System.out.println("Load time: " + (System.currentTimeMillis() - start)); System.out.println("Load time: " + (System.currentTimeMillis() - start));
@@ -58,17 +121,17 @@ public class AVMStressTestP extends AVMServiceTestBase
for (int i = 0; i < nThreads; i++) for (int i = 0; i < nThreads; i++)
{ {
AVMTester tester AVMTester tester
= new AVMTester(400, // create file. = new AVMTester(createFile,
20, // create dir, createDir,
5, // rename rename,
5, // create layered dir createLayeredDir,
5, // create layered file createLayeredFile,
10, // remove node removeNode,
20, // modify file. modifyFile,
3200, // read file readFile,
10, // snapshot snapshot,
40000, // # ops opCount,
fService); fService);
tester.refresh(); tester.refresh();
Thread thread = new Thread(tester); Thread thread = new Thread(tester);
testers.add(tester); testers.add(tester);
@@ -101,7 +164,8 @@ public class AVMStressTestP extends AVMServiceTestBase
{ {
tester.setExit(); tester.setExit();
} }
fail(); //fail();
System.err.println("Stress tester error");
} }
exited++; exited++;
} }
@@ -112,11 +176,33 @@ public class AVMStressTestP extends AVMServiceTestBase
// Do nothing. // Do nothing.
} }
} }
int errorCnt = 0;
for (AVMTester tester : testers)
{
errorCnt += (tester.getError() ? 1 : 0);
}
if (errorCnt > 0)
{
StringBuffer errorStack = new StringBuffer();
errorStack.append("Stress tester errors: ").append(errorCnt).append(" out of ").append(testers.size()).append(" are in error state");
for (AVMTester tester : testers)
{
if (tester.getError())
{
errorStack.append("\n\n").append(tester.getErrorStackTrace());
}
}
fail(errorStack.toString());
}
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
} }

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.avm;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* AVM test suite
*/
public class AVMTestSuite extends TestSuite
{
/**
* Creates the test suite
*
* @return the test suite
*/
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTestSuite(AVMNodeConverterTest.class);
suite.addTestSuite(AVMExpiredContentTest.class);
suite.addTestSuite(FileNameValidatorTest.class);
suite.addTestSuite(AVMServiceTestBase.class);
suite.addTestSuite(AVMServiceTest.class);
suite.addTestSuite(AVMServiceLocalTest.class);
suite.addTestSuite(AVMServiceIndexTest.class);
suite.addTestSuite(AVMServicePerfTest.class);
suite.addTestSuite(AVMCrawlTestP.class);
suite.addTestSuite(AVMScaleTestP.class);
suite.addTestSuite(AVMStressTestP.class);
suite.addTestSuite(PurgeTestP.class);
suite.addTestSuite(SimultaneousLoadTest.class);
return suite;
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -26,6 +26,8 @@ package org.alfresco.repo.avm;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -60,7 +62,6 @@ class AVMTester implements Runnable
private List<String> fAllDirectories; private List<String> fAllDirectories;
private List<String> fAllFiles; private List<String> fAllFiles;
private static boolean fgFrozen = false;
private static int fgOpCount = 0; private static int fgOpCount = 0;
/** /**
@@ -92,6 +93,7 @@ class AVMTester implements Runnable
* Flag for whether this thread errored out. * Flag for whether this thread errored out.
*/ */
private boolean fError; private boolean fError;
private String fErrorStackTrace = null;
/** /**
* Flag for whether this thread should exit. * Flag for whether this thread should exit.
@@ -203,56 +205,74 @@ class AVMTester implements Runnable
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (int i = 0; i < fOpCount; i++) for (int i = 0; i < fOpCount; i++)
{ {
if (fgFrozen)
{
Thread.sleep(3600000);
}
if (fExit) if (fExit)
{ {
return; return;
} }
System.out.print(threadID + ":" + i + ":"); System.out.print(threadID + ":" + i + ":");
int which = fgRandom.nextInt(fOpTable.length); int which = fgRandom.nextInt(fOpTable.length);
switch (fOpTable[which])
try
{ {
case CREATE_FILE : switch (fOpTable[which])
createFile(); {
break; case CREATE_FILE :
case CREATE_DIR : createFile();
createDirectory(); break;
break; case CREATE_DIR :
case RENAME : createDirectory();
rename(); break;
break; case RENAME :
case CREATE_LAYERED_DIR : rename();
createLayeredDir(); break;
break; case CREATE_LAYERED_DIR :
case CREATE_LAYERED_FILE : createLayeredDir();
createLayeredFile(); break;
break; case CREATE_LAYERED_FILE :
case REMOVE_NODE : createLayeredFile();
removeNode(); break;
break; case REMOVE_NODE :
case MODIFY_FILE : removeNode();
modifyFile(); break;
break; case MODIFY_FILE :
case READ_FILE : modifyFile();
readFile(); break;
break; case READ_FILE :
case SNAPSHOT : readFile();
snapshot(); break;
break; case SNAPSHOT :
} snapshot();
IncCount(); break;
}
IncCount();
}
catch (Exception e)
{
e.printStackTrace(System.err);
if (e instanceof AVMException)
{
continue;
}
if (e instanceof ContentIOException)
{
continue;
}
throw new AVMException("Failure", e);
}
} }
System.out.println(fAllPaths.size() + " fses in " + (System.currentTimeMillis() - startTime) + System.out.println(fAllPaths.size() + " fses in " + (System.currentTimeMillis() - startTime) +
"ms"); "ms");
} }
catch (Exception e) catch (Throwable t)
{ {
e.printStackTrace(System.err); t.printStackTrace();
fgFrozen = true;
fError = true; StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
fError = true;
fErrorStackTrace = sw.toString();
} }
} }
@@ -260,17 +280,20 @@ class AVMTester implements Runnable
{ {
String name = "PF" + fNames[fgRandom.nextInt(26 * 26)]; String name = "PF" + fNames[fgRandom.nextInt(26 * 26)];
String path = randomDirectory(); String path = randomDirectory();
try if (path != null)
{ {
System.out.println("create " + path + " " + name); try
PrintStream out = new PrintStream(fService.createFile(path, name)); {
out.println(path + "/" + name); System.out.println("create " + path + " " + name);
out.close(); PrintStream out = new PrintStream(fService.createFile(path, name));
addFile(appendPath(path, name)); out.println(path + "/" + name);
} out.close();
catch (Exception e) addFile(appendPath(path, name));
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
@@ -278,15 +301,18 @@ class AVMTester implements Runnable
{ {
String name = "PD" + fNames[fgRandom.nextInt(26 * 26)]; String name = "PD" + fNames[fgRandom.nextInt(26 * 26)];
String path = randomDirectory(); String path = randomDirectory();
try if (path != null)
{ {
System.out.println("mkdir " + path + " " + name); try
fService.createDirectory(path, name); {
addDirectory(appendPath(path, name)); System.out.println("mkdir " + path + " " + name);
} fService.createDirectory(path, name);
catch (Exception e) addDirectory(appendPath(path, name));
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
@@ -311,24 +337,27 @@ class AVMTester implements Runnable
} }
String srcName = path.substring(lastSlash + 1); String srcName = path.substring(lastSlash + 1);
String dstPath = randomDirectory(); String dstPath = randomDirectory();
try if (dstPath != null)
{ {
System.out.println("rename " + srcPath + " " + srcName + " " + dstPath + " " + name); try
fService.rename(srcPath, srcName, dstPath, name);
removePath(path);
if (desc.isDirectory())
{ {
addDirectory(appendPath(dstPath, name)); System.out.println("rename " + srcPath + " " + srcName + " " + dstPath + " " + name);
fService.rename(srcPath, srcName, dstPath, name);
removePath(path);
if (desc.isDirectory())
{
addDirectory(appendPath(dstPath, name));
}
else
{
addFile(appendPath(dstPath, name));
}
} }
else catch (Exception e)
{ {
addFile(appendPath(dstPath, name)); handleException(e);
} }
} }
catch (Exception e)
{
handleException(e);
}
} }
private void createLayeredDir() private void createLayeredDir()
@@ -336,15 +365,18 @@ class AVMTester implements Runnable
String name = "LD" + fNames[fgRandom.nextInt(26 * 26)]; String name = "LD" + fNames[fgRandom.nextInt(26 * 26)];
String path = randomDirectory(); String path = randomDirectory();
String target = randomDirectory(); String target = randomDirectory();
try if ((path != null) && (target != null))
{ {
System.out.println("mklayereddir " + path + " " + name + " " + target); try
fService.createLayeredDirectory(target, path, name); {
addDirectory(appendPath(path, name)); System.out.println("mklayereddir " + path + " " + name + " " + target);
} fService.createLayeredDirectory(target, path, name);
catch (Exception e) addDirectory(appendPath(path, name));
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
@@ -353,15 +385,18 @@ class AVMTester implements Runnable
String name = "LF" + fNames[fgRandom.nextInt(26 * 26)]; String name = "LF" + fNames[fgRandom.nextInt(26 * 26)];
String path = randomDirectory(); String path = randomDirectory();
String target = randomFile(); String target = randomFile();
try if ((path != null) && (target != null))
{ {
System.out.println("createlayered " + path + " " + name + " " + target); try
fService.createLayeredFile(target, path, name); {
addFile(appendPath(path, name)); System.out.println("createlayered " + path + " " + name + " " + target);
} fService.createLayeredFile(target, path, name);
catch (Exception e) addFile(appendPath(path, name));
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
@@ -390,35 +425,41 @@ class AVMTester implements Runnable
private void modifyFile() private void modifyFile()
{ {
String path = randomFile(); String path = randomFile();
try if (path != null)
{ {
System.out.println("modify " + path); try
PrintStream out = {
new PrintStream(fService.getFileOutputStream(path)); System.out.println("modify " + path);
out.println("I am " + path); PrintStream out =
out.close(); new PrintStream(fService.getFileOutputStream(path));
} out.println("I am " + path);
catch (Exception e) out.close();
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
private void readFile() private void readFile()
{ {
String path = randomFile(); String path = randomFile();
try if (path != null)
{ {
System.out.println("read " + path); try
BufferedReader reader = {
new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, path))); System.out.println("read " + path);
String line = reader.readLine(); BufferedReader reader =
System.out.println(line); new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, path)));
reader.close(); String line = reader.readLine();
} System.out.println(line);
catch (Exception e) reader.close();
{ }
handleException(e); catch (Exception e)
{
handleException(e);
}
} }
} }
@@ -489,11 +530,22 @@ class AVMTester implements Runnable
} }
} }
/**
* Is this thread in an error state.
*/
public boolean getError() public boolean getError()
{ {
return fError; return fError;
} }
/**
* Get error stack trace
*/
public String getErrorStackTrace()
{
return fErrorStackTrace;
}
public void setExit() public void setExit()
{ {
fExit = true; fExit = true;
@@ -549,16 +601,31 @@ class AVMTester implements Runnable
private String randomDirectory() private String randomDirectory()
{ {
if (fAllDirectories.size() == 0)
{
System.out.println("cannot select random directory since no directories");
return null;
}
return fAllDirectories.get(fgRandom.nextInt(fAllDirectories.size())); return fAllDirectories.get(fgRandom.nextInt(fAllDirectories.size()));
} }
private String randomFile() private String randomFile()
{ {
if (fAllFiles.size() == 0)
{
System.out.println("cannot select random file since no files");
return null;
}
return fAllFiles.get(fgRandom.nextInt(fAllFiles.size())); return fAllFiles.get(fgRandom.nextInt(fAllFiles.size()));
} }
private String randomPath() private String randomPath()
{ {
if (fAllPaths.size() == 0)
{
System.out.println("cannot select random path since no paths");
return null;
}
return fAllPaths.get(fgRandom.nextInt(fAllPaths.size())); return fAllPaths.get(fgRandom.nextInt(fAllPaths.size()));
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -34,7 +34,7 @@ public class PurgeTestP extends AVMServiceTestBase
/** /**
* Test purging a version. * Test purging a version.
*/ */
public void testPurgeVersion() public void testPurgeVersion() throws Throwable
{ {
try try
{ {
@@ -42,7 +42,12 @@ public class PurgeTestP extends AVMServiceTestBase
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
loader.recursiveLoad("source/web", "main:/");
//loader.recursiveLoad("source/web", "main:/");
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
@@ -52,6 +57,7 @@ public class PurgeTestP extends AVMServiceTestBase
{ {
try try
{ {
System.out.print(".");
Thread.sleep(2000); Thread.sleep(2000);
} }
catch (InterruptedException e) catch (InterruptedException e)
@@ -59,18 +65,19 @@ public class PurgeTestP extends AVMServiceTestBase
// Do nothing. // Do nothing.
} }
} }
System.out.println("\nReaper finished");
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
/** /**
* Test purging a version that's not the latest. * Test purging a version that's not the latest.
*/ */
public void testPurgeOlderVersion() public void testPurgeOlderVersion() throws Throwable
{ {
try try
{ {
@@ -78,11 +85,21 @@ public class PurgeTestP extends AVMServiceTestBase
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
loader.recursiveLoad("source", "main:/");
//loader.recursiveLoad("source", "main:/");
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
fService.removeNode("main:/source/java/org/alfresco", "repo");
//fService.removeNode("main:/source/java/org/alfresco", "repo");
fService.removeNode("main:/avm", "actions");
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
fService.purgeVersion(2, "main"); fService.purgeVersion(2, "main");
fReaper.activate(); fReaper.activate();
@@ -90,6 +107,7 @@ public class PurgeTestP extends AVMServiceTestBase
{ {
try try
{ {
System.out.print(".");
Thread.sleep(2000); Thread.sleep(2000);
} }
catch (InterruptedException e) catch (InterruptedException e)
@@ -97,18 +115,19 @@ public class PurgeTestP extends AVMServiceTestBase
// Do nothing. // Do nothing.
} }
} }
System.out.println("\nReaper finished");
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
/** /**
* Test purging an entire store. * Test purging an entire store.
*/ */
public void testPurgeStore() public void testPurgeStore() throws Throwable
{ {
try try
{ {
@@ -116,13 +135,25 @@ public class PurgeTestP extends AVMServiceTestBase
BulkLoader loader = new BulkLoader(); BulkLoader loader = new BulkLoader();
loader.setAvmService(fService); loader.setAvmService(fService);
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
loader.recursiveLoad("source", "main:/");
//loader.recursiveLoad("source", "main:/");
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms"); System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
fService.createLayeredDirectory("main:/source", "main:/", "layer");
fService.removeNode("main:/layer/java/org/alfresco", "repo");
fService.createFile("main:/layer/java/org/alfresco", "goofy").close(); //fService.createLayeredDirectory("main:/source", "main:/", "layer");
//fService.removeNode("main:/layer/java/org/alfresco", "repo");
//fService.createFile("main:/layer/java/org/alfresco", "goofy").close();
fService.createLayeredDirectory("main:/avm", "main:/", "layer");
fService.removeNode("main:/layer", "actions");
fService.createFile("main:/layer", "goofy").close();
fService.createSnapshot("main", null, null); fService.createSnapshot("main", null, null);
fService.purgeStore("main"); fService.purgeStore("main");
fReaper.activate(); fReaper.activate();
@@ -130,6 +161,7 @@ public class PurgeTestP extends AVMServiceTestBase
{ {
try try
{ {
System.out.print(".");
Thread.sleep(2000); Thread.sleep(2000);
} }
catch (InterruptedException e) catch (InterruptedException e)
@@ -137,11 +169,12 @@ public class PurgeTestP extends AVMServiceTestBase
// Do nothing. // Do nothing.
} }
} }
System.out.println("\nReaper finished");
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(System.err); e.printStackTrace(System.err);
fail(); throw e;
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -31,41 +31,50 @@ import org.alfresco.repo.avm.util.BulkLoader;
*/ */
public class SimultaneousLoadTest extends AVMServiceTestBase public class SimultaneousLoadTest extends AVMServiceTestBase
{ {
public void testSimulLoadA() throws Throwable
{
testSimultaneousLoad(1,1);
}
public void testSimulLoadB() throws Throwable
{
testSimultaneousLoad(5,3);
}
/** /**
* Test loading content simultaneously. * Test loading content simultaneously.
*/ */
public void testSimultaneousLoad() private void testSimultaneousLoad(int n, int m) throws Throwable
{ {
// try try
// { {
// int n = 1; fReaper.setActiveBaseSleep(60000);
// int m = 1; for (int i = 0; i < n; i++)
// fReaper.setInactiveBaseSleep(60000); {
// for (int i = 0; i < n; i++) fService.createDirectory("main:/", "d" + i);
// { }
// fService.createDirectory("main:/", "d" + i); fService.createSnapshot("main", null, null);
// } Thread [] threads = new Thread[n];
// fService.createSnapshot("main", null, null); for (int i = 0; i < n; i++)
// Thread [] threads = new Thread[n]; {
// for (int i = 0; i < n; i++) //Loader loader = new Loader("/Users/britt/stuff/" + i, "main:/d" + i, m);
// { Loader loader = new Loader("source/java/org/alfresco/repo/avm", "main:/d" + i, m);
// Loader loader = new Loader("/Users/britt/stuff/" + i, "main:/d" + i, m);
// threads[i] = new Thread(loader); threads[i] = new Thread(loader);
// threads[i].start(); threads[i].start();
// } }
// for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
// { {
// threads[i].join(); threads[i].join();
// } }
// } }
// catch (Exception e) catch (Exception e)
// { {
// e.printStackTrace(System.err); e.printStackTrace(System.err);
// fail(); throw e;
// } }
} }
@SuppressWarnings("unused")
private class Loader implements Runnable private class Loader implements Runnable
{ {
/** /**

View File

@@ -34,10 +34,9 @@ import javax.transaction.UserTransaction;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.ehcache.CacheManager; import net.sf.ehcache.CacheManager;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;