Derek Hulley add74c1a59 Merged V3.2 to HEAD
17332: ETHREEOH-2020: Original tag disappears after a new one has been added to a wiki page
   17711: Fix ETHREEOH-3720 - blocker (upgrade from 2.x)
   17712: Build/test fix (FeedCleanerTest.testConcurrentAccessAndRemoval)
   17726: DownloadContentServlet wraps call in read-only RetryingTransactionHelper
   17736: Fix ETHREEOH-2821 - deployment of layered file (fix for 3.2 deployment)
   17745: Fixed broken PostgreSQL (AVM, audit, etc) and Oracle (audit)
   17746: Merged V3.1 to V3.2
      17290: Merged V2.2 to V3.1
         17282: (record-only) Fix for ETWOTWO-1387: Node deletions transactions not properly detected ...
      17381: (record-only) Putting explicit version name on PDFRenderer.jar
      17413: (record-only) Removed dev from label
   17749: Type handler fixes for PostgreSQL: Use LONGVARBINARY
   17750: Fixed propval mappings for DB2
   17754: Fixed "invalid character" in Oracle port of propval
   17757: Re-added fix for ETHREEOH-2789 that got lost in a merge.
   17762: Fix FeedCleanerTest (for Oracle 10g) + exposed feed cleaner issue (maxSize)
   17765: Assorted minor build fixes for Oracle
   17767: Empty String property values are persisted as '.empty'
   17768: Merged DEV/BELARUS/V3.2-2009_11_24 to V3.2
      17758: ETHREEOH-3757: Oracle upgrade issue: failed "inviteEmailTemplate" patch
   17772: Fix build (JBPMEngineUnitTest) - fallout from r17765
   17774: Fix JSONtoFmModelTest
   17781: Build/test fix (AVMCrawlTestP)
   17791: Fix for ETHREEOH-3793: Oracle unit test failure for JobLockServiceTest - Missing unique indexes for all DB ports
   17795: ETHREEOH-3696: Attempt to navigate into any existent web-project or create new one after upgrade from Enterprise 2.1.7 ...
   17799: ETHREEOH-3796: org.alfresco.repo.importer.ImporterComponentTest fails
   17807: Fix ETHREEOH-3723 - MT blocker (can't restart)
   17816: Merged DEV/BELARUS/V3.2-2009_12_15 to V3.2
      17814: ETHREEOH-3808: Upgrade fails if content cm:name contains curly brackets ('{}')
   17822: Fix for ETHREEOH-3828: Mistake porting AlfrescoPostCreate-3.2-PropertyValueTables.sql script to mssql dialect
   17823: Fix for ETHREEOH-3829: SQLServer index limit reached for 'idx_alf_props_str'
   17831: Fix ETHREEOH-3818 - upgrade from Community 3.2r2 to Enterprise 3.2
   17862: Merged V3.1 to V3.2
      17722: Fix ETHREEOH-3643 - WCM layered folders (flatten) - also add unit test
      17835: ETHREEOH-3763 - fix for WCM layered folders - also add unit test
   17871: Merged V3.1 to V3.2
      17855: ACT 12915 - create web project performance (-> setPermission -> buildIndirections)
      17863: ETHREEOH-3852 - perf tweak (WCM layered files)
-------------------------------------
Modified: svn:mergeinfo
   Merged /alfresco/BRANCHES/DEV/BELARUS/V3.2-2009_11_24:r17758
   Merged /alfresco/BRANCHES/DEV/BELARUS/V3.2-2009_12_15:r17814
   Merged /alfresco/BRANCHES/V2.2:r17282
   Merged /alfresco/BRANCHES/V3.1:r17290,17381,17413,17722,17835,17855,17863
   Merged /alfresco/BRANCHES/V3.2:r17332,17711-17712,17726,17736,17745-17746,17749-17750,17754,17757,17762,17765,17767-17768,17772,17774,17781,17791,17795,17799,17807,17816,17822-17823,17831,17862,17871


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18169 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2010-01-20 12:30:14 +00:00

573 lines
22 KiB
Java

/*
* Copyright (C) 2005-2009 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 java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
/**
* Base class for AVMService tests.
* @author britt
*/
public class AVMServiceTestBase extends TestCase
{
/**
* The AVMService we are testing.
*/
protected static AVMService fService;
/**
* The reaper thread.
*/
protected static OrphanReaper fReaper;
/**
* The AVMSyncService.
*/
protected static AVMSyncService fSyncService;
/**
* The application context.
*/
protected static ApplicationContext fContext;
/**
* The start time of actual work for a test.
*/
private long fStartTime;
protected static AVMSnapShotTriggeredIndexingMethodInterceptor fIndexingInterceptor;
protected static TransactionService fTransactionService;
protected static IndexerAndSearcher fIndexerAndSearcher;
protected static AVMLockingService fLockingService;
protected static AuthenticationService fAuthService;
public void testSetup() throws Exception
{
setupBasicTree();
}
/**
* Setup for AVM tests. Note that we set the polling
* interval for the reaper to 4 seconds so that tests will
* finish reasonably quickly.
*/
@Override
protected void setUp() throws Exception
{
if (fContext == null)
{
fContext = ApplicationContextHelper.getApplicationContext();
fService = (AVMService)fContext.getBean("AVMService");
fReaper = (OrphanReaper)fContext.getBean("orphanReaper");
fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
fIndexerAndSearcher = (IndexerAndSearcher)fContext.getBean("indexerAndSearcherFactory");
fTransactionService = (TransactionService)fContext.getBean("transactionComponent");
fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService");
fIndexingInterceptor = (AVMSnapShotTriggeredIndexingMethodInterceptor)fContext.getBean("avmSnapShotTriggeredIndexingMethodInterceptor");
fAuthService = (AuthenticationService)fContext.getBean("AuthenticationService");
CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener");
cstl.addCallback(
new CreateStoreCallback()
{
public void storeCreated(String name)
{
System.err.println("Store created: " + name);
}
}
);
PurgeStoreTxnListener pstl = (PurgeStoreTxnListener)fContext.getBean("purgeStoreTxnListener");
pstl.addCallback(
new PurgeStoreCallback()
{
public void storePurged(String name)
{
System.err.println("Store purged: " + name);
}
}
);
CreateVersionTxnListener cvtl = (CreateVersionTxnListener)fContext.getBean("createVersionTxnListener");
cvtl.addCallback(
new CreateVersionCallback()
{
public void versionCreated(String name, int versionID)
{
System.err.println("Version created: " + name + " " + versionID);
}
}
);
PurgeVersionTxnListener pvtl = (PurgeVersionTxnListener)fContext.getBean("purgeVersionTxnListener");
pvtl.addCallback(
new PurgeVersionCallback()
{
public void versionPurged(String name, int versionID)
{
System.err.println("Version purged: " + name + " " + versionID);
}
}
);
}
fAuthService.authenticate(AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
if (fService.getStore("main") != null)
{
fService.purgeStore("main");
}
fService.createStore("main");
if (fService.getStore("layer") != null)
{
fService.purgeStore("layer");
}
if (!fLockingService.getWebProjects().contains("main"))
{
fLockingService.addWebProject("main");
}
fStartTime = System.currentTimeMillis();
}
/**
* Cleanup after a test. Purge main store.
*/
@Override
protected void tearDown() throws Exception
{
long now = System.currentTimeMillis();
System.out.println("Timing: " + (now - fStartTime) + "ms");
if (fService.getStore("main") != null) { fService.purgeStore("main"); }
// Move alf_data directory aside.
// fContext.close();
// File alfData = new File("alf_data");
// File target = new File("alf_data" + now);
// alfData.renameTo(target);
AuthenticationUtil.clearCurrentSecurityContext();
}
/**
* Get the recursive contents of the given path and version.
* @param path
* @param version
* @return A string representation of the contents.
*/
protected String recursiveContents(String path, int version, boolean followLinks)
{
String val = recursiveList(path, version, 0, followLinks);
return val.substring(val.indexOf('\n'));
}
/**
* Helper to write a recursive listing of an AVMStore at a given version.
* @param repoName The name of the AVMStore.
* @param version The version to look under.
*/
protected String recursiveList(String repoName, int version, boolean followLinks)
{
return recursiveList(repoName + ":/", version, 0, followLinks);
}
/**
* Recursive list the given path.
* @param path The path.
* @param version The version.
* @param indent The current indent level.
*/
protected String recursiveList(String path, int version, int indent, boolean followLinks)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < indent; i++)
{
builder.append(' ');
}
builder.append(path.substring(path.lastIndexOf('/') + 1));
builder.append(' ');
AVMNodeDescriptor desc = fService.lookup(version, path, true);
builder.append(desc.toString());
builder.append('\n');
if (desc.getType() == AVMNodeType.PLAIN_DIRECTORY ||
(desc.getType() == AVMNodeType.LAYERED_DIRECTORY && followLinks))
{
String basename = path.endsWith("/") ? path : path + "/";
Map<String, AVMNodeDescriptor> listing = fService.getDirectoryListing(version, path, true);
for (String name : listing.keySet())
{
System.err.println(name);
builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
}
}
return builder.toString();
}
/**
* Setup a basic tree.
*/
protected void setupBasicTree0()
throws IOException
{
fService.createDirectory("main:/", "a");
fService.createDirectory("main:/a", "b");
fService.createDirectory("main:/a/b", "c");
fService.createDirectory("main:/", "d");
fService.createDirectory("main:/d", "e");
fService.createDirectory("main:/d/e", "f");
fService.createFile("main:/a/b/c", "foo").close();
ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo");
writer.setEncoding("UTF-8");
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.putContent("I am main:/a/b/c/foo");
fService.createFile("main:/a/b/c", "bar").close();
writer = fService.getContentWriter("main:/a/b/c/bar");
// Force a conversion
writer.setEncoding("UTF-16");
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.putContent("I am main:/a/b/c/bar");
fService.createSnapshot("main", null, null);
}
protected void setupBasicTree()
throws IOException
{
setupBasicTree0();
runQueriesAgainstBasicTree("main");
}
protected void runQueriesAgainstBasicTree(String store)
{
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
// Text index
SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true);
ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\"");
assertEquals(2, results.length());
results.close();
// Basic properties
// Note "a" is a stop word and therefore not findable ...
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NAME)+":\"foo\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NAME)+":foo");
assertEquals(1, results.length());
results.close();
// TODO: Fix auth in AVMDiskDriver and more??
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_CREATOR)+":admin");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_MODIFIER)+":admin");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_OWNER)+":admin");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NODE_UUID)+":unknown");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_STORE_PROTOCOL)+":avm");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_STORE_IDENTIFIER)+":"+store);
assertEquals(9, results.length());
results.close();
// Basic paths
results = searchService.query(storeRef, "lucene", "PATH:\"/\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(9, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//*\"");
assertEquals(8, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\"");
assertEquals(5, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\"");
assertEquals(4, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\"");
assertEquals(0, results.length());
results.close();
}
protected void runQueriesAgainstBasicTreeWithAOnly(String store)
{
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
// Text index
SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true);
ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\"");
assertEquals(2, results.length());
results.close();
// Basic properties
// Note "a" is a stop word and therefore not findable ...
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NAME)+":\"foo\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NAME)+":foo");
assertEquals(1, results.length());
results.close();
// TODO: Fix auth in AVMDiskDriver and more??
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_CREATOR)+":admin");
if(results.length() == 10)
{
for (ResultSetRow row : results)
{
System.out.println(row.getNodeRef());
}
}
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_MODIFIER)+":admin");
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_OWNER)+":admin");
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_NODE_UUID)+":unknown");
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_STORE_PROTOCOL)+":avm");
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@"+ContentModel.PROP_STORE_IDENTIFIER)+":"+store);
assertEquals(6, results.length());
results.close();
// Basic paths
results = searchService.query(storeRef, "lucene", "PATH:\"/\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\"");
assertEquals(0, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
assertEquals(6, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//*\"");
assertEquals(5, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\"");
assertEquals(5, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\"");
assertEquals(4, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\"");
assertEquals(1, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\"");
assertEquals(2, results.length());
results.close();
results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\"");
assertEquals(0, results.length());
results.close();
}
/**
* Check that history has not been screwed up.
*/
protected void checkHistory(TreeMap<Integer, String> history, String repName)
{
for (Integer i : history.keySet())
{
assertEquals(history.get(i), recursiveList(repName, i, false));
}
int latest = fService.getNextVersionID(repName);
history.put(latest - 1, recursiveList(repName, -1, false));
}
}