ALF-9689 - Reinstate FTP tests

ALF-9404 - Save As New file.
ALF-8756 - Robocopy and Touch

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29551 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2011-08-05 09:05:37 +00:00
parent 5857c90025
commit 41a735de30
8 changed files with 358 additions and 124 deletions

View File

@@ -317,7 +317,7 @@ public class FTPServerTest extends TestCase
*
* @throws Exception
*/
public void DISABLED_testCRUD() throws Exception
public void testCRUD() throws Exception
{
final String PATH1 = "FTPServerTest";
final String PATH2 = "Second part";
@@ -413,7 +413,7 @@ public class FTPServerTest extends TestCase
*
* So we need to check how high characters and problematic are encoded
*/
public void DISABLED_testPathNames() throws Exception
public void testPathNames() throws Exception
{
logger.debug("Start testPathNames");
@@ -491,7 +491,7 @@ public class FTPServerTest extends TestCase
*
* @throws Exception
*/
public void DISABLED_testTwoUserUpdate() throws Exception
public void testTwoUserUpdate() throws Exception
{
logger.debug("Start testFTPConnect");

View File

@@ -47,10 +47,8 @@ import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -160,8 +158,9 @@ public class BufferedContentDiskDriver implements ExtendedDiskInterface,
public FileInfo getFileInformation(SrvSession sess, TreeConnection tree,
String path) throws IOException
{
String userName = sess.getClientInformation().getUserName();
String userName = AuthenticationUtil.getFullyAuthenticatedUser();
if(logger.isDebugEnabled())
{
logger.debug("getFileInformation userName:" + userName + ", path:" + path);
@@ -208,8 +207,9 @@ public class BufferedContentDiskDriver implements ExtendedDiskInterface,
@Override
public int fileExists(SrvSession sess, TreeConnection tree, String path)
{
String userName = sess.getClientInformation().getUserName();
String userName = AuthenticationUtil.getFullyAuthenticatedUser();
if(logger.isDebugEnabled())
{
logger.debug("fileExists userName:" + userName + ", path:" + path);

View File

@@ -515,6 +515,9 @@ public class CifsHelper
/**
* Attempts to fetch a specific single node at the given path.
* <p>
* The path may contain wild cards
* <p>
*
* @throws FileNotFoundException if the path can't be resolved to a node
*

View File

@@ -1336,17 +1336,32 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
try
{
// get the device root
NodeRef deviceRootNodeRef = ctx.getRootNode();
NodeRef dirNodeRef;
String folderName;
String path = params.getPath();
String parentPath = null;
// If the state table is available then try to find the parent folder node for the new folder
// to save having to walk the path
String[] paths = FileName.splitPath(path);
if (paths[0] != null && paths[0].length() > 1)
{
// lookup parent directory
dirNodeRef = getNodeForPath(tree, paths[0]);
folderName = paths[1];
}
else
{
dirNodeRef = ctx.getRootNode();
folderName = path;
}
if(dirNodeRef == null)
{
throw new IOException("Create directory parent folder not found" + params.getFullPath());
}
NodeRef nodeRef = getCifsHelper().createNode(dirNodeRef, folderName, ContentModel.TYPE_FOLDER);
NodeRef nodeRef = getCifsHelper().createNode(deviceRootNodeRef, path, ContentModel.TYPE_FOLDER);
if (logger.isDebugEnabled())
{
@@ -2037,14 +2052,13 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
if (logger.isDebugEnabled())
{
logger.debug("truncateFile file=" + file);
logger.debug("truncateFile file:" + file + ", size: "+ size);
}
long allocSize = 0L;
long releaseSize = 0L;
// Check if there is a quota manager
QuotaManager quotaMgr = ctx.getQuotaManager();
if ( ctx.hasQuotaManager()) {
@@ -2058,6 +2072,10 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
{
contentFile.openContent( false, false);
}
}
else if( file instanceof TempNetworkFile)
{
}
else
{
@@ -2079,10 +2097,9 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
else
{
// Calculate the space to be released as the file is to be truncated, release the space if
// the file truncation is successful
releaseSize = file.getFileSize() - size;
// Calculate the space to be released as the file is to be truncated, release the space if
// the file truncation is successful
releaseSize = file.getFileSize() - size;
}
}
@@ -2091,11 +2108,22 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
if ( file instanceof ContentNetworkFile) {
// Get the cached state for the file
ContentNetworkFile contentFile = (ContentNetworkFile) file;
FileState fstate = contentFile.getFileState();
if ( fstate != null && size > fstate.getAllocationSize())
fstate.setAllocationSize( size);
{
fstate.setAllocationSize(size);
}
}
if( file instanceof TempNetworkFile)
{
TempNetworkFile contentFile = (TempNetworkFile) file;
FileState fstate = contentFile.getFileState();
if ( fstate != null && size > fstate.getAllocationSize())
{
fstate.setAllocationSize(size);
}
}
// Set the file length
@@ -2106,14 +2134,14 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
}
catch (IOException ex)
{
// Check if we allocated space to the file
if ( allocSize > 0 && quotaMgr != null)
{
quotaMgr.releaseSpace(sess, tree, file.getFileId(), null, allocSize);
}
// Rethrow the exception
// Rethrow the exception
throw ex;
}
@@ -2303,14 +2331,8 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
*/
private NodeRef getNodeForPath(TreeConnection tree, String path)
throws FileNotFoundException
{
if(logger.isDebugEnabled())
{
logger.debug("getNodeRefForPath:" + path);
}
ContentContext ctx = (ContentContext) tree.getContext();
{
ContentContext ctx = (ContentContext) tree.getContext();
return getCifsHelper().getNodeRef(ctx.getRootNode(), path);
}
@@ -3156,11 +3178,24 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
try
{
// Get the device root
NodeRef deviceRootNodeRef = rootNode;
NodeRef nodeRef = cifsHelper.createNode(deviceRootNodeRef, path, ContentModel.TYPE_CONTENT);
NodeRef dirNodeRef;
String folderName;
String[] paths = FileName.splitPath(path);
if (paths[0] != null && paths[0].length() > 1)
{
// lookup parent directory
dirNodeRef = getNodeForPath(rootNode, paths[0]);
folderName = paths[1];
}
else
{
dirNodeRef = rootNode;
folderName = path;
}
NodeRef nodeRef = cifsHelper.createNode(dirNodeRef, folderName, ContentModel.TYPE_CONTENT);
nodeService.addAspect(nodeRef, ContentModel.ASPECT_NO_CONTENT, null);
@@ -3302,44 +3337,48 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
TempNetworkFile tempFile =(TempNetworkFile)file;
tempFile.flushFile();
tempFile.close();
// Take an initial guess at the mimetype (if it has not been set by something already)
String mimetype = mimetypeService.guessMimetype(tempFile.getFullName(), new FileContentReader(tempFile.getFile()));
logger.debug("guesssed mimetype:" + mimetype);
String encoding;
// Take a guess at the locale
InputStream is = new BufferedInputStream(new FileInputStream(tempFile.getFile()));
try
if(tempFile.getWriteCount() > 0)
{
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
Charset charset = charsetFinder.getCharset(is, mimetype);
encoding = charset.name();
}
finally
{
if(is != null)
// Some content was written to the temp file.
tempFile.flushFile();
tempFile.close();
// Take an initial guess at the mimetype (if it has not been set by something already)
String mimetype = mimetypeService.guessMimetype(tempFile.getFullName(), new FileContentReader(tempFile.getFile()));
logger.debug("guesssed mimetype:" + mimetype);
String encoding;
// Take a guess at the locale
InputStream is = new BufferedInputStream(new FileInputStream(tempFile.getFile()));
try
{
is.close();
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
Charset charset = charsetFinder.getCharset(is, mimetype);
encoding = charset.name();
}
finally
{
if(is != null)
{
is.close();
}
}
}
NodeRef target = getCifsHelper().getNodeRef(rootNode, tempFile.getFullName());
ContentWriter writer = contentService.getWriter(target, ContentModel.PROP_CONTENT, true);
writer.setMimetype(mimetype);
writer.setEncoding(encoding);
writer.putContent(tempFile.getFile());
NodeRef target = getCifsHelper().getNodeRef(rootNode, tempFile.getFullName());
ContentWriter writer = contentService.getWriter(target, ContentModel.PROP_CONTENT, true);
writer.setMimetype(mimetype);
writer.setEncoding(encoding);
writer.putContent(tempFile.getFile());
long size = writer.getSize();
if(nodeService.hasAspect(target, ContentModel.ASPECT_NO_CONTENT) && size > 0)
{
if(logger.isDebugEnabled())
long size = writer.getSize();
if(nodeService.hasAspect(target, ContentModel.ASPECT_NO_CONTENT) && size > 0)
{
logger.debug("removed no content aspect");
if(logger.isDebugEnabled())
{
logger.debug("removed no content aspect");
}
nodeService.removeAspect(target, ContentModel.ASPECT_NO_CONTENT);
}
nodeService.removeAspect(target, ContentModel.ASPECT_NO_CONTENT);
}
}
@@ -3362,20 +3401,19 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
}
}
}
// Make sure we clean up before propagating exceptions
catch (IOException e)
{
if ( logger.isDebugEnabled())
{
logger.debug("Exception in closeFile - ", e);
logger.debug("Exception in closeFile - path:" + path, e);
}
throw e;
throw new IOException("Unable to closeFile :" + path + e.toString(), e);
}
catch (Error e)
{
if ( logger.isDebugEnabled())
{
logger.debug("Exception in closeFile - ", e);
logger.debug("Exception in closeFile - path:" + path, e);
}
throw e;

View File

@@ -233,7 +233,7 @@ public class ContentDiskDriverTest extends TestCase
int openAction = FileAction.CreateNotExist;
final String FILE_NAME="testCreateFile.new";
final String FILE_NAME="testCreateFileA.new";
final String FILE_PATH="\\"+FILE_NAME;
FileOpenParams params = new FileOpenParams(FILE_PATH, openAction, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
@@ -248,7 +248,7 @@ public class ContentDiskDriverTest extends TestCase
public Void execute() throws Throwable
{
byte[] stuff = "Hello World".getBytes();
driver.writeFile(testSession, testConnection, file, stuff, stuff.length, 0, 0);
driver.writeFile(testSession, testConnection, file, stuff, 0, stuff.length, 0);
driver.closeFile(testSession, testConnection, file);
return null;
}
@@ -3013,6 +3013,127 @@ public class ContentDiskDriverTest extends TestCase
} // testOpenCloseFileScenario
/**
* Unit test of open read/write close versionable file - should not do anything.
* <p>
* This is done with a CIFS shuffle from word. Basically Word holds the file open with a read/write lock while the
* shuffle is going on.
* <p>
* Create a file.
* Apply versionable aspect
* Open the file ReadWrite + OpLocks
* Close the file
* Check Version has not incremented.
*/
public void testOpenCloseVersionableFile() throws Exception
{
logger.debug("testOpenCloseVersionableFile");
ServerConfiguration scfg = new ServerConfiguration("testServer");
TestServer testServer = new TestServer("testServer", scfg);
SrvSession testSession = new TestSrvSession(666, testServer, "test", "remoteName");
DiskSharedDevice share = getDiskSharedDevice();
final TreeConnection testConnection = testServer.getTreeConnection(share);
final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper();
final String FILE_PATH1=TEST_ROOT_DOS_PATH + "\\OpenCloseFile.new";
class TestContext
{
};
final TestContext testContext = new TestContext();
FileOpenParams dirParams = new FileOpenParams(TEST_ROOT_DOS_PATH, 0, AccessMode.ReadOnly, FileAttribute.NTDirectory, 0);
driver.createDirectory(testSession, testConnection, dirParams);
FileOpenParams params1 = new FileOpenParams(FILE_PATH1, 0, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
NetworkFile file1 = driver.createFile(testSession, testConnection, params1);
driver.closeFile(testSession, testConnection, file1);
/**
* Make Node 1 versionable
*/
RetryingTransactionCallback<Void> makeVersionableCB = new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
NodeRef file1NodeRef = getNodeForPath(testConnection, FILE_PATH1);
nodeService.addAspect(file1NodeRef, ContentModel.ASPECT_VERSIONABLE, null);
ContentWriter contentWriter2 = contentService.getWriter(file1NodeRef, ContentModel.PROP_CONTENT, true);
contentWriter2.putContent("test open close versionable node");
return null;
}
};
tran.doInTransaction(makeVersionableCB, false, true);
RetryingTransactionCallback<String> readVersionCB = new RetryingTransactionCallback<String>() {
@Override
public String execute() throws Throwable
{
NodeRef shuffledNodeRef = getNodeForPath(testConnection, FILE_PATH1);
Map<QName,Serializable> props = nodeService.getProperties(shuffledNodeRef);
assertTrue("versionable aspect not present", nodeService.hasAspect(shuffledNodeRef, ContentModel.ASPECT_VERSIONABLE));
props.get(ContentModel.PROP_VERSION_LABEL);
return (String)props.get(ContentModel.PROP_VERSION_LABEL);
}
};
String version = tran.doInTransaction(readVersionCB, false, true);
/**
* Step 1: Open The file Read/Write
* TODO Check primary assoc, peer assocs, child assocs, modified date, created date, nodeid, permissions.
*/
NetworkFile file = driver.openFile(testSession, testConnection, params1);
assertNotNull( "file is null", file);
/**
* Step 2: Close the file
*/
driver.closeFile(testSession, testConnection, file);
/**
* Validate that there is no version increment.
*/
String version2 = tran.doInTransaction(readVersionCB, false, true);
assertEquals("version has incremented", version, version2);
/**
* Now do an update and check the version increments
*/
file = driver.openFile(testSession, testConnection, params1);
assertNotNull( "file is null", file);
byte[] stuff = "Hello World".getBytes();
driver.writeFile(testSession, testConnection, file, stuff, 0, stuff.length, 0);
/**
* Step 2: Close the file
*/
driver.closeFile(testSession, testConnection, file);
String version3 = tran.doInTransaction(readVersionCB, false, true);
assertFalse("version not incremented", version.equals(version3));
} // OpenCloseVersionableFile
/**
* Test server
*/

View File

@@ -142,8 +142,9 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
UserQuotaDetails userQuota = getQuotaDetails(sess, true);
if ( userQuota != null)
{
return userQuota.getAvailableSpace();
}
// No quota details available
return 0L;
@@ -268,22 +269,22 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
* @exception QuotaManagerException
*/
public void startManager(DiskInterface disk, DiskDeviceContext ctx)
throws QuotaManagerException {
throws QuotaManagerException
{
if(logger.isDebugEnabled())
{
logger.debug("Start Quota Manager");
}
// Save the filesystem driver details
m_filesys = disk;
// if ( disk instanceof ContentDiskDriver)
// m_filesys = (ContentDiskDriver) disk;
// else
// throw new QuotaManagerException("Invalid filesystem type, " + disk.getClass().getName());
// Allocate the live usage table
m_liveUsage = new HashMap<String, UserQuotaDetails>();
// Create the inactivity checker thread
// Create the inactivity checker thread
m_thread = new Thread(this);
m_thread.setDaemon(true);
m_thread.setName("ContentQuotaManagerChecker");
@@ -298,7 +299,13 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
* @exception QuotaManagerException
*/
public void stopManager(DiskInterface disk, DiskDeviceContext ctx)
throws QuotaManagerException {
throws QuotaManagerException
{
if(logger.isDebugEnabled())
{
logger.debug("Stop Quota Manager");
}
// Clear out the live usage details
@@ -315,26 +322,34 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
*
* @param sess SrvSession
* @param loadDetails boolean
* @return UserQuotaDetails
* @return UserQuotaDetails or null
*/
private UserQuotaDetails getQuotaDetails(SrvSession sess, boolean loadDetails) {
UserQuotaDetails userQuota = null;
if ( sess != null && sess.hasClientInformation()) {
String userName = AuthenticationUtil.getFullyAuthenticatedUser();
if ( sess != null && userName != null)
{
// Get the live usage values
userQuota = m_liveUsage.get( AuthenticationUtil.getFullyAuthenticatedUser() );
if ( userQuota == null && loadDetails == true) {
userQuota = m_liveUsage.get(userName);
if ( userQuota == null && loadDetails == true)
{
// User is not in the live tracking table, load details for the user
try {
userQuota = loadUsageDetails( sess);
try
{
logger.debug("user is not in cache - load details");
userQuota = loadUsageDetails(userName);
}
catch ( QuotaManagerException ex) {
catch ( QuotaManagerException ex)
{
if ( logger.isDebugEnabled())
logger.debug( ex);
{
logger.debug("Unable to load usage details", ex);
}
}
}
}
@@ -347,33 +362,25 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
/**
* Load the user quota details
*
* @param sess SrvSession
* @param user - name of the user.
* @return UserQuotaDetails
* @throws QuotaManagerException
*/
private UserQuotaDetails loadUsageDetails(SrvSession sess)
private UserQuotaDetails loadUsageDetails(String userName)
throws QuotaManagerException {
// Check if the user name is available
if ( sess == null || sess.hasClientInformation() == false)
throw new QuotaManagerException("No session/client information");
UserQuotaDetails quotaDetails = null;
String userName = null;
try {
// Get the user name
userName = AuthenticationUtil.getFullyAuthenticatedUser();
try
{
if ( userName == null || userName.length() == 0)
{
logger.debug("user name is null or empty - throw QuotaManagerException");
throw new QuotaManagerException("No user name for client");
// Start a transaction
// m_filesys.beginReadTransaction(sess);
}
// Get the usage quota and current usage values for the user
long userQuota = m_usageService.getUserQuota( userName);
@@ -383,7 +390,9 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
quotaDetails = new UserQuotaDetails( userName, userQuota);
if ( userUsage > 0L)
{
quotaDetails.setCurrentUsage( userUsage);
}
// Add the details to the live tracking table
@@ -393,23 +402,31 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
UserQuotaDetails details = m_liveUsage.get( userName);
if ( details != null)
{
quotaDetails = details;
}
else
{
m_liveUsage.put( userName, quotaDetails);
}
}
// DEBUG
if ( logger.isDebugEnabled())
{
logger.debug( "Added live usage tracking " + quotaDetails);
}
}
catch ( Exception ex) {
catch ( Exception ex)
{
// Log the error
if ( logger.isErrorEnabled())
logger.error( ex);
if ( logger.isDebugEnabled())
{
logger.debug("Failed to load usage for" + userName, ex);
}
// Failed to load usage details
throw new QuotaManagerException("Failed to load usage for " + userName + ", " + ex);
@@ -493,7 +510,8 @@ public class ContentQuotaManager implements QuotaManager, Runnable {
// Remove inactive records from the live quota tracking
while ( removeNameList.numberOfStrings() > 0) {
while ( removeNameList.numberOfStrings() > 0)
{
// Get the current user name and remove the record

View File

@@ -156,7 +156,7 @@ public class NonTransactionalRuleContentDiskDriver implements ExtendedDiskInterf
{
if(logger.isDebugEnabled())
{
logger.debug("closeFile");
logger.debug("closeFile:" + param.getFullName());
}
ContentContext tctx = (ContentContext) tree.getContext();
@@ -208,7 +208,42 @@ public class NonTransactionalRuleContentDiskDriver implements ExtendedDiskInterf
{
if(logger.isDebugEnabled())
{
logger.debug("createFile");
int sharedAccess = params.getSharedAccess();
String strSharedAccess = "none";
switch(sharedAccess)
{
case SharingMode.NOSHARING:
strSharedAccess = "nosharing";
break;
case SharingMode.READ:
strSharedAccess = "read";
break;
case SharingMode.WRITE:
strSharedAccess = "write";
break;
case SharingMode.READWRITE:
strSharedAccess = "read-write";
break;
case SharingMode.DELETE:
strSharedAccess = "delete";
break;
}
logger.debug("createFile:" + params.getPath()
+ ", isDirectory: " + params.isDirectory()
+ ", isStream: " + params.isStream()
+ ", readOnlyAccess: " + params.isReadOnlyAccess()
+ ", readWriteAccess: " + params.isReadWriteAccess()
+ ", writeOnlyAccess:" +params.isWriteOnlyAccess()
+ ", attributesOnlyAccess:" +params.isAttributesOnlyAccess()
+ ", sequentialAccessOnly:" + params.isSequentialAccessOnly()
+ ", requestBatchOpLock:" +params.requestBatchOpLock()
+ ", requestExclusiveOpLock:" +params.requestExclusiveOpLock()
+ ", isDeleteOnClose:" +params.isDeleteOnClose()
+ ", sharedAccess: " + strSharedAccess
+ " allocationSize: " + params.getAllocationSize());
}
ContentContext tctx = (ContentContext) tree.getContext();

View File

@@ -128,6 +128,12 @@ class ScenarioOpenFileInstance implements ScenarioInstance
if(operation instanceof DeleteFileOperation)
{
DeleteFileOperation d = (DeleteFileOperation)operation;
if(d.getName() == null)
{
return null;
}
if(name.equalsIgnoreCase(d.getName()))
{
logger.debug("Anti-Pattern - delete of the open file, scenario:" + this);
@@ -169,6 +175,12 @@ class ScenarioOpenFileInstance implements ScenarioInstance
if(operation instanceof CloseFileOperation)
{
CloseFileOperation c = (CloseFileOperation)operation;
if(c.getName() == null)
{
return null;
}
if(name.equalsIgnoreCase(c.getName()))
{
NetworkFile file = c.getNetworkFile();
@@ -279,6 +291,11 @@ class ScenarioOpenFileInstance implements ScenarioInstance
{
OpenFileOperation o = (OpenFileOperation)operation;
if(o.getName() == null)
{
return null;
}
if(name.equalsIgnoreCase(o.getName()))
{
if(o.isWriteAccess())
@@ -413,5 +430,7 @@ class ScenarioOpenFileInstance implements ScenarioInstance
}
};
}
}