up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-26 07:47:08 +02:00
parent 56e2f64d07
commit 1c782897f7
184 changed files with 8991 additions and 649 deletions

View File

@@ -0,0 +1,34 @@
using System.Text.Json;
using FluentAssertions;
using StellaOps.Replay.Core;
using Xunit;
namespace StellaOps.Replay.Core.Tests;
public sealed class CanonicalJsonTests
{
[Fact]
public void CanonicalJson_OrdersPropertiesLexicographically()
{
var payload = new
{
zeta = 1,
alpha = new { z = 9, m = 7 },
list = new[] { new { y = 2, x = 1 } }
};
var canonical = CanonicalJson.Serialize(payload);
canonical.Should().Be("{\"alpha\":{\"m\":7,\"z\":9},\"list\":[{\"x\":1,\"y\":2}],\"zeta\":1}");
}
[Fact]
public void CanonicalJson_PreservesNumbersAndBooleans()
{
var payload = JsonSerializer.Deserialize<JsonElement>("{\"b\":true,\"a\":1.25}");
var canonical = CanonicalJson.Serialize(payload);
canonical.Should().Be("{\"a\":1.25,\"b\":true}");
}
}

View File

@@ -0,0 +1,30 @@
using System.Text;
using FluentAssertions;
using StellaOps.Replay.Core;
using Xunit;
namespace StellaOps.Replay.Core.Tests;
public sealed class DeterministicHashTests
{
[Fact]
public void Sha256Hex_ComputesLowercaseDigest()
{
var digest = DeterministicHash.Sha256Hex("replay-core");
digest.Should().Be("a914f5ac6a57aab0189bb55bcb0ef6bcdbd86f77198c8669eab5ae38a325e41d");
}
[Fact]
public void MerkleRootHex_IsDeterministic()
{
var leaves = new[] { "alpha", "beta", "gamma" }
.Select(Encoding.UTF8.GetBytes)
.ToList();
var root = DeterministicHash.MerkleRootHex(leaves);
root.Should().Be("50298939464ed02cbf2b587250a55746b3422e133ac4f09b7e2b07869023bc9e");
DeterministicHash.MerkleRootHex(leaves).Should().Be(root);
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Text;
using FluentAssertions;
using StellaOps.Replay.Core;
using Xunit;
namespace StellaOps.Replay.Core.Tests;
public sealed class DsseEnvelopeTests
{
[Fact]
public void BuildUnsigned_ProducesCanonicalPayload()
{
var manifest = new ReplayManifest
{
Scan = new ReplayScanMetadata
{
Id = "scan-123",
Time = DateTimeOffset.UnixEpoch
}
};
var envelope = DssePayloadBuilder.BuildUnsigned(manifest);
envelope.PayloadType.Should().Be(DssePayloadBuilder.ReplayPayloadType);
envelope.Signatures.Should().BeEmpty();
var payload = Convert.FromBase64String(envelope.Payload);
var json = Encoding.UTF8.GetString(payload);
json.Should().Be("{\"reachability\":{\"graphs\":[],\"runtimeTraces\":[]},\"scan\":{\"id\":\"scan-123\",\"time\":\"1970-01-01T00:00:00+00:00\"},\"schemaVersion\":\"1.0\"}");
envelope.DigestSha256.Should().Be(DeterministicHash.Sha256Hex(payload));
}
}

View File

@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Formats.Tar;
using System.IO;
using FluentAssertions;
using StellaOps.Replay.Core;
using ZstdSharp;
using Xunit;
namespace StellaOps.Replay.Core.Tests;
public sealed class ReplayBundleWriterTests
{
[Fact]
public async Task WriteTarZstAsync_IsDeterministicAndSorted()
{
var entries = new[]
{
new ReplayBundleEntry("b.txt", "beta"u8.ToArray()),
new ReplayBundleEntry("a.txt", "alpha"u8.ToArray())
};
await using var buffer = new MemoryStream();
var first = await ReplayBundleWriter.WriteTarZstAsync(entries, buffer, compressionLevel: 3);
var firstBytes = buffer.ToArray();
await using var buffer2 = new MemoryStream();
var second = await ReplayBundleWriter.WriteTarZstAsync(entries.Reverse(), buffer2, compressionLevel: 3);
first.ZstSha256.Should().Be(second.ZstSha256);
first.TarSha256.Should().Be(second.TarSha256);
firstBytes.Should().Equal(buffer2.ToArray());
// Decompress and verify ordering/content
buffer.Position = 0;
await using var decompressed = new MemoryStream();
await using (var decompress = new DecompressionStream(buffer, 16 * 1024, leaveOpen: true, enableMultiThreaded: false))
{
await decompress.CopyToAsync(decompressed);
}
decompressed.Position = 0;
var reader = new TarReader(decompressed, leaveOpen: true);
var names = new List<string>();
TarEntry? entry;
while ((entry = reader.GetNextEntry()) != null)
{
names.Add(entry.Name);
using var ms = new MemoryStream();
entry.DataStream!.CopyTo(ms);
var text = System.Text.Encoding.UTF8.GetString(ms.ToArray());
text.Should().Be(entry.Name.StartsWith("a") ? "alpha" : "beta");
}
names.Should().BeEquivalentTo(new[] { "a.txt", "b.txt" }, opts => opts.WithStrictOrdering());
}
[Fact]
public void BuildCasUri_UsesPrefixAndShard()
{
ReplayBundleWriter.BuildCasUri("abcdef", null).Should().Be("cas://replay/ab/abcdef.tar.zst");
ReplayBundleWriter.BuildCasUri("1234", "custom").Should().Be("cas://custom/12/1234.tar.zst");
}
}

View File

@@ -0,0 +1,57 @@
using FluentAssertions;
using MongoDB.Bson.Serialization;
using StellaOps.Replay.Core;
using Xunit;
namespace StellaOps.Replay.Core.Tests;
public sealed class ReplayMongoModelsTests
{
[Fact]
public void ReplayRunRecord_SerializesWithExpectedFields()
{
var record = new ReplayRunRecord
{
Id = "scan-1",
ManifestHash = "sha256:abc",
Status = "verified",
Outputs = new ReplayRunOutputs { Sbom = "sha256:sbom", Findings = "sha256:findings", Vex = "sha256:vex" },
Signatures = new() { new ReplaySignatureRecord { Profile = "FIPS", Verified = true } }
};
var bson = record.ToBsonDocument();
bson.Should().ContainKey("_id");
bson["manifestHash"].AsString.Should().Be("sha256:abc");
bson["status"].AsString.Should().Be("verified");
bson["outputs"].AsBsonDocument["sbom"].AsString.Should().Be("sha256:sbom");
bson["signatures"].AsBsonArray.Should().HaveCount(1);
}
[Fact]
public void ReplayBundleRecord_UsesIdAsDigest()
{
var record = new ReplayBundleRecord { Id = "abc", Type = "input", Size = 10, Location = "cas://replay/ab/abc.tar.zst" };
var bson = record.ToBsonDocument();
bson["_id"].AsString.Should().Be("abc");
bson["type"].AsString.Should().Be("input");
}
[Fact]
public void ReplaySubjectRecord_StoresLayers()
{
var record = new ReplaySubjectRecord
{
OciDigest = "sha256:img",
Layers = new()
{
new ReplayLayerRecord { LayerDigest = "l1", MerkleRoot = "m1", LeafCount = 2 },
new ReplayLayerRecord { LayerDigest = "l2", MerkleRoot = "m2", LeafCount = 3 }
}
};
var doc = record.ToBsonDocument();
doc["layers"].AsBsonArray.Should().HaveCount(2);
}
}