Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using StellaOps.Scanner.Core.Contracts;
|
||||
using StellaOps.Scanner.Emit.Composition;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.Emit.Tests.Composition;
|
||||
|
||||
public sealed class SpdxComposerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Compose_ProducesJsonLdArtifact()
|
||||
{
|
||||
var request = BuildRequest();
|
||||
var composer = new SpdxComposer();
|
||||
|
||||
var result = composer.Compose(request, new SpdxCompositionOptions());
|
||||
|
||||
Assert.Equal("application/spdx+json; version=3.0.1", result.JsonMediaType);
|
||||
Assert.Equal(result.JsonSha256, result.ContentHash);
|
||||
Assert.Equal(64, result.JsonSha256.Length);
|
||||
Assert.Null(result.TagValueBytes);
|
||||
|
||||
using var document = JsonDocument.Parse(result.JsonBytes);
|
||||
var root = document.RootElement;
|
||||
Assert.Equal("https://spdx.org/rdf/3.0.1/spdx-context.jsonld", root.GetProperty("@context").GetString());
|
||||
|
||||
var graph = root.GetProperty("@graph").EnumerateArray().ToArray();
|
||||
Assert.NotEmpty(graph);
|
||||
|
||||
var docNode = graph.Single(node => node.GetProperty("type").GetString() == "SpdxDocument");
|
||||
var rootElement = docNode.GetProperty("rootElement").EnumerateArray().Select(element => element.GetString()).ToArray();
|
||||
Assert.Single(rootElement);
|
||||
|
||||
var packages = graph
|
||||
.Where(node => node.GetProperty("type").GetString() == "software_Package")
|
||||
.ToArray();
|
||||
Assert.Equal(3, packages.Length);
|
||||
|
||||
var lodash = packages.Single(node => node.GetProperty("name").GetString() == "component-b");
|
||||
Assert.Equal("pkg:npm/b@2.0.0", lodash.GetProperty("software_packageUrl").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compose_WithTagValue_IncludesLegacyOutput()
|
||||
{
|
||||
var request = BuildRequest();
|
||||
var composer = new SpdxComposer();
|
||||
|
||||
var result = composer.Compose(request, new SpdxCompositionOptions { IncludeTagValue = true });
|
||||
|
||||
Assert.NotNull(result.TagValueBytes);
|
||||
var tagValue = System.Text.Encoding.UTF8.GetString(result.TagValueBytes!);
|
||||
Assert.Contains("SPDXVersion: SPDX-2.3", tagValue, StringComparison.Ordinal);
|
||||
Assert.Contains("DocumentNamespace:", tagValue, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compose_IsDeterministic()
|
||||
{
|
||||
var request = BuildRequest();
|
||||
var composer = new SpdxComposer();
|
||||
|
||||
var first = composer.Compose(request, new SpdxCompositionOptions());
|
||||
var second = composer.Compose(request, new SpdxCompositionOptions());
|
||||
|
||||
Assert.Equal(first.JsonSha256, second.JsonSha256);
|
||||
}
|
||||
|
||||
private static SbomCompositionRequest BuildRequest()
|
||||
{
|
||||
var fragments = new[]
|
||||
{
|
||||
LayerComponentFragment.Create("sha256:layer1", new[]
|
||||
{
|
||||
new ComponentRecord
|
||||
{
|
||||
Identity = ComponentIdentity.Create("pkg:npm/a", "component-a", "1.0.0", "pkg:npm/a@1.0.0", "library"),
|
||||
LayerDigest = "sha256:layer1",
|
||||
Evidence = ImmutableArray.Create(ComponentEvidence.FromPath("/app/node_modules/a/package.json")),
|
||||
Dependencies = ImmutableArray.Create("pkg:npm/b"),
|
||||
Usage = ComponentUsage.Create(true, new[] { "/app/start.sh" }),
|
||||
Metadata = new ComponentMetadata
|
||||
{
|
||||
Scope = "runtime",
|
||||
Licenses = new[] { "MIT" },
|
||||
Properties = new Dictionary<string, string>
|
||||
{
|
||||
["stellaops:source"] = "package-lock.json",
|
||||
},
|
||||
BuildId = "ABCDEF1234567890ABCDEF1234567890ABCDEF12",
|
||||
},
|
||||
}
|
||||
}),
|
||||
LayerComponentFragment.Create("sha256:layer2", new[]
|
||||
{
|
||||
new ComponentRecord
|
||||
{
|
||||
Identity = ComponentIdentity.Create("pkg:npm/b", "component-b", "2.0.0", "pkg:npm/b@2.0.0", "library"),
|
||||
LayerDigest = "sha256:layer2",
|
||||
Evidence = ImmutableArray.Create(ComponentEvidence.FromPath("/app/node_modules/b/package.json")),
|
||||
Usage = ComponentUsage.Create(false),
|
||||
Metadata = new ComponentMetadata
|
||||
{
|
||||
Scope = "development",
|
||||
Licenses = new[] { "Apache-2.0" },
|
||||
Properties = new Dictionary<string, string>
|
||||
{
|
||||
["stellaops.os.analyzer"] = "language-node",
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
var image = new ImageArtifactDescriptor
|
||||
{
|
||||
ImageDigest = "sha256:1234567890abcdef",
|
||||
ImageReference = "registry.example.com/app/service:1.2.3",
|
||||
Repository = "registry.example.com/app/service",
|
||||
Tag = "1.2.3",
|
||||
Architecture = "amd64",
|
||||
};
|
||||
|
||||
return SbomCompositionRequest.Create(
|
||||
image,
|
||||
fragments,
|
||||
new DateTimeOffset(2025, 10, 19, 12, 0, 0, TimeSpan.Zero),
|
||||
generatorName: "StellaOps.Scanner",
|
||||
generatorVersion: "0.10.0",
|
||||
properties: new Dictionary<string, string>
|
||||
{
|
||||
["stellaops:scanId"] = "scan-1234",
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user