/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.quicksetup.util;
import static org.testng.Assert.*;
import org.testng.annotations.*;
import org.opends.quicksetup.QuickSetupTestCase;
import org.opends.quicksetup.TestUtilities;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.ApplicationException;
import org.opends.server.util.StaticUtils;
import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileFilter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
* FileManager Tester.
*/
@Test(groups = {"slow"}, sequential=true)
public class FileManagerTest extends QuickSetupTestCase {
File fmWorkspace = null;
FileManager fileManager = null;
@BeforeClass
public void setUp() throws Exception {
fileManager = new FileManager();
fmWorkspace = new File(TestUtilities.getQuickSetupTestWorkspace(),
"filemanagertests");
if (fmWorkspace.exists()) {
fileManager.deleteRecursively(fmWorkspace);
}
if (!fmWorkspace.mkdir()) {
throw new IllegalStateException("cannot create FileManagerTest workspace");
}
}
@AfterMethod
public void cleanupWorkspace() throws Exception {
String[] children = fmWorkspace.list();
if (children != null) {
for (String child : children) {
fileManager.deleteRecursively(new File(fmWorkspace, child));
}
}
}
/**
* Tests synchronized.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testSynchronize() throws Exception {
File s = new File(fmWorkspace, "s");
File t = new File(fmWorkspace, "t");
String childOfS = "child of s";
String childOfT = "child of t";
createSourceFiles(s, childOfS);
createSourceFiles(t, childOfT);
File t_d1 = new File(t, "d1");
File t_f1a = new File(t_d1, "f1a");
File t_f1b = new File(t_d1, "f1b");
File t_d2 = new File(t, "d2");
File t_f2a = new File(t_d2, "f2a");
File t_d2b = new File(t_d2, "d2b");
File t_f2b1 = new File(t_d2b, "f2b1");
assertTrue(t_d1.exists());
assertTrue(t_f1a.exists());
assertTrue(t_f1b.exists());
assertTrue(t_d2.exists());
assertTrue(t_f2a.exists());
assertTrue(t_d2b.exists());
assertTrue(t_f2b1.exists());
assertTrue(t_f2b1.delete());
assertTrue(t_d2b.delete());
assertTrue(t_f1a.delete());
fileManager.synchronize(s, t);
// Make sure files we deleted above were copied from the source dir
assertTrue(t_f2b1.exists());
assertTrue(childOfS.equals(contentsOf(t_f2b1)));
assertTrue(t_d2b.exists());
assertTrue(t_f1a.exists());
assertTrue(childOfS.equals(contentsOf(t_f1a)));
// Make sure files that pre-existed didn't get touched
assertTrue(childOfT.equals(contentsOf(t_f1b)));
assertTrue(childOfT.equals(contentsOf(t_f2a)));
}
/**
* Tests the rename.
* @throws Exception
*/
@Test
public void testRenameNonExistentTarget() throws Exception {
File src = File.createTempFile("src", null);
File target = new File(src.getParentFile(), "target");
try {
if (target.exists()) {
target.delete();
assert(!target.exists());
}
fileManager.rename(src, target);
assert(!src.exists());
assert(target.exists());
} finally {
src.delete();
target.delete();
}
}
/**
* Tests the {@link StaticUtils#renameFile(java.io.File, java.io.File)}
* method.
*
* @throws Exception If the test failed unexpectedly.
*/
@Test(enabled = false)
public void testRenameFileExistentTarget() throws Exception {
File src = File.createTempFile("src", null);
File target = File.createTempFile("target", null);
try {
StaticUtils.renameFile(src, target);
assert(!src.exists());
assert(target.exists());
} finally {
src.delete();
target.delete();
}
}
/**
* Tests the {@link StaticUtils#renameFile(java.io.File, java.io.File)}
* method. Renaming locked files is a problem on Windows but not so
* much on other platforms.
*
* @throws Exception If the test failed unexpectedly.
*/
@Test(enabled = false, groups={"windows"}, expectedExceptions=IOException.class)
public void testRenameFileLockedTarget() throws Exception {
File src = File.createTempFile("src", null);
File target = File.createTempFile("target", null);
FileChannel c = new RandomAccessFile(target, "rw").getChannel();
FileLock lock = c.lock();
try {
StaticUtils.renameFile(src, target);
} finally {
lock.release();
src.delete();
target.delete();
}
}
/**
* Tests basic move.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testMove() throws Exception {
File fromDir = new File(fmWorkspace, "from");
fromDir.mkdir();
File toDir = new File(fmWorkspace, "to");
toDir.mkdir();
createSourceFiles(fromDir, "abc");
fileManager.move(fromDir, toDir);
assertFalse(fromDir.exists());
assertTrue(new File(toDir, fromDir.getName()).exists());
}
/**
* Tests basic move with filtering.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testMove2() throws Exception {
File fromDir = new File(fmWorkspace, "from");
fromDir.mkdir();
File toDir = new File(fmWorkspace, "to");
toDir.mkdir();
createSourceFiles(fromDir, "abc");
// Create a filter that should reject the operation
FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
return false;
}
};
fileManager.move(fromDir, toDir, filter);
assertTrue(fromDir.exists());
assertFalse(new File(toDir, fromDir.getName()).exists());
}
/**
* Tests basic delete.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testDelete() throws Exception {
File dir = new File(fmWorkspace, "dir");
dir.mkdir();
assertTrue(dir.exists());
fileManager.delete(dir);
assertFalse(dir.exists());
File file = new File(fmWorkspace, "file");
writeContents(file, "abc");
assertTrue(file.exists());
fileManager.delete(file);
assertFalse(file.exists());
}
/**
* Tests basic delete with filtering.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testDelete2() throws Exception {
// Create a filter that should reject the operation
FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
return false;
}
};
File dir = new File(fmWorkspace, "dir");
dir.mkdir();
assertTrue(dir.exists());
fileManager.delete(dir, filter);
assertTrue(dir.exists());
File file = new File(fmWorkspace, "file");
writeContents(file, "abc");
assertTrue(file.exists());
fileManager.delete(file, filter);
assertTrue(file.exists());
}
/**
* Test recursive delete.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testDeleteRecursively() throws Exception {
File dir = new File(fmWorkspace, "dir");
createSourceFiles(dir, "abc");
assertTrue(dir.exists());
fileManager.deleteRecursively(dir);
assertFalse(dir.exists());
}
/**
* Test recursive delete with filtering.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testDeleteRecursively1() throws Exception {
File dir = new File(fmWorkspace, "dir");
createSourceFiles(dir, "abc");
File d2 = new File(dir, "d2");
File d2b = new File(d2, "d2b");
final File f2b1 = new File(d2b, "f2b1");
// Test that a filter can stop a delete altogether
FileFilter rejectOpFilter = new FileFilter() {
public boolean accept(File pathname) {
return false;
}
};
int childCount = countSelfAndAllChildren(dir);
assertTrue(dir.exists());
fileManager.deleteRecursively(dir, rejectOpFilter,
FileManager.DeletionPolicy.DELETE_IMMEDIATELY);
assertTrue(dir.exists());
// Make sure we didn't lose any kids
assertTrue(childCount == countSelfAndAllChildren(dir));
// Test that using a filter to delete one file works
FileFilter killChildFileFilter = new FileFilter() {
public boolean accept(File f) {
return f.equals(f2b1);
}
};
assertTrue(dir.exists());
assertTrue(f2b1.exists());
fileManager.deleteRecursively(dir, killChildFileFilter,
FileManager.DeletionPolicy.DELETE_IMMEDIATELY);
assertTrue(dir.exists());
assertTrue((childCount -1) == countSelfAndAllChildren(dir));
assertFalse(f2b1.exists());
}
/**
* Test basic copy.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testCopy() throws Exception {
File file = new File(fmWorkspace, "file");
writeContents(file, "abc");
File dir = new File(fmWorkspace, "dir");
String[] children = dir.list();
assertTrue(children == null || children.length == 0);
fileManager.copy(file, dir);
assertTrue(file.exists());
assertTrue(dir.list().length == 1);
}
/**
* Make sure things fail if target is a file and not a directory.
* @throws Exception if something unexpected
*/
@Test(enabled = false, expectedExceptions = ApplicationException.class)
public void testCopy1() throws Exception {
File file = new File(fmWorkspace, "file");
writeContents(file, "abc");
File file2 = new File(fmWorkspace, "file2");
writeContents(file2, "abc");
fileManager.copy(file, file2);
}
/**
* Make sure things fail if target is a file and not a directory.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testCopy2() throws Exception {
File file = new File(fmWorkspace, "file");
String NEW_CHILD_CONTENT = "new";
writeContents(file, NEW_CHILD_CONTENT);
File dir = new File(fmWorkspace, "dir");
dir.mkdir();
File dirChild = new File(dir, "file");
String ORIGINAL_CHILD_CONTENT = "orinld";
writeContents(dirChild, ORIGINAL_CHILD_CONTENT);
// Try a copy without overwriting and make sure the original
// file didn't get replaced.
fileManager.copy(file, dir, false);
assertTrue(contentsOf(dirChild).equals(ORIGINAL_CHILD_CONTENT));
// New try a copy with overwrite true and make sure the original
// file got replaced.
fileManager.copy(file, dir, true);
assertTrue(contentsOf(dirChild).equals(NEW_CHILD_CONTENT));
}
/**
* Test copy recursively.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testCopyRecursively() throws Exception {
File source = new File(fmWorkspace, "source");
createSourceFiles(source, "abc");
int count = countSelfAndAllChildren(source);
File dest = new File(fmWorkspace, "dest");
fileManager.copyRecursively(source, dest);
File copiedSource = new File(dest, "source");
assertTrue(copiedSource.exists());
assertTrue(count == countSelfAndAllChildren(copiedSource));
}
/**
* Tests copy recursively with filtering.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testCopyRecursively1() throws Exception {
// Test that a filter can stop a delete altogether
FileFilter rejectOpFilter = new FileFilter() {
public boolean accept(File pathname) {
return false;
}
};
File source = new File(fmWorkspace, "source");
createSourceFiles(source, "abc");
File d2 = new File(source, "d2");
File d2b = new File(d2, "d2b");
final File f2b1 = new File(d2b, "f2b1");
File dest = new File(fmWorkspace, "dest");
// Make sure a copy with a rejection filter doesn't do anything
fileManager.copyRecursively(source, dest, rejectOpFilter);
File copiedSource = new File(dest, "source");
assertFalse(copiedSource.exists());
assertTrue(countSelfAndAllChildren(dest) == 1);
// Test that using a filter to delete one file works
FileFilter copyChildFileFilter = new FileFilter() {
public boolean accept(File f) {
return f.equals(f2b1);
}
};
fileManager.copyRecursively(source, dest, copyChildFileFilter);
File copiedD2 = new File(copiedSource, "d2");
File copiedD2b = new File(d2, "d2b");
final File copiedF2b1 = new File(d2b, "f2b1");
assertTrue(copiedSource.exists());
assertTrue(countSelfAndAllChildren(copiedSource) == 4);
assertTrue(copiedD2.exists());
assertTrue(countSelfAndAllChildren(copiedD2) == 3);
assertTrue(copiedD2b.exists());
assertTrue(countSelfAndAllChildren(copiedD2b) == 2);
assertTrue(copiedF2b1.exists());
}
/**
* Tests copy recursively with filtering and overwrite.
* @throws Exception if something unexpected
*/
@Test(enabled = false)
public void testCopyRecursively2() throws Exception {
File source = new File(fmWorkspace, "source");
String FILES_TO_COPY = "to copy";
createSourceFiles(source, FILES_TO_COPY);
File d2 = new File(source, "d2");
File d2b = new File(d2, "d2b");
final File f2b1 = new File(d2b, "f2b1");
File dest = new File(fmWorkspace, "dest");
File copiedSource = new File(dest, "source");
File copiedD2 = new File(copiedSource, "d2");
copiedD2.mkdir();
File copiedD2b = new File(d2, "d2b");
copiedD2b.mkdir();
final File copiedF2b1 = new File(d2b, "f2b1");
String ORIGINAL = "original";
writeContents(copiedF2b1, ORIGINAL);
// Test that using a filter to delete one file works
FileFilter copyChildFileFilter = new FileFilter() {
public boolean accept(File f) {
return f.equals(f2b1);
}
};
// With overwrite off make sure it doesn't get replaced
fileManager.copyRecursively(source, dest, copyChildFileFilter, false);
assertTrue(ORIGINAL.equals(contentsOf(copiedF2b1)));
// Now with overwrite make sure it gets replaced.
fileManager.copyRecursively(source, dest, copyChildFileFilter, true);
assertTrue(ORIGINAL.equals(contentsOf(copiedF2b1)));
}
@DataProvider(name = "differTestData")
public Object[][] differTestData() {
return new Object[][] {
new Object[] { "abc", "abc" },
new Object[] { "abc", "xyz" },
new Object[] { "abc", "abc\n" },
new Object[] { "abc\n", "abc\n" },
new Object[] { "abc\nabc", "abc\nabc" },
new Object[] { "abc\nabc\nabc", "abc\nabc\nabc" }
};
}
@Test(dataProvider = "differTestData")
public void testFilesDiffer(String contents1, String contents2)
throws Exception
{
File f1 = new File(fmWorkspace, "f1");
File f2 = new File(fmWorkspace, "f2");
writeContents(f1, contents1);
writeContents(f2, contents2);
if (!contents1.equals(contents2)) {
assertTrue(fileManager.filesDiffer(f1, f2),
"File contents '" + contents1 + "' and '" + contents2 + "' are " +
"not equal despite what FileManager claims");
} else {
assertFalse(fileManager.filesDiffer(f1, f2),
"File contents '" + contents1 + "' and '" + contents2 + "' are " +
"equal despite what FileManager claims");
}
f1.delete();
f2.delete();
}
/**
* Creates a set of file for testing.
* @param parent of the files.
* @param childContent content of non-directory files.
* @throws IOException if something unexpected
*/
private void createSourceFiles(File parent, String childContent)
throws IOException {
if (!parent.exists()) {
parent.mkdir();
}
File d1 = new File(parent, "d1");
File f1a = new File(d1, "f1a");
File f1b = new File(d1, "f1b");
File d2 = new File(parent, "d2");
File f2a = new File(d2, "f2a");
File d2b = new File(d2, "d2b");
File f2b1 = new File(d2b, "f2b1");
d1.mkdir();
d2.mkdir();
d2b.mkdir();
writeContents(f1a, childContent);
writeContents(f1b, childContent);
writeContents(f2a, childContent);
writeContents(f2b1, childContent);
}
private void writeContents(File f, String content) throws IOException {
if (!f.exists()) f.createNewFile();
FileWriter fw = new FileWriter(f);
fw.write(content);
fw.flush();
fw.close();
}
private String contentsOf(File f) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(f));
StringBuilder sb = new StringBuilder();
String s;
s = br.readLine();
while (s != null) {
sb.append(s);
s = br.readLine();
if (s != null) {
sb.append(Constants.LINE_SEPARATOR);
}
}
br.close();
return sb.toString();
}
private int countSelfAndAllChildren(File f) {
int count = 0;
if (f != null) {
count = 1;
if (f.isDirectory()) {
File[] children = f.listFiles();
if (children != null) {
for (File child : children) {
count += countSelfAndAllChildren(child);
}
}
}
}
return count;
}
}