Add tests for SBOM generation determinism across multiple formats

- Created `StellaOps.TestKit.Tests` project for unit tests related to determinism.
- Implemented `DeterminismManifestTests` to validate deterministic output for canonical bytes and strings, file read/write operations, and error handling for invalid schema versions.
- Added `SbomDeterminismTests` to ensure identical inputs produce consistent SBOMs across SPDX 3.0.1 and CycloneDX 1.6/1.7 formats, including parallel execution tests.
- Updated project references in `StellaOps.Integration.Determinism` to include the new determinism testing library.
This commit is contained in:
master
2025-12-23 18:56:12 +02:00
committed by StellaOps Bot
parent 7ac70ece71
commit 491e883653
409 changed files with 23797 additions and 17779 deletions

View File

@@ -0,0 +1,87 @@
using System.Reflection;
using NetArchTest.Rules;
using Xunit;
using FluentAssertions;
namespace StellaOps.Architecture.Tests;
/// <summary>
/// Architecture tests for lattice engine placement rules.
/// Ensures lattice algorithms are only in Scanner.WebService, not in Concelier or Excititor.
/// </summary>
[Trait("Category", "Architecture")]
public sealed class LatticeEngineRulesTests
{
private const string ScannerLatticeNamespace = "StellaOps.Scanner.Lattice";
/// <summary>
/// Concelier modules must not reference Scanner lattice engine.
/// Lattice decisions are made in Scanner, not in Concelier.
/// </summary>
[Fact]
public void Concelier_MustNot_Reference_ScannerLattice()
{
var concelierAssemblies = GetAssembliesByPattern("StellaOps.Concelier");
if (!concelierAssemblies.Any())
{
// Skip if assemblies not loaded (test discovery phase)
return;
}
var result = Types.InAssemblies(concelierAssemblies)
.ShouldNot()
.HaveDependencyOn(ScannerLatticeNamespace)
.GetResult();
result.IsSuccessful.Should().BeTrue(
$"Concelier assemblies must not reference Scanner lattice. " +
$"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty<string>())}");
}
/// <summary>
/// Excititor modules must not reference Scanner lattice engine.
/// Excititor preserves prune source - does not evaluate lattice decisions.
/// </summary>
[Fact]
public void Excititor_MustNot_Reference_ScannerLattice()
{
var excititorAssemblies = GetAssembliesByPattern("StellaOps.Excititor");
if (!excititorAssemblies.Any())
{
return;
}
var result = Types.InAssemblies(excititorAssemblies)
.ShouldNot()
.HaveDependencyOn(ScannerLatticeNamespace)
.GetResult();
result.IsSuccessful.Should().BeTrue(
$"Excititor assemblies must not reference Scanner lattice. " +
$"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty<string>())}");
}
/// <summary>
/// Scanner.WebService MAY reference Scanner lattice engine (it's the authorized host).
/// This test documents the allowed dependency.
/// </summary>
[Fact]
public void ScannerWebService_May_Reference_ScannerLattice()
{
// This is a documentation test - Scanner.WebService is allowed to use lattice
// The test validates that the architectural rule is correctly documented
var allowedAssemblies = new[] { "StellaOps.Scanner.WebService" };
// Positive assertion: these assemblies ARE allowed to reference lattice
allowedAssemblies.Should().Contain("StellaOps.Scanner.WebService",
"Scanner.WebService is the authorized host for lattice algorithms");
}
private static IEnumerable<Assembly> GetAssembliesByPattern(string pattern)
{
return AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.GetName().Name?.StartsWith(pattern) == true);
}
}