Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add WarningsAsMessages, WarningsAsErrors, WarningsNotAsErrors and Tre… #10942

Merged
merged 10 commits into from
Nov 20, 2024
1 change: 1 addition & 0 deletions documentation/wiki/ChangeWaves.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ A wave of features is set to "rotate out" (i.e. become standard functionality) t

### 17.14
- [.SLNX support - use the new parser for .sln and .slnx](https://github.com/dotnet/msbuild/pull/10836)
- [TreatWarningsAsErrors, WarningsAsMessages, WarningsAsErrors, WarningsNotAsErrors are now supported on the engine side of MSBuild](https://github.com/dotnet/msbuild/pull/10942)

### 17.12
- [Log TaskParameterEvent for scalar parameters](https://github.com/dotnet/msbuild/pull/9908)
Expand Down
209 changes: 182 additions & 27 deletions src/Build.UnitTests/WarningsAsMessagesAndErrors_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ public void TreatAllWarningsAsErrors()
ObjectModelHelpers.BuildProjectExpectSuccess(GetTestProject(treatAllWarningsAsErrors: false));
}

[Fact]
public void TreatAllWarningsAsErrorsNoPrefix()
{
MockLogger logger = ObjectModelHelpers.BuildProjectExpectFailure(GetTestProject(customProperties: new Dictionary<string, string>
{
{"TreatWarningsAsErrors", "true"},
}));

VerifyBuildErrorEvent(logger);

ObjectModelHelpers.BuildProjectExpectSuccess(GetTestProject(treatAllWarningsAsErrors: false));
}

/// <summary>
/// https://github.com/dotnet/msbuild/issues/2667
/// </summary>
Expand Down Expand Up @@ -91,22 +104,6 @@ public void TreatWarningsAsErrorsWhenSpecifiedIndirectly()
VerifyBuildErrorEvent(logger);
}

[Fact]
public void TreatWarningsAsErrorsWhenSpecifiedThroughAdditiveProperty()
{
MockLogger logger = ObjectModelHelpers.BuildProjectExpectFailure(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("MSBuildWarningsAsErrors", "123"),
new KeyValuePair<string, string>("MSBuildWarningsAsErrors", $@"$(MSBuildWarningsAsErrors);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>("MSBuildWarningsAsErrors", "$(MSBuildWarningsAsErrors);ABC")
}));

VerifyBuildErrorEvent(logger);
}

[Fact]
public void NotTreatWarningsAsErrorsWhenCodeNotSpecified()
{
Expand Down Expand Up @@ -177,22 +174,99 @@ public void TreatWarningsAsMessagesWhenSpecifiedIndirectly()
VerifyBuildMessageEvent(logger);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void TreatWarningsAsMessagesWhenSpecifiedThroughAdditiveProperty(bool usePrefix)
{
string prefix = usePrefix ? "MSBuild" : "";
MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>($"{prefix}WarningsAsMessages", "123"),
new KeyValuePair<string, string>($"{prefix}WarningsAsMessages", $@"$({prefix}WarningsAsMessages);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>($"{prefix}WarningsAsMessages", $"$({prefix}WarningsAsMessages);ABC")
}));
SimaTian marked this conversation as resolved.
Show resolved Hide resolved

VerifyBuildMessageEvent(logger);
}

[Fact]
public void TreatWarningsAsMessagesWhenSpecifiedThroughAdditiveProperty()
///
/// This is for chaining the properties together via addition.
/// Furthermore it is intended to check if the prefix and no prefix variant interacts properly with each other.
///
public void TreatWarningsAsMessagesWhenSpecifiedThroughAdditivePropertyCombination()
{
MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", "123"),
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", $@"$(MSBuildWarningsAsMessages);
new KeyValuePair<string, string>("WarningsAsMessages", $@"$(MSBuildWarningsAsMessages);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", "$(MSBuildWarningsAsMessages);ABC")
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", "$(WarningsAsMessages);ABC")
}));

VerifyBuildMessageEvent(logger);
}

[Fact]
public void TreatWarningsNotAsErrorsWhenSpecifiedThroughAdditivePropertyCombination()
{
MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("MSBuildWarningsNotAsErrors", "123"),
new KeyValuePair<string, string>("WarningsNotAsErrors", $@"$(MSBuildWarningsNotAsErrors);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>("MSBuildWarningsNotAsErrors", "$(WarningsNotAsErrors);ABC")
}),
_output);

VerifyBuildWarningEvent(logger);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void TreatWarningsAsErrorsWhenSpecifiedThroughAdditiveProperty(bool MSBuildPrefix)
{
string prefix = MSBuildPrefix ? "MSBuild" : "";
MockLogger logger = ObjectModelHelpers.BuildProjectExpectFailure(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>($@"{prefix}WarningsAsErrors", "123"),
new KeyValuePair<string, string>($@"{prefix}WarningsAsErrors", $@"$({prefix}WarningsAsErrors);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>($@"{prefix}WarningsAsErrors", $@"$({prefix}WarningsAsErrors);ABC")
}),
_output);

VerifyBuildErrorEvent(logger);
}

[Fact]
public void TreatWarningsAsErrorsWhenSpecifiedThroughAdditivePropertyCombination()
{
MockLogger logger = ObjectModelHelpers.BuildProjectExpectFailure(
GetTestProject(
customProperties: new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("WarningsAsErrors", "123"),
new KeyValuePair<string, string>("MSBuildWarningsAsErrors", $@"$(WarningsAsErrors);
{ExpectedEventCode.ToLowerInvariant()}"),
new KeyValuePair<string, string>("WarningsAsErrors", "$(MSBuildWarningsAsErrors);ABC")
}),
_output);

VerifyBuildErrorEvent(logger);
}

[Fact]
public void NotTreatWarningsAsMessagesWhenCodeNotSpecified()
{
Expand All @@ -202,7 +276,8 @@ public void NotTreatWarningsAsMessagesWhenCodeNotSpecified()
{
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", "123"),
new KeyValuePair<string, string>("MSBuildWarningsAsMessages", "$(MSBuildWarningsAsMessages);ABC")
}));
}),
_output);

VerifyBuildWarningEvent(logger);
}
Expand Down Expand Up @@ -273,27 +348,33 @@ private string GetTestProject(bool? treatAllWarningsAsErrors = null, string warn
</Project>";
}


[Theory]

[InlineData("MSB1235", "MSB1234", "MSB1234", "MSB1234", false)] // Log MSB1234, treat as error via MSBuildWarningsAsErrors
[InlineData("MSB1235", "", "MSB1234", "MSB1234", true)] // Log MSB1234, expect MSB1234 as error via MSBuildTreatWarningsAsErrors
[InlineData("MSB1234", "MSB1234", "MSB1234", "MSB4181", true)]// Log MSB1234, MSBuildWarningsAsMessages takes priority
[InlineData("MSB1235", "MSB1234", "MSB1234", "MSB1234", false, false)] // Log MSB1234, treat as error via BuildWarningsAsErrors
[InlineData("MSB1235", "", "MSB1234", "MSB1234", true, false)] // Log MSB1234, expect MSB1234 as error via BuildTreatWarningsAsErrors
[InlineData("MSB1234", "MSB1234", "MSB1234", "MSB4181", true, false)]// Log MSB1234, BuildWarningsAsMessages takes priority
public void WarningsAsErrorsAndMessages_Tests(string WarningsAsMessages,
string WarningsAsErrors,
string WarningToLog,
string LogShouldContain,
bool allWarningsAreErrors = false)
bool allWarningsAreErrors = false,
bool useMSPrefix = true)
{
using (TestEnvironment env = TestEnvironment.Create(_output))
{
var prefix = useMSPrefix ? "MSBuild" : "";
TransientTestProjectWithFiles proj = env.CreateTestProjectWithFiles($@"
<Project>
<UsingTask TaskName = ""ReturnFailureWithoutLoggingErrorTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/>
<UsingTask TaskName = ""CustomLogAndReturnTask"" AssemblyName=""Microsoft.Build.Engine.UnitTests""/>
<PropertyGroup>
<MSBuildTreatWarningsAsErrors>{allWarningsAreErrors}</MSBuildTreatWarningsAsErrors>
<MSBuildWarningsAsMessages>{WarningsAsMessages}</MSBuildWarningsAsMessages>
<MSBuildWarningsAsErrors>{WarningsAsErrors}</MSBuildWarningsAsErrors>
<{prefix}TreatWarningsAsErrors>{allWarningsAreErrors}</{prefix}TreatWarningsAsErrors>
<{prefix}WarningsAsMessages>{WarningsAsMessages}</{prefix}WarningsAsMessages>
<{prefix}WarningsAsErrors>{WarningsAsErrors}</{prefix}WarningsAsErrors>
</PropertyGroup>
<Target Name='Build'>
<CustomLogAndReturnTask Return=""true"" ReturnHasLoggedErrors=""true"" WarningCode=""{WarningToLog}""/>
Expand All @@ -310,6 +391,77 @@ public void WarningsAsErrorsAndMessages_Tests(string WarningsAsMessages,
}
}

[Theory]

[InlineData(true)]// Log MSB1234, BuildWarningsNotAsErrors takes priority
[InlineData(false)]
public void WarningsNotAsErrorsAndMessages_Tests(bool useMSPrefix)
{
string Warning = "MSB1235";
using (TestEnvironment env = TestEnvironment.Create(_output))
{
string prefix = useMSPrefix ? "MSBuild" : "";
TransientTestProjectWithFiles proj = env.CreateTestProjectWithFiles($@"
<Project>
<PropertyGroup>
<{prefix}TreatWarningsAsErrors>true</{prefix}TreatWarningsAsErrors>
<{prefix}WarningsNotAsErrors>{Warning}</{prefix}WarningsNotAsErrors>
</PropertyGroup>
<Target Name='Build'>
<Warning Text=""some random text"" Code='{Warning}' />
</Target>
</Project>");

MockLogger logger = proj.BuildProjectExpectSuccess();

logger.WarningCount.ShouldBe(1);
logger.ErrorCount.ShouldBe(0);

logger.AssertLogContains(Warning);
}
}



[Theory]
[InlineData("TreatWarningsAsErrors", "true", false)] // All warnings are treated as errors
[InlineData("WarningsAsErrors", "MSB1007", false)]
[InlineData("WarningsAsMessages", "MSB1007", false)]
[InlineData("WarningsNotAsErrors", "MSB1007", true)]
public void WarningsChangeWaveTest(string property, string propertyData, bool treatWarningsAsErrors)
{
using (TestEnvironment env = TestEnvironment.Create(_output))
{
string warningCode = "MSB1007";
string treatWarningsAsErrorsCodeProperty = treatWarningsAsErrors ? "<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>" : "";
env.SetEnvironmentVariable("MSBUILDDISABLEFEATURESFROMVERSION", ChangeWaves.Wave17_14.ToString());
SimaTian marked this conversation as resolved.
Show resolved Hide resolved
TransientTestProjectWithFiles proj = env.CreateTestProjectWithFiles($@"
<Project>
<PropertyGroup>
{treatWarningsAsErrorsCodeProperty}
<{property}>{propertyData}</{property}>
</PropertyGroup>
<Target Name='Build'>
<Warning Text=""some random text"" Code='{warningCode}' />
</Target>
</Project>");
if (treatWarningsAsErrors)
{
// Since the "no prefix" variations can't do anything with the change wave disabled, this should always fail.
MockLogger logger = proj.BuildProjectExpectFailure();
SimaTian marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
MockLogger logger = proj.BuildProjectExpectSuccess();

logger.WarningCount.ShouldBe(1);
logger.ErrorCount.ShouldBe(0);

logger.AssertLogContains(warningCode);
}
}
}

/// <summary>
/// Item1 and Item2 log warnings and continue, item 3 logs a warn-> error and prevents item 4 from running in the batched build.
/// </summary>
Expand Down Expand Up @@ -371,17 +523,20 @@ public void TaskLogsWarningAsError_BatchedBuild()
[Theory]
[InlineData("MSB1234", false, 1, 1)]
[InlineData("MSB0000", true, 0, 2)]
public void TaskReturnsTrue_Tests(string warningsAsErrors, bool treatAllWarningsAsErrors, int warningCountShouldBe, int errorCountShouldBe)
[InlineData("MSB1234", false, 1, 1, false)]
[InlineData("MSB0000", true, 0, 2, false)]
public void TaskReturnsTrue_Tests(string warningsAsErrors, bool treatAllWarningsAsErrors, int warningCountShouldBe, int errorCountShouldBe, bool useMSPrefix = true)
{
string prefix = useMSPrefix ? "MSBuild" : "";
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>
<MSBuildTreatWarningsAsErrors>{treatAllWarningsAsErrors}</MSBuildTreatWarningsAsErrors>
<MSBuildWarningsAsErrors>{warningsAsErrors}</MSBuildWarningsAsErrors>
<{prefix}TreatWarningsAsErrors>{treatAllWarningsAsErrors}</{prefix}TreatWarningsAsErrors>
<{prefix}WarningsAsErrors>{warningsAsErrors}</{prefix}WarningsAsErrors>
</PropertyGroup>
<Target Name='Build'>
<CustomLogAndReturnTask Return=""true"" WarningCode=""MSB1234""/>
Expand Down
Loading