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;
34 namespace MonoTests.Microsoft.Build.Tasks {
37 public class CopyTest {
38 string source_path, target_path;
41 public void CreateDir ()
43 source_path = Path.Combine (Path.Combine ("Test", "resources"), "Copy");
44 Directory.CreateDirectory (source_path);
45 target_path = Path.Combine (Path.Combine ("Test", "resources"), "Target");
46 Directory.CreateDirectory (target_path);
50 public void RemoveDirectories ()
52 Directory.Delete (source_path, true);
53 Directory.Delete (target_path, true);
57 public void TestCopy1 ()
61 string file_path = Path.Combine (source_path, "copy.txt");
62 string target_file = Path.Combine (target_path, "copy.txt");
64 using (File.CreateText (file_path)) { }
66 string documentString = @"
67 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
68 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
70 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
71 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
74 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' SkipUnchangedFiles='true' >
75 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
76 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
78 <Message Text=""I0 : @(I0), I1: @(I1)""/>
83 engine = new Engine (Consts.BinPath);
84 project = engine.CreateNewProject ();
86 TestMessageLogger testLogger = new TestMessageLogger ();
87 engine.RegisterLogger (testLogger);
89 project.LoadXml (documentString);
91 if (!project.Build ("1")) {
92 var sb = new StringBuilder ();
93 testLogger.DumpMessages (sb);
94 Assert.Fail ("Build failed " + sb.ToString ());
96 Assert.IsTrue (File.Exists (target_file), "A2");
98 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
99 Assert.AreEqual (1, big.Count, "A3");
100 BuildItem bi = big [0];
101 Assert.AreEqual (target_file, bi.FinalItemSpec, "A4");
102 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A4");
103 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A5");
105 big = project.GetEvaluatedItemsByName ("I1");
106 Assert.AreEqual (1, big.Count, "A10");
108 Assert.AreEqual (target_file, bi.FinalItemSpec, "A11");
109 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A12");
110 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A13");
112 // build again, this time files won't get copied because
113 // of SkipUnchangedFiles=true
114 if (!project.Build ("1")) {
115 testLogger.DumpMessages ();
116 Assert.Fail ("Build failed #2");
118 Assert.IsTrue (File.Exists (target_file), "A20");
120 big = project.GetEvaluatedItemsByName ("I0");
121 Assert.AreEqual (1, big.Count, "A21");
123 Assert.AreEqual (target_file, bi.FinalItemSpec, "A22");
124 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A23");
125 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A24");
127 big = project.GetEvaluatedItemsByName ("I1");
128 Assert.AreEqual (1, big.Count, "A25");
130 Assert.AreEqual (target_file, bi.FinalItemSpec, "A26");
131 Assert.AreEqual ("1", bi.GetMetadata ("Md"), "A27");
132 Assert.AreEqual ("2", bi.GetMetadata ("Mde"), "A28");
136 public void TestCopy2 ()
140 string [] file_paths = new string [] {
141 Path.Combine (source_path, "copy1.txt"),
142 Path.Combine (source_path, "copy2.txt")
145 using (File.CreateText (file_paths[0])) { }
146 using (File.CreateText (file_paths[1])) { }
148 string documentString = @"
149 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
150 <PropertyGroup><TargetPath>" + target_path + @"</TargetPath></PropertyGroup>
152 <SFiles Include='" + file_paths [0] + @"'><Md>1</Md></SFiles>
153 <SFiles Include='" + file_paths [1] + @"'><Md>2</Md></SFiles>
156 <Copy SourceFiles='@(SFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
157 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
158 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
163 engine = new Engine (Consts.BinPath);
164 project = engine.CreateNewProject ();
166 TestMessageLogger testLogger = new TestMessageLogger ();
167 engine.RegisterLogger (testLogger);
169 project.LoadXml (documentString);
171 if (!project.Build ("1")) {
172 testLogger.DumpMessages ();
173 Assert.Fail ("Build failed");
176 CheckCopyBuildItems (project, file_paths, target_path, "A1");
178 // build again, this time files won't get copied because
179 // of SkipUnchangedFiles=true
180 if (!project.Build ("1")) {
181 testLogger.DumpMessages ();
182 Assert.Fail ("Build failed #2");
184 CheckCopyBuildItems (project, file_paths, target_path, "A2");
188 public void TestCopy_EmptySources () {
192 string documentString = @"
193 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
195 <Copy SourceFiles='@(NonExistantSourceFiles)' DestinationFolder='$(TargetPath)' SkipUnchangedFiles='true' >
196 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
197 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
202 engine = new Engine (Consts.BinPath);
203 project = engine.CreateNewProject ();
205 TestMessageLogger testLogger = new TestMessageLogger ();
206 engine.RegisterLogger (testLogger);
208 project.LoadXml (documentString);
211 if (!project.Build ("1")) {
212 testLogger.DumpMessages ();
213 Assert.Fail ("Build failed");
218 public void TestCopy_EmptyDestFolder () {
222 string documentString = @"
223 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
225 <SFiles Include='foo.txt'><Md>1</Md></SFiles>
228 <Copy SourceFiles='@(SFiles)' DestinationFolder='@(NonExistant)' DestinationFiles='@(NonExistant)' SkipUnchangedFiles='true' >
229 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
230 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
235 engine = new Engine (Consts.BinPath);
236 project = engine.CreateNewProject ();
238 TestMessageLogger testLogger = new TestMessageLogger ();
239 engine.RegisterLogger (testLogger);
241 project.LoadXml (documentString);
242 if (project.Build ("1")) {
243 testLogger.DumpMessages ();
244 Assert.Fail ("Build should have failed");
249 public void TestCopy_ReadOnlyUpdate ()
253 string file_path = Path.Combine (source_path, "copyro.txt");
254 string target_file = Path.Combine (target_path, "copyro.txt");
256 using (File.CreateText (file_path)) { }
258 string documentString = @"
259 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
260 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
262 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
263 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
266 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' >
267 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
268 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
270 <Message Text=""I0 : @(I0), I1: @(I1)""/>
275 engine = new Engine (Consts.BinPath);
276 project = engine.CreateNewProject ();
278 TestMessageLogger testLogger = new TestMessageLogger ();
279 engine.RegisterLogger (testLogger);
281 project.LoadXml (documentString);
283 if (!project.Build ("1")) {
284 testLogger.DumpMessages ();
285 Assert.Fail ("Build failed");
287 Assert.IsTrue (File.Exists (target_file), "A2");
288 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
293 public void TestCopy_OverwriteReadOnlyTrue ()
297 string file_path = Path.Combine (source_path, "copyro1.txt");
298 string target_file = Path.Combine (target_path, "copyro1.txt");
300 using (File.CreateText (file_path)) { }
301 using (File.CreateText (target_file)) { }
303 File.SetAttributes (target_file, FileAttributes.ReadOnly);
304 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
306 string documentString = @"
307 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
308 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
310 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
311 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
314 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)' OverwriteReadOnlyFiles='true'>
315 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
316 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
318 <Message Text=""I0 : @(I0), I1: @(I1)""/>
323 engine = new Engine (Consts.BinPath);
324 project = engine.CreateNewProject ();
326 TestMessageLogger testLogger = new TestMessageLogger ();
327 engine.RegisterLogger (testLogger);
329 project.LoadXml (documentString);
331 if (!project.Build ("1")) {
332 var sb = new StringBuilder ();
333 testLogger.DumpMessages (sb);
334 Assert.Fail ("Build failed " + sb.ToString ());
336 Assert.IsTrue (File.Exists (target_file), "A2");
337 Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3");
341 public void TestCopy_OverwriteReadOnlyFalse ()
345 string file_path = Path.Combine (source_path, "copyro2.txt");
346 string target_file = Path.Combine (target_path, "copyro2.txt");
348 using (File.CreateText (file_path)) { }
349 using (File.CreateText (target_file)) { }
351 File.SetAttributes (target_file, FileAttributes.ReadOnly);
352 Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1");
354 string documentString = @"
355 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
356 <PropertyGroup><DestFile>" + target_file + @"</DestFile></PropertyGroup>
358 <SFiles Include='" + file_path + @"'><Md>1</Md></SFiles>
359 <DFiles Include='$(DestFile)'><Mde>2</Mde></DFiles>
362 <Copy SourceFiles='@(SFiles)' DestinationFiles='@(DFiles)'>
363 <Output TaskParameter='CopiedFiles' ItemName='I0'/>
364 <Output TaskParameter='DestinationFiles' ItemName='I1'/>
366 <Message Text=""I0 : @(I0), I1: @(I1)""/>
371 engine = new Engine (Consts.BinPath);
372 project = engine.CreateNewProject ();
374 TestMessageLogger testLogger = new TestMessageLogger ();
375 engine.RegisterLogger (testLogger);
377 project.LoadXml (documentString);
379 // build should fail because of the readonly target file
380 Assert.IsFalse (project.Build ("1"));
382 File.SetAttributes (target_file, FileAttributes.Normal);
386 void CheckCopyBuildItems (Project project, string [] source_files, string destination_folder, string prefix)
388 int num = source_files.Length;
389 for (int i = 0; i < num; i ++)
390 Assert.IsTrue (File.Exists (source_files [i]), prefix + " C1");
392 BuildItemGroup big = project.GetEvaluatedItemsByName ("I0");
394 Assert.AreEqual (num, big.Count, prefix + " C2");
395 for (int i = 0; i < num; i++) {
396 string suffix = (i + 1).ToString ();
397 BuildItem bi = big [i];
398 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
399 bi.FinalItemSpec, prefix + " C3 #" + suffix);
401 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C4 #" + suffix);
404 big = project.GetEvaluatedItemsByName ("I1");
405 Assert.AreEqual (num, big.Count, prefix + " C6");
406 for (int i = 0; i < num; i++) {
407 string suffix = (i + 1).ToString ();
408 BuildItem bi = big [i];
409 Assert.AreEqual (Path.Combine (destination_folder, Path.GetFileName (source_files [i])),
410 bi.FinalItemSpec, prefix + " C7 #" + suffix);
411 Assert.AreEqual (suffix, bi.GetMetadata ("Md"), prefix + " C8 #" + suffix);