Add support for ToolsVersion and correctly build msbuild+xbuild assemblies
[mcs.git] / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / EngineTest.cs
blobb64c1f5bcf141edbb791a8a7d34351e00b6118b0
1 //
2 // EngineTest.cs:
3 //
4 // Author:
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2005 Marek Sieradzki
8 //
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.
28 using System;
29 using Microsoft.Build.BuildEngine;
30 using Microsoft.Build.Framework;
31 using Microsoft.Build.Utilities;
32 using NUnit.Framework;
33 using System.IO;
35 namespace MonoTests.Microsoft.Build.BuildEngine {
37 class CheckUnregisterLogger : Logger {
38 bool anything = false;
40 public override void Initialize (IEventSource eventSource)
42 eventSource.AnyEventRaised += delegate { anything = true; };
43 eventSource.BuildFinished += delegate { anything = true; };
44 eventSource.BuildStarted += delegate { anything = true; };
45 eventSource.CustomEventRaised += delegate { anything = true; };
46 eventSource.ErrorRaised += delegate { anything = true; };
47 eventSource.MessageRaised += delegate { anything = true; };
48 eventSource.ProjectFinished += delegate { anything = true; };
49 eventSource.ProjectStarted += delegate { anything = true; };
50 eventSource.StatusEventRaised += delegate { anything = true; };
51 eventSource.TargetFinished += delegate { anything = true; };
52 eventSource.TargetStarted += delegate { anything = true; };
53 eventSource.TaskFinished += delegate { anything = true; };
54 eventSource.TaskStarted += delegate { anything = true; };
55 eventSource.WarningRaised += delegate { anything = true; };
58 public bool Anything { get { return anything; } }
61 [TestFixture]
62 public class EngineTest {
64 Engine engine;
65 string secondProject;
67 static string GetPropValue (BuildPropertyGroup bpg, string name)
69 foreach (BuildProperty bp in bpg) {
70 if (bp.Name == name) {
71 return bp.FinalValue;
74 return String.Empty;
77 [SetUp]
78 public void Setup ()
80 secondProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
81 <PropertyGroup Condition=""'$(foo)' == 'hello'"">
82 <A>FooWasHello</A>
83 </PropertyGroup>
84 <Target Name=""TargetA"">
85 <Message Text=""(TargetA) foo: $(foo) A: $(A) External: $(External)""/>
86 </Target>
88 <Target Name=""TargetB"">
89 <Message Text=""(TargetB) foo: $(foo) A: $(A) External: $(External)""/>
90 </Target>
91 </Project>";
95 [Test]
96 public void TestCtor ()
98 engine = new Engine (Consts.BinPath);
101 // Before a project can be instantiated, Engine.BinPath must be set to the location on disk where MSBuild is installed.
102 // This is used to evaluate $(MSBuildBinPath).
103 /* This isn't valid for 3.5
105 [Test]
106 [ExpectedException (typeof (InvalidOperationException))]
107 public void TestNewProject ()
109 engine = new Engine ();
111 engine.CreateNewProject ();
114 [Test]
115 public void TestBinPath ()
117 engine = new Engine (Consts.BinPath);
119 Assert.AreEqual (Consts.BinPath, engine.BinPath, "A1");
122 [Test]
123 public void TestBuildEnabled ()
125 engine = new Engine (Consts.BinPath);
127 Assert.AreEqual (true, engine.BuildEnabled, "A1");
130 [Test]
131 public void TestOnlyLogCriticalEvents ()
133 engine = new Engine (Consts.BinPath);
135 Assert.AreEqual (false, engine.OnlyLogCriticalEvents, "A1");
138 [Test]
139 public void TestGlobalProperties ()
141 engine = new Engine (Consts.BinPath);
142 Project project;
144 Assert.IsNotNull (engine.GlobalProperties, "A1");
145 Assert.AreEqual (0, engine.GlobalProperties.Count, "A2");
146 Assert.AreEqual (String.Empty, engine.GlobalProperties.Condition, "A3");
147 Assert.IsFalse (engine.GlobalProperties.IsImported, "A4");
149 engine.GlobalProperties.SetProperty ("GlobalA", "value1");
150 Assert.AreEqual (1, engine.GlobalProperties.Count, "A5");
151 engine.GlobalProperties.SetProperty ("GlobalB", "value1");
152 Assert.AreEqual (2, engine.GlobalProperties.Count, "A6");
153 engine.GlobalProperties.SetProperty ("GlobalA", "value2");
154 Assert.AreEqual (2, engine.GlobalProperties.Count, "A7");
156 project = engine.CreateNewProject ();
157 Assert.AreEqual (2, project.GlobalProperties.Count, "A8");
158 project.GlobalProperties.SetProperty ("GlobalC", "value3");
159 Assert.AreEqual (3, project.GlobalProperties.Count, "A9");
160 Assert.AreEqual (2, engine.GlobalProperties.Count, "A10");
162 project.GlobalProperties.SetProperty ("GlobalA", "value3");
163 Assert.AreEqual ("value2", GetPropValue(engine.GlobalProperties, "GlobalA"), "A11");
164 engine.GlobalProperties.SetProperty ("GlobalB", "value3");
165 Assert.AreEqual ("value1", GetPropValue(project.GlobalProperties, "GlobalB"), "A12");
167 engine.GlobalProperties.SetProperty ("GlobalC", "value4");
168 engine.GlobalProperties.SetProperty ("GlobalD", "value5");
169 Assert.AreEqual (4, engine.GlobalProperties.Count, "A13");
170 Assert.AreEqual (3, project.GlobalProperties.Count, "A14");
172 project = new Project (engine);
173 Assert.AreEqual (4, project.GlobalProperties.Count, "A15");
176 [Test]
177 public void TestGlobalEngine ()
179 engine = new Engine ();
180 Assert.IsFalse (engine == Engine.GlobalEngine, "1");
181 Assert.IsNotNull (Engine.GlobalEngine, "2");
182 engine = Engine.GlobalEngine;
183 Assert.AreSame (engine, Engine.GlobalEngine, "3");
186 [Test]
187 [ExpectedException (typeof (ArgumentNullException))]
188 [Category ("NotDotNet")]
189 public void TestRegisterLogger ()
191 engine = new Engine (Consts.BinPath);
192 engine.RegisterLogger (null);
195 // The "Project" object specified does not belong to the correct "Engine" object.
196 [Test]
197 [ExpectedException (typeof (InvalidOperationException))]
198 public void TestUnloadProject1 ()
200 Engine a = new Engine (Consts.BinPath);
201 Engine b = new Engine (Consts.BinPath);
203 Project p = a.CreateNewProject ();
205 b.UnloadProject (p);
208 [Test]
209 [ExpectedException (typeof (ArgumentNullException))]
210 [Category ("NotDotNet")]
211 public void TestUnloadProject2 ()
213 Engine a = new Engine (Consts.BinPath);
215 a.UnloadProject (null);
218 // This project object has been unloaded from the MSBuild engine and is no longer valid.
219 [Test]
220 [ExpectedException (typeof (InvalidOperationException))]
221 public void TestUnloadProject3 ()
223 Engine a = new Engine (Consts.BinPath);
224 Project p = a.CreateNewProject ();
226 a.UnloadProject (p);
227 a.UnloadProject (p);
230 [Test]
231 [Category ("NotWorking")]
232 public void TestUnregisterAllLoggers ()
234 engine = new Engine (Consts.BinPath);
235 CheckUnregisterLogger cul = new CheckUnregisterLogger ();
236 engine.RegisterLogger (cul);
238 engine.UnregisterAllLoggers ();
240 Assert.IsFalse (cul.Anything, "A1");
243 [Test]
244 public void TestBuildError1 ()
246 engine = new Engine (Consts.BinPath);
247 Project project = engine.CreateNewProject ();
249 Assert.IsFalse (project.Build (), "A1");
250 Assert.IsFalse (project.Build ((string)null), "A2");
251 Assert.IsFalse (project.Build ((string [])null), "A3");
252 Assert.IsFalse (project.Build (new string [0]), "A4");
253 Assert.IsFalse (project.Build (null, null), "A5");
254 Assert.IsFalse (project.Build (null, null, BuildSettings.None), "A6");
255 //FIXME: Add test for Build (null, non-null-target)
258 [Test]
259 public void TestBuildProjectFile1 ()
261 engine = new Engine (Consts.BinPath);
262 Project project = engine.CreateNewProject ();
263 project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
264 <Target Name='1'>
265 <Message Text='Target 1 called'/>
266 </Target>
267 </Project>");
269 Assert.IsTrue (project.Build ((string)null), "A1");
270 Assert.IsTrue (project.Build ((string [])null), "A2");
271 Assert.IsTrue (project.Build (new string [0]), "A3");
272 Assert.IsTrue (project.Build (null, null), "A4");
273 Assert.IsTrue (project.Build (null, null, BuildSettings.None), "A5");
274 //FIXME: Add test for Build (null, non-null-target)
277 [Test]
278 [ExpectedException (typeof (ArgumentException))]
279 public void TestBuildProject1 ()
281 engine = new Engine (Consts.BinPath);
282 engine.BuildProject (null);
285 [Test]
286 public void TestBuildProject2 ()
288 engine = new Engine (Consts.BinPath);
289 Project project = engine.CreateNewProject ();
291 Assert.IsFalse (engine.BuildProject (project, (string)null), "#A1");
292 Assert.IsFalse (engine.BuildProject (project, (string [])null), "#A2");
293 Assert.IsFalse (engine.BuildProject (project, (string [])null, null), "#A3");
294 Assert.IsFalse (engine.BuildProject (project, (string [])null, null, BuildSettings.None), "#A4");
296 bool caught_exception = false;
297 try {
298 //null string in targetNames [] param
299 engine.BuildProject (project, new string [] {null}, null);
300 } catch {
301 caught_exception = true;
303 if (!caught_exception)
304 Assert.Fail ("Expected exception for Engine.BuildProject");
307 [Test]
308 [ExpectedException (typeof (ArgumentException))]
309 public void TestBuildProjectNull1 ()
311 engine = new Engine (Consts.BinPath);
312 engine.BuildProject (null, "foo");
315 [Test]
316 [ExpectedException (typeof (ArgumentException))]
317 public void TestBuildProjectNull2 ()
319 engine = new Engine (Consts.BinPath);
320 engine.BuildProject (null, (string)null);
323 // Tests to check global properties behavior
324 [Test]
325 public void TestGlobalProperties1 ()
327 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
328 + GetUsingTask ("MSBuild")
329 + @"
330 <Target Name=""main"">
331 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
332 <Message Text=""second""/>
333 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
334 </Target>
335 </Project>";
337 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
338 + GetUsingTask ("MSBuild")
339 + @"
340 <Target Name = ""1"">
341 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
342 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
343 </Target>
344 <Target Name=""2"">
345 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
346 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
347 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
348 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
349 </Target>
350 </Project>
353 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
354 9, 7, 13,
355 new string [] {
356 "(TargetA) foo: bar A: External: ",
357 "(TargetB) foo: foofoo A: External: ",
358 "(TargetA) foo: A: External: ",
359 "(TargetB) foo: foofoo1 A: External: ",
360 "second" });
363 [Test]
364 public void TestGlobalProperties1a ()
366 Directory.CreateDirectory ("Test/resources/foo");
367 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
368 + GetUsingTask ("MSBuild")
369 + @"
370 <Target Name=""main"">
371 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
372 <Message Text=""second""/>
373 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
374 </Target>
375 </Project>";
377 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
378 + GetUsingTask ("MSBuild")
379 + @"
380 <Target Name = ""1"">
381 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
382 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
383 </Target>
384 <Target Name=""2"">
385 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
386 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
387 <MSBuild Projects=""second.proj"" Targets = ""TargetA"" Properties=""foo=bar""/>
388 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
389 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
390 </Target>
391 </Project>
393 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
394 10, 7, 14,
395 new string [] {
396 "(TargetA) foo: bar A: External: ",
397 "(TargetB) foo: foofoo A: External: ",
398 "(TargetA) foo: A: External: ",
399 "(TargetB) foo: foofoo1 A: External: ",
400 "second"});
403 [Test]
404 public void TestGlobalProperties1b ()
406 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
407 + GetUsingTask ("MSBuild")
408 + @"
409 <Target Name=""main"">
410 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
411 <Message Text=""second""/>
412 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
413 </Target>
414 </Project>";
416 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
417 + GetUsingTask ("MSBuild")
418 + @"
419 <Target Name = ""1"">
420 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
421 <MSBuild Projects=""second.proj""/>
422 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
423 </Target>
424 <Target Name=""2"">
425 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
426 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
427 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
428 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
429 </Target>
430 </Project>
432 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
433 10, 7, 14,
434 new string [] {
435 "(TargetA) foo: bar A: External: ",
436 "(TargetA) foo: A: External: ",
437 "(TargetB) foo: foofoo A: External: ",
438 "(TargetB) foo: foofoo1 A: External: ",
439 "second"});
442 [Test]
443 public void TestGlobalProperties2 ()
445 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
446 + GetUsingTask ("MSBuild")
447 + @"
448 <Target Name=""main"">
449 <MSBuild Projects=""first.proj"" Targets = ""1""/>
450 <MSBuild Projects=""first.proj"" Targets = ""2""/>
451 <Message Text=""second""/>
452 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
453 </Target>
454 </Project>";
456 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
457 + GetUsingTask ("MSBuild")
458 + @"
459 <Target Name = ""1"">
460 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
461 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
462 </Target>
463 <Target Name=""2"">
464 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
465 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
466 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
467 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
468 </Target>
469 </Project>
472 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
473 10, 7, 14,
474 new string [] {
475 "(TargetA) foo: bar A: External: ",
476 "(TargetB) foo: foofoo A: External: ",
477 "(TargetA) foo: A: External: ",
478 "(TargetB) foo: foofoo1 A: External: ",
479 "second"});
482 [Test]
483 public void TestGlobalProperties3 ()
485 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
486 + GetUsingTask ("MSBuild")
487 + @"
488 <Target Name=""main"">
489 <MSBuild Projects=""first.proj"" Targets = ""1""/>
490 <CallTarget Targets=""Call2""/>
491 <Message Text=""second""/>
492 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
493 </Target>
494 <Target Name=""Call2"">
495 <MSBuild Projects=""first.proj"" Targets = ""2""/>
496 </Target>
497 </Project>";
499 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
500 + GetUsingTask ("MSBuild")
501 + @"
502 <Target Name = ""1"">
503 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
504 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
505 </Target>
506 <Target Name=""2"">
507 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
508 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
509 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
510 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
511 </Target>
512 </Project>
515 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
516 10, 8, 15,
517 new string [] {
518 "(TargetA) foo: bar A: External: ",
519 "(TargetB) foo: foofoo A: External: ",
520 "(TargetA) foo: A: External: ",
521 "(TargetB) foo: foofoo1 A: External: ",
522 "second"});
525 //externally set global properties
526 [Test]
527 public void TestGlobalProperties4 ()
529 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
530 + GetUsingTask ("MSBuild")
531 + @"
532 <Target Name=""main"">
533 <MSBuild Projects=""first.proj"" Targets = ""1""/>
534 <CallTarget Targets=""Call2""/>
535 <Message Text=""second""/>
536 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
537 </Target>
538 <Target Name=""Call2"">
539 <MSBuild Projects=""first.proj"" Targets = ""2""/>
540 </Target>
541 </Project>";
543 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
544 + GetUsingTask ("MSBuild")
545 + @"
546 <Target Name = ""1"">
547 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
548 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
549 </Target>
550 <Target Name=""2"">
551 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
552 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
553 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
554 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
555 </Target>
556 </Project>
559 BuildPropertyGroup globalprops = new BuildPropertyGroup ();
560 globalprops.SetProperty ("foo", "hello");
561 engine.GlobalProperties = globalprops;
563 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
564 globalprops, null, 10, 8, 15,
565 new string [] {
566 "(TargetA) foo: bar A: External: ",
567 "(TargetB) foo: foofoo A: External: ",
568 "(TargetA) foo: hello A: FooWasHello External: ",
569 "(TargetB) foo: foofoo1 A: External: ",
570 "second"});
573 //externally set global properties, merge with explicit
574 [Test]
575 public void TestGlobalProperties4a ()
577 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
578 + GetUsingTask ("MSBuild")
579 + @"
580 <Target Name=""main"">
581 <MSBuild Projects=""first.proj"" Targets = ""1""/>
582 <CallTarget Targets=""Call2""/>
583 <Message Text=""second""/>
584 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
585 </Target>
586 <Target Name=""Call2"">
587 <MSBuild Projects=""first.proj"" Targets = ""2""/>
588 </Target>
589 </Project>";
591 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
592 + GetUsingTask ("MSBuild")
593 + @"
594 <Target Name = ""1"">
595 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
596 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
597 </Target>
598 <Target Name=""2"">
599 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
600 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
601 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
602 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
603 </Target>
604 </Project>
607 BuildPropertyGroup globalprops = new BuildPropertyGroup ();
608 globalprops.SetProperty ("external", "ExternalValue");
610 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
611 globalprops, null,
612 10, 8, 15,
613 new string [] {
614 "(TargetA) foo: bar A: External: ExternalValue",
615 "(TargetB) foo: foofoo A: External: ExternalValue",
616 "(TargetA) foo: A: External: ExternalValue",
617 "(TargetB) foo: foofoo1 A: External: ExternalValue",
618 "second"});
621 //set global properties on _project_, merge with explicit
622 [Test]
623 public void TestGlobalProperties4b ()
625 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
626 + GetUsingTask ("MSBuild")
627 + @"
628 <Target Name=""main"">
629 <MSBuild Projects=""first.proj"" Targets = ""1""/>
630 <CallTarget Targets=""Call2""/>
631 <Message Text=""second""/>
632 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
633 </Target>
634 <Target Name=""Call2"">
635 <MSBuild Projects=""first.proj"" Targets = ""2""/>
636 </Target>
637 </Project>";
639 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
640 + GetUsingTask ("MSBuild")
641 + @"
642 <Target Name = ""1"">
643 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
644 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
645 </Target>
646 <Target Name=""2"">
647 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
648 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
649 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
650 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
651 </Target>
652 </Project>
655 BuildPropertyGroup globalprops = new BuildPropertyGroup ();
656 globalprops.SetProperty ("external", "ExternalValue");
658 BuildPropertyGroup project_globalprops = new BuildPropertyGroup ();
659 project_globalprops.SetProperty ("external", "ProjExternalValue");
660 project_globalprops.SetProperty ("foo", "ProjFooValue");
662 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
663 globalprops, project_globalprops,
664 10, 8, 15,
665 new string [] {
666 "(TargetA) foo: bar A: External: ProjExternalValue",
667 "(TargetB) foo: foofoo A: External: ProjExternalValue",
668 "(TargetA) foo: ProjFooValue A: External: ProjExternalValue",
669 "(TargetB) foo: foofoo1 A: External: ProjExternalValue",
670 "second"});
673 //set global properties on _project_, and engine and explicit via msbuild
674 [Test]
675 public void TestGlobalProperties4c ()
677 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
678 + GetUsingTask ("MSBuild")
679 + @"
680 <Target Name=""main"">
681 <MSBuild Projects=""first.proj"" Targets = ""1""/>
682 <CallTarget Targets=""Call2""/>
683 <Message Text=""second""/>
684 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
685 </Target>
686 <Target Name=""Call2"">
687 <MSBuild Projects=""first.proj"" Targets = ""2""/>
688 </Target>
689 </Project>";
691 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
692 + GetUsingTask ("MSBuild")
693 + @"
694 <Target Name = ""1"">
695 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
696 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
697 </Target>
698 <Target Name=""2"">
699 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
700 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
701 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
702 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
703 </Target>
704 </Project>
707 BuildPropertyGroup globalprops = new BuildPropertyGroup ();
708 globalprops.SetProperty ("foo", "EngineFooValue");
710 BuildPropertyGroup project_globalprops = new BuildPropertyGroup ();
711 project_globalprops.SetProperty ("foo", "ProjFooValue");
713 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
714 globalprops, project_globalprops,
715 10, 8, 15,
716 new string [] {
717 "(TargetA) foo: bar A: External: ",
718 "(TargetB) foo: foofoo A: External: ",
719 "(TargetA) foo: ProjFooValue A: External: ",
720 "(TargetB) foo: foofoo1 A: External: ",
721 "second"});
723 [Test]
724 public void TestMSBuildOutputs ()
726 string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
727 + GetUsingTask ("MSBuild")
728 + @"
729 <ItemGroup>
730 <ProjectRef Include=""first.proj"">
731 <Prop3>value</Prop3>
732 <Unique>true</Unique>
733 </ProjectRef>
734 <ProjectRef Include=""first.proj"">
735 <Prop3>value2</Prop3>
736 <Unique>false</Unique>
737 </ProjectRef>
739 <ProjectRef Include=""second.proj"">
740 <Prop3>value3</Prop3>
741 <Unique>unique</Unique>
742 </ProjectRef>
744 </ItemGroup>
746 <Target Name='Main'>
747 <MSBuild Projects=""@(ProjectRef)"" Targets=""GetData"">
748 <Output TaskParameter=""TargetOutputs"" ItemName=""F""/>
749 </MSBuild>
750 <Message Text=""@(F): F.Unique: %(F.Unique)""/>
751 <Message Text=""@(F): F.Prop1: %(F.Prop1)""/>
752 <Message Text=""@(F): F.Prop2: %(F.Prop2)""/>
753 <Message Text=""@(F): F.Prop3: %(F.Prop3)""/>
754 </Target>
755 </Project>";
757 string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
758 <ItemGroup>
759 <A Include=""foofoo"">
760 <Prop1>false</Prop1>
761 <Prop2>false</Prop2>
762 <Prop3>foo value</Prop3>
763 </A>
765 <A Include=""barbar"">
766 <Prop1>bar_false</Prop1>
767 <Prop2>bar_false</Prop2>
768 <Prop3>bar value</Prop3>
769 </A>
771 </ItemGroup>
773 <Target Name=""GetData"" Outputs=""@(AbcOutputs)"">
774 <CreateItem Include=""@(A)"">
775 <Output TaskParameter=""Include"" ItemName=""AbcOutputs""/>
776 </CreateItem>
777 </Target>
778 </Project>
780 string secondProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
781 <ItemGroup>
782 <A Include=""from_second"">
783 <Prop1>false</Prop1>
784 <Prop2>false</Prop2>
785 <Prop3>new value</Prop3>
786 </A>
787 </ItemGroup>
789 <Target Name=""GetData"" Outputs=""@(AbcOutputs)"">
790 <CreateItem Include=""@(A)"">
791 <Output TaskParameter=""Include"" ItemName=""AbcOutputs""/>
792 </CreateItem>
793 </Target>
794 </Project>
797 CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
798 null, null,
799 4, 3, 12,
800 new string [] {
801 "foofoo;barbar;foofoo;barbar: F.Unique: true",
802 "from_second: F.Unique: unique",
803 "foofoo;foofoo;from_second: F.Prop1: false",
804 "barbar;barbar: F.Prop1: bar_false",
805 "foofoo;foofoo;from_second: F.Prop2: false",
806 "barbar;barbar: F.Prop2: bar_false",
807 "foofoo;foofoo: F.Prop3: foo value",
808 "barbar;barbar: F.Prop3: bar value",
809 "from_second: F.Prop3: new value",
813 // Helper Methods for TestGlobalProperties*
815 void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,
816 int project_count, int target_count, int task_count, string [] messages)
818 CreateAndCheckGlobalPropertiesTest (main, first, second, null, null,
819 project_count, target_count, task_count, messages);
822 void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,
823 BuildPropertyGroup engine_globals, BuildPropertyGroup project_globals,
824 int project_count, int target_count, int task_count, string [] messages)
826 WriteGlobalPropertiesProjects (main, first, second);
828 Engine engine = new Engine (Consts.BinPath);
829 if (engine_globals != null)
830 engine.GlobalProperties = engine_globals;
831 MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
832 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
833 engine.RegisterLogger (logger);
835 Project project = engine.CreateNewProject ();
836 project.Load (Path.Combine ("Test", Path.Combine ("resources", "main.proj")));
837 if (project_globals != null)
838 project.GlobalProperties = project_globals;
840 bool result = project.Build ();
841 if (!result) {
842 logger.DumpMessages ();
843 Assert.Fail ("Build failed");
846 CheckEventCounts (logger, project_count, target_count, task_count);
848 CheckLoggedMessages (logger, messages, "A1");
851 void CheckEventCounts (MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger,
852 int project, int target, int task)
854 try {
855 Assert.AreEqual (project, logger.ProjectStarted, "#project started events");
856 Assert.AreEqual (project, logger.ProjectFinished, "#project finished events");
857 Assert.AreEqual (target, logger.TargetStarted, "#target started events");
858 Assert.AreEqual (target, logger.TargetFinished, "#target finished events");
859 Assert.AreEqual (task, logger.TaskStarted, "#task started events");
860 Assert.AreEqual (task, logger.TaskFinished, "#task finished events");
861 Assert.AreEqual (1, logger.BuildStarted, "#build started events");
862 Assert.AreEqual (1, logger.BuildFinished, "#build finished events");
863 } catch (AssertionException) {
864 logger.DumpMessages ();
865 throw;
869 void CheckLoggedMessages (MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger, string [] messages,
870 string prefix)
872 try {
873 for (int i = 0; i < messages.Length; i++) {
874 logger.CheckLoggedMessageHead (messages [i], String.Format ("{0} #{1}", prefix, i));
876 } catch {
877 logger.DumpMessages ();
878 throw;
881 Assert.AreEqual (0, logger.NormalMessageCount, "Number of remaining messages");
884 // helper methods for TestGlobalProperties*
885 void WriteGlobalPropertiesProjects (string mainProject, string firstProject, string secondProject)
887 using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "main.proj")))) {
888 sw.Write (mainProject);
891 using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "first.proj")))) {
892 sw.Write (firstProject);
895 using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
896 sw.Write (secondProject);
900 public static string GetUsingTask (string taskName)
902 return "<UsingTask TaskName='Microsoft.Build.Tasks." + taskName + "' AssemblyFile='" + Consts.GetTasksAsmPath () + "' />";