Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -10,6 +10,7 @@ using FluentAssertions;
|
||||
using StellaOps.Testing.Determinism;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Testing.Determinism.Tests;
|
||||
|
||||
public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
@@ -34,7 +35,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
|
||||
#region CreateBaseline Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateBaseline_WithValidInput_ReturnsCorrectHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -52,7 +54,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
baseline.UpdatedAt.Should().BeCloseTo(DateTimeOffset.UtcNow, TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateBaseline_WithSameInput_ProducesSameHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -66,7 +69,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
baseline1.CanonicalHash.Should().Be(baseline2.CanonicalHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateBaseline_WithDifferentInput_ProducesDifferentHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -81,7 +85,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
baseline1.CanonicalHash.Should().NotBe(baseline2.CanonicalHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateBaseline_WithMetadata_IncludesMetadata()
|
||||
{
|
||||
// Arrange
|
||||
@@ -105,7 +110,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
|
||||
#region Store and Retrieve Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StoreBaseline_AndRetrieve_RoundTripsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
@@ -123,7 +129,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
retrieved.Algorithm.Should().Be("SHA-256");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetBaseline_WhenNotExists_ReturnsNull()
|
||||
{
|
||||
// Act
|
||||
@@ -133,7 +140,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StoreBaseline_CreatesCorrectDirectoryStructure()
|
||||
{
|
||||
// Arrange
|
||||
@@ -149,7 +157,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
File.Exists(expectedPath).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task StoreBaseline_OverwritesExistingBaseline()
|
||||
{
|
||||
// Arrange
|
||||
@@ -175,7 +184,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
|
||||
#region Compare Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Compare_WhenMatches_ReturnsMatchStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -193,7 +203,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
result.Message.Should().Contain("matches baseline");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Compare_WhenDrifted_ReturnsDriftStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -214,7 +225,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
result.Message.Should().Contain("DRIFT DETECTED");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Compare_WhenMissing_ReturnsMissingStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -235,7 +247,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
|
||||
#region ListBaselines Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ListBaselines_WhenEmpty_ReturnsEmptyList()
|
||||
{
|
||||
// Act
|
||||
@@ -245,7 +258,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
baselines.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ListBaselines_ReturnsAllStoredBaselines()
|
||||
{
|
||||
// Arrange
|
||||
@@ -266,7 +280,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
baselines.Should().Contain(e => e.ArtifactType == "vex" && e.ArtifactName == "document1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ListBaselines_ReturnsOrderedResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -292,7 +307,8 @@ public sealed class DeterminismBaselineStoreTests : IDisposable
|
||||
|
||||
#region CreateDefault Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateDefault_CreatesStoreWithCorrectPath()
|
||||
{
|
||||
// Act
|
||||
|
||||
@@ -3,11 +3,13 @@ using StellaOps.Canonical.Json;
|
||||
using StellaOps.Testing.Determinism;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Testing.Determinism.Tests;
|
||||
|
||||
public sealed class DeterminismManifestTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalBytes_WithValidManifest_ProducesDeterministicOutput()
|
||||
{
|
||||
// Arrange
|
||||
@@ -21,7 +23,8 @@ public sealed class DeterminismManifestTests
|
||||
bytes1.Should().Equal(bytes2, "Same manifest should produce identical canonical bytes");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_WithValidManifest_ProducesDeterministicString()
|
||||
{
|
||||
// Arrange
|
||||
@@ -37,7 +40,8 @@ public sealed class DeterminismManifestTests
|
||||
json1.Should().NotContain(" ", "Canonical JSON should have no indentation");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void WriteToFile_AndReadFromFile_RoundTripsSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
@@ -64,7 +68,8 @@ public sealed class DeterminismManifestTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task WriteToFileAsync_AndReadFromFileAsync_RoundTripsSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
@@ -91,7 +96,8 @@ public sealed class DeterminismManifestTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FromBytes_WithValidJson_DeserializesSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
@@ -105,7 +111,8 @@ public sealed class DeterminismManifestTests
|
||||
deserialized.Should().BeEquivalentTo(manifest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FromString_WithValidJson_DeserializesSuccessfully()
|
||||
{
|
||||
// Arrange
|
||||
@@ -119,7 +126,8 @@ public sealed class DeterminismManifestTests
|
||||
deserialized.Should().BeEquivalentTo(manifest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalBytes_WithInvalidSchemaVersion_ThrowsInvalidOperationException()
|
||||
{
|
||||
// Arrange
|
||||
@@ -133,7 +141,8 @@ public sealed class DeterminismManifestTests
|
||||
.WithMessage("*schema version*2.0*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryReadFromFileAsync_WithNonExistentFile_ReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
@@ -146,7 +155,8 @@ public sealed class DeterminismManifestTests
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ReadFromFile_WithNonExistentFile_ThrowsFileNotFoundException()
|
||||
{
|
||||
// Arrange
|
||||
@@ -159,7 +169,8 @@ public sealed class DeterminismManifestTests
|
||||
act.Should().Throw<FileNotFoundException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ComputeCanonicalHash_ProducesDeterministicHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -174,7 +185,8 @@ public sealed class DeterminismManifestTests
|
||||
hash1.Should().MatchRegex("^[0-9a-f]{64}$", "Hash should be 64-character hex string");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateManifest_WithValidInputs_CreatesManifestWithCorrectHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -215,7 +227,8 @@ public sealed class DeterminismManifestTests
|
||||
manifest.CanonicalHash.Value.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateManifestForJsonArtifact_WithValidInputs_CreatesManifestWithCanonicalHash()
|
||||
{
|
||||
// Arrange
|
||||
@@ -254,7 +267,8 @@ public sealed class DeterminismManifestTests
|
||||
manifest.CanonicalHash.Value.Should().Be(expectedHash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateManifest_WithInputStamps_IncludesInputStamps()
|
||||
{
|
||||
// Arrange
|
||||
@@ -291,7 +305,8 @@ public sealed class DeterminismManifestTests
|
||||
manifest.Inputs.SourceCodeHash.Should().Be("789abc");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateManifest_WithReproducibilityMetadata_IncludesMetadata()
|
||||
{
|
||||
// Arrange
|
||||
@@ -330,7 +345,8 @@ public sealed class DeterminismManifestTests
|
||||
manifest.Reproducibility.NormalizationRules.Should().ContainInOrder("UTF-8", "LF line endings", "sorted JSON keys");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void CreateManifest_WithVerificationInfo_IncludesVerification()
|
||||
{
|
||||
// Arrange
|
||||
@@ -367,7 +383,8 @@ public sealed class DeterminismManifestTests
|
||||
manifest.Verification.Baseline.Should().Be("tests/baselines/sbom-alpine-3.18.determinism.json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ManifestSerialization_WithComplexMetadata_PreservesAllFields()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -9,6 +9,7 @@ using FluentAssertions;
|
||||
using StellaOps.Testing.Determinism;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Testing.Determinism.Tests;
|
||||
|
||||
public sealed class DeterminismSummaryTests : IDisposable
|
||||
@@ -31,7 +32,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
|
||||
#region DeterminismSummaryBuilder Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithNoResults_ReturnsPassStatus()
|
||||
{
|
||||
// Act
|
||||
@@ -45,7 +47,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Statistics.Missing.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithAllMatching_ReturnsPassStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -67,7 +70,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Missing.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithDrift_ReturnsFailStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -89,7 +93,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Drift![0].ArtifactName.Should().Be("artifact2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithMissing_ReturnsWarningStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -109,7 +114,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Missing![0].ArtifactName.Should().Be("artifact2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithMissing_AndFailOnMissing_ReturnsFailStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -125,7 +131,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Status.Should().Be(DeterminismCheckStatus.Fail);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_DriftTakesPrecedenceOverMissing()
|
||||
{
|
||||
// Arrange
|
||||
@@ -142,7 +149,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.Statistics.Missing.Should().Be(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithSourceRef_IncludesSourceRef()
|
||||
{
|
||||
// Arrange
|
||||
@@ -157,7 +165,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.SourceRef.Should().Be("abc123def456");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_WithCiRunId_IncludesCiRunId()
|
||||
{
|
||||
// Arrange
|
||||
@@ -172,7 +181,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
summary.CiRunId.Should().Be("run-12345");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_SetsGeneratedAtToUtcNow()
|
||||
{
|
||||
// Arrange
|
||||
@@ -192,7 +202,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
|
||||
#region DeterminismSummaryWriter Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task WriteToFileAsync_CreatesValidJsonFile()
|
||||
{
|
||||
// Arrange
|
||||
@@ -214,7 +225,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
content.Should().Contain("\"status\": \"pass\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task WriteToFileAsync_CreatesDirectoryIfNeeded()
|
||||
{
|
||||
// Arrange
|
||||
@@ -228,7 +240,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
File.Exists(filePath).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToJson_ReturnsValidJson()
|
||||
{
|
||||
// Arrange
|
||||
@@ -247,7 +260,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
json.Should().Contain("\"drifted\": 1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task WriteHashFilesAsync_CreatesHashFilesForAllArtifacts()
|
||||
{
|
||||
// Arrange
|
||||
@@ -266,7 +280,8 @@ public sealed class DeterminismSummaryTests : IDisposable
|
||||
File.Exists(Path.Combine(hashDir, "vex_document1.sha256.txt")).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task WriteHashFilesAsync_HashFileContainsCorrectFormat()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -20,5 +20,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\StellaOps.Testing.Determinism\StellaOps.Testing.Determinism.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user