Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -31,7 +31,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
// DSSE-8200-013: Cosign-compatible envelope structure tests
|
||||
// ==========================================================================
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnvelopeStructure_HasRequiredFields_ForCosignVerification()
|
||||
{
|
||||
// Arrange
|
||||
@@ -45,7 +46,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(result.IsValid, $"Structure validation failed: {string.Join(", ", result.Errors)}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnvelopePayload_IsBase64Encoded_InSerializedForm()
|
||||
{
|
||||
// Arrange
|
||||
@@ -70,7 +72,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.Equal(payload, decoded);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnvelopeSignature_IsBase64Encoded_InSerializedForm()
|
||||
{
|
||||
// Arrange
|
||||
@@ -99,7 +102,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(sigBytes.Length > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnvelopePayloadType_IsCorrectMimeType_ForInToto()
|
||||
{
|
||||
// Arrange
|
||||
@@ -112,7 +116,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.Equal("application/vnd.in-toto+json", envelope.PayloadType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnvelopeSerialization_ProducesValidJson_WithoutWhitespace()
|
||||
{
|
||||
// Arrange
|
||||
@@ -136,7 +141,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
// DSSE-8200-014: Fulcio certificate chain tests
|
||||
// ==========================================================================
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FulcioCertificate_HasCodeSigningEku()
|
||||
{
|
||||
// Arrange & Act
|
||||
@@ -161,7 +167,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(hasCodeSigning, "Certificate should have Code Signing EKU");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FulcioCertificate_HasDigitalSignatureKeyUsage()
|
||||
{
|
||||
// Arrange & Act
|
||||
@@ -173,7 +180,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(keyUsage.KeyUsages.HasFlag(X509KeyUsageFlags.DigitalSignature));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FulcioCertificate_IsShortLived()
|
||||
{
|
||||
// Arrange - Fulcio certs are typically valid for ~20 minutes
|
||||
@@ -186,7 +194,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(validity.TotalHours <= 24, $"Certificate validity ({validity.TotalHours}h) should be <= 24 hours");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BundleWithCertificate_HasValidPemFormat()
|
||||
{
|
||||
// Arrange
|
||||
@@ -207,7 +216,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
// DSSE-8200-015: Rekor transparency log offline verification tests
|
||||
// ==========================================================================
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_HasValidLogIndex()
|
||||
{
|
||||
// Arrange
|
||||
@@ -221,7 +231,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(rekorEntry.LogIndex >= 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_HasValidIntegratedTime()
|
||||
{
|
||||
// Arrange
|
||||
@@ -238,7 +249,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(integratedTime >= now.AddHours(-1), "Integrated time should not be too old");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_HasValidInclusionProof()
|
||||
{
|
||||
// Arrange
|
||||
@@ -256,7 +268,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.NotEmpty(rekorEntry.InclusionProof.Hashes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_CanonicalizedBody_IsBase64Encoded()
|
||||
{
|
||||
// Arrange
|
||||
@@ -276,7 +289,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.NotNull(json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_InclusionProof_HashesAreBase64()
|
||||
{
|
||||
// Arrange
|
||||
@@ -294,7 +308,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BundleWithRekor_ContainsValidTransparencyEntry()
|
||||
{
|
||||
// Arrange
|
||||
@@ -310,7 +325,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(bundle.RekorEntry.LogIndex >= 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RekorEntry_CheckpointFormat_IsValid()
|
||||
{
|
||||
// Arrange
|
||||
@@ -329,7 +345,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
// Integration tests
|
||||
// ==========================================================================
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void FullBundle_SignVerifyRoundtrip_Succeeds()
|
||||
{
|
||||
// Arrange
|
||||
@@ -349,7 +366,8 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
Assert.True(structureResult.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void DeterministicSigning_SamePayload_ProducesConsistentEnvelope()
|
||||
{
|
||||
// Arrange
|
||||
@@ -366,6 +384,7 @@ public sealed class DsseCosignCompatibilityTests : IDisposable
|
||||
// Note: Signatures may differ if using randomized ECDSA
|
||||
// (which is the default for security), so we only verify structure
|
||||
Assert.Equal(envelope1.Signatures.Count, envelope2.Signatures.Count);
|
||||
using StellaOps.TestKit;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
@@ -6,13 +6,16 @@ using System.Text.Json;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
using EnvelopeModel = StellaOps.Attestor.Envelope;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Attestor.Envelope.Tests;
|
||||
|
||||
public sealed class DsseEnvelopeSerializerTests
|
||||
{
|
||||
private static readonly byte[] SamplePayload = Encoding.UTF8.GetBytes("deterministic-dsse-payload");
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Serialize_ProducesDeterministicCompactJson_ForSignaturePermutations()
|
||||
{
|
||||
var signatures = new[]
|
||||
|
||||
@@ -7,6 +7,8 @@ using StellaOps.Attestor.Envelope;
|
||||
using StellaOps.Cryptography;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Attestor.Envelope.Tests;
|
||||
|
||||
public sealed class EnvelopeSignatureServiceTests
|
||||
@@ -23,7 +25,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
|
||||
private readonly EnvelopeSignatureService service = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void SignAndVerify_Ed25519_Succeeds()
|
||||
{
|
||||
var signingKey = EnvelopeKey.CreateEd25519Signer(Ed25519Seed, Ed25519Public);
|
||||
@@ -44,7 +47,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
signingKey.KeyId.Should().Be(expectedKeyId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Verify_Ed25519_InvalidSignature_ReturnsError()
|
||||
{
|
||||
var signingKey = EnvelopeKey.CreateEd25519Signer(Ed25519Seed, Ed25519Public);
|
||||
@@ -62,7 +66,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
verifyResult.Error.Code.Should().Be(EnvelopeSignatureErrorCode.SignatureInvalid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void SignAndVerify_EcdsaEs256_Succeeds()
|
||||
{
|
||||
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
@@ -80,7 +85,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
verifyResult.Value.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Sign_WithVerificationOnlyKey_ReturnsMissingPrivateKey()
|
||||
{
|
||||
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
@@ -93,7 +99,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
signResult.Error.Code.Should().Be(EnvelopeSignatureErrorCode.MissingPrivateKey);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Verify_WithMismatchedKeyId_ReturnsError()
|
||||
{
|
||||
var signingKey = EnvelopeKey.CreateEd25519Signer(Ed25519Seed, Ed25519Public);
|
||||
@@ -107,7 +114,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
verifyResult.Error.Code.Should().Be(EnvelopeSignatureErrorCode.KeyIdMismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Verify_WithInvalidSignatureLength_ReturnsFormatError()
|
||||
{
|
||||
var verifyKey = EnvelopeKey.CreateEd25519Verifier(Ed25519Public);
|
||||
@@ -119,7 +127,8 @@ public sealed class EnvelopeSignatureServiceTests
|
||||
verifyResult.Error.Code.Should().Be(EnvelopeSignatureErrorCode.InvalidSignatureFormat);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Verify_WithAlgorithmMismatch_ReturnsError()
|
||||
{
|
||||
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\\StellaOps.Attestor.Envelope.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -7,11 +7,14 @@ using System.Text.Json;
|
||||
using StellaOps.Attestor.Envelope;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Attestor.Envelope.Tests;
|
||||
|
||||
public sealed class DsseEnvelopeSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Serialize_WithDefaultOptions_ProducesCompactAndExpandedJson()
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes("{\"foo\":\"bar\"}");
|
||||
@@ -46,7 +49,8 @@ public sealed class DsseEnvelopeSerializerTests
|
||||
Assert.Equal("bar", preview.GetProperty("json").GetProperty("foo").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Serialize_WithCompressionEnabled_EmbedsCompressedPayloadMetadata()
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes("{\"foo\":\"bar\",\"count\":1}");
|
||||
@@ -87,7 +91,8 @@ public sealed class DsseEnvelopeSerializerTests
|
||||
Assert.Equal(compressedBytes.Length, result.EmbeddedPayloadLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Serialize_WithDetachedReference_WritesMetadata()
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes("detached payload preview");
|
||||
@@ -117,7 +122,8 @@ public sealed class DsseEnvelopeSerializerTests
|
||||
Assert.Equal(reference.MediaType, detached.GetProperty("mediaType").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Serialize_CompactOnly_SkipsExpandedPayload()
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes("payload");
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\\..\\StellaOps.Attestor.Envelope.csproj" />
|
||||
<ProjectReference Include="../../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user