Dave Ward 051508c21d Merged PATCHES/V3.2.r to HEAD
19546: (RECORD ONLY) Merged V3.2 to PATCHES/V3.2.r
      19432: Merged V3.1 to V3.2
         19427: Merged V3.0 to V3.1
            19423: Merged V2.2 to V3.0
               19391: Fix for ALF-2076: AUTO does not work if a document has been added and deleted since the index backup
               19419: V2.2 Build Fix
               19421: Fix for ALF-2076: AUTO does not work if a document has been added and deleted since the index backup
      19463: Merged V3.1 to V3.2
         19459: Merged V3.0 to V3.1
            19457: Merged V2.2 to V3.0
               19449: Addition Fix for ALF-2076: AUTO does not work if a document has been added and deleted since the index backup
      19493 Merged V3.1 to V3.2
         19471: Build fix after changes for ALF-2076 were merged forward. Index checker correctly understands INDETERMINATE state of indexed transactions
   19547: (RECORD ONLY) Incremented version label
   19555: (RECORD ONLY) Merged V3.2 to PATCHES/V3.2.r
      19552: Merged V3.1 to V3.2
         19551: Further fix after changes for ALF-2076 were merged forward. Final fix to check for InIndex.No
   19566: (RECORD ONLY) Merged V3.2 to PATCHES/V3.2.r
      19539: Merged HEAD to V3.2
         19538: ALF-2076: Build fix - fix build speed
   19802: (RECORD ONLY) ALF-2382, ALF-2383: Merged V3.2 to PATCHES/V3.2.r
      19647: ALF-2231: Merged DEV/BELARUS/V2.2-2009_12_01 to V3.2 
         17704: ENH-681: alfresco webdav does not respect webdav locks 
      19624: ALF-2231: Merged DEV/BELARUS/V2.2-2009_12_01 to V3.2
         17704: ENH-681: alfresco webdav does not respect webdav locks
      19623: ALF-1890: Correction to previous checkin to allow defaulting of request body charset
      19617: ALF-1890: Improvements to make ALL WebDAV methods retryable
         - Solution from PutMethod promoted to request wrapper that will handle ALL calls to getInputStream and getReader
      19614: ALF-1890: Merged V2.2 to V3.2
         17709: Merged DEV_TEMPORARY to V2.2
            17700: ETWOTWO-1393: concurrent writes to webdav lead to data loss (0kb resulting file)
         19613: Merged DEV/BELARUS/V2.2-2010_02_03 to V2.2
            19157: ALF-1890: concurrent writes to webdav lead to data loss (0kb resulting file)
   19803: ALF-558: File servers (CIFS / FTP / NFS) can now handle concurrent write operations on Alfresco repository
      - ContentDiskDriver / AVMDiskDriver now use retrying transactions for write operations
      - Disable EagerContentStoreCleaner on ContentDiskDriver / AVMDiskDriver closeFile() operations so that they may be retried after rollback (Sony zero byte problem)
      - Allow manual association of AVM ContentData with nodes so that closeFile() may be retried
      - Propagation of new argument through AVM interfaces
   19804: (RECORD ONLY) Merged PATCHES/V3.2.0 to PATCHES/V3.2.r
      Merged HEAD to V3.2.0
         19786: Refactor of previous test fix. I have pushed down the OOo-specific parts of the change from AbstractContentTransformerTest to OpenOfficeContentTransformerTest leaving an extension point in the base class should other transformations need to be excluded in the future.
         19785: Fix for failing test OpenOfficeContentTransformerTest.testAllConversions.
            Various OOo-related transformations are returned as available but fail on our test server with OOo on it.
            Pending further work on these failings, I am disabling those transformations in test code whilst leaving them available in the product code. This is because in the wild a different OOo version may succeed with these transformations.
            I had previously explicitly disabled 3 transformations in the product and I am moving that restriction from product to test code for the same reason.
         19707: Return value from isTransformationBlocked was inverted. Fixed now.
         19705: Refinement of previous check-in re OOo transformations.
            I have pulled up the code that handles blocked transformations into a superclass so that the JodConverter-based transformer worker can inherit the same list of blocked transformations. To reiterate, blocked transformations are those that the OOo integration code believes should work but which are broken in practice. These are blocked by the transformers and will always be unavailable regardless of the OOo connection state.
         19702: Fix for HEAD builds running on panda build server.
            OOo was recently installed on panda which has activated various OOo-related transformations/extractions in the test code.
            It appears that OOo does not support some transformations from Office 97 to Office 2007. Specifically doc to docx and xls to xlsx. These transformations have now been marked as unavailable.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@20004 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2010-04-27 10:57:47 +00:00

581 lines
22 KiB
Java

/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* 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.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.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
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 RetryingTransactionHelper fRetryingTransactionHelper;
protected static AuthenticationComponent fAuthenticationComponent;
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");
fAuthenticationComponent = (AuthenticationComponent) fContext.getBean("authenticationComponent");
fRetryingTransactionHelper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper");
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", true);
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", true);
/*
// Force a conversion
writer.setEncoding("UTF-16");
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.putContent(new ByteArrayInputStream("I am main:/a/b/c/bar".getBytes("UTF-16")));
*/
writer.setEncoding("UTF-8");
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));
}
}