5 // Ankit Jain (jankit@novell.com)
7 // Copyright 2009 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using Microsoft.Build.BuildEngine;
31 using NUnit.Framework;
33 using Microsoft.Build.Tasks;
34 using Microsoft.Build.Framework;
35 using Microsoft.Build.Utilities;
37 namespace MonoTests.Microsoft.Build.Tasks {
40 public class CopyTest {
41 string source_path, target_path;
44 public void CreateDir ()
46 source_path = Path.Combine (Path.Combine ("Test", "resources"), "Copy");
47 Directory.CreateDirectory (source_path);
48 target_path = Path.Combine (Path.Combine ("Test", "resources"), "Target");
49 Directory.CreateDirectory (target_path);
53 public void RemoveDirectories ()
55 Directory.Delete (source_path, true);
56 Directory.Delete (target_path, true);
60 public void TestCopy_MissingSourceFile ()
62 Copy copy = new Copy ();
63 copy.BuildEngine = new TestEngine ();
64 copy.SourceFiles = new ITaskItem [1];
65 copy.SourceFiles [0] = new TaskItem ("SourceDoesNotExist");
66 copy.DestinationFiles = new ITaskItem [1];
67 copy.DestinationFiles [0] = new TaskItem ("DestDoesNotExist");
68 Assert.IsFalse (copy.Execute ());
72 public void TestCopy1 ()
76 string file_path = Path.Combine (source_path, "copy.txt");
77 string target_file = Path.Combine (target_path, "copy.txt");
79 using (File.CreateText (file_path)) { }
81 string documentString = @"
82 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
83 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
85 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
86 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
89 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' SkipUnchangedFiles='true' >
90 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
91 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
93 <Message Text=""I0 : @(I0), I1: @(I1)""/>
98 engine = new Engine (Consts.BinPath);
99 project = engine.CreateNewProject ();
101 TestMessageLogger testLogger = new TestMessageLogger ();
102 engine.RegisterLogger (testLogger);
104 project.LoadXml (documentString);
106 if (!project.Build ("1")) {
107 var sb = new StringBuilder ();
108 testLogger.DumpMessages (sb);
109 Assert.Fail ("Build failed " + sb.ToString ());
111 Assert.IsTrue (File.Exists (target_file), "A2");
113 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
114 Assert.AreEqual (1, big.Count, "A3");
115 BuildItem bi = big [0];
116 Assert.AreEqual (target_file, bi.FinalItemSpec, "A4");
117 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A4");
118 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A5");
120 big = project.GetEvaluatedItemsByName ("I1");
121 Assert.AreEqual (1, big.Count, "A10");
123 Assert.AreEqual (target_file, bi.FinalItemSpec, "A11");
124 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A12");
125 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A13");
127 // build again, this time files won't get copied because
128 // of SkipUnchangedFiles=true
129 if (!project.Build ("1")) {
130 testLogger.DumpMessages ();
131 Assert.Fail ("Build failed #2");
133 Assert.IsTrue (File.Exists (target_file), "A20");
135 big = project.GetEvaluatedItemsByName ("I0");
136 Assert.AreEqual (1, big.Count, "A21");
138 Assert.AreEqual (target_file, bi.FinalItemSpec, "A22");
139 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A23");
140 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A24");
142 big = project.GetEvaluatedItemsByName ("I1");
143 Assert.AreEqual (1, big.Count, "A25");
145 Assert.AreEqual (target_file, bi.FinalItemSpec, "A26");
146 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A27");
147 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A28");
151 public void TestCopy2 ()
155 string [] file_paths = new string [] {
156 Path.Combine (source_path, "copy1.txt"),
157 Path.Combine (source_path, "copy2.txt")
160 using (File.CreateText (file_paths[0])) { }
161 using (File.CreateText (file_paths[1])) { }
163 string documentString = @"
164 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
165 <PropertyGroup><TargetPath>" + target_path + @"</TargetPath></PropertyGroup>
167 <SFiles Include='" + file_paths [0] + @"'><Md>1</Md></SFiles>
168 <SFiles Include='" + file_paths [1] + @"'><Md>2</Md></SFiles>
171 <Copy SourceFiles='@(SFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
172 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
173 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
178 engine = new Engine (Consts.BinPath);
179 project = engine.CreateNewProject ();
181 TestMessageLogger testLogger = new TestMessageLogger ();
182 engine.RegisterLogger (testLogger);
184 project.LoadXml (documentString);
186 if (!project.Build ("1")) {
187 testLogger.DumpMessages ();
188 Assert.Fail ("Build failed");
191 CheckCopyBuildItems (project, file_paths, target_path, "A1");
193 // build again, this time files won't get copied because
194 // of SkipUnchangedFiles=true
195 if (!project.Build ("1")) {
196 testLogger.DumpMessages ();
197 Assert.Fail ("Build failed #2");
199 CheckCopyBuildItems (project, file_paths, target_path, "A2");
203 public void TestCopy_EmptySources () {
207 string documentString = @"
208 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
210 <Copy SourceFiles='@(NonExistantSourceFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
211 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
212 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
217 engine = new Engine (Consts.BinPath);
218 project = engine.CreateNewProject ();
220 TestMessageLogger testLogger = new TestMessageLogger ();
221 engine.RegisterLogger (testLogger);
223 project.LoadXml (documentString);
226 if (!project.Build ("1")) {
227 testLogger.DumpMessages ();
228 Assert.Fail ("Build failed");
233 public void TestCopy_EmptyDestFolder () {
237 string documentString = @"
238 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
240 <SFiles Include='foo.txt'><Md>1</Md></SFiles>
243 <Copy SourceFiles='@(SFiles)' DestinationFolder='@(NonExistant)' DestinationFiles='@(NonExistant)' SkipUnchangedFiles='true' >
244 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
245 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
250 engine = new Engine (Consts.BinPath);
251 project = engine.CreateNewProject ();
253 TestMessageLogger testLogger = new TestMessageLogger ();
254 engine.RegisterLogger (testLogger);
256 project.LoadXml (documentString);
257 if (project.Build ("1")) {
258 testLogger.DumpMessages ();
259 Assert.Fail ("Build should have failed");
264 public void TestCopy_ReadOnlyUpdate ()
268 string file_path = Path.Combine (source_path, "copyro.txt");
269 string target_file = Path.Combine (target_path, "copyro.txt");
271 using (File.CreateText (file_path)) { }
273 string documentString = @"
274 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
275 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
277 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
278 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
281 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' >
282 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
283 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
285 <Message Text=""I0 : @(I0), I1: @(I1)""/>
290 engine = new Engine (Consts.BinPath);
291 project = engine.CreateNewProject ();
293 TestMessageLogger testLogger = new TestMessageLogger ();
294 engine.RegisterLogger (testLogger);
296 project.LoadXml (documentString);
298 if (!project.Build ("1")) {
299 testLogger.DumpMessages ();
300 Assert.Fail ("Build failed");
302 Assert.IsTrue (File.Exists (target_file), "A2");
303 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
308 public void TestCopy_OverwriteReadOnlyTrue ()
312 string file_path = Path.Combine (source_path, "copyro1.txt");
313 string target_file = Path.Combine (target_path, "copyro1.txt");
315 using (File.CreateText (file_path)) { }
316 using (File.CreateText (target_file)) { }
318 File.SetAttributes (target_file, FileAttributes.ReadOnly);
319 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
321 string documentString = @"
322 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
323 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
325 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
326 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
329 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' OverwriteReadOnlyFiles='true'>
330 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
331 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
333 <Message Text=""I0 : @(I0), I1: @(I1)""/>
338 engine = new Engine (Consts.BinPath);
339 project = engine.CreateNewProject ();
341 TestMessageLogger testLogger = new TestMessageLogger ();
342 engine.RegisterLogger (testLogger);
344 project.LoadXml (documentString);
346 if (!project.Build ("1")) {
347 var sb = new StringBuilder ();
348 testLogger.DumpMessages (sb);
349 Assert.Fail ("Build failed " + sb.ToString ());
351 Assert.IsTrue (File.Exists (target_file), "A2");
352 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
356 public void TestCopy_OverwriteReadOnlyFalse ()
360 string file_path = Path.Combine (source_path, "copyro2.txt");
361 string target_file = Path.Combine (target_path, "copyro2.txt");
363 using (File.CreateText (file_path)) { }
364 using (File.CreateText (target_file)) { }
366 File.SetAttributes (target_file, FileAttributes.ReadOnly);
367 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
369 string documentString = @"
370 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
371 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
373 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
374 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
377 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)'>
378 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
379 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
381 <Message Text=""I0 : @(I0), I1: @(I1)""/>
386 engine = new Engine (Consts.BinPath);
387 project = engine.CreateNewProject ();
389 TestMessageLogger testLogger = new TestMessageLogger ();
390 engine.RegisterLogger (testLogger);
392 project.LoadXml (documentString);
394 // build should fail because of the readonly target file
395 Assert.IsFalse (project.Build ("1"));
397 File.SetAttributes (target_file, FileAttributes.Normal);
401 void CheckCopyBuildItems (Project project, string [] source_files, string destination_folder, string prefix)
403 int num = source_files.Length;
404 for (int i = 0; i < num; i ++)
405 Assert.IsTrue (File.Exists (source_files [i]), prefix + " C1");
407 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
409 Assert.AreEqual (num, big.Count, prefix + " C2");
410 for (int i = 0; i < num; i++) {
411 string suffix = (i + 1).ToString ();
412 BuildItem bi = big [i];
413 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
414 bi.FinalItemSpec, prefix + " C3 #" + suffix);
416 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C4 #" + suffix);
419 big = project.GetEvaluatedItemsByName ("I1");
420 Assert.AreEqual (num, big.Count, prefix + " C6");
421 for (int i = 0; i < num; i++) {
422 string suffix = (i + 1).ToString ();
423 BuildItem bi = big [i];
424 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
425 bi.FinalItemSpec, prefix + " C7 #" + suffix);
426 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C8 #" + suffix);