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 namespace MonoTests.Microsoft.Build.Tasks {
36 public class CopyTest {
37 string source_path, target_path;
40 public void CreateDir ()
42 source_path = Path.Combine (Path.Combine ("Test", "resources"), "Copy");
43 Directory.CreateDirectory (source_path);
44 target_path = Path.Combine (Path.Combine ("Test", "resources"), "Target");
45 Directory.CreateDirectory (target_path);
49 public void RemoveDirectories ()
51 Directory.Delete (source_path, true);
52 Directory.Delete (target_path, true);
56 public void TestCopy1 ()
60 string file_path = Path.Combine (source_path, "copy.txt");
61 string target_file = Path.Combine (target_path, "copy.txt");
63 using (File.CreateText (file_path)) { }
65 string documentString = @"
66 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
67 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
69 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
70 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
73 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' SkipUnchangedFiles='true' >
74 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
75 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
77 <Message Text=""I0 : @(I0), I1: @(I1)""/>
82 engine = new Engine (Consts.BinPath);
83 project = engine.CreateNewProject ();
85 TestMessageLogger testLogger = new TestMessageLogger ();
86 engine.RegisterLogger (testLogger);
88 project.LoadXml (documentString);
90 if (!project.Build ("1")) {
91 testLogger.DumpMessages ();
92 Assert.Fail ("Build failed");
94 Assert.IsTrue (File.Exists (target_file), "A2");
96 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
97 Assert.AreEqual (1, big.Count, "A3");
98 BuildItem bi = big [0];
99 Assert.AreEqual (target_file, bi.FinalItemSpec, "A4");
100 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A4");
101 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A5");
103 big = project.GetEvaluatedItemsByName ("I1");
104 Assert.AreEqual (1, big.Count, "A10");
106 Assert.AreEqual (target_file, bi.FinalItemSpec, "A11");
107 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A12");
108 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A13");
110 // build again, this time files won't get copied because
111 // of SkipUnchangedFiles=true
112 if (!project.Build ("1")) {
113 testLogger.DumpMessages ();
114 Assert.Fail ("Build failed #2");
116 Assert.IsTrue (File.Exists (target_file), "A20");
118 big = project.GetEvaluatedItemsByName ("I0");
119 Assert.AreEqual (1, big.Count, "A21");
121 Assert.AreEqual (target_file, bi.FinalItemSpec, "A22");
122 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A23");
123 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A24");
125 big = project.GetEvaluatedItemsByName ("I1");
126 Assert.AreEqual (1, big.Count, "A25");
128 Assert.AreEqual (target_file, bi.FinalItemSpec, "A26");
129 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A27");
130 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A28");
134 public void TestCopy2 ()
138 string [] file_paths = new string [] {
139 Path.Combine (source_path, "copy1.txt"),
140 Path.Combine (source_path, "copy2.txt")
143 using (File.CreateText (file_paths[0])) { }
144 using (File.CreateText (file_paths[1])) { }
146 string documentString = @"
147 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
148 <PropertyGroup><TargetPath>" + target_path + @"</TargetPath></PropertyGroup>
150 <SFiles Include='" + file_paths [0] + @"'><Md>1</Md></SFiles>
151 <SFiles Include='" + file_paths [1] + @"'><Md>2</Md></SFiles>
154 <Copy SourceFiles='@(SFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
155 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
156 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
161 engine = new Engine (Consts.BinPath);
162 project = engine.CreateNewProject ();
164 TestMessageLogger testLogger = new TestMessageLogger ();
165 engine.RegisterLogger (testLogger);
167 project.LoadXml (documentString);
169 if (!project.Build ("1")) {
170 testLogger.DumpMessages ();
171 Assert.Fail ("Build failed");
174 CheckCopyBuildItems (project, file_paths, target_path, "A1");
176 // build again, this time files won't get copied because
177 // of SkipUnchangedFiles=true
178 if (!project.Build ("1")) {
179 testLogger.DumpMessages ();
180 Assert.Fail ("Build failed #2");
182 CheckCopyBuildItems (project, file_paths, target_path, "A2");
186 public void TestCopy_EmptySources () {
190 string documentString = @"
191 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
193 <Copy SourceFiles='@(NonExistantSourceFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
194 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
195 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
200 engine = new Engine (Consts.BinPath);
201 project = engine.CreateNewProject ();
203 TestMessageLogger testLogger = new TestMessageLogger ();
204 engine.RegisterLogger (testLogger);
206 project.LoadXml (documentString);
209 if (!project.Build ("1")) {
210 testLogger.DumpMessages ();
211 Assert.Fail ("Build failed");
216 public void TestCopy_EmptyDestFolder () {
220 string documentString = @"
221 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
223 <SFiles Include='foo.txt'><Md>1</Md></SFiles>
226 <Copy SourceFiles='@(SFiles)' DestinationFolder='@(NonExistant)' DestinationFiles='@(NonExistant)' SkipUnchangedFiles='true' >
227 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
228 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
233 engine = new Engine (Consts.BinPath);
234 project = engine.CreateNewProject ();
236 TestMessageLogger testLogger = new TestMessageLogger ();
237 engine.RegisterLogger (testLogger);
239 project.LoadXml (documentString);
240 if (project.Build ("1")) {
241 testLogger.DumpMessages ();
242 Assert.Fail ("Build should have failed");
247 public void TestCopy_ReadOnlyUpdate ()
251 string file_path = Path.Combine (source_path, "copyro.txt");
252 string target_file = Path.Combine (target_path, "copyro.txt");
254 using (File.CreateText (file_path)) { }
256 string documentString = @"
257 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
258 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
260 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
261 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
264 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' >
265 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
266 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
268 <Message Text=""I0 : @(I0), I1: @(I1)""/>
273 engine = new Engine (Consts.BinPath);
274 project = engine.CreateNewProject ();
276 TestMessageLogger testLogger = new TestMessageLogger ();
277 engine.RegisterLogger (testLogger);
279 project.LoadXml (documentString);
281 if (!project.Build ("1")) {
282 testLogger.DumpMessages ();
283 Assert.Fail ("Build failed");
285 Assert.IsTrue (File.Exists (target_file), "A2");
286 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
289 #if NET_3_5 || NET_4_0
291 public void TestCopy_OverwriteReadOnlyTrue ()
295 string file_path = Path.Combine (source_path, "copyro1.txt");
296 string target_file = Path.Combine (target_path, "copyro1.txt");
298 using (File.CreateText (file_path)) { }
299 using (File.CreateText (target_file)) { }
301 File.SetAttributes (target_file, FileAttributes.ReadOnly);
302 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
304 string documentString = @"
305 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
306 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
308 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
309 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
312 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' OverwriteReadOnlyFiles='true'>
313 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
314 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
316 <Message Text=""I0 : @(I0), I1: @(I1)""/>
321 engine = new Engine (Consts.BinPath);
322 project = engine.CreateNewProject ();
324 TestMessageLogger testLogger = new TestMessageLogger ();
325 engine.RegisterLogger (testLogger);
327 project.LoadXml (documentString);
329 if (!project.Build ("1")) {
330 testLogger.DumpMessages ();
331 Assert.Fail ("Build failed");
333 Assert.IsTrue (File.Exists (target_file), "A2");
334 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
338 public void TestCopy_OverwriteReadOnlyFalse ()
342 string file_path = Path.Combine (source_path, "copyro2.txt");
343 string target_file = Path.Combine (target_path, "copyro2.txt");
345 using (File.CreateText (file_path)) { }
346 using (File.CreateText (target_file)) { }
348 File.SetAttributes (target_file, FileAttributes.ReadOnly);
349 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
351 string documentString = @"
352 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
353 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
355 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
356 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
359 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)'>
360 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
361 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
363 <Message Text=""I0 : @(I0), I1: @(I1)""/>
368 engine = new Engine (Consts.BinPath);
369 project = engine.CreateNewProject ();
371 TestMessageLogger testLogger = new TestMessageLogger ();
372 engine.RegisterLogger (testLogger);
374 project.LoadXml (documentString);
376 // build should fail because of the readonly target file
377 Assert.IsFalse (project.Build ("1"));
379 File.SetAttributes (target_file, FileAttributes.Normal);
383 void CheckCopyBuildItems (Project project, string [] source_files, string destination_folder, string prefix)
385 int num = source_files.Length;
386 for (int i = 0; i < num; i ++)
387 Assert.IsTrue (File.Exists (source_files [i]), prefix + " C1");
389 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
391 Assert.AreEqual (num, big.Count, prefix + " C2");
392 for (int i = 0; i < num; i++) {
393 string suffix = (i + 1).ToString ();
394 BuildItem bi = big [i];
395 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
396 bi.FinalItemSpec, prefix + " C3 #" + suffix);
398 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C4 #" + suffix);
401 big = project.GetEvaluatedItemsByName ("I1");
402 Assert.AreEqual (num, big.Count, prefix + " C6");
403 for (int i = 0; i < num; i++) {
404 string suffix = (i + 1).ToString ();
405 BuildItem bi = big [i];
406 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
407 bi.FinalItemSpec, prefix + " C7 #" + suffix);
408 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C8 #" + suffix);