Skip to content

Commit

Permalink
Add test etc
Browse files Browse the repository at this point in the history
  • Loading branch information
Porges committed Apr 10, 2023
1 parent d43701e commit 271df7c
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,22 @@ private async Task ParseNugetLockfileAsync(ProcessRequest processRequest)
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
var stream = processRequest.ComponentStream;

var lockfile = await JsonSerializer.DeserializeAsync<NugetLockfileShape>(stream.Stream);
NuGetLockfileShape lockfile;
try
{
lockfile = await JsonSerializer.DeserializeAsync<NuGetLockfileShape>(stream.Stream).ConfigureAwait(false);
}
catch (Exception e)
{
this.Logger.LogError(e, "Error loading NuGet lockfile from {Location}", stream.Location);
singleFileComponentRecorder.RegisterPackageParseFailure(stream.Location);
return;
}

if (lockfile.Version != 1)
{
// only version 1 is supported
this.Logger.LogError("Unsupported NuGet lockfile version {Version}", lockfile.Version);
singleFileComponentRecorder.RegisterPackageParseFailure(stream.Location);
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
namespace Microsoft.ComponentDetection.Detectors.NuGet;

using System.Collections.Generic;
using System.Text.Json.Serialization;

internal class NugetLockfileShape
internal record NuGetLockfileShape
{
[JsonPropertyName("version")]
public int Version { get; set; }

public Dictionary<string, Dictionary<string, PackageShape>> Dependencies { get; set; }
[JsonPropertyName("dependencies")]
public Dictionary<string, Dictionary<string, PackageShape>> Dependencies { get; set; } = new();

public class PackageShape
public record PackageShape
{
[JsonPropertyName("type")]
public string Type { get; set; }

[JsonPropertyName("resolved")]
public string Resolved { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.ComponentDetection.Contracts.Internal;
using Microsoft.ComponentDetection.Contracts.TypedComponent;
using Microsoft.ComponentDetection.Detectors.NuGet;
using Microsoft.ComponentDetection.Detectors.Tests.Utilities;
using Microsoft.ComponentDetection.TestsUtilities;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -23,14 +24,17 @@
public class NuGetComponentDetectorTests : BaseDetectorTest<NuGetComponentDetector>
{
private static readonly IEnumerable<string> DetectorSearchPattern =
new List<string> { "*.nupkg", "*.nuspec", "nuget.config", "paket.lock" };
new List<string> { "*.nupkg", "*.nuspec", "nuget.config", "packages.lock.json", "paket.lock" };

private readonly Mock<ILogger<NuGetComponentDetector>> mockLogger;
private ILogger<NuGetComponentDetector> logger;

public NuGetComponentDetectorTests()
public TestContext TestContext { get; set; }

[TestInitialize]
public void Setup()
{
this.mockLogger = new Mock<ILogger<NuGetComponentDetector>>();
this.DetectorTestUtility.AddServiceMock(this.mockLogger);
this.logger = new TestLogger<NuGetComponentDetector>(this.TestContext);
this.DetectorTestUtility.AddService(this.logger);
}

[TestMethod]
Expand Down Expand Up @@ -114,6 +118,57 @@ public async Task TestNugetDetector_ReturnsValidMixedComponentAsync()
Assert.AreEqual(2, componentRecorder.GetDetectedComponents().Count());
}

[TestMethod]
public async Task TestNugetDetector_ReturnsPackagesLockfileAsync()
{
var lockfile = @"{
""version"": 1,
""dependencies"": {
""net7.0"": {
""Azure.Core"": {
""type"": ""Direct"",
""requested"": ""[1.25.0, )"",
""resolved"": ""1.25.0"",
""contentHash"": ""X8Dd4sAggS84KScWIjEbFAdt2U1KDolQopTPoHVubG2y3CM54f9l6asVrP5Uy384NWXjsspPYaJgz5xHc+KvTA=="",
""dependencies"": {
""Microsoft.Bcl.AsyncInterfaces"": ""1.1.1"",
""System.Diagnostics.DiagnosticSource"": ""4.6.0"",
""System.Memory.Data"": ""1.0.2"",
""System.Numerics.Vectors"": ""4.5.0"",
""System.Text.Encodings.Web"": ""4.7.2"",
""System.Text.Json"": ""4.7.2"",
""System.Threading.Tasks.Extensions"": ""4.5.4""
}
}
},
""net6.0"": {
""Azure.Data.Tables"": {
""type"": ""Direct"",
""requested"": ""[12.5.0, )"",
""resolved"": ""12.5.0"",
""contentHash"": ""XeIxPf+rF1NXkX3NJSB0ZTNgU233vyPXGmaFsR0lUVibtWP/lj+Qu1FcPxoslURcX0KC+UgTb226nqVdHjoweQ=="",
""dependencies"": {
""Azure.Core"": ""1.22.0"",
""System.Text.Json"": ""4.7.2""
}
}
}
}
}";

var (scanResult, componentRecorder) = await this.DetectorTestUtility
.WithFile("packages.lock.json", lockfile)
.ExecuteDetectorAsync();

Assert.AreEqual(ProcessingResultCode.Success, scanResult.ResultCode);

// should be 2 components found; one per framework
var components = new HashSet<string>(componentRecorder.GetDetectedComponents().Select(x => x.Component.Id));
Assert.AreEqual(2, components.Count);
Assert.IsTrue(components.Contains("Azure.Core 1.25.0 - NuGet"));
Assert.IsTrue(components.Contains("Azure.Data.Tables 12.5.0 - NuGet"));
}

[TestMethod]
public async Task TestNugetDetector_ReturnsValidPaketComponentAsync()
{
Expand Down Expand Up @@ -170,16 +225,9 @@ public async Task TestNugetDetector_HandlesMalformedComponentsInComponentListAsy
.WithFile("test.nuspec", nuspec)
.WithFile("test.nupkg", validNupkg)
.WithFile("malformed.nupkg", malformedNupkg)
.AddServiceMock(this.mockLogger)
.AddService(this.logger)
.ExecuteDetectorAsync();

this.mockLogger.Verify(x => x.Log(
It.IsAny<LogLevel>(),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()));

Assert.AreEqual(ProcessingResultCode.Success, scanResult.ResultCode);
Assert.AreEqual(2, componentRecorder.GetDetectedComponents().Count());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Microsoft.ComponentDetection.Detectors.Tests.Utilities;

using System;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;

internal class TestLogger<T> : ILogger<T>, IDisposable
{
private readonly TestContext context;

public TestLogger(TestContext context)
=> this.context = context;

public IDisposable BeginScope<TState>(TState state)
where TState : notnull
=> this;

public void Dispose()
{
}

public bool IsEnabled(LogLevel logLevel) => true;

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
=> this.context.WriteLine($"{logLevel} ({eventId}): {formatter(state, exception)}");
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ public DetectorTestUtilityBuilder()
public DetectorTestUtilityBuilder<T> WithFile(string fileName, string fileContents, IEnumerable<string> searchPatterns = null, string fileLocation = null) =>
this.WithFile(fileName, fileContents.ToStream(), searchPatterns, fileLocation);

public DetectorTestUtilityBuilder<T> AddService<TService>(TService it)
where TService : class
{
this.serviceCollection.AddSingleton(it);
return this;
}

public DetectorTestUtilityBuilder<T> AddServiceMock<TMock>(Mock<TMock> mock)
where TMock : class
{
Expand Down

0 comments on commit 271df7c

Please sign in to comment.