public void OverridePropertiesInInferredCreateProperty() { string[] files = null; try { files = ObjectModelHelpers.GetTempFiles(2, new DateTime(2005, 1, 1)); MockLogger logger = new MockLogger(); string projectFileContents = ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <i Include='" + files[0] + "'><output>" + files[1] + @"</output></i> </ItemGroup> <ItemGroup> <EmbeddedResource Include='a.resx'> <LogicalName>foo</LogicalName> </EmbeddedResource> <EmbeddedResource Include='b.resx'> <LogicalName>bar</LogicalName> </EmbeddedResource> <EmbeddedResource Include='c.resx'> <LogicalName>barz</LogicalName> </EmbeddedResource> </ItemGroup> <Target Name='t2' DependsOnTargets='t'> <Message Text='final:[$(LinkSwitches)]'/> </Target> <Target Name='t' Inputs='%(i.Identity)' Outputs='%(i.Output)'> <Message Text='start:[Hello]'/> <CreateProperty Value=""@(EmbeddedResource->'/assemblyresource:%(Identity),%(LogicalName)', ' ')"" Condition=""'%(LogicalName)' != '' ""> <Output TaskParameter=""Value"" PropertyName=""LinkSwitches""/> </CreateProperty> <Message Text='end:[hello]'/> </Target> </Project>"); Project project = new Project(XmlReader.Create(new StringReader(projectFileContents))); List <ILogger> loggers = new List <ILogger>(); loggers.Add(logger); project.Build("t2", loggers); // We should only see messages from the second target, as the first is only inferred logger.AssertLogDoesntContain("start:"); logger.AssertLogDoesntContain("end:"); logger.AssertLogContains(new string[] { "final:[/assemblyresource:c.resx,barz]" }); logger.AssertLogDoesntContain(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("TaskStarted", "CreateProperty")); logger.AssertLogContains(new string[] { ResourceUtilities.FormatResourceStringStripCodeAndKeyword("PropertyOutputOverridden", "LinkSwitches", "/assemblyresource:a.resx,foo", "/assemblyresource:b.resx,bar") }); logger.AssertLogContains(new string[] { ResourceUtilities.FormatResourceStringStripCodeAndKeyword("PropertyOutputOverridden", "LinkSwitches", "/assemblyresource:b.resx,bar", "/assemblyresource:c.resx,barz") }); } finally { ObjectModelHelpers.DeleteTempFiles(files); } }
public void EmptyItemSpecInTargetOutputs() { MockLogger ml = ObjectModelHelpers.BuildProjectExpectFailure(@" <Project ToolsVersion=`3.5` xmlns=`msbuildnamespace`> <Target Name=`generatemsbtasks` Inputs=`@(TASKXML)` Outputs=`@(TASKXML->'%(OutputFile)');@(TASKXML->'%(PasFile)');`> <Message Text=`Running Build target` Importance=`High`/> </Target> <ItemGroup> <TASKXML Include=`bcc32task.xml`> <OutputFile>bcc32task.cs</OutputFile> <PasFile>bcc32task.pas</PasFile> </TASKXML> <TASKXML Include=`ccc32task.xml`> <OutputFile>cpp32task.cs</OutputFile> </TASKXML> </ItemGroup> </Project>"); // It should have actually skipped the "Build" target since some output metadata was missing ml.AssertLogDoesntContain("Running Build target"); ml.AssertLogContains("MSB4168"); // Clear the mock logger object out so it is not reused ml = null; ml = ObjectModelHelpers.BuildProjectExpectFailure(@" <Project ToolsVersion=`3.5` xmlns=`msbuildnamespace`> <Target Name=`generatemsbtasks` Inputs=`@(TASKXML)` Outputs=`@(TASKXML->'%(OutputFile)');@(TASKXML->'%(PasFile)');`> <Message Text=`Running Build target` Importance=`High`/> </Target> <ItemGroup> <TASKXML Include=`bcc32task.xml`> <OutputFile>bcc32task.cs</OutputFile> <PasFile>bcc32task.pas</PasFile> </TASKXML> <TASKXML Include=`ccc32task.xml`> <OutputFile>cpp32task.cs</OutputFile> <!-- Note PasFile not defined for this item! --> <PasFile></PasFile> </TASKXML> </ItemGroup> </Project> "); // It should have actually skipped the "Build" target since some output metadata was missing ml.AssertLogDoesntContain("Running Build target"); ml.AssertLogContains("MSB4168"); }
/// <summary> /// Executes an STA task test. /// </summary> private void TestSTATask(bool requireSTA, bool failTask, bool throwException) { MockLogger logger = new MockLogger(); logger.AllowTaskCrashes = throwException; string taskAssemblyName = null; Project project = CreateSTATestProject(requireSTA, failTask, throwException, out taskAssemblyName); List <ILogger> loggers = new List <ILogger>(); loggers.Add(logger); BuildParameters parameters = new BuildParameters(); parameters.Loggers = new ILogger[] { logger }; BuildResult result = BuildManager.DefaultBuildManager.Build(parameters, new BuildRequestData(project.CreateProjectInstance(), new string[] { "Foo" })); if (requireSTA) { logger.AssertLogContains("STA"); } else { logger.AssertLogContains("MTA"); } if (throwException) { logger.AssertLogContains("EXCEPTION"); Assert.Equal(BuildResultCode.Failure, result.OverallResult); return; } else { logger.AssertLogDoesntContain("EXCEPTION"); } if (failTask) { logger.AssertLogContains("FAIL"); Assert.Equal(BuildResultCode.Failure, result.OverallResult); } else { logger.AssertLogDoesntContain("FAIL"); } if (!throwException && !failTask) { Assert.Equal(BuildResultCode.Success, result.OverallResult); } }
/// <summary> /// Assert that the log doesnt contain the given string. /// First check if the string is in the log string. If not /// than make sure it is also not in the MockLogger /// </summary> /// <param name="contains"></param> public void AssertLogDoesntContain(string contains) { Console.WriteLine(log); if (upperLog == null) { upperLog = log; upperLog = upperLog.ToUpperInvariant(); } Assert.IsTrue ( !upperLog.Contains ( contains.ToUpperInvariant() ) ); // If we do not contain this string than pass it to // MockLogger. Since MockLogger is also registered as // a logger it may have this string. mockLogger.AssertLogDoesntContain ( contains ); }
public void SameAssemblyFromDifferentRelativePathsSharesAssemblyLoadContext() { string realTaskPath = Assembly.GetExecutingAssembly().Location; string fileName = Path.GetFileName(realTaskPath); string directoryName = Path.GetDirectoryName(realTaskPath); using var env = TestEnvironment.Create(); string customTaskFolder = Path.Combine(directoryName, "buildCrossTargeting"); env.CreateFolder(customTaskFolder); string projectContents = @"<Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <UsingTask TaskName=`RegisterObject` AssemblyFile=`" + Path.Combine(customTaskFolder, "..", fileName) + @"` /> <UsingTask TaskName=`RetrieveObject` AssemblyFile=`" + realTaskPath + @"` /> <Target Name=`Build`> <RegisterObject /> <RetrieveObject /> </Target> </Project>"; MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(projectContents, _testOutput); logger.AssertLogDoesntContain("MSB4018"); }
// Ignore: Changes to the current directory interfere with the toolset reader. public void CommandLineErrorsReportFullCommandline() { string projectFile = @" <Project ToolsVersion=`msbuilddefaulttoolsversion` DefaultTargets=`XamlTaskFactory` xmlns=`http://schemas.microsoft.com/developer/msbuild/2003`> <UsingTask TaskName=`TestTask` TaskFactory=`XamlTaskFactory` AssemblyName=`Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`> <Task> <![CDATA[ <ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`> <Rule Name=`TestTask` ToolName=`echoparameters.exe`> <StringProperty Name=`test` /> </Rule> </ProjectSchemaDefinitions> ]]> </Task> </UsingTask> <Target Name=`XamlTaskFactory`> <TestTask CommandLineTemplate=`where /x` /> </Target> </Project>"; Project p = ObjectModelHelpers.CreateInMemoryProject(projectFile); MockLogger logger = new MockLogger(); bool success = p.Build(logger); Assert.IsFalse(success, "Build should have failed"); // Should not be logging ToolTask.ToolCommandFailed, should be logging Xaml.CommandFailed logger.AssertLogDoesntContain("MSB6006"); logger.AssertLogContains("MSB3721"); }
public void TaskReturnsHasLoggedErrorAndLogsWarningAsError_BuildShouldFinishAndFail() { using (TestEnvironment env = TestEnvironment.Create(_output)) { TransientTestProjectWithFiles proj = env.CreateTestProjectWithFiles($@" <Project> <UsingTask TaskName = ""ReturnFailureWithoutLoggingErrorTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/> <UsingTask TaskName = ""CustomLogAndReturnTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/> <PropertyGroup> <MSBuildWarningsAsErrors>MSB1234</MSBuildWarningsAsErrors> </PropertyGroup> <Target Name='Build'> <CustomLogAndReturnTask Return=""true"" ReturnHasLoggedErrors=""true"" WarningCode=""MSB1234""/> <ReturnFailureWithoutLoggingErrorTask/> </Target> </Project>"); MockLogger logger = proj.BuildProjectExpectFailure(); logger.WarningCount.ShouldBe(0); logger.ErrorCount.ShouldBe(1); // The build should STOP when a task logs an error, make sure ReturnFailureWithoutLoggingErrorTask doesn't run. logger.AssertLogDoesntContain("MSB4181"); } }
public void EmptyItemSpecInTargetOutputs() { MockLogger ml = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Build' Inputs='@(TASKXML)' Outputs=""@(TASKXML->'%(OutputFile)');@(TASKXML->'%(PasFile)');""> <Message Text='Running Build target' Importance='High'/> </Target> <ItemGroup> <TASKXML Include='bcc32task.xml'> <OutputFile>bcc32task.cs</OutputFile> </TASKXML> <TASKXML Include='ccc32task.xml'> <PasFile>ccc32task.pas</PasFile> </TASKXML> </ItemGroup> </Project>")))); bool success = p.Build("Build", new ILogger[] { ml }); Assert.True(success); // It should not have skipped the "Build" target since some output metadata was missing ml.AssertLogContains("Running Build target"); ml = new MockLogger(); p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Build' Inputs='@(TASKXML)' Outputs=""@(TASKXML->'%(OutputFile)');@(TASKXML->'%(PasFile)');""> <Message Text='Running Build target' Importance='High'/> </Target> <ItemGroup> <TASKXML Include='bcc32task.xml'> </TASKXML> <TASKXML Include='ccc32task.xml'> </TASKXML> </ItemGroup> </Project>")))); success = p.Build("Build", new ILogger[] { ml }); Assert.True(success); // It should have actually skipped the "Build" target since some output metadata was missing ml.AssertLogDoesntContain("Running Build target"); }
// Ignore: Test requires installed toolset. public void CommandLineErrorsReportFullCommandlineAmpersandTemp() { string projectFile = @" <Project ToolsVersion=`msbuilddefaulttoolsversion` DefaultTargets=`XamlTaskFactory` xmlns=`http://schemas.microsoft.com/developer/msbuild/2003`> <UsingTask TaskName=`TestTask` TaskFactory=`XamlTaskFactory` AssemblyName=`Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`> <Task> <![CDATA[ <ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`> <Rule Name=`TestTask` ToolName=`findstr.exe`> <StringProperty Name=`test` /> </Rule> </ProjectSchemaDefinitions> ]]> </Task> </UsingTask> <Target Name=`XamlTaskFactory`> <TestTask CommandLineTemplate='findstr'/> </Target> </Project>"; string directoryWithAmpersand = "foo&bar"; string newTmp = Path.Combine(Path.GetTempPath(), directoryWithAmpersand); string oldTmp = Environment.GetEnvironmentVariable("TMP"); try { Directory.CreateDirectory(newTmp); Environment.SetEnvironmentVariable("TMP", newTmp); Project p = ObjectModelHelpers.CreateInMemoryProject(projectFile); MockLogger logger = new MockLogger(); bool success = p.Build(logger); Assert.IsFalse(success); logger.AssertLogContains("FINDSTR"); // Should not be logging ToolTask.ToolCommandFailed, should be logging Xaml.CommandFailed logger.AssertLogDoesntContain("MSB6006"); logger.AssertLogContains("MSB3721"); } finally { Environment.SetEnvironmentVariable("TMP", oldTmp); ObjectModelHelpers.DeleteDirectory(newTmp); if (Directory.Exists(newTmp)) { Directory.Delete(newTmp); } } }
public void TaskLogsWarningAsError_BatchedBuild() { using (TestEnvironment env = TestEnvironment.Create(_output)) { TransientTestProjectWithFiles proj = env.CreateTestProjectWithFiles($@" <Project> <UsingTask TaskName = ""ReturnFailureWithoutLoggingErrorTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/> <UsingTask TaskName = ""CustomLogAndReturnTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/> <PropertyGroup> <MSBuildWarningsAsErrors>MSB1234</MSBuildWarningsAsErrors> </PropertyGroup> <ItemGroup> <SomeItem Include=""Item1""> <Return>true</Return> <ReturnHasLoggedErrors>true</ReturnHasLoggedErrors> <WarningCode>MSB1235</WarningCode> </SomeItem> <SomeItem Include=""Item2""> <Return>true</Return> <ReturnHasLoggedErrors>true</ReturnHasLoggedErrors> <WarningCode>MSB1236</WarningCode> </SomeItem> <SomeItem Include=""Item3""> <Return>true</Return> <ReturnHasLoggedErrors>true</ReturnHasLoggedErrors> <WarningCode>MSB1234</WarningCode> </SomeItem> <SomeItem Include=""Item4""> <Return>true</Return> <ReturnHasLoggedErrors>true</ReturnHasLoggedErrors> <WarningCode>MSB1237</WarningCode> </SomeItem> </ItemGroup> <Target Name='Build'> <CustomLogAndReturnTask Sources=""@(SomeItem)"" Return=""true"" ReturnHasLoggedErrors=""true"" WarningCode=""%(WarningCode)""/> <ReturnFailureWithoutLoggingErrorTask/> </Target> </Project>"); MockLogger logger = proj.BuildProjectExpectFailure(); logger.WarningCount.ShouldBe(2); logger.ErrorCount.ShouldBe(1); // The build should STOP when a task logs an error, make sure ReturnFailureWithoutLoggingErrorTask doesn't run. logger.AssertLogDoesntContain("MSB1237"); } }
public void EmptyItemSpecInTargetInputs() { MockLogger ml = ObjectModelHelpers.BuildProjectExpectSuccess(@" <Project ToolsVersion=`3.5` xmlns=`msbuildnamespace`> <ItemGroup> <MyFile Include=`a.cs; b.cs; c.cs`/> </ItemGroup> <Target Name=`Build` Inputs=`@(MyFile->'%(NonExistentMetadata)')` Outputs=`foo.exe`> <Message Text=`Running Build target` Importance=`High`/> </Target> </Project> "); // It should have actually skipped the "Build" target since there were no inputs. ml.AssertLogDoesntContain("Running Build target"); }
public void TasksAreDiscoveredWhenTaskConditionTrue() { MockLogger logger = new MockLogger(); string projectFileContents = ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <NonExistantTask Condition=""'1'=='1'""/> <Message Text='Made it'/> </Target> </Project>"); Project project = new Project(XmlReader.Create(new StringReader(projectFileContents))); List <ILogger> loggers = new List <ILogger>(); loggers.Add(logger); project.Build("t", loggers); logger.AssertLogContains("MSB4036"); logger.AssertLogDoesntContain("Made it"); }
public void EmptyItemSpecInTargetInputs() { MockLogger ml = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <MyFile Include='a.cs; b.cs; c.cs'/> </ItemGroup> <Target Name='Build' Inputs=""@(MyFile->'%(NonExistentMetadata)')"" Outputs='foo.exe'> <Message Text='Running Build target' Importance='High'/> </Target> </Project>")))); bool success = p.Build(new string[] { "Build" }, new ILogger[] { ml }); Assert.True(success); // It should have actually skipped the "Build" target since there were no inputs. ml.AssertLogDoesntContain("Running Build target"); }
public void ProjectResolverContextRefersToBuildingProject(string projectFormatString) { string projectInnerContents = _projectInnerContents; File.WriteAllText(_sdkPropsPath, _sdkPropsContent); File.WriteAllText(_sdkTargetsPath, _sdkTargetsContent); // Use custom SDK resolution to ensure resolver context is logged. var mapping = new Dictionary <string, string> { { SdkName, _testSdkDirectory } }; var projectOptions = SdkUtilities.CreateProjectOptionsWithResolver(new SdkUtilities.FileBasedMockSdkResolver(mapping)); // Create a normal project (p1) which imports an SDK style project (p2). var projectFolder = _env.CreateFolder().Path; var p1 = @"<Project> <Import Project=""p2.proj"" /> </Project>"; var p2 = string.Format(projectFormatString, SdkName, projectInnerContents); var p1Path = Path.Combine(projectFolder, "p1.proj"); var p2Path = Path.Combine(projectFolder, "p2.proj"); File.WriteAllText(p1Path, p1); File.WriteAllText(p2Path, p2); var logger = new MockLogger(); var pc = _env.CreateProjectCollection().Collection; pc.RegisterLogger(logger); ProjectRootElement projectRootElement = ProjectRootElement.Open(p1Path, pc); projectOptions.ProjectCollection = pc; var project = Project.FromProjectRootElement(projectRootElement, projectOptions); // ProjectFilePath should be logged with the path to p1 and not the path to p2. logger.AssertLogContains($"ProjectFilePath = {p1Path}"); logger.AssertLogDoesntContain($"ProjectFilePath = {p2Path}"); }
public void EmptyItemSpecInTargetInputs() { MockLogger ml = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <MyFile Include='a.cs; b.cs; c.cs'/> </ItemGroup> <Target Name='Build' Inputs=""@(MyFile->'%(NonExistentMetadata)')"" Outputs='foo.exe'> <Message Text='Running Build target' Importance='High'/> </Target> </Project>" )))); bool success = p.Build(new string[] { "Build" }, new ILogger[] { ml }); Assert.True(success); // It should have actually skipped the "Build" target since there were no inputs. ml.AssertLogDoesntContain("Running Build target"); }
public void ProjectResolverContextRefersToBuildingProject(string projectFormatString) { string projectInnerContents = @"<PropertyGroup><UsedToTestIfImplicitImportsAreInTheCorrectLocation>null</UsedToTestIfImplicitImportsAreInTheCorrectLocation></PropertyGroup>"; File.WriteAllText(_sdkPropsPath, "<Project><PropertyGroup><InitialImportProperty>Hello</InitialImportProperty></PropertyGroup></Project>"); File.WriteAllText(_sdkTargetsPath, "<Project><PropertyGroup><FinalImportProperty>World</FinalImportProperty></PropertyGroup></Project>"); // Use custom SDK resolution to ensure resolver context is logged. var mapping = new Dictionary <string, string> { { SdkName, _testSdkDirectory } }; _env.CustomSdkResolution(mapping); // Create a normal project (p1) which imports an SDK style project (p2). var projectFolder = _env.CreateFolder().FolderPath; var p1 = @"<Project> <Import Project=""p2.proj"" /> </Project>"; var p2 = string.Format(projectFormatString, SdkName, projectInnerContents); var p1Path = Path.Combine(projectFolder, "p1.proj"); var p2Path = Path.Combine(projectFolder, "p2.proj"); File.WriteAllText(p1Path, p1); File.WriteAllText(p2Path, p2); var logger = new MockLogger(); var pc = new ProjectCollection(); pc.RegisterLogger(logger); ProjectRootElement projectRootElement = ProjectRootElement.Open(p1Path, pc); var project = new Project(projectRootElement, null, null, pc); // ProjectFilePath should be logged with the path to p1 and not the path to p2. logger.AssertLogContains($"ProjectFilePath = {p1Path}"); logger.AssertLogDoesntContain($"ProjectFilePath = {p2Path}"); }
public void BucketsWithEmptyListForBatchedItemList() { string content = @" <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <ItemGroup> <i Include=""b""/> <j Include=""a""> <k>x</k> </j> </ItemGroup> <Target Name=""t""> <ItemGroup> <Obj Condition=""'%(j.k)'==''"" Include=""@(j->'%(Filename).obj');%(i.foo)""/> </ItemGroup> <Message Text=""@(Obj)"" /> </Target> </Project> "; MockLogger log = Helpers.BuildProjectWithNewOMExpectSuccess(content); log.AssertLogDoesntContain("a.obj"); }
public void LogWithLoggersOnProjectCollectionCustomOneUsed() { MockLogger mockLogger = new MockLogger(); MockLogger mockLogger2 = new MockLogger(); string projectFileContent = ObjectModelHelpers.CleanupFileContents(@" <Project xmlns='msbuildnamespace'> <Target Name=""BUild""> <Message Text=""IHaveBeenLogged"" Importance=""High""/> </Target> </Project>"); ProjectRootElement xml = ProjectRootElement.Create(XmlReader.Create(new StringReader(projectFileContent))); ProjectCollection collection = new ProjectCollection(); collection.RegisterLogger(mockLogger2); Project project = new Project(xml, null, null, collection); bool result = project.Build(mockLogger); Assert.Equal(true, result); mockLogger.AssertLogContains("IHaveBeenLogged"); mockLogger2.AssertLogDoesntContain("IHaveBeenLogged"); }
public void TwoSubmissionsWithSeparateLoggers() { string projectBody1 = ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Test'> <Message Text='Foo'/> <Error Text='Error'/> </Target> </Project> "); string projectBody2 = ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Test'> <Message Text='Bar'/> <Warning Text='Warning'/> </Target> </Project> "); ProjectInstance project1 = (new Project(XmlReader.Create(new StringReader(projectBody1)))).CreateProjectInstance(); ProjectInstance project2 = (new Project(XmlReader.Create(new StringReader(projectBody2)))).CreateProjectInstance(); BuildManager buildManager = BuildManager.DefaultBuildManager; MuxLogger muxLogger = new MuxLogger(); BuildParameters parameters = new BuildParameters(ProjectCollection.GlobalProjectCollection); parameters.Loggers = new ILogger[] { muxLogger }; MockLogger mockLogger1 = new MockLogger(); MockLogger mockLogger2 = new MockLogger(); buildManager.BeginBuild(parameters); try { BuildSubmission submission1 = buildManager.PendBuildRequest(new BuildRequestData(project1, new string[0], null)); muxLogger.RegisterLogger(submission1.SubmissionId, mockLogger1); submission1.Execute(); BuildSubmission submission2 = buildManager.PendBuildRequest(new BuildRequestData(project2, new string[0], null)); muxLogger.RegisterLogger(submission2.SubmissionId, mockLogger2); submission2.Execute(); } finally { buildManager.EndBuild(); } mockLogger1.AssertLogContains("Foo"); mockLogger1.AssertLogContains("Error"); mockLogger1.AssertLogDoesntContain("Bar"); mockLogger1.AssertLogDoesntContain("Warning"); Assert.Equal(1, mockLogger1.ErrorCount); Assert.Equal(0, mockLogger1.WarningCount); mockLogger2.AssertLogDoesntContain("Foo"); mockLogger2.AssertLogDoesntContain("Error"); mockLogger2.AssertLogContains("Bar"); mockLogger2.AssertLogContains("Warning"); Assert.Equal(0, mockLogger2.ErrorCount); Assert.Equal(1, mockLogger2.WarningCount); }
public void PropertiesInInferredBuildCreateProperty() { string[] files = null; try { files = ObjectModelHelpers.GetTempFiles(2, new DateTime(2005, 1, 1)); MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <i Include='" + files.First() + "'><output>" + files.ElementAt(1) + @"</output></i> </ItemGroup> <Target Name='t2' DependsOnTargets='t'> <Message Text='final:[$(p)]'/> </Target> <Target Name='t' Inputs='%(i.Identity)' Outputs='%(i.Output)'> <Message Text='start:[$(p)]'/> <CreateProperty Value='@(i)'> <Output TaskParameter='Value' PropertyName='p'/> </CreateProperty> <Message Text='end:[$(p)]'/> </Target> </Project> ")))); p.Build(new string[] { "t2" }, new ILogger[] { logger }); // We should only see messages from the second target, as the first is only inferred logger.AssertLogDoesntContain("start:"); logger.AssertLogDoesntContain("end:"); logger.AssertLogContains(new string[] { "final:[" + files.First() + "]" }); } finally { ObjectModelHelpers.DeleteTempFiles(files); } }
public void ItemGroupWithConditionOnGroup() { MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <ItemGroup Condition='false'> <i1 Include='a1'/> <i2 Include='b1'/> </ItemGroup> <Message Text='[@(i1)][@(i2)]'/> </Target> </Project>")))); p.Build(new string[] { "t" }, new ILogger[] { logger }); logger.AssertLogDoesntContain("[a1][b1]"); logger.ClearLog(); p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <ItemGroup Condition='true'> <i1 Include='a1'/> <i2 Include='b1'/> </ItemGroup> <Message Text='[@(i1)][@(i2)]'/> </Target> </Project>")))); p.Build(new string[] { "t" }, new ILogger[] { logger }); logger.AssertLogContains("[a1][b1]"); }
public void FilterItemPreviouslyModified2() { MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <x Include='a'/> </ItemGroup> <Target Name='t'> <ItemGroup> <x> <m1>1</m1> </x> <x> <m1 Condition=""'%(x.m1)'=='1'"">2</m1> </x> </ItemGroup> <Message Text='[%(x.m1)]'/> </Target> </Project> ")))); p.Build(new string[] { "t" }, new ILogger[] { logger }); logger.AssertLogDoesntContain("[1]"); logger.AssertLogContains("[2]"); }
public void PropertyGroupWithConditionOnGroup() { MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <PropertyGroup Condition='false'> <p1>v1</p1> <p2>v2</p2> </PropertyGroup> <Message Text='[$(P1)][$(P2)]'/> </Target> </Project>")))); p.Build(new string[] { "t" }, new ILogger[] { logger }); logger.AssertLogDoesntContain("[v1][v2]"); logger.ClearLog(); p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <PropertyGroup Condition='true'> <p1>v1</p1> <p2>v2</p2> </PropertyGroup> <Message Text='[$(P1)][$(P2)]'/> </Target> </Project>")))); p.Build(new string[] { "t" }, new ILogger[] { logger }); logger.AssertLogContains("[v1][v2]"); }
public void TasksCanAddRecursiveDirBuiltInMetadata() { MockLogger logger = new MockLogger(); string projectFileContents = ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <CreateItem Include='$(programfiles)\reference assemblies\**\*.dll;'> <Output TaskParameter='Include' ItemName='x' /> </CreateItem> <Message Text='@(x)'/> <Message Text='[%(x.RecursiveDir)]'/> </Target> </Project>"); Project project = new Project(XmlReader.Create(new StringReader(projectFileContents))); List<ILogger> loggers = new List<ILogger>(); loggers.Add(logger); bool result = project.Build("t", loggers); Assert.AreEqual(true, result); logger.AssertLogDoesntContain("[]"); logger.AssertLogDoesntContain("MSB4118"); logger.AssertLogDoesntContain("MSB3031"); }
public void TasksAreDiscoveredWhenTaskConditionTrue() { MockLogger logger = new MockLogger(); string projectFileContents = ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='t'> <NonExistantTask Condition=""'1'=='1'""/> <Message Text='Made it'/> </Target> </Project>"); Project project = new Project(XmlReader.Create(new StringReader(projectFileContents))); List<ILogger> loggers = new List<ILogger>(); loggers.Add(logger); project.Build("t", loggers); logger.AssertLogContains("MSB4036"); logger.AssertLogDoesntContain("Made it"); }
public void ItemsEmittedByIntrinsicTaskConsumingItemExpression_DestinationDefaultMetadataOverriddenBySourceDefaultMetadata() { MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(@" <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <ItemDefinitionGroup> <i> <m>m1</m> </i> <j> <m>m2</m> </j> </ItemDefinitionGroup> <ItemGroup> <i Include=""n1""/> <j Include=""@(i)""/> </ItemGroup> <Target Name=""t""> <ItemGroup> <i Include=""n2""/> <j Include=""@(i)""/> </ItemGroup> <Message Text=""[%(j.m)]""/> </Target> </Project> "))); Assert.AreEqual("m1", p.GetItems("j").First().GetMetadataValue("m")); p.Build("t", new ILogger[] { logger }); logger.AssertLogContains("[m1]"); logger.AssertLogDoesntContain("[m2]"); }
public void CurrentDirectoryRestoredAfterException() { ObjectModelHelpers.DeleteTempProjectDirectory(); // --------------------- // dirs.proj // --------------------- ObjectModelHelpers.CreateFileInTempProjectDirectory("dirs.proj", @" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <ItemGroup> <Project Include=`a\a.proj` /> <Project Include=`b\b.proj` /> </ItemGroup> <Target Name=`dirs`> <MSBuild Projects=`@(Project)` /> </Target> </Project> "); // --------------------- // a.proj // An invalid project file that will cause an InvalidProjectException // --------------------- ObjectModelHelpers.CreateFileInTempProjectDirectory(@"a\a.proj", @" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <Message Text=`a` /> <Target Name=`a`> <Message Text=`Greetings from an invalid project!`/> </Target> </Project> "); // --------------------- // b.proj // A control project file that should build correctly after a.proj throws // --------------------- ObjectModelHelpers.CreateFileInTempProjectDirectory(@"b\b.proj", @" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <Target Name=`b`> <Message Text=`Greetings from a valid project!`/> </Target> </Project> "); // Create a logger. MockLogger logger = new MockLogger(); Project project = ObjectModelHelpers.LoadProjectFileInTempProjectDirectory("dirs.proj", logger); bool success = project.Build(null, null); Assertion.Assert("Build should have failed. See Standard Out tab for details", !success); logger.AssertLogDoesntContain("Greetings from an invalid project!"); logger.AssertLogContains("Greetings from a valid project!"); }
public void MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2() { Console.WriteLine("MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2"); string currentDirectory = Directory.GetCurrentDirectory(); try { Directory.SetCurrentDirectory(ObjectModelHelpers.TempProjectDir); MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project InitialTargets='Setup' xmlns='msbuildnamespace'> <ItemGroup> <A Include='A' /> <B Include='B' /> </ItemGroup> <Target Name='Build' DependsOnTargets='GAFT'> <Message Text='Build: @(Outs)' /> <Message Text='Build: GAFTOutsA @(GAFTOutsA)' /> <Message Text='Build: GAFTOutsB @(GAFTOutsB)' /> </Target> <Target Name='Setup'> <WriteLinesToFile File='A' Lines='A' Overwrite='true'/> <WriteLinesToFile File='B.out' Lines='B.out' Overwrite='true'/> <Exec Command='sleep.exe 1' /> <WriteLinesToFile File='B' Lines='B' Overwrite='true'/> <WriteLinesToFile File='A.out' Lines='A.out' Overwrite='true'/> </Target> <Target Name='GAFT' Inputs='@(A);@(B)' Outputs=""@(A->'%(Filename).out');@(B->'%(Filename).out')""> <CreateItem Include=""@(A->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsA' /> </CreateItem> <Message Text='GAFT A:@(A)' /> <CreateItem Include=""@(B->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsB' /> </CreateItem> <Message Text='GAFT B:@(B)' /> </Target> </Project> ")))); p.Build(new string[] { "Build" }, new ILogger[] { logger }); // If the log contains B.out twice, then there is leakage from the parent lookup logger.AssertLogDoesntContain("B.out;B.out"); } finally { Directory.SetCurrentDirectory(currentDirectory); } }
public void MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2() { Console.WriteLine("MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2"); MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project InitialTargets='Setup' xmlns='msbuildnamespace'> <ItemGroup> <A Include='A' /> <B Include='B' /> </ItemGroup> <Target Name='Build' DependsOnTargets='GAFT'> <Message Text='Build: @(Outs)' /> <Message Text='Build: GAFTOutsA @(GAFTOutsA)' /> <Message Text='Build: GAFTOutsB @(GAFTOutsB)' /> </Target> <Target Name='Setup'> <WriteLinesToFile File='A' Lines='A' Overwrite='true'/> <WriteLinesToFile File='B.out' Lines='B.out' Overwrite='true'/> <Exec Command='sleep.exe 1' /> <WriteLinesToFile File='B' Lines='B' Overwrite='true'/> <WriteLinesToFile File='A.out' Lines='A.out' Overwrite='true'/> </Target> <Target Name='GAFT' Inputs='@(A);@(B)' Outputs=""@(A->'%(Filename).out');@(B->'%(Filename).out')""> <CreateItem Include=""@(A->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsA' /> </CreateItem> <Message Text='GAFT A:@(A)' /> <CreateItem Include=""@(B->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsB' /> </CreateItem> <Message Text='GAFT B:@(B)' /> </Target> </Project> ")))); p.Build(new string[] { "Build" }, new ILogger[] { logger }); // If the log contains B.out twice, then there is leakage from the parent lookup logger.AssertLogDoesntContain("B.out;B.out"); }
public void CommandLineErrorsReportFullCommandlineAmpersandTemp() { string projectFile = @" <Project ToolsVersion=`msbuilddefaulttoolsversion` DefaultTargets=`XamlTaskFactory` xmlns=`http://schemas.microsoft.com/developer/msbuild/2003`> <UsingTask TaskName=`TestTask` TaskFactory=`XamlTaskFactory` AssemblyName=`Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`> <Task> <![CDATA[ <ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`> <Rule Name=`TestTask` ToolName=`findstr.exe`> <StringProperty Name=`test` /> </Rule> </ProjectSchemaDefinitions> ]]> </Task> </UsingTask> <Target Name=`XamlTaskFactory`> <TestTask CommandLineTemplate='findstr'/> </Target> </Project>"; string directoryWithAmpersand = "foo&bar"; string newTmp = Path.Combine(Path.GetTempPath(), directoryWithAmpersand); string oldTmp = Environment.GetEnvironmentVariable("TMP"); try { Directory.CreateDirectory(newTmp); Environment.SetEnvironmentVariable("TMP", newTmp); Project p = ObjectModelHelpers.CreateInMemoryProject(projectFile); MockLogger logger = new MockLogger(); bool success = p.Build(logger); Assert.IsFalse(success); logger.AssertLogContains("FINDSTR"); // Should not be logging ToolTask.ToolCommandFailed, should be logging Xaml.CommandFailed logger.AssertLogDoesntContain("MSB6006"); logger.AssertLogContains("MSB3721"); } finally { Environment.SetEnvironmentVariable("TMP", oldTmp); ObjectModelHelpers.DeleteDirectory(newTmp); if (Directory.Exists(newTmp)) Directory.Delete(newTmp); } }
public void OverridePropertiesInInferredCreateProperty() { string[] files = null; try { files = ObjectModelHelpers.GetTempFiles(2, new DateTime(2005, 1, 1)); MockLogger logger = new MockLogger(); string projectFileContents = ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <ItemGroup> <i Include='" + files[0] + "'><output>" + files[1] + @"</output></i> </ItemGroup> <ItemGroup> <EmbeddedResource Include='a.resx'> <LogicalName>foo</LogicalName> </EmbeddedResource> <EmbeddedResource Include='b.resx'> <LogicalName>bar</LogicalName> </EmbeddedResource> <EmbeddedResource Include='c.resx'> <LogicalName>barz</LogicalName> </EmbeddedResource> </ItemGroup> <Target Name='t2' DependsOnTargets='t'> <Message Text='final:[$(LinkSwitches)]'/> </Target> <Target Name='t' Inputs='%(i.Identity)' Outputs='%(i.Output)'> <Message Text='start:[Hello]'/> <CreateProperty Value=""@(EmbeddedResource->'/assemblyresource:%(Identity),%(LogicalName)', ' ')"" Condition=""'%(LogicalName)' != '' ""> <Output TaskParameter=""Value"" PropertyName=""LinkSwitches""/> </CreateProperty> <Message Text='end:[hello]'/> </Target> </Project>"); Project project = new Project(XmlReader.Create(new StringReader(projectFileContents))); List<ILogger> loggers = new List<ILogger>(); loggers.Add(logger); project.Build("t2", loggers); // We should only see messages from the second target, as the first is only inferred logger.AssertLogDoesntContain("start:"); logger.AssertLogDoesntContain("end:"); logger.AssertLogContains(new string[] { "final:[/assemblyresource:c.resx,barz]" }); logger.AssertLogDoesntContain(ResourceUtilities.FormatResourceString("TaskStarted", "CreateProperty")); logger.AssertLogContains(new string[] { ResourceUtilities.FormatResourceString("PropertyOutputOverridden", "LinkSwitches", "/assemblyresource:a.resx,foo", "/assemblyresource:b.resx,bar") }); logger.AssertLogContains(new string[] { ResourceUtilities.FormatResourceString("PropertyOutputOverridden", "LinkSwitches", "/assemblyresource:b.resx,bar", "/assemblyresource:c.resx,barz") }); } finally { ObjectModelHelpers.DeleteTempFiles(files); } }
public void CommandLineErrorsReportFullCommandline() { string projectFile = @" <Project ToolsVersion=`msbuilddefaulttoolsversion` DefaultTargets=`XamlTaskFactory` xmlns=`http://schemas.microsoft.com/developer/msbuild/2003`> <UsingTask TaskName=`TestTask` TaskFactory=`XamlTaskFactory` AssemblyName=`Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`> <Task> <![CDATA[ <ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`> <Rule Name=`TestTask` ToolName=`echoparameters.exe`> <StringProperty Name=`test` /> </Rule> </ProjectSchemaDefinitions> ]]> </Task> </UsingTask> <Target Name=`XamlTaskFactory`> <TestTask CommandLineTemplate=`where /x` /> </Target> </Project>"; Project p = ObjectModelHelpers.CreateInMemoryProject(projectFile); MockLogger logger = new MockLogger(); bool success = p.Build(logger); Assert.IsFalse(success, "Build should have failed"); // Should not be logging ToolTask.ToolCommandFailed, should be logging Xaml.CommandFailed logger.AssertLogDoesntContain("MSB6006"); logger.AssertLogContains("MSB3721"); }
/// <summary> /// Executes an STA task test. /// </summary> private void TestSTATask(bool requireSTA, bool failTask, bool throwException) { MockLogger logger = new MockLogger(); logger.AllowTaskCrashes = throwException; string taskAssemblyName = null; Project project = CreateSTATestProject(requireSTA, failTask, throwException, out taskAssemblyName); List<ILogger> loggers = new List<ILogger>(); loggers.Add(logger); BuildParameters parameters = new BuildParameters(); parameters.Loggers = new ILogger[] { logger }; BuildResult result = BuildManager.DefaultBuildManager.Build(parameters, new BuildRequestData(project.CreateProjectInstance(), new string[] { "Foo" })); if (requireSTA) { logger.AssertLogContains("STA"); } else { logger.AssertLogContains("MTA"); } if (throwException) { logger.AssertLogContains("EXCEPTION"); Assert.AreEqual(BuildResultCode.Failure, result.OverallResult); return; } else { logger.AssertLogDoesntContain("EXCEPTION"); } if (failTask) { logger.AssertLogContains("FAIL"); Assert.AreEqual(BuildResultCode.Failure, result.OverallResult); } else { logger.AssertLogDoesntContain("FAIL"); } if (!throwException && !failTask) { Assert.AreEqual(BuildResultCode.Success, result.OverallResult); } }
public void ToolsVersionFallbackIfCurrentToolsVersionDoesNotExist_ProjectInstance() { ProjectCollection p = new ProjectCollection(); p.RemoveToolset(ObjectModelHelpers.MSBuildDefaultToolsVersion); MockLogger mockLogger = new MockLogger(); LoggingService service = (LoggingService)LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1); service.RegisterLogger(mockLogger); bool success = false; Project project = new Project(XmlReader.Create(new StringReader(@"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='Foo'> </Target> </Project>")), null /* no global properties */, null /* don't explicitly set the toolsversion */, p); ProjectInstance pi = new ProjectInstance(project.Xml, null /* no global properties */, null /* don't explicitly set the toolsversion */, p); Assert.AreEqual("4.0", pi.ToolsVersion); success = pi.Build(new ILogger[] { mockLogger }); Assert.IsTrue(success); mockLogger.AssertLogContains("\"4.0\""); mockLogger.AssertLogDoesntContain(ObjectModelHelpers.CleanupFileContents("\"msbuilddefaulttoolsversion\"")); }