New error message.
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / EngineTest.cs
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
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;
34
35 namespace MonoTests.Microsoft.Build.BuildEngine {
36
37         class CheckUnregisterLogger : Logger {
38                 bool anything = false;
39
40                 public override void Initialize (IEventSource eventSource)
41                 {
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; };
56                 }
57
58                 public bool Anything { get { return anything; } }
59         }
60
61         [TestFixture]
62         public class EngineTest {
63
64                 Engine engine;
65                 string secondProject;
66
67                 static string GetPropValue (BuildPropertyGroup bpg, string name)
68                 {
69                         foreach (BuildProperty bp in bpg) {
70                                 if (bp.Name == name) {
71                                         return bp.FinalValue;
72                                 }
73                         }
74                         return String.Empty;
75                 }
76
77                 [SetUp]
78                 public void Setup ()
79                 {
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>
87
88         <Target Name=""TargetB"">
89                 <Message Text=""(TargetB) foo: $(foo) A: $(A) External: $(External)""/>
90         </Target>
91 </Project>";
92
93                 }
94
95                 [Test]
96                 public void TestCtor ()
97                 {
98                         engine = new Engine (Consts.BinPath);
99                 }
100
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                 [Test]
104                 [ExpectedException (typeof (InvalidOperationException))]
105                 public void TestNewProject ()
106                 {
107                         engine = new Engine ();
108
109                         engine.CreateNewProject ();
110                 }
111
112                 [Test]
113                 public void TestBinPath ()
114                 {
115                         engine = new Engine (Consts.BinPath);
116
117                         Assert.AreEqual (Consts.BinPath, engine.BinPath, "A1");
118                 }
119
120                 [Test]
121                 public void TestBuildEnabled ()
122                 {
123                         engine = new Engine (Consts.BinPath);
124
125                         Assert.AreEqual (true, engine.BuildEnabled, "A1");
126                 }
127
128                 [Test]
129                 public void TestOnlyLogCriticalEvents ()
130                 {
131                         engine = new Engine (Consts.BinPath);
132
133                         Assert.AreEqual (false, engine.OnlyLogCriticalEvents, "A1");
134                 }
135
136                 [Test]
137                 public void TestGlobalProperties ()
138                 {
139                         engine = new Engine (Consts.BinPath);
140                         Project project;
141
142                         Assert.IsNotNull (engine.GlobalProperties, "A1");
143                         Assert.AreEqual (0, engine.GlobalProperties.Count, "A2");
144                         Assert.AreEqual (String.Empty, engine.GlobalProperties.Condition, "A3");
145                         Assert.IsFalse (engine.GlobalProperties.IsImported, "A4");
146                         
147                         engine.GlobalProperties.SetProperty ("GlobalA", "value1");
148                         Assert.AreEqual (1, engine.GlobalProperties.Count, "A5");
149                         engine.GlobalProperties.SetProperty ("GlobalB", "value1");
150                         Assert.AreEqual (2, engine.GlobalProperties.Count, "A6");
151                         engine.GlobalProperties.SetProperty ("GlobalA", "value2");
152                         Assert.AreEqual (2, engine.GlobalProperties.Count, "A7");
153
154                         project = engine.CreateNewProject ();
155                         Assert.AreEqual (2, project.GlobalProperties.Count, "A8");
156                         project.GlobalProperties.SetProperty ("GlobalC", "value3");
157                         Assert.AreEqual (3, project.GlobalProperties.Count, "A9");
158                         Assert.AreEqual (2, engine.GlobalProperties.Count, "A10");
159
160                         project.GlobalProperties.SetProperty ("GlobalA", "value3");
161                         Assert.AreEqual ("value2", GetPropValue(engine.GlobalProperties, "GlobalA"), "A11");
162                         engine.GlobalProperties.SetProperty ("GlobalB", "value3");
163                         Assert.AreEqual ("value1", GetPropValue(project.GlobalProperties, "GlobalB"), "A12");
164
165                         engine.GlobalProperties.SetProperty ("GlobalC", "value4");
166                         engine.GlobalProperties.SetProperty ("GlobalD", "value5");
167                         Assert.AreEqual (4, engine.GlobalProperties.Count, "A13");
168                         Assert.AreEqual (3, project.GlobalProperties.Count, "A14");
169
170                         project = new Project (engine);
171                         Assert.AreEqual (4, project.GlobalProperties.Count, "A15");
172                 }
173
174                 [Test]
175                 public void TestGlobalEngine ()
176                 {
177                         engine = new Engine ();
178                         Assert.IsFalse (engine == Engine.GlobalEngine, "1");
179                         Assert.IsNotNull (Engine.GlobalEngine, "2");
180                         engine = Engine.GlobalEngine;
181                         Assert.AreSame (engine, Engine.GlobalEngine, "3");
182                 }
183
184                 [Test]
185                 [ExpectedException (typeof (ArgumentNullException))]
186                 [Category ("NotDotNet")]
187                 public void TestRegisterLogger ()
188                 {
189                         engine = new Engine (Consts.BinPath);
190                         engine.RegisterLogger (null);
191                 }
192
193                 // The "Project" object specified does not belong to the correct "Engine" object.
194                 [Test]
195                 [ExpectedException (typeof (InvalidOperationException))]
196                 public void TestUnloadProject1 ()
197                 {
198                         Engine a = new Engine (Consts.BinPath);
199                         Engine b = new Engine (Consts.BinPath);
200
201                         Project p = a.CreateNewProject ();
202
203                         b.UnloadProject (p);
204                 }
205
206                 [Test]
207                 [ExpectedException (typeof (ArgumentNullException))]
208                 [Category ("NotDotNet")]
209                 public void TestUnloadProject2 ()
210                 {
211                         Engine a = new Engine (Consts.BinPath);
212
213                         a.UnloadProject (null);
214                 }
215
216                 // This project object has been unloaded from the MSBuild engine and is no longer valid.
217                 [Test]
218                 [ExpectedException (typeof (InvalidOperationException))]
219                 public void TestUnloadProject3 ()
220                 {
221                         Engine a = new Engine (Consts.BinPath);
222                         Project p = a.CreateNewProject ();
223
224                         a.UnloadProject (p);
225                         a.UnloadProject (p);
226                 }
227
228                 [Test]
229                 [Category ("NotWorking")]
230                 public void TestUnregisterAllLoggers ()
231                 {
232                         engine = new Engine (Consts.BinPath);
233                         CheckUnregisterLogger cul = new CheckUnregisterLogger ();
234                         engine.RegisterLogger (cul);
235
236                         engine.UnregisterAllLoggers ();
237
238                         Assert.IsFalse (cul.Anything, "A1");
239                 }
240
241                 [Test]
242                 public void TestBuildError1 ()
243                 {
244                         engine = new Engine (Consts.BinPath);
245                         Project project = engine.CreateNewProject ();
246
247                         Assert.IsFalse (project.Build (), "A1");
248                         Assert.IsFalse (project.Build ((string)null), "A2");
249                         Assert.IsFalse (project.Build ((string [])null), "A3");
250                         Assert.IsFalse (project.Build (new string [0]), "A4");
251                         Assert.IsFalse (project.Build (null, null), "A5");
252                         Assert.IsFalse (project.Build (null, null, BuildSettings.None), "A6");
253                         //FIXME: Add test for Build (null, non-null-target)
254                 }
255
256                 [Test]
257                 public void TestBuildProjectFile1 ()
258                 {
259                         engine = new Engine (Consts.BinPath);
260                         Project project = engine.CreateNewProject ();
261                         project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
262                                         <Target Name='1'>
263                                                 <Message Text='Target 1 called'/>
264                                         </Target>
265                                 </Project>");
266
267                         Assert.IsTrue (project.Build ((string)null), "A1");
268                         Assert.IsTrue (project.Build ((string [])null), "A2");
269                         Assert.IsTrue (project.Build (new string [0]), "A3");
270                         Assert.IsTrue (project.Build (null, null), "A4");
271                         Assert.IsTrue (project.Build (null, null, BuildSettings.None), "A5");
272                         //FIXME: Add test for Build (null, non-null-target)
273                 }
274
275                 [Test]
276                 [ExpectedException (typeof (ArgumentException))]
277                 public void TestBuildProject1 ()
278                 {
279                         engine = new Engine (Consts.BinPath);
280                         engine.BuildProject (null);
281                 }
282
283                 [Test]
284                 public void TestBuildProject2 ()
285                 {
286                         engine = new Engine (Consts.BinPath);
287                         Project project = engine.CreateNewProject ();
288
289                         Assert.IsFalse (engine.BuildProject (project, (string)null), "#A1");
290                         Assert.IsFalse (engine.BuildProject (project, (string [])null), "#A2");
291                         Assert.IsFalse (engine.BuildProject (project, (string [])null, null), "#A3");
292                         Assert.IsFalse (engine.BuildProject (project, (string [])null, null, BuildSettings.None), "#A4");
293
294                         bool caught_exception = false;
295                         try {
296                                 //null string in targetNames [] param
297                                 engine.BuildProject (project, new string [] {null}, null);
298                         } catch {
299                                 caught_exception = true;
300                         }
301                         if (!caught_exception)
302                                 Assert.Fail ("Expected exception for Engine.BuildProject");
303                 }
304
305                 [Test]
306                 [ExpectedException (typeof (ArgumentException))]
307                 public void TestBuildProjectNull1 ()
308                 {
309                         engine = new Engine (Consts.BinPath);
310                         engine.BuildProject (null, "foo");
311                 }
312
313                 [Test]
314                 [ExpectedException (typeof (ArgumentException))]
315                 public void TestBuildProjectNull2 ()
316                 {
317                         engine = new Engine (Consts.BinPath);
318                         engine.BuildProject (null, (string)null);
319                 }
320
321                 // Tests to check global properties behavior
322                 [Test]
323                 public void TestGlobalProperties1 ()
324                 {
325                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
326         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
327         <Target Name=""main"">
328                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
329                 <Message Text=""second""/>
330                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
331         </Target>
332 </Project>";
333
334                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
335         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
336                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
337         <Target Name = ""1"">
338                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
339                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
340         </Target>
341         <Target Name=""2"">
342                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
343                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
344                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
345                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
346         </Target>
347 </Project>
348 ";
349
350                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
351                                 9, 7, 13,
352                                 new string [] {
353                                         "(TargetA) foo: bar A:  External: ",
354                                         "(TargetB) foo: foofoo A:  External: ",
355                                         "(TargetA) foo:  A:  External: ",
356                                         "(TargetB) foo: foofoo1 A:  External: ",
357                                         "second" });
358                 }
359
360                 [Test]
361                 public void TestGlobalProperties1a ()
362                 {
363                         Directory.CreateDirectory ("Test/resources/foo");
364                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
365         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
366         <Target Name=""main"">
367                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
368                 <Message Text=""second""/>
369                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
370         </Target>
371 </Project>";
372
373                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
374         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
375                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
376         <Target Name = ""1"">
377                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
378                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
379         </Target>
380         <Target Name=""2"">
381                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
382                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
383                 <MSBuild Projects=""second.proj"" Targets = ""TargetA"" Properties=""foo=bar""/>
384                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
385                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
386         </Target>
387 </Project>
388 ";
389                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
390                                 10, 7, 14,
391                                  new string [] {
392                                         "(TargetA) foo: bar A:  External: ",
393                                         "(TargetB) foo: foofoo A:  External: ",
394                                         "(TargetA) foo:  A:  External: ",
395                                         "(TargetB) foo: foofoo1 A:  External: ",
396                                         "second"});
397                 }
398
399                 [Test]
400                 public void TestGlobalProperties1b ()
401                 {
402                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
403         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
404         <Target Name=""main"">
405                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
406                 <Message Text=""second""/>
407                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
408         </Target>
409 </Project>";
410
411                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
412         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
413                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
414         <Target Name = ""1"">
415                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
416                 <MSBuild Projects=""second.proj""/>
417                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
418         </Target>
419         <Target Name=""2"">
420                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
421                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
422                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
423                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
424         </Target>
425 </Project>
426 ";
427                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
428                                 10, 7, 14,
429                                 new string [] {
430                                         "(TargetA) foo: bar A:  External: ",
431                                         "(TargetA) foo:  A:  External: ",
432                                         "(TargetB) foo: foofoo A:  External: ",
433                                         "(TargetB) foo: foofoo1 A:  External: ",
434                                         "second"});
435                 }
436
437                 [Test]
438                 public void TestGlobalProperties2 ()
439                 {
440                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
441         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
442         <Target Name=""main"">
443                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
444                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
445                 <Message Text=""second""/>
446                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
447         </Target>
448 </Project>";
449
450                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
451         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
452                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
453         <Target Name = ""1"">
454                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
455                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
456         </Target>
457         <Target Name=""2"">
458                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
459                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
460                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
461                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
462         </Target>
463 </Project>
464 ";
465
466                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
467                                 10, 7, 14,
468                                 new string [] {
469                                         "(TargetA) foo: bar A:  External: ",
470                                         "(TargetB) foo: foofoo A:  External: ",
471                                         "(TargetA) foo:  A:  External: ",
472                                         "(TargetB) foo: foofoo1 A:  External: ",
473                                         "second"});
474                 }
475
476                 [Test]
477                 public void TestGlobalProperties3 ()
478                 {
479                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
480         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
481         <Target Name=""main"">
482                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
483                 <CallTarget Targets=""Call2""/>
484                 <Message Text=""second""/>
485                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
486         </Target>
487         <Target Name=""Call2"">
488                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
489         </Target>
490 </Project>";
491
492                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
493         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
494                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
495         <Target Name = ""1"">
496                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
497                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
498         </Target>
499         <Target Name=""2"">
500                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
501                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
502                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
503                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
504         </Target>
505 </Project>
506 ";
507
508                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
509                                 10, 8, 15,
510                                 new string [] {
511                                         "(TargetA) foo: bar A:  External: ",
512                                         "(TargetB) foo: foofoo A:  External: ",
513                                         "(TargetA) foo:  A:  External: ",
514                                         "(TargetB) foo: foofoo1 A:  External: ",
515                                         "second"});
516                 }
517
518                 //externally set global properties
519                 [Test]
520                 public void TestGlobalProperties4 ()
521                 {
522                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
523         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
524         <Target Name=""main"">
525                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
526                 <CallTarget Targets=""Call2""/>
527                 <Message Text=""second""/>
528                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
529         </Target>
530         <Target Name=""Call2"">
531                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
532         </Target>
533 </Project>";
534
535                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
536         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
537                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
538         <Target Name = ""1"">
539                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
540                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
541         </Target>
542         <Target Name=""2"">
543                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
544                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
545                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
546                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
547         </Target>
548 </Project>
549 ";
550
551                         BuildPropertyGroup globalprops = new BuildPropertyGroup ();
552                         globalprops.SetProperty ("foo", "hello");
553                         engine.GlobalProperties = globalprops;
554
555                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
556                                 globalprops, null, 10, 8, 15,
557                                 new string [] {
558                                         "(TargetA) foo: bar A:  External: ",
559                                         "(TargetB) foo: foofoo A:  External: ",
560                                         "(TargetA) foo: hello A: FooWasHello External: ",
561                                         "(TargetB) foo: foofoo1 A:  External: ",
562                                         "second"});
563                 }
564
565                 //externally set global properties, merge with explicit
566                 [Test]
567                 public void TestGlobalProperties4a ()
568                 {
569                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
570         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
571         <Target Name=""main"">
572                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
573                 <CallTarget Targets=""Call2""/>
574                 <Message Text=""second""/>
575                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
576         </Target>
577         <Target Name=""Call2"">
578                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
579         </Target>
580 </Project>";
581
582                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
583         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
584                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
585         <Target Name = ""1"">
586                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
587                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
588         </Target>
589         <Target Name=""2"">
590                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
591                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
592                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
593                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
594         </Target>
595 </Project>
596 ";
597
598                         BuildPropertyGroup globalprops = new BuildPropertyGroup ();
599                         globalprops.SetProperty ("external", "ExternalValue");
600
601                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
602                                 globalprops, null,
603                                 10, 8, 15,
604                                 new string [] {
605                                         "(TargetA) foo: bar A:  External: ExternalValue",
606                                         "(TargetB) foo: foofoo A:  External: ExternalValue",
607                                         "(TargetA) foo:  A:  External: ExternalValue",
608                                         "(TargetB) foo: foofoo1 A:  External: ExternalValue",
609                                         "second"});
610                 }
611
612                 //set global properties on _project_, merge with explicit
613                 [Test]
614                 public void TestGlobalProperties4b ()
615                 {
616                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
617         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
618         <Target Name=""main"">
619                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
620                 <CallTarget Targets=""Call2""/>
621                 <Message Text=""second""/>
622                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
623         </Target>
624         <Target Name=""Call2"">
625                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
626         </Target>
627 </Project>";
628
629                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
630         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
631                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
632         <Target Name = ""1"">
633                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
634                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
635         </Target>
636         <Target Name=""2"">
637                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
638                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
639                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
640                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
641         </Target>
642 </Project>
643 ";
644
645                         BuildPropertyGroup globalprops = new BuildPropertyGroup ();
646                         globalprops.SetProperty ("external", "ExternalValue");
647
648                         BuildPropertyGroup project_globalprops = new BuildPropertyGroup ();
649                         project_globalprops.SetProperty ("external", "ProjExternalValue");
650                         project_globalprops.SetProperty ("foo", "ProjFooValue");
651
652                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
653                                 globalprops, project_globalprops,
654                                 10, 8, 15,
655                                 new string [] {
656                                         "(TargetA) foo: bar A:  External: ProjExternalValue",
657                                         "(TargetB) foo: foofoo A:  External: ProjExternalValue",
658                                         "(TargetA) foo: ProjFooValue A:  External: ProjExternalValue",
659                                         "(TargetB) foo: foofoo1 A:  External: ProjExternalValue",
660                                         "second"});
661                 }
662
663                 //set global properties on _project_, and engine and explicit via msbuild
664                 [Test]
665                 public void TestGlobalProperties4c ()
666                 {
667                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
668         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
669         <Target Name=""main"">
670                 <MSBuild Projects=""first.proj"" Targets = ""1""/>
671                 <CallTarget Targets=""Call2""/>
672                 <Message Text=""second""/>
673                 <MSBuild Projects=""first.proj"" Targets = ""1;2""/>
674         </Target>
675         <Target Name=""Call2"">
676                 <MSBuild Projects=""first.proj"" Targets = ""2""/>
677         </Target>
678 </Project>";
679
680                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
681         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
682                 AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
683         <Target Name = ""1"">
684                 <MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
685                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
686         </Target>
687         <Target Name=""2"">
688                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
689                 <MSBuild Projects=""second.proj"" Targets = ""TargetA""/>
690                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo"" />
691                 <MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo1"" />
692         </Target>
693 </Project>
694 ";
695
696                         BuildPropertyGroup globalprops = new BuildPropertyGroup ();
697                         globalprops.SetProperty ("foo", "EngineFooValue");
698
699                         BuildPropertyGroup project_globalprops = new BuildPropertyGroup ();
700                         project_globalprops.SetProperty ("foo", "ProjFooValue");
701
702                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
703                                 globalprops, project_globalprops,
704                                 10, 8, 15,
705                                 new string [] {
706                                         "(TargetA) foo: bar A:  External: ",
707                                         "(TargetB) foo: foofoo A:  External: ",
708                                         "(TargetA) foo: ProjFooValue A:  External: ",
709                                         "(TargetB) foo: foofoo1 A:  External: ",
710                                         "second"});
711                 }
712                 [Test]
713                 public void TestMSBuildOutputs ()
714                 {
715                         string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
716                         <UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
717                                         AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
718
719         <ItemGroup>
720                 <ProjectRef Include=""first.proj"">
721                         <Prop3>value</Prop3>
722                         <Unique>true</Unique>
723                 </ProjectRef>
724                 <ProjectRef Include=""first.proj"">
725                         <Prop3>value2</Prop3>
726                         <Unique>false</Unique>
727                 </ProjectRef>
728                 
729                 <ProjectRef Include=""second.proj"">
730                         <Prop3>value3</Prop3>
731                         <Unique>unique</Unique>
732                 </ProjectRef>
733
734         </ItemGroup>
735
736         <Target Name='Main'>
737                 <MSBuild Projects=""@(ProjectRef)"" Targets=""GetData"">
738                         <Output TaskParameter=""TargetOutputs"" ItemName=""F""/>
739                 </MSBuild>
740                 <Message Text=""@(F): F.Unique: %(F.Unique)""/>
741                 <Message Text=""@(F): F.Prop1: %(F.Prop1)""/>
742                 <Message Text=""@(F): F.Prop2: %(F.Prop2)""/>
743                 <Message Text=""@(F): F.Prop3: %(F.Prop3)""/>
744         </Target>
745 </Project>";
746
747                         string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
748         <ItemGroup>
749                 <A Include=""foofoo"">
750                         <Prop1>false</Prop1>
751                         <Prop2>false</Prop2>
752                         <Prop3>foo value</Prop3>
753                 </A>
754                 
755                 <A Include=""barbar"">
756                         <Prop1>bar_false</Prop1>
757                         <Prop2>bar_false</Prop2>
758                         <Prop3>bar value</Prop3>
759                 </A>
760
761         </ItemGroup>
762
763         <Target Name=""GetData"" Outputs=""@(AbcOutputs)"">
764                 <CreateItem Include=""@(A)"">
765                         <Output TaskParameter=""Include"" ItemName=""AbcOutputs""/>
766                 </CreateItem>
767         </Target>
768 </Project>
769 ";
770                         string secondProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
771         <ItemGroup>
772                 <A Include=""from_second"">
773                         <Prop1>false</Prop1>
774                         <Prop2>false</Prop2>
775                         <Prop3>new value</Prop3>
776                 </A>
777         </ItemGroup>
778
779         <Target Name=""GetData"" Outputs=""@(AbcOutputs)"">
780                 <CreateItem Include=""@(A)"">
781                         <Output TaskParameter=""Include"" ItemName=""AbcOutputs""/>
782                 </CreateItem>
783         </Target>
784 </Project>
785 ";
786
787                         CreateAndCheckGlobalPropertiesTest (mainProject, firstProject, secondProject,
788                                 null, null,
789                                 4, 3, 12,
790                                 new string [] {
791                                         "foofoo;barbar;foofoo;barbar: F.Unique: true",
792                                         "from_second: F.Unique: unique",
793                                         "foofoo;foofoo;from_second: F.Prop1: false",
794                                         "barbar;barbar: F.Prop1: bar_false",
795                                         "foofoo;foofoo;from_second: F.Prop2: false",
796                                         "barbar;barbar: F.Prop2: bar_false",
797                                         "foofoo;foofoo: F.Prop3: foo value",
798                                         "barbar;barbar: F.Prop3: bar value",
799                                         "from_second: F.Prop3: new value",
800                                 });
801                 }
802
803                 // Helper Methods for TestGlobalProperties*
804
805                 void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,
806                         int project_count, int target_count, int task_count, string [] messages)
807                 {
808                         CreateAndCheckGlobalPropertiesTest (main, first, second, null, null,
809                                 project_count, target_count, task_count, messages);
810                 }
811
812                 void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,
813                         BuildPropertyGroup engine_globals, BuildPropertyGroup project_globals,
814                         int project_count, int target_count, int task_count, string [] messages)
815                 {
816                         WriteGlobalPropertiesProjects (main, first, second);
817
818                         Engine engine = new Engine (Consts.BinPath);
819                         if (engine_globals != null)
820                                 engine.GlobalProperties = engine_globals;
821                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
822                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
823                         engine.RegisterLogger (logger);
824
825                         Project project = engine.CreateNewProject ();
826                         project.Load (Path.Combine ("Test", Path.Combine ("resources", "main.proj")));
827                         if (project_globals != null)
828                                 project.GlobalProperties = project_globals;
829
830                         bool result = project.Build ();
831                         if (!result) {
832                                 logger.DumpMessages ();
833                                 Assert.Fail ("Build failed");
834                         }
835
836                         CheckEventCounts (logger, project_count, target_count, task_count);
837
838                         CheckLoggedMessages (logger, messages, "A1");
839                 }
840
841                 void CheckEventCounts (MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger,
842                         int project, int target, int task)
843                 {
844                         try {
845                                 Assert.AreEqual (project, logger.ProjectStarted, "#project started events");
846                                 Assert.AreEqual (project, logger.ProjectFinished, "#project finished events");
847                                 Assert.AreEqual (target, logger.TargetStarted, "#target started events");
848                                 Assert.AreEqual (target, logger.TargetFinished, "#target finished events");
849                                 Assert.AreEqual (task, logger.TaskStarted, "#task started events");
850                                 Assert.AreEqual (task, logger.TaskFinished, "#task finished events");
851                                 Assert.AreEqual (1, logger.BuildStarted, "#build started events");
852                                 Assert.AreEqual (1, logger.BuildFinished, "#build finished events");
853                         } catch (AssertionException) {
854                                 logger.DumpMessages ();
855                                 throw;
856                         }
857                 }
858
859                 void CheckLoggedMessages (MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger, string [] messages,
860                         string prefix)
861                 {
862                         try {
863                                 for (int i = 0; i < messages.Length; i++) {
864                                         logger.CheckLoggedMessageHead (messages [i], String.Format ("{0} #{1}", prefix, i));
865                                 }
866                         } catch {
867                                 logger.DumpMessages ();
868                                 throw;
869                         }
870
871                         Assert.AreEqual (0, logger.NormalMessageCount, "Number of remaining messages");
872                 }
873
874                 // helper methods for TestGlobalProperties*
875                 void WriteGlobalPropertiesProjects (string mainProject, string firstProject, string secondProject)
876                 {
877                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "main.proj")))) {
878                                 sw.Write (mainProject);
879                         }
880
881                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "first.proj")))) {
882                                 sw.Write (firstProject);
883                         }
884
885                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
886                                 sw.Write (secondProject);
887                         }
888                 }
889
890
891         }
892 }