| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.qpid.util; |
| |
| import org.apache.qpid.test.utils.QpidTestCase; |
| |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.List; |
| import java.util.Properties; |
| |
| public class FileUtilsTest extends QpidTestCase |
| { |
| private static final String COPY = "-Copy"; |
| private static final String SUB = "-Sub"; |
| |
| /** |
| * Additional test for the copy method. |
| * Ensures that the directory count did increase by more than 1 after the copy. |
| */ |
| public void testCopyFile() |
| { |
| final String TEST_DATA = "FileUtilsTest-testCopy-TestDataTestDataTestDataTestDataTestDataTestData"; |
| String fileName = "FileUtilsTest-testCopy"; |
| String fileNameCopy = fileName + COPY; |
| |
| File[] beforeCopyFileList = null; |
| |
| //Create initial file |
| File test = createTestFile(fileName, TEST_DATA); |
| |
| try |
| { |
| //Check number of files before copy |
| beforeCopyFileList = test.getAbsoluteFile().getParentFile().listFiles(); |
| int beforeCopy = beforeCopyFileList.length; |
| |
| //Perform Copy |
| File destination = new File(fileNameCopy); |
| FileUtils.copy(test, destination); |
| //Ensure the JVM cleans up if cleanup failues |
| destination.deleteOnExit(); |
| |
| //Retrieve counts after copy |
| int afterCopy = test.getAbsoluteFile().getParentFile().listFiles().length; |
| |
| int afterCopyFromCopy = new File(fileNameCopy).getAbsoluteFile().getParentFile().listFiles().length; |
| |
| // Validate the copy counts |
| assertEquals("The file listing from the original and the copy differ in length.", afterCopy, afterCopyFromCopy); |
| assertEquals("The number of files did not increase.", beforeCopy + 1, afterCopy); |
| assertEquals("The number of files did not increase.", beforeCopy + 1, afterCopyFromCopy); |
| |
| //Validate copy |
| // Load content |
| String copiedFileContent = FileUtils.readFileAsString(fileNameCopy); |
| assertEquals(TEST_DATA, copiedFileContent); |
| } |
| finally // Ensure clean |
| { |
| //Clean up |
| assertTrue("Unable to cleanup", FileUtils.deleteFile(fileNameCopy)); |
| |
| //Check file list after cleanup |
| File[] afterCleanup = new File(test.getAbsoluteFile().getParent()).listFiles(); |
| checkFileLists(beforeCopyFileList, afterCleanup); |
| |
| //Remove original file |
| assertTrue("Unable to cleanup", test.delete()); |
| } |
| } |
| |
| /** |
| * Create and Copy the following structure: |
| * |
| * testDirectory --+ |
| * +-- testSubDirectory --+ |
| * +-- testSubFile |
| * +-- File |
| * |
| * to testDirectory-Copy |
| * |
| * Validate that the file count in the copy is correct and contents of the copied files is correct. |
| */ |
| public void testCopyRecursive() |
| { |
| final String TEST_DATA = "FileUtilsTest-testDirectoryCopy-TestDataTestDataTestDataTestDataTestDataTestData"; |
| String fileName = "FileUtilsTest-testCopy"; |
| String TEST_DIR = "testDirectoryCopy"; |
| |
| //Create Initial Structure |
| File testDir = new File(TEST_DIR); |
| |
| //Check number of files before copy |
| File[] beforeCopyFileList = testDir.getAbsoluteFile().getParentFile().listFiles(); |
| |
| try |
| { |
| //Create Directories |
| assertTrue("Test directory already exists cannot test.", !testDir.exists()); |
| |
| if (!testDir.mkdir()) |
| { |
| fail("Unable to make test Directory"); |
| } |
| |
| File testSubDir = new File(TEST_DIR + File.separator + TEST_DIR + SUB); |
| if (!testSubDir.mkdir()) |
| { |
| fail("Unable to make test sub Directory"); |
| } |
| |
| //Create Files |
| createTestFile(testDir.toString() + File.separator + fileName, TEST_DATA); |
| createTestFile(testSubDir.toString() + File.separator + fileName + SUB, TEST_DATA); |
| |
| //Ensure the JVM cleans up if cleanup failues |
| testSubDir.deleteOnExit(); |
| testDir.deleteOnExit(); |
| |
| //Perform Copy |
| File copyDir = new File(testDir.toString() + COPY); |
| try |
| { |
| FileUtils.copyRecursive(testDir, copyDir); |
| } |
| catch (FileNotFoundException e) |
| { |
| fail(e.getMessage()); |
| } |
| catch (FileUtils.UnableToCopyException e) |
| { |
| fail(e.getMessage()); |
| } |
| |
| //Validate Copy |
| assertEquals("Copied directory should only have one file and one directory in it.", 2, copyDir.listFiles().length); |
| |
| //Validate Copy File Contents |
| String copiedFileContent = FileUtils.readFileAsString(copyDir.toString() + File.separator + fileName); |
| assertEquals(TEST_DATA, copiedFileContent); |
| |
| //Validate Name of Sub Directory |
| assertTrue("Expected subdirectory is not a directory", new File(copyDir.toString() + File.separator + TEST_DIR + SUB).isDirectory()); |
| |
| //Assert that it contains only one item |
| assertEquals("Copied sub directory should only have one directory in it.", 1, new File(copyDir.toString() + File.separator + TEST_DIR + SUB).listFiles().length); |
| |
| //Validate content of Sub file |
| copiedFileContent = FileUtils.readFileAsString(copyDir.toString() + File.separator + TEST_DIR + SUB + File.separator + fileName + SUB); |
| assertEquals(TEST_DATA, copiedFileContent); |
| } |
| finally |
| { |
| //Clean up source and copy directory. |
| assertTrue("Unable to cleanup", FileUtils.delete(testDir, true)); |
| assertTrue("Unable to cleanup", FileUtils.delete(new File(TEST_DIR + COPY), true)); |
| |
| //Check file list after cleanup |
| File[] afterCleanup = testDir.getAbsoluteFile().getParentFile().listFiles(); |
| checkFileLists(beforeCopyFileList, afterCleanup); |
| } |
| } |
| |
| |
| /** |
| * Helper method to create a temporary file with test content. |
| * |
| * @param test_data The data to store in the file |
| * |
| * @return The File reference |
| */ |
| private File createTestFileInTmpDir(final String testData) throws Exception |
| { |
| final File tmpFile = File.createTempFile("test", "tmp"); |
| |
| return createTestFile(tmpFile.getCanonicalPath(), testData); |
| } |
| /** |
| * Helper method to create a test file with a string content |
| * |
| * @param fileName The fileName to use in the creation |
| * @param test_data The data to store in the file |
| * |
| * @return The File reference |
| */ |
| private File createTestFile(String fileName, String test_data) |
| { |
| File test = new File(fileName); |
| |
| try |
| { |
| test.createNewFile(); |
| //Ensure the JVM cleans up if cleanup failues |
| test.deleteOnExit(); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| |
| BufferedWriter writer = null; |
| try |
| { |
| writer = new BufferedWriter(new FileWriter(test)); |
| try |
| { |
| writer.write(test_data); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| finally |
| { |
| try |
| { |
| if (writer != null) |
| { |
| writer.close(); |
| } |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| } |
| |
| return test; |
| } |
| |
| /** Test that deleteFile only deletes the specified file */ |
| public void testDeleteFile() |
| { |
| File test = new File("FileUtilsTest-testDelete"); |
| //Record file count in parent directory to check it is not changed by delete |
| String path = test.getAbsolutePath(); |
| File[] filesBefore = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountBefore = filesBefore.length; |
| |
| try |
| { |
| test.createNewFile(); |
| //Ensure the JVM cleans up if cleanup failues |
| test.deleteOnExit(); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| |
| assertTrue("File does not exists", test.exists()); |
| assertTrue("File is not a file", test.isFile()); |
| |
| //Check that file creation can be seen on disk |
| int fileCountCreated = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles().length; |
| assertEquals("File creation was no registered", fileCountBefore + 1, fileCountCreated); |
| |
| //Perform Delete |
| assertTrue("Unable to cleanup", FileUtils.deleteFile("FileUtilsTest-testDelete")); |
| |
| assertTrue("File exists after delete", !test.exists()); |
| |
| //Check that after deletion the file count is now accurate |
| File[] filesAfter = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountAfter = filesAfter.length; |
| assertEquals("File creation was no registered", fileCountBefore, fileCountAfter); |
| |
| checkFileLists(filesBefore, filesAfter); |
| } |
| |
| public void testDeleteNonExistentFile() |
| { |
| File test = new File("FileUtilsTest-testDelete-" + System.currentTimeMillis()); |
| |
| assertTrue("File exists", !test.exists()); |
| assertFalse("File is a directory", test.isDirectory()); |
| |
| assertTrue("Delete Succeeded ", !FileUtils.delete(test, true)); |
| } |
| |
| public void testDeleteNull() |
| { |
| try |
| { |
| FileUtils.delete(null, true); |
| fail("Delete with null value should throw NPE."); |
| } |
| catch (NullPointerException npe) |
| { |
| // expected path |
| } |
| } |
| |
| /** |
| * Tests that openFileOrDefaultResource can open a file on the filesystem. |
| * |
| */ |
| public void testOpenFileOrDefaultResourceOpensFileOnFileSystem() throws Exception |
| { |
| final File testFile = createTestFileInTmpDir("src=tmpfile"); |
| final String filenameOnFilesystem = testFile.getCanonicalPath(); |
| final String defaultResource = "org/apache/qpid/util/default.properties"; |
| |
| |
| final InputStream is = FileUtils.openFileOrDefaultResource(filenameOnFilesystem, defaultResource, this.getClass().getClassLoader()); |
| assertNotNull("Stream must not be null", is); |
| final Properties p = new Properties(); |
| p.load(is); |
| assertEquals("tmpfile", p.getProperty("src")); |
| } |
| |
| /** |
| * Tests that openFileOrDefaultResource can open a file on the classpath. |
| * |
| */ |
| public void testOpenFileOrDefaultResourceOpensFileOnClasspath() throws Exception |
| { |
| final String mydefaultsResource = "org/apache/qpid/util/mydefaults.properties"; |
| final String defaultResource = "org/apache/qpid/util/default.properties"; |
| |
| |
| final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader()); |
| assertNotNull("Stream must not be null", is); |
| final Properties p = new Properties(); |
| p.load(is); |
| assertEquals("mydefaults", p.getProperty("src")); |
| } |
| |
| /** |
| * Tests that openFileOrDefaultResource returns the default resource when file cannot be found. |
| */ |
| public void testOpenFileOrDefaultResourceOpensDefaultResource() throws Exception |
| { |
| final File fileThatDoesNotExist = new File("/does/not/exist.properties"); |
| assertFalse("Test must not exist", fileThatDoesNotExist.exists()); |
| |
| final String defaultResource = "org/apache/qpid/util/default.properties"; |
| |
| final InputStream is = FileUtils.openFileOrDefaultResource(fileThatDoesNotExist.getCanonicalPath(), defaultResource, this.getClass().getClassLoader()); |
| assertNotNull("Stream must not be null", is); |
| Properties p = new Properties(); |
| p.load(is); |
| assertEquals("default.properties", p.getProperty("src")); |
| } |
| |
| /** |
| * Tests that openFileOrDefaultResource returns null if neither the file nor |
| * the default resource can be found.. |
| */ |
| public void testOpenFileOrDefaultResourceReturnsNullWhenNeitherCanBeFound() throws Exception |
| { |
| |
| final String mydefaultsResource = "org/apache/qpid/util/doesnotexisteiether.properties"; |
| final String defaultResource = "org/apache/qpid/util/doesnotexisteiether.properties"; |
| |
| final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader()); |
| assertNull("Stream must be null", is); |
| } |
| |
| /** |
| * Given two lists of File arrays ensure they are the same length and all entries in Before are in After |
| * |
| * @param filesBefore File[] |
| * @param filesAfter File[] |
| */ |
| private void checkFileLists(File[] filesBefore, File[] filesAfter) |
| { |
| assertNotNull("Before file list cannot be null", filesBefore); |
| assertNotNull("After file list cannot be null", filesAfter); |
| |
| assertEquals("File lists are unequal", filesBefore.length, filesAfter.length); |
| |
| for (File fileBefore : filesBefore) |
| { |
| boolean found = false; |
| |
| for (File fileAfter : filesAfter) |
| { |
| if (fileBefore.getAbsolutePath().equals(fileAfter.getAbsolutePath())) |
| { |
| found = true; |
| break; |
| } |
| } |
| |
| assertTrue("File'" + fileBefore.getName() + "' was not in directory afterwards", found); |
| } |
| } |
| |
| public void testNonRecursiveNonEmptyDirectoryDeleteFails() |
| { |
| String directoryName = "FileUtilsTest-testRecursiveDelete"; |
| File test = new File(directoryName); |
| |
| //Record file count in parent directory to check it is not changed by delete |
| String path = test.getAbsolutePath(); |
| File[] filesBefore = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountBefore = filesBefore.length; |
| |
| assertTrue("Directory exists", !test.exists()); |
| |
| test.mkdir(); |
| |
| //Create a file in the directory |
| String fileName = test.getAbsolutePath() + File.separatorChar + "testFile"; |
| File subFile = new File(fileName); |
| try |
| { |
| subFile.createNewFile(); |
| //Ensure the JVM cleans up if cleanup failues |
| subFile.deleteOnExit(); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| //Ensure the JVM cleans up if cleanup failues |
| // This must be after the subFile as the directory must be empty before |
| // the delete is performed |
| test.deleteOnExit(); |
| |
| //Try and delete the non-empty directory |
| assertFalse("Non Empty Directory was successfully deleted.", FileUtils.deleteDirectory(directoryName)); |
| |
| //Check directory is still there |
| assertTrue("Directory was deleted.", test.exists()); |
| |
| // Clean up |
| assertTrue("Unable to cleanup", FileUtils.delete(test, true)); |
| |
| //Check that after deletion the file count is now accurate |
| File[] filesAfter = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountAfter = filesAfter.length; |
| assertEquals("File creation was no registered", fileCountBefore, fileCountAfter); |
| |
| checkFileLists(filesBefore, filesAfter); |
| } |
| |
| /** Test that an empty directory can be deleted with deleteDirectory */ |
| public void testEmptyDirectoryDelete() |
| { |
| String directoryName = "FileUtilsTest-testRecursiveDelete"; |
| File test = new File(directoryName); |
| |
| //Record file count in parent directory to check it is not changed by delete |
| String path = test.getAbsolutePath(); |
| File[] filesBefore = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountBefore = filesBefore.length; |
| |
| assertTrue("Directory exists", !test.exists()); |
| |
| test.mkdir(); |
| //Ensure the JVM cleans up if cleanup failues |
| test.deleteOnExit(); |
| |
| //Try and delete the empty directory |
| assertTrue("Non Empty Directory was successfully deleted.", FileUtils.deleteDirectory(directoryName)); |
| |
| //Check directory is still there |
| assertTrue("Directory was deleted.", !test.exists()); |
| |
| //Check that after deletion the file count is now accurate |
| File[] filesAfter = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountAfter = filesAfter.length; |
| assertEquals("File creation was no registered", fileCountBefore, fileCountAfter); |
| |
| checkFileLists(filesBefore, filesAfter); |
| |
| } |
| |
| /** Test that deleteDirectory on a non empty directory to complete */ |
| public void testNonEmptyDirectoryDelete() |
| { |
| String directoryName = "FileUtilsTest-testRecursiveDelete"; |
| File test = new File(directoryName); |
| |
| assertTrue("Directory exists", !test.exists()); |
| |
| //Record file count in parent directory to check it is not changed by delete |
| String path = test.getAbsolutePath(); |
| File[] filesBefore = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountBefore = filesBefore.length; |
| |
| test.mkdir(); |
| |
| //Create a file in the directory |
| String fileName = test.getAbsolutePath() + File.separatorChar + "testFile"; |
| File subFile = new File(fileName); |
| try |
| { |
| subFile.createNewFile(); |
| //Ensure the JVM cleans up if cleanup failues |
| subFile.deleteOnExit(); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| |
| // Ensure the JVM cleans up if cleanup failues |
| // This must be after the subFile as the directory must be empty before |
| // the delete is performed |
| test.deleteOnExit(); |
| |
| //Try and delete the non-empty directory non-recursively |
| assertFalse("Non Empty Directory was successfully deleted.", FileUtils.delete(test, false)); |
| |
| //Check directory is still there |
| assertTrue("Directory was deleted.", test.exists()); |
| |
| // Clean up |
| assertTrue("Unable to cleanup", FileUtils.delete(test, true)); |
| |
| //Check that after deletion the file count is now accurate |
| File[] filesAfter = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountAfter = filesAfter.length; |
| assertEquals("File creation was no registered", fileCountBefore, fileCountAfter); |
| |
| checkFileLists(filesBefore, filesAfter); |
| |
| } |
| |
| /** Test that a recursive delete successeds */ |
| public void testRecursiveDelete() |
| { |
| String directoryName = "FileUtilsTest-testRecursiveDelete"; |
| File test = new File(directoryName); |
| |
| assertTrue("Directory exists", !test.exists()); |
| |
| //Record file count in parent directory to check it is not changed by delete |
| String path = test.getAbsolutePath(); |
| File[] filesBefore = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountBefore = filesBefore.length; |
| |
| test.mkdir(); |
| |
| createSubDir(directoryName, 2, 4); |
| |
| //Ensure the JVM cleans up if cleanup failues |
| // This must be after the sub dir creation as the delete order is |
| // recorded and the directory must be empty to be deleted. |
| test.deleteOnExit(); |
| |
| assertFalse("Non recursive delete was able to directory", FileUtils.delete(test, false)); |
| |
| assertTrue("File does not exist after non recursive delete", test.exists()); |
| |
| assertTrue("Unable to cleanup", FileUtils.delete(test, true)); |
| |
| assertTrue("File exist after recursive delete", !test.exists()); |
| |
| //Check that after deletion the file count is now accurate |
| File[] filesAfter = new File(path.substring(0, path.lastIndexOf(File.separator))).listFiles(); |
| int fileCountAfter = filesAfter.length; |
| assertEquals("File creation was no registered", fileCountBefore, fileCountAfter); |
| |
| checkFileLists(filesBefore, filesAfter); |
| |
| } |
| |
| private void createSubDir(String path, int directories, int files) |
| { |
| File directory = new File(path); |
| |
| assertTrue("Directory" + path + " does not exists", directory.exists()); |
| |
| for (int dir = 0; dir < directories; dir++) |
| { |
| String subDirName = path + File.separatorChar + "sub" + dir; |
| File subDir = new File(subDirName); |
| |
| subDir.mkdir(); |
| |
| createSubDir(subDirName, directories - 1, files); |
| //Ensure the JVM cleans up if cleanup failues |
| // This must be after the sub dir creation as the delete order is |
| // recorded and the directory must be empty to be deleted. |
| subDir.deleteOnExit(); |
| } |
| |
| for (int file = 0; file < files; file++) |
| { |
| String subDirName = path + File.separatorChar + "file" + file; |
| File subFile = new File(subDirName); |
| try |
| { |
| subFile.createNewFile(); |
| //Ensure the JVM cleans up if cleanup failues |
| subFile.deleteOnExit(); |
| } |
| catch (IOException e) |
| { |
| fail(e.getMessage()); |
| } |
| } |
| } |
| |
| public static final String SEARCH_STRING = "testSearch"; |
| |
| /** |
| * Test searchFile(File file, String search) will find a match when it |
| * exists. |
| * |
| * @throws java.io.IOException if unable to perform test setup |
| */ |
| public void testSearchSucceed() throws IOException |
| { |
| File _logfile = File.createTempFile("FileUtilsTest-testSearchSucceed", ".out"); |
| |
| prepareFileForSearchTest(_logfile); |
| |
| List<String> results = FileUtils.searchFile(_logfile, SEARCH_STRING); |
| |
| assertNotNull("Null result set returned", results); |
| |
| assertEquals("Results do not contain expected count", 1, results.size()); |
| } |
| |
| /** |
| * Test searchFile(File file, String search) will not find a match when the |
| * test string does not exist. |
| * |
| * @throws java.io.IOException if unable to perform test setup |
| */ |
| public void testSearchFail() throws IOException |
| { |
| File _logfile = File.createTempFile("FileUtilsTest-testSearchFail", ".out"); |
| |
| prepareFileForSearchTest(_logfile); |
| |
| List<String> results = FileUtils.searchFile(_logfile, "Hello"); |
| |
| assertNotNull("Null result set returned", results); |
| |
| //Validate we only got one message |
| if (results.size() > 0) |
| { |
| System.err.println("Unexpected messages"); |
| |
| for (String msg : results) |
| { |
| System.err.println(msg); |
| } |
| } |
| |
| assertEquals("Results contains data when it was not expected", |
| 0, results.size()); |
| } |
| |
| /** |
| * Write the SEARCH_STRING in to the given file. |
| * |
| * @param logfile The file to write the SEARCH_STRING into |
| * |
| * @throws IOException if an error occurs |
| */ |
| private void prepareFileForSearchTest(File logfile) throws IOException |
| { |
| BufferedWriter writer = new BufferedWriter(new FileWriter(logfile)); |
| writer.append(SEARCH_STRING); |
| writer.flush(); |
| writer.close(); |
| } |
| |
| } |