diff --git a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
index 97eed247c57..3a22b628446 100644
--- a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
+++ b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
@@ -61,8 +61,6 @@ Copyright (c) .NET Foundation. All rights reserved.
true
<_CentralPackageVersionsEnabled Condition="'$(ManagePackageVersionsCentrally)' == 'true' AND '$(CentralPackageVersionsFileImported)' == 'true'">true
-
- default
diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
index 0a3f34a2262..8cfe6240caa 100644
--- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
+++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
@@ -303,9 +303,12 @@ await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1803,
});
}
- AuditUtility.EnabledValue enableAudit = AuditUtility.ParseEnableValue(_request.Project.RestoreMetadata?.RestoreAuditProperties?.EnableAudit);
+ AuditUtility.EnabledValue enableAudit = AuditUtility.ParseEnableValue(
+ _request.Project.RestoreMetadata?.RestoreAuditProperties?.EnableAudit,
+ _request.Project.FilePath,
+ _logger);
telemetry.TelemetryEvent[AuditEnabled] = AuditUtility.GetString(enableAudit);
- if (enableAudit == AuditUtility.EnabledValue.ImplicitOptIn || enableAudit == AuditUtility.EnabledValue.ExplicitOptIn)
+ if (enableAudit != AuditUtility.EnabledValue.ExplicitOptOut)
{
await PerformAuditAsync(enableAudit, graphs, telemetry, token);
}
diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs
index 9618c7097f7..dde1bab487a 100644
--- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs
+++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs
@@ -22,7 +22,7 @@ namespace NuGet.Commands.Restore.Utility
internal class AuditUtility
{
private readonly EnabledValue _auditEnabled;
- private readonly ProjectModel.RestoreAuditProperties _restoreAuditProperties;
+ private readonly ProjectModel.RestoreAuditProperties? _restoreAuditProperties;
private readonly string _projectFullPath;
private readonly IEnumerable _targetGraphs;
private readonly IReadOnlyList _vulnerabilityInfoProviders;
@@ -49,7 +49,7 @@ internal class AuditUtility
public AuditUtility(
EnabledValue auditEnabled,
- ProjectModel.RestoreAuditProperties restoreAuditProperties,
+ ProjectModel.RestoreAuditProperties? restoreAuditProperties,
string projectFullPath,
IEnumerable graphs,
IReadOnlyList vulnerabilityInformationProviders,
@@ -366,7 +366,7 @@ private static (string severityLabel, NuGetLogCode code) GetSeverityLabelAndCode
private PackageVulnerabilitySeverity ParseAuditLevel()
{
- string? auditLevel = _restoreAuditProperties.AuditLevel?.Trim();
+ string? auditLevel = _restoreAuditProperties?.AuditLevel?.Trim();
if (auditLevel == null)
{
@@ -402,7 +402,7 @@ internal enum NuGetAuditMode { Unknown, Direct, All }
// Enum parsing and ToString are a magnitude of times slower than a naive implementation.
private NuGetAuditMode ParseAuditMode()
{
- string? auditMode = _restoreAuditProperties.AuditMode?.Trim();
+ string? auditMode = _restoreAuditProperties?.AuditMode?.Trim();
if (auditMode == null)
{
@@ -426,16 +426,16 @@ private NuGetAuditMode ParseAuditMode()
internal enum EnabledValue
{
- Undefined,
+ Invalid,
ImplicitOptIn,
ExplicitOptIn,
ExplicitOptOut
}
// Enum parsing and ToString are a magnitude of times slower than a naive implementation.
- public static EnabledValue ParseEnableValue(string value)
+ public static EnabledValue ParseEnableValue(string? value, string projectFullPath, ILogger logger)
{
- if (string.Equals(value, "default", StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(value) || string.Equals(value, "default", StringComparison.OrdinalIgnoreCase))
{
return EnabledValue.ImplicitOptIn;
}
@@ -449,7 +449,12 @@ public static EnabledValue ParseEnableValue(string value)
{
return EnabledValue.ExplicitOptOut;
}
- return EnabledValue.Undefined;
+
+ string messageText = string.Format(Strings.Error_InvalidNuGetAuditValue, value, "true, false");
+ RestoreLogMessage message = RestoreLogMessage.CreateError(NuGetLogCode.NU1014, messageText);
+ message.ProjectPath = projectFullPath;
+ logger.Log(message);
+ return EnabledValue.Invalid;
}
// Enum parsing and ToString are a magnitude of times slower than a naive implementation.
@@ -457,7 +462,7 @@ internal static string GetString(EnabledValue enableAudit)
{
return enableAudit switch
{
- EnabledValue.Undefined => nameof(EnabledValue.Undefined),
+ EnabledValue.Invalid => nameof(EnabledValue.Invalid),
EnabledValue.ExplicitOptIn => nameof(EnabledValue.ExplicitOptIn),
EnabledValue.ExplicitOptOut => nameof(EnabledValue.ExplicitOptOut),
EnabledValue.ImplicitOptIn => nameof(EnabledValue.ImplicitOptIn),
diff --git a/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs b/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs
index ed583c5ca3e..d3120592c71 100644
--- a/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs
+++ b/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs
@@ -475,7 +475,7 @@ internal static string Error_InvalidLockFileInput {
}
///
- /// Looks up a localized string similar to Invalid NuGetAuditLevel value '{0}'. Expected values: {1}.
+ /// Looks up a localized string similar to Invalid NuGetAuditLevel value '{0}'. Valid values: {1}.
///
internal static string Error_InvalidNuGetAuditLevelValue {
get {
@@ -484,7 +484,7 @@ internal static string Error_InvalidNuGetAuditLevelValue {
}
///
- /// Looks up a localized string similar to Invalid NuGetAuditMode value '{0}'. Expected values: {1}.
+ /// Looks up a localized string similar to Invalid NuGetAuditMode value '{0}'. Valid values: {1}.
///
internal static string Error_InvalidNuGetAuditModeValue {
get {
@@ -492,6 +492,15 @@ internal static string Error_InvalidNuGetAuditModeValue {
}
}
+ ///
+ /// Looks up a localized string similar to Invalid NuGetAudit value '{0}'. Valid values: {1}.
+ ///
+ internal static string Error_InvalidNuGetAuditValue {
+ get {
+ return ResourceManager.GetString("Error_InvalidNuGetAuditValue", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Invalid project-package combination for {0} {1}. DotnetToolReference project style can only contain references of the DotnetTool type.
///
diff --git a/src/NuGet.Core/NuGet.Commands/Strings.resx b/src/NuGet.Core/NuGet.Commands/Strings.resx
index 5c63c7cd5d4..11aaa512d3c 100644
--- a/src/NuGet.Core/NuGet.Commands/Strings.resx
+++ b/src/NuGet.Core/NuGet.Commands/Strings.resx
@@ -1069,7 +1069,7 @@ Non-HTTPS access will be removed in a future version. Consider migrating to 'HTT
{3} - URL for more info on the known vulnerability
- Invalid NuGetAuditLevel value '{0}'. Expected values: {1}
+ Invalid NuGetAuditLevel value '{0}'. Valid values: {1}
Don't translate 'NuGetAuditLevel'
{0} - is the value from the customer's project file
{1} is the list of valid values "low, moderate, high, critical" (these should not be translated either)
@@ -1083,7 +1083,7 @@ Non-HTTPS access will be removed in a future version. Consider migrating to 'HTT
{0} is the value supplied
- Invalid NuGetAuditMode value '{0}'. Expected values: {1}
+ Invalid NuGetAuditMode value '{0}'. Valid values: {1}
Don't translate 'NuGetAuditMode'
{0} - is the value from the customer's project file
{1} is the list of valid values "direct, all"
@@ -1092,4 +1092,10 @@ Non-HTTPS access will be removed in a future version. Consider migrating to 'HTT
NuGetAudit is enabled, but no package sources contain known vulnerability data.
Do not translate NuGetAudit
+
+ Invalid NuGetAudit value '{0}'. Valid values: {1}
+ Don't translate 'NuGetAudit'
+{0} - is the value from the customer's project file
+{1} is the list of valid values "true, false"
+
\ No newline at end of file
diff --git a/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs b/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs
index ebf3e5a5e87..f8df3f82984 100644
--- a/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs
+++ b/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs
@@ -122,7 +122,7 @@ public enum NuGetLogCode
NU1013 = 1013,
///
- /// NuGetAuditLevel input errors
+ /// NuGetAudit* MSBuild property input errors
///
NU1014 = 1014,
diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/ProjectPropertyTests.cs b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/ProjectPropertyTests.cs
deleted file mode 100644
index 5323b317718..00000000000
--- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/ProjectPropertyTests.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.IO;
-using NuGet.Test.Utility;
-using Xunit;
-
-namespace Dotnet.Integration.Test
-{
- [Collection(DotnetIntegrationCollection.Name)]
- public class ProjectPropertyTests
- {
- private DotnetIntegrationTestFixture _msbuildFixture;
-
- public ProjectPropertyTests(DotnetIntegrationTestFixture fixture)
- {
- _msbuildFixture = fixture;
- }
-
- [Fact]
- public void NuGetAudit_EnabledByDefaultOnNet8AndHigher()
- {
- // Arrange
- using TestDirectory testDirectory = TestDirectory.Create();
- string projectFilePath = Path.Combine(testDirectory.Path, "test.csproj");
- var projectFileContents = @"
-
-
-
-
-
-";
- File.WriteAllText(projectFilePath, projectFileContents);
-
- // Dotnet.Integration.Tests works by finding the test assembly compile TFM, then finding the SDK that maches the TFM's major version.
- // (see TestDotnetCliUtility.GetSdkToTestByAssemblyPath).
- // Therefore, we can depend on this file's compile time TFM to tell us if we're testing the .NET 7 or 8 SDK.
- string expected =
-#if NET8_0_OR_GREATER
- "default";
-#else
- "";
-#endif
-
- // Act
- var result = _msbuildFixture.RunDotnetExpectSuccess(testDirectory.Path, $"msbuild -t:ValidateNuGetAuditValue -p:ExpectedValue={expected}");
- }
- }
-}
diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs
index cb9ef8fb52b..12690963152 100644
--- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs
+++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs
@@ -2135,7 +2135,8 @@ public async Task RestoreCommand_RestoreFloatingVersionWithIgnoreFailingLocalSou
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2184,7 +2185,8 @@ public async Task RestoreCommand_RestoreFloatingVersionWithIgnoreFailingHttpSour
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2402,7 +2404,8 @@ public async Task RestoreCommand_RestoreNonExistingWithIgnoreFailingLocalSourceA
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2451,7 +2454,8 @@ public async Task RestoreCommand_RestoreNonExistingWithIgnoreFailingHttpSourceAs
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2500,7 +2504,8 @@ public async Task RestoreCommand_RestoreNonExistingWithIgnoreFailingV3HttpSource
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2549,7 +2554,8 @@ public async Task RestoreCommand_RestoreInexactWithIgnoreFailingLocalSourceAsync
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2598,7 +2604,8 @@ public async Task RestoreCommand_RestoreInexactWithIgnoreFailingHttpSourceAsync(
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
@@ -2647,7 +2654,8 @@ public async Task RestoreCommand_RestoreInexactWithIgnoreFailingV3HttpSourceAsyn
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
using (var context = new SourceCacheContext())
diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs
index 4670d6c4f71..bb47d8b7fe4 100644
--- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs
+++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs
@@ -146,7 +146,8 @@ public async Task UWPRestore_BlankUWPAppWithExcludes()
}");
var specPath = Path.Combine(projectDir, "TestProject", "project.json");
- var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath);
+ var spec = JsonPackageSpecReader.GetPackageSpec(configJson.ToString(), "TestProject", specPath)
+ .EnsureProjectJsonRestoreMetadata();
var logger = new TestLogger();
var clientPolicyContext = ClientPolicyContext.GetClientPolicy(NullSettings.Instance, logger);
diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs
index 6a691a58841..991c47e93fd 100644
--- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs
+++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs
@@ -2787,6 +2787,7 @@ public async Task ExecuteAsync_WithSinglePackage_PopulatesCorrectTelemetry()
var projectName = "TestProject";
var projectPath = Path.Combine(pathContext.SolutionRoot, projectName);
PackageSpec packageSpec = ProjectTestHelpers.GetPackageSpec(projectName, pathContext.SolutionRoot, "net472", "a");
+ packageSpec.RestoreMetadata.RestoreAuditProperties.EnableAudit = bool.TrueString;
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
pathContext.PackageSource,
@@ -2820,36 +2821,71 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async(
var projectInformationEvent = telemetryEvents.Single(e => e.Name.Equals("ProjectRestoreInformation"));
- projectInformationEvent.Count.Should().Be(29);
- projectInformationEvent["RestoreSuccess"].Should().Be(true);
- projectInformationEvent["NoOpResult"].Should().Be(false);
- projectInformationEvent["IsCentralVersionManagementEnabled"].Should().Be(false);
- projectInformationEvent["NoOpCacheFileEvaluationResult"].Should().Be(false);
- projectInformationEvent["IsLockFileEnabled"].Should().Be(false);
- projectInformationEvent["IsLockFileValidForRestore"].Should().Be(false);
- projectInformationEvent["LockFileEvaluationResult"].Should().Be(true);
- projectInformationEvent["NoOpDuration"].Should().NotBeNull();
- projectInformationEvent["TotalUniquePackagesCount"].Should().Be(1);
- projectInformationEvent["NewPackagesInstalledCount"].Should().Be(1);
- projectInformationEvent["EvaluateLockFileDuration"].Should().NotBeNull();
- projectInformationEvent["CreateRestoreTargetGraphDuration"].Should().NotBeNull();
- projectInformationEvent["GenerateRestoreGraphDuration"].Should().NotBeNull();
- projectInformationEvent["CreateRestoreResultDuration"].Should().NotBeNull();
- projectInformationEvent["WalkFrameworkDependencyDuration"].Should().NotBeNull();
- projectInformationEvent["GenerateAssetsFileDuration"].Should().NotBeNull();
- projectInformationEvent["ValidateRestoreGraphsDuration"].Should().NotBeNull();
- projectInformationEvent["EvaluateDownloadDependenciesDuration"].Should().NotBeNull();
- projectInformationEvent["NoOpCacheFileEvaluateDuration"].Should().NotBeNull();
- projectInformationEvent["StartTime"].Should().NotBeNull();
- projectInformationEvent["EndTime"].Should().NotBeNull();
- projectInformationEvent["OperationId"].Should().NotBeNull();
- projectInformationEvent["Duration"].Should().NotBeNull();
- projectInformationEvent["PackageSourceMapping.IsMappingEnabled"].Should().Be(false);
- projectInformationEvent["SourcesCount"].Should().Be(1);
- projectInformationEvent["HttpSourcesCount"].Should().Be(0);
- projectInformationEvent["LocalSourcesCount"].Should().Be(1);
- projectInformationEvent["FallbackFoldersCount"].Should().Be(0);
- projectInformationEvent["Audit.Enabled"].Should().Be("Undefined");
+ var expectedProperties = new Dictionary>()
+ {
+ ["RestoreSuccess"] = value => value.Should().Be(true),
+ ["NoOpResult"] = value => value.Should().Be(false),
+ ["IsCentralVersionManagementEnabled"] = value => value.Should().Be(false),
+ ["NoOpCacheFileEvaluationResult"] = value => value.Should().Be(false),
+ ["IsLockFileEnabled"] = value => value.Should().Be(false),
+ ["IsLockFileValidForRestore"] = value => value.Should().Be(false),
+ ["LockFileEvaluationResult"] = value => value.Should().Be(true),
+ ["NoOpDuration"] = value => value.Should().NotBeNull(),
+ ["TotalUniquePackagesCount"] = value => value.Should().Be(1),
+ ["NewPackagesInstalledCount"] = value => value.Should().Be(1),
+ ["EvaluateLockFileDuration"] = value => value.Should().NotBeNull(),
+ ["CreateRestoreTargetGraphDuration"] = value => value.Should().NotBeNull(),
+ ["GenerateRestoreGraphDuration"] = value => value.Should().NotBeNull(),
+ ["CreateRestoreResultDuration"] = value => value.Should().NotBeNull(),
+ ["WalkFrameworkDependencyDuration"] = value => value.Should().NotBeNull(),
+ ["GenerateAssetsFileDuration"] = value => value.Should().NotBeNull(),
+ ["ValidateRestoreGraphsDuration"] = value => value.Should().NotBeNull(),
+ ["EvaluateDownloadDependenciesDuration"] = value => value.Should().NotBeNull(),
+ ["NoOpCacheFileEvaluateDuration"] = value => value.Should().NotBeNull(),
+ ["StartTime"] = value => value.Should().NotBeNull(),
+ ["EndTime"] = value => value.Should().NotBeNull(),
+ ["OperationId"] = value => value.Should().NotBeNull(),
+ ["Duration"] = value => value.Should().NotBeNull(),
+ ["PackageSourceMapping.IsMappingEnabled"] = value => value.Should().Be(false),
+ ["SourcesCount"] = value => value.Should().Be(1),
+ ["HttpSourcesCount"] = value => value.Should().Be(0),
+ ["LocalSourcesCount"] = value => value.Should().Be(1),
+ ["FallbackFoldersCount"] = value => value.Should().Be(0),
+ ["WarningCodes"] = value => value.Should().Be("NU1905"),
+ ["Audit.Enabled"] = value => value.Should().Be("ExplicitOptIn"),
+ ["Audit.Level"] = value => value.Should().Be(0),
+ ["Audit.Mode"] = value => value.Should().Be("Unknown"),
+ ["Audit.Vulnerability.Direct.Count"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Direct.Severity0"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Direct.Severity1"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Direct.Severity2"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Direct.Severity3"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Direct.SeverityInvalid"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.Count"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.Severity0"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.Severity1"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.Severity2"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.Severity3"] = value => value.Should().Be(0),
+ ["Audit.Vulnerability.Transitive.SeverityInvalid"] = value => value.Should().Be(0),
+ ["Audit.DataSources"] = value => value.Should().Be(0),
+ ["Audit.Duration.Download"] = value => value.Should().BeOfType(),
+ ["Audit.Duration.Total"] = value => value.Should().BeOfType(),
+ };
+
+ HashSet actualProperties = new();
+ foreach (var eventProperty in projectInformationEvent)
+ {
+ actualProperties.Add(eventProperty.Key);
+ }
+
+ expectedProperties.Keys.Except(actualProperties).Should().BeEmpty();
+ actualProperties.Except(expectedProperties.Keys).Should().BeEmpty();
+
+ foreach (var kvp in expectedProperties)
+ {
+ object value = projectInformationEvent[kvp.Key];
+ kvp.Value(value);
+ }
}
[Fact]
diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/Utility/AuditUtilityTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/Utility/AuditUtilityTests.cs
index 925e8a21033..85bb4589692 100644
--- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/Utility/AuditUtilityTests.cs
+++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/Utility/AuditUtilityTests.cs
@@ -31,6 +31,41 @@ public class AuditUtilityTests
private static Uri CveUrl = new Uri("https://cve.test/1");
private static VersionRange UpToV2 = new VersionRange(maxVersion: new NuGetVersion(2, 0, 0), includeMaxVersion: false);
+ [Theory]
+ [InlineData(null, nameof(AuditUtility.EnabledValue.ImplicitOptIn))]
+ [InlineData("", nameof(AuditUtility.EnabledValue.ImplicitOptIn))]
+ [InlineData("default", nameof(AuditUtility.EnabledValue.ImplicitOptIn))]
+ [InlineData("true", nameof(AuditUtility.EnabledValue.ExplicitOptIn))]
+ [InlineData("enable", nameof(AuditUtility.EnabledValue.ExplicitOptIn))]
+ [InlineData("TRUE", nameof(AuditUtility.EnabledValue.ExplicitOptIn))]
+ [InlineData("false", nameof(AuditUtility.EnabledValue.ExplicitOptOut))]
+ [InlineData("disable", nameof(AuditUtility.EnabledValue.ExplicitOptOut))]
+ [InlineData("FALSE", nameof(AuditUtility.EnabledValue.ExplicitOptOut))]
+ [InlineData("invalid", nameof(AuditUtility.EnabledValue.Invalid))]
+ public void ParseEnableValue_WithValue_ReturnsExpectedEnum(string input, string expected)
+ {
+ // Arrange
+ AuditUtility.EnabledValue expectedValue = (AuditUtility.EnabledValue)Enum.Parse(typeof(AuditUtility.EnabledValue), expected);
+ string projectPath = "my.csproj";
+ TestLogger? logger = expectedValue == AuditUtility.EnabledValue.Invalid
+ ? new TestLogger()
+ : null;
+
+ // Act
+ AuditUtility.EnabledValue actual = AuditUtility.ParseEnableValue(input, projectPath, logger ?? NullLogger.Instance);
+
+ // Assert
+ actual.Should().Be(expectedValue);
+
+ if (logger is not null)
+ {
+ logger.Errors.Should().Be(1);
+ RestoreLogMessage message = logger.LogMessages.Cast().Single();
+ message.Code.Should().Be(NuGetLogCode.NU1014);
+ message.Level.Should().Be(LogLevel.Error);
+ }
+ }
+
[Fact]
public async Task Check_VulnerabilityProviderWithExceptions_WarningsReplayedToLogger()
{
@@ -56,7 +91,7 @@ public async Task Check_VulnerabilityProviderWithExceptions_WarningsReplayedToLo
}
[Theory]
- [InlineData("default", false)]
+ [InlineData("", false)]
[InlineData("true", true)]
public async Task Check_WithNoVulnerabilitySources_NU1905Warning(string enable, bool expectWarning)
{
@@ -364,17 +399,12 @@ public async Task Check_MultiTargetingProjectFile_WarningsHaveExpectedProperties
await createGraphTasks[1]
};
- RestoreAuditProperties restoreAuditProperties = new()
- {
- EnableAudit = "default",
- };
-
var log = new TestLogger();
// Act
var audit = new AuditUtility(
- AuditUtility.ParseEnableValue(restoreAuditProperties.EnableAudit),
- restoreAuditProperties,
+ AuditUtility.ParseEnableValue(null, "/path/proj.csproj", log),
+ restoreAuditProperties: null,
"/path/proj.csproj",
graphs,
vulnerabilityProviders,
@@ -413,7 +443,7 @@ static async Task CreateGraphAsync(DependencyProvider packag
private class AuditTestContext
{
public string ProjectFullPath { get; set; } = RuntimeEnvironmentHelper.IsWindows ? @"n:\proj\proj.csproj" : "/src/proj/proj.csproj";
- public string? Enabled { get; set; } = "default";
+ public string? Enabled { get; set; }
public string? Level { get; set; }
public string? Mode { get; set; }
@@ -458,10 +488,8 @@ public VulnerabilityProviderTestContext WithVulnerabilityProvider()
public async Task CheckPackageVulnerabilitiesAsync(CancellationToken cancellationToken)
{
- AuditUtility.EnabledValue enabled;
- if (Enabled is null
- || (enabled = AuditUtility.ParseEnableValue(Enabled)) == AuditUtility.EnabledValue.Undefined
- || enabled == AuditUtility.EnabledValue.ExplicitOptOut)
+ AuditUtility.EnabledValue enabled = AuditUtility.ParseEnableValue(Enabled, ProjectFullPath, Log);
+ if (enabled == AuditUtility.EnabledValue.ExplicitOptOut)
{
throw new InvalidOperationException($"{nameof(Enabled)} must have a value that does not disable NuGetAudit.");
}
diff --git a/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs b/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs
index 50c34ec9d60..600faeffc83 100644
--- a/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs
+++ b/test/TestUtilities/Test.Utility/Commands/ProjectTestHelpers.cs
@@ -162,6 +162,11 @@ public static PackageSpec WithTestRestoreMetadata(this PackageSpec spec)
updated.RestoreMetadata.CentralPackageVersionsEnabled = spec.RestoreMetadata?.CentralPackageVersionsEnabled ?? false;
updated.RestoreMetadata.CentralPackageTransitivePinningEnabled = spec.RestoreMetadata?.CentralPackageTransitivePinningEnabled ?? false;
+ updated.RestoreMetadata.RestoreAuditProperties = new RestoreAuditProperties()
+ {
+ EnableAudit = bool.FalseString
+ };
+
// Update the Target Alias.
foreach (var framework in updated.TargetFrameworks)
{
@@ -193,6 +198,10 @@ private static PackageSpec WithProjectJsonTestRestoreMetadata(this PackageSpec s
metadata.ProjectUniqueName = msbuildProjectFilePath;
metadata.CacheFilePath = NoOpRestoreUtilities.GetProjectCacheFilePath(msbuildProjectExtensionsPath);
metadata.ConfigFilePaths = new List();
+ metadata.RestoreAuditProperties = new RestoreAuditProperties()
+ {
+ EnableAudit = bool.FalseString
+ };
foreach (var framework in updated.TargetFrameworks)
{