Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 5 additions & 88 deletions src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,15 @@ public void MSBuildLoadContext_AcceptsNewerAssemblyVersions()
#endif


#if FEATURE_CODETASKFACTORY
/// <summary>
/// If an item being output from a task has null metadata, we shouldn't crash.
/// If an item being output from an inline task has null metadata, we shouldn't crash.
/// </summary>
[Fact]
public void NullMetadataOnOutputItems_InlineTask()
{
string projectContents = @"
<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName=`NullMetadataTask_v12` TaskFactory=`CodeTaskFactory` AssemblyFile=`$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll`>
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be curious about the meaning of "v12" here, it seems a bit arbitrary but there could be some reason I'm not catching.

<Project>
<UsingTask TaskName=`NullMetadataTask_Roslyn` TaskFactory=`RoslynCodeTaskFactory` AssemblyFile=`$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll`>
<ParameterGroup>
<OutputItems ParameterType=`Microsoft.Build.Framework.ITaskItem[]` Output=`true` />
</ParameterGroup>
Expand All @@ -719,9 +718,9 @@ public void NullMetadataOnOutputItems_InlineTask()
</Task>
</UsingTask>
<Target Name=`Build`>
<NullMetadataTask_v12>
<NullMetadataTask_Roslyn>
<Output TaskParameter=`OutputItems` ItemName=`Outputs` />
</NullMetadataTask_v12>
</NullMetadataTask_Roslyn>

<Message Text=`[%(Outputs.Identity): %(Outputs.a)]` Importance=`High` />
</Target>
Expand All @@ -731,88 +730,6 @@ public void NullMetadataOnOutputItems_InlineTask()
logger.AssertLogContains("[foo: ]");
}

/// <summary>
/// If an item being output from a task has null metadata, we shouldn't crash.
/// </summary>
[Fact(Skip = "This test fails when diagnostic logging is available, as deprecated EscapingUtilities.UnescapeAll method cannot handle null value. This is not relevant to non-deprecated version of this method.")]
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to discuss this, I deleted this mostly since I don't see a ticket to bring this back online, let me know what would be a good other action here

public void NullMetadataOnLegacyOutputItems_InlineTask()
{
string projectContents = @"
<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName=`NullMetadataTask_v4` TaskFactory=`CodeTaskFactory` AssemblyFile=`$(MSBuildFrameworkToolsPath)\Microsoft.Build.Tasks.v4.0.dll`>
<ParameterGroup>
<OutputItems ParameterType=`Microsoft.Build.Framework.ITaskItem[]` Output=`true` />
</ParameterGroup>
<Task>
<Code>
<![CDATA[
OutputItems = new ITaskItem[1];

IDictionary<string, string> metadata = new Dictionary<string, string>();
metadata.Add(`a`, null);

OutputItems[0] = new TaskItem(`foo`, (IDictionary)metadata);

return true;
]]>
</Code>
</Task>
</UsingTask>
<Target Name=`Build`>
<NullMetadataTask_v4>
<Output TaskParameter=`OutputItems` ItemName=`Outputs` />
</NullMetadataTask_v4>

<Message Text=`[%(Outputs.Identity): %(Outputs.a)]` Importance=`High` />
</Target>
</Project>";

MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(projectContents, _testOutput);
logger.AssertLogContains("[foo: ]");
}

/// <summary>
/// If an item being output from a task has null metadata, we shouldn't crash.
/// </summary>
[Fact(Skip = "This test fails when diagnostic logging is available, as deprecated EscapingUtilities.UnescapeAll method cannot handle null value. This is not relevant to non-deprecated version of this method.")]
[Trait("Category", "non-mono-tests")]
public void NullMetadataOnLegacyOutputItems_InlineTask_Diagnostic()
{
string projectContents = @"
<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName=`NullMetadataTask_v4` TaskFactory=`CodeTaskFactory` AssemblyFile=`$(MSBuildFrameworkToolsPath)\Microsoft.Build.Tasks.v4.0.dll`>
<ParameterGroup>
<OutputItems ParameterType=`Microsoft.Build.Framework.ITaskItem[]` Output=`true` />
</ParameterGroup>
<Task>
<Code>
<![CDATA[
OutputItems = new ITaskItem[1];

IDictionary<string, string> metadata = new Dictionary<string, string>();
metadata.Add(`a`, null);

OutputItems[0] = new TaskItem(`foo`, (IDictionary)metadata);

return true;
]]>
</Code>
</Task>
</UsingTask>
<Target Name=`Build`>
<NullMetadataTask_v4>
<Output TaskParameter=`OutputItems` ItemName=`Outputs` />
</NullMetadataTask_v4>

<Message Text=`[%(Outputs.Identity): %(Outputs.a)]` Importance=`High` />
</Target>
</Project>";

MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(projectContents, _testOutput, loggerVerbosity: LoggerVerbosity.Diagnostic);
logger.AssertLogContains("[foo: ]");
}
#endif

/// <summary>
/// Validates that the defining project metadata is set (or not set) as expected in
/// various task output-related operations, using a task built against the current
Expand Down
178 changes: 86 additions & 92 deletions src/Build.UnitTests/BackEnd/TaskHost_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -546,37 +546,35 @@ public void IsRunningMultipleNodes4Nodes()
Assert.True(_taskHost.IsRunningMultipleNodes); // "Expect IsRunningMultipleNodes to be true with 4 nodes"
}

#if FEATURE_CODETASKFACTORY
/// <summary>
/// Task logging after it's done should not crash us.
/// </summary>
[Fact]
public void LogCustomAfterTaskIsDone()
{
string projectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName='test' TaskFactory='CodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll' >
<Task>
<Using Namespace='System' />
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
string projectFileContents = """
<Project>
<UsingTask TaskName='test' TaskFactory='RoslynCodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll'>
<Task>
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
<![CDATA[
Log.LogWarning(""[1]"");
ThreadPool.QueueUserWorkItem(state=>
{
Thread.Sleep(100);
Log.LogExternalProjectStarted(""a"", ""b"", ""c"", ""d""); // this logs a custom event
});

Log.LogWarning("[1]");
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(100);
Log.LogExternalProjectStarted("a", "b", "c", "d");
});
]]>
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Warning Text=""[3]""/>
</Target>
</Project>";
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Warning Text="[3]"/>
</Target>
</Project>
""";

MockLogger mockLogger = Helpers.BuildProjectWithNewOMExpectSuccess(projectFileContents);
mockLogger.AssertLogContains("[1]");
Expand All @@ -589,108 +587,104 @@ public void LogCustomAfterTaskIsDone()
[Fact]
public void LogCommentAfterTaskIsDone()
{
string projectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName='test' TaskFactory='CodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll' >
<Task>
<Using Namespace='System' />
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
string projectFileContents = """
<Project>
<UsingTask TaskName='test' TaskFactory='RoslynCodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll'>
<Task>
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
<![CDATA[
Log.LogMessage(""[1]"");
ThreadPool.QueueUserWorkItem(state=>
{
Thread.Sleep(100);
Log.LogMessage(""[2]"");
});

Log.LogMessage("[1]");
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(100);
Log.LogMessage("[2]");
});
]]>
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Message Text=""[3]""/>
</Target>
</Project>";
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Message Text="[3]"/>
</Target>
</Project>
""";

MockLogger mockLogger = Helpers.BuildProjectWithNewOMExpectSuccess(projectFileContents);
mockLogger.AssertLogContains("[1]");
mockLogger.AssertLogContains("[3]"); // [2] may or may not appear.
}

/// <summary>
/// Task logging after it's done should not crash us.
/// Task logging a warning after it's done should not crash us.
/// </summary>
[Fact]
public void LogWarningAfterTaskIsDone()
{
string projectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName='test' TaskFactory='CodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll' >
<Task>
<Using Namespace='System' />
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
string projectFileContents = """
<Project>
<UsingTask TaskName='test' TaskFactory='RoslynCodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll'>
<Task>
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
<![CDATA[
Log.LogWarning(""[1]"");
ThreadPool.QueueUserWorkItem(state=>
{
Thread.Sleep(100);
Log.LogWarning(""[2]"");
});

Log.LogWarning("[1]");
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(100);
Log.LogWarning("[2]");
});
]]>
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Warning Text=""[3]""/>
</Target>
</Project>";
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test/>
<Warning Text="[3]"/>
</Target>
</Project>
""";

MockLogger mockLogger = Helpers.BuildProjectWithNewOMExpectSuccess(projectFileContents);
mockLogger.AssertLogContains("[1]");
mockLogger.AssertLogContains("[3]"); // [2] may or may not appear.
}

/// <summary>
/// Task logging after it's done should not crash us.
/// Task logging an error after it's done should not crash us.
/// </summary>
[Fact]
public void LogErrorAfterTaskIsDone()
{
string projectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion'>
<UsingTask TaskName='test' TaskFactory='CodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll' >
<Task>
<Using Namespace='System' />
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
string projectFileContents = """
<Project>
<UsingTask TaskName='test' TaskFactory='RoslynCodeTaskFactory' AssemblyFile='$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll'>
<Task>
<Using Namespace='System.Threading' />
<Code Type='Fragment' Language='cs'>
<![CDATA[
Log.LogError(""[1]"");
ThreadPool.QueueUserWorkItem(state=>
{
Thread.Sleep(100);
Log.LogError(""[2]"");
});

Log.LogError("[1]");
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(100);
Log.LogError("[2]");
});
]]>
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test ContinueOnError=""true""/>
<Warning Text=""[3]""/>
</Target>
</Project>";
</Code>
</Task>
</UsingTask>
<Target Name='Build'>
<test ContinueOnError="true"/>
<Warning Text="[3]"/>
</Target>
</Project>
""";

MockLogger mockLogger = Helpers.BuildProjectWithNewOMExpectSuccess(projectFileContents);
mockLogger.AssertLogContains("[1]");
mockLogger.AssertLogContains("[3]"); // [2] may or may not appear.
}
#endif

/// <summary>
/// Verifies that tasks can get global properties.
Expand Down