// NAnt - A .NET build tool // Copyright (C) 2002-2003 Scott Hernandez (ScottHernandez@hotmail.com) // // 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Scott Hernandez (ScottHernandez@hotmail.com) using System; using System.IO; using System.Reflection; using System.Text; using System.Xml; using System.Globalization; using NUnit.Framework; using NAnt.Core; namespace Tests.NAnt.Core.Tasks { /// /// Tests the deletion of the following: /// /// /// file /// folder /// folder with a file (recursive) /// /// /// /// This test should also test for failures, like permission errors, and filesets [TestFixture] public class CopyTest : BuildTestBase { const string _xmlProjectTemplate = @" "; const string _xmlProjectTemplate2 = @" "; const string _xmlProjectTemplate3 = @" "; string tempFile1, tempFile2, tempFile3, tempFile4, tempFile5, tempFile6, tempFile7; string tempDir1, tempDir2, tempDir3, tempDir4, tempDir5; /// /// Creates a structure like so: /// a.b\ /// a.bb /// a.bc /// foo\* /// x.x /// goo\* /// x\ /// y.y /// ha.he /// ha.he2* /// ha.he3* /// empty\ -- note: empty directory /// [SetUp] protected override void SetUp() { base.SetUp(); tempDir1 = CreateTempDir("a.b"); tempDir2 = CreateTempDir(Path.Combine(tempDir1, "foo")); tempDir3 = CreateTempDir(Path.Combine(tempDir1, "goo")); tempDir4 = CreateTempDir(Path.Combine(tempDir1, Path.Combine(tempDir3, "x"))); tempDir5 = CreateTempDir(Path.Combine(tempDir1, "empty")); tempFile1 = CreateTempFile(Path.Combine(tempDir1, "a.bb")); tempFile2 = CreateTempFile(Path.Combine(tempDir1, "a.bc")); tempFile3 = CreateTempFile(Path.Combine(tempDir2, "x.x")); tempFile4 = CreateTempFile(Path.Combine(tempDir4, "y.y")); tempFile5 = CreateTempFile(Path.Combine(tempDir3, "ha.he")); tempFile6 = CreateTempFile(Path.Combine(tempDir3, "ha.he2")); tempFile7 = CreateTempFile(Path.Combine(tempDir3, "ha.he3")); File.SetAttributes(tempDir2, FileAttributes.ReadOnly); File.SetAttributes(tempDir3, FileAttributes.ReadOnly); File.SetAttributes(Path.Combine(tempDir3, "ha.he3"), FileAttributes.ReadOnly); File.SetAttributes(Path.Combine(tempDir3, "ha.he2"), FileAttributes.ReadOnly); } private string GetPath(string rootPath, params string[] fileParts) { string path = rootPath; foreach (string filePart in fileParts) { path = Path.Combine(path, Path.GetFileName(filePart)); } return path; } /// /// Copy only the directory given. /// [Test] public void Test_Copy_Only_Directory() { string dest = CreateTempDir("a.99"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1, string.Empty)); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should not have been created:" + tempFile1); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should not have been created:" + tempFile2); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should not have been created:" + tempFile3); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should not have been created:" + tempFile4); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should not have been created:" + tempFile5); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should not have been created:" + tempFile6); Assert.IsFalse(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should not have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsFalse(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should not have been created:" + tempDir2); Assert.IsFalse(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should not have been created:" + tempDir3); Assert.IsFalse(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should not have been created:" + tempDir4); Assert.IsFalse(Directory.Exists(GetPath(dest,tempDir1,tempDir5)), "Dir should not have been created:" + tempDir5); } /// /// Ensure that an invalid path for destination directory causes a /// to be thrown. /// [Test] public void Test_Copy_InvalidDestinationDirectory() { if (!PlatformHelper.IsUnix) { try { RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, "|", tempDir1, string.Empty)); // have the test fail Assert.Fail("Build should have failed."); } catch (TestBuildException ex) { // assert that a BuildException was the cause of the TestBuildException Assert.IsTrue((ex.InnerException != null && ex.InnerException.GetType() == typeof(BuildException))); } } } /// /// Copy everything from under tempDir1 to a new temp directory and /// ensure it exists. /// [Test] public void Test_Copy_Structure() { string dest = CreateTempDir("a.xx"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "\\**\\*", string.Empty)); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should have been created:" + tempDir2); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should have been created:" + tempDir3); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should have been created:" + tempDir4); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir5)), "Dir should have been created:" + tempDir5); } /// /// Copy everything from under tempDir1 to a new temp directory and /// ensure it exists. /// [Test] public void Test_Copy_Structure_IncludeEmptyDirs() { string dest = CreateTempDir("a.xx"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "\\**\\*", " includeemptydirs='true' ")); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should have been created:" + tempDir2); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should have been created:" + tempDir3); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should have been created:" + tempDir4); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir5)), "Dir should have been created:" + tempDir5); } /// /// Copy everything from under tempDir1 to a new temp directory and /// ensure it exists. Do NOT copy empty dirs. /// [Test] public void Test_Copy_Structure_ExcludeEmptyDirs() { string dest = CreateTempDir("a.xx"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "\\**\\*", " includeemptydirs='false' ")); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should have been created:" + tempDir2); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should have been created:" + tempDir3); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should have been created:" + tempDir4); Assert.IsFalse(Directory.Exists(GetPath(dest, tempDir1, tempDir5)), "Dir should not have been created:" + tempDir5); } [Test] public void Test_Copy_Structure_Overwrite() { string dest = CreateTempDir("a.c"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "/**/*", string.Empty)); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should have been created:" + tempDir2); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should have been created:" + tempDir3); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should have been created:" + tempDir4); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir5)), "Dir should have been created:" + tempDir5); // delete some files and directories File.Delete(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)); File.Delete(GetPath(dest,tempDir1,tempDir2,tempFile3)); Directory.Delete(GetPath(dest,tempDir1,tempDir5)); // ensure file is outdated File.SetLastWriteTime(GetPath(dest,tempDir1,tempDir3,tempFile5), new DateTime(2000, 1,1)); // set some read-only attributes File.SetAttributes(GetPath(dest,tempDir1,tempDir3,tempFile5), FileAttributes.ReadOnly); // run it again to overwrite RunBuild(String.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "/**/*", string.Empty)); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir2,tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4,tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest,tempDir1,tempDir3,tempFile7)), "File should have been created:" + tempFile7); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1)), "Dir should have been created:" + tempDir1); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir2)), "Dir should have been created:" + tempDir2); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3)), "Dir should have been created:" + tempDir3); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir3,tempDir4)), "Dir should have been created:" + tempDir4); Assert.IsTrue(Directory.Exists(GetPath(dest,tempDir1,tempDir5)), "Dir should have been created:" + tempDir5); // check whether readonly file was overwritten (no longer readonly) Assert.IsTrue((File.GetAttributes(GetPath(dest,tempDir1,tempDir3,tempFile5)) & FileAttributes.ReadOnly) != FileAttributes.ReadOnly); } /// /// Ensure that nested files are in fact flattened, nested directories /// are not created and up-to-date checking compares the flattened files. /// [Test] public void Test_Copy_Files_Flatten() { string dest = CreateTempDir("a.f"); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "/**/*", "flatten=\"true\"")); Assert.IsTrue(File.Exists(GetPath(dest, tempFile1)), "File should have been created:" + tempFile1); Assert.IsTrue(File.Exists(GetPath(dest, tempFile2)), "File should have been created:" + tempFile2); Assert.IsTrue(File.Exists(GetPath(dest, tempFile3)), "File should have been created:" + tempFile3); Assert.IsTrue(File.Exists(GetPath(dest, tempFile4)), "File should have been created:" + tempFile4); Assert.IsTrue(File.Exists(GetPath(dest, tempFile5)), "File should have been created:" + tempFile5); Assert.IsTrue(File.Exists(GetPath(dest, tempFile6)), "File should have been created:" + tempFile6); Assert.IsTrue(File.Exists(GetPath(dest, tempFile7)), "File should have been created:" + tempFile7); Assert.IsFalse(Directory.Exists(GetPath(dest, tempDir1)), "Dir should not have been created:" + tempDir1); // make a file read-only File.SetAttributes(GetPath(dest, tempFile1), FileAttributes.ReadOnly); // run build again RunBuild(String.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate, dest, tempDir1 + "/**/*", "flatten=\"true\"")); // if up-to-date check works, build should not have failed and // read-only file should still be read-only Assert.IsTrue((File.GetAttributes(GetPath(dest, tempFile1)) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly); } /// /// When multiple source files match the same destination file, then /// only the last updated file should actually be copied. /// [Test] public void Test_Copy_Files_Flatten_UpToDate() { const string buildXml = @" dest dir1 dir2 dir3 File content was '${file.content}'. "; RunBuild(buildXml, Level.Debug); } /// /// Ensure that an invalid path for source file causes a /// to be thrown. /// [Test] public void Test_Copy_Files_InvalidSourceFilePath() { File.Delete(tempFile2); if (! PlatformHelper.IsUnix ) { try { RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate3, "|", tempFile2)); // have the test fail Assert.Fail("Build should have failed."); } catch (TestBuildException ex) { // assert that a BuildException was the cause of the TestBuildException Assert.IsTrue((ex.InnerException != null && ex.InnerException.GetType() == typeof(BuildException))); } } } /// /// Ensure that an invalid path for destination file causes a /// to be thrown. /// [Test] public void Test_Copy_Files_InvalidDestinationFilePath() { if (! PlatformHelper.IsUnix ) { try { RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate3, tempFile1, "|")); // have the test fail Assert.Fail("Build should have failed."); } catch (TestBuildException ex) { // assert that a BuildException was the cause of the TestBuildException Assert.IsTrue((ex.InnerException != null && ex.InnerException.GetType() == typeof(BuildException))); } } } [Test] public void Test_Copy_Files_No_Overwrite() { File.Delete(tempFile2); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate3, tempFile1, tempFile2)); Assert.IsTrue(File.Exists(tempFile2), "File should have been created:" + tempFile2); } [Test] public void Test_Copy_Files_Overwrite() { RunBuild(String.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate3, tempFile1, tempFile2)); Assert.IsTrue(File.Exists(tempFile2), "File should have been created:" + tempFile2); } [Test] public void Test_Copy_Files_Overwrite_Readonly() { File.SetAttributes(tempFile2, FileAttributes.ReadOnly); RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate3, tempFile1, tempFile2)); Assert.IsTrue(File.Exists(tempFile2), "File should have been created:" + tempFile2); } /// /// /// This test suggested by gert.driesen@pandora.be. Tests copying subdirectories only. /// /// /// Empty directories should be copied when includeemptydirs /// is not specified (default is ). /// /// [Test] public void Test_Copy_Structure_Directories() { RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate2, tempDir1, string.Empty)); Assert.IsTrue(Directory.Exists(GetPath(tempDir1, "destination")), "Dir should have been created:" + GetPath(tempDir1, "destination")); Assert.IsTrue(Directory.Exists(GetPath(tempDir1, "source", "test")), "Dir should have been created:" + GetPath(tempDir1, "source", "test")); Assert.IsTrue(Directory.Exists(GetPath(tempDir1, "destination", "source", "test")), "Dir should have been created:" + GetPath(tempDir1, "destination", "source","test")); } /// /// /// This test suggested by gert.driesen@pandora.be. Tests copying subdirectories only. /// /// /// Empty directories should not be copied when includeemptydirs /// is . /// /// [Test] public void Test_Copy_Structure_Directories_ExcludeEmptyDirs() { RunBuild(string.Format(CultureInfo.InvariantCulture, _xmlProjectTemplate2, tempDir1, " includeemptydirs='false' ")); Assert.IsTrue(Directory.Exists(GetPath(tempDir1, "destination")), "Dir should have been created:" + GetPath(tempDir1, "destination")); Assert.IsTrue(Directory.Exists(GetPath(tempDir1, "source", "test")), "Dir should have been created:" + GetPath(tempDir1, "source", "test")); Assert.IsFalse(Directory.Exists(GetPath(tempDir1, "destination", "source", "test")), "Dir should not have been created:" + GetPath(tempDir1, "destination", "source","test")); } /// /// The todir and tofile attribute of the <copy> /// task should not be combined. /// [Test] [ExpectedException(typeof(TestBuildException))] public void Test_ToFile_ToDir() { const string xmlProjectTemplate = @" "; RunBuild(xmlProjectTemplate); } /// /// The tofile attribute of the <copy> task cannot /// be combined with a <fileset> element. /// [Test] [ExpectedException(typeof(TestBuildException))] public void Test_ToFile_FileSet() { const string xmlProjectTemplate = @" "; RunBuild(xmlProjectTemplate); } /// /// The file attribute of the <copy> task cannot /// be combined with a <fileset> element. /// [Test] [ExpectedException(typeof(TestBuildException))] public void Test_File_FileSet() { const string xmlProjectTemplate = @" "; RunBuild(xmlProjectTemplate); } } }