- 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.
88 lines
3.1 KiB
C#
88 lines
3.1 KiB
C#
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);
|
|
}
|
|
}
|