Add unit tests for RabbitMq and Udp transport servers and clients
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Implemented comprehensive unit tests for RabbitMqTransportServer, covering constructor, disposal, connection management, event handlers, and exception handling.
- Added configuration tests for RabbitMqTransportServer to validate SSL, durable queues, auto-recovery, and custom virtual host options.
- Created unit tests for UdpFrameProtocol, including frame parsing and serialization, header size validation, and round-trip data preservation.
- Developed tests for UdpTransportClient, focusing on connection handling, event subscriptions, and exception scenarios.
- Established tests for UdpTransportServer, ensuring proper start/stop behavior, connection state management, and event handling.
- Included tests for UdpTransportOptions to verify default values and modification capabilities.
- Enhanced service registration tests for Udp transport services in the dependency injection container.
This commit is contained in:
master
2025-12-05 19:01:12 +02:00
parent 53508ceccb
commit cc69d332e3
245 changed files with 22440 additions and 27719 deletions

View File

@@ -3,6 +3,7 @@ using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Cryptography;
using StellaOps.Findings.Ledger.Domain;
using StellaOps.Findings.Ledger.Observability;
using StellaOps.Findings.Ledger.Options;
@@ -14,6 +15,7 @@ public sealed class LedgerMerkleAnchorWorker : BackgroundService
{
private readonly LedgerAnchorQueue _queue;
private readonly IMerkleAnchorRepository _repository;
private readonly ICryptoHash _cryptoHash;
private readonly TimeProvider _timeProvider;
private readonly LedgerServiceOptions.MerkleOptions _options;
private readonly ILogger<LedgerMerkleAnchorWorker> _logger;
@@ -22,12 +24,14 @@ public sealed class LedgerMerkleAnchorWorker : BackgroundService
public LedgerMerkleAnchorWorker(
LedgerAnchorQueue queue,
IMerkleAnchorRepository repository,
ICryptoHash cryptoHash,
IOptions<LedgerServiceOptions> options,
TimeProvider timeProvider,
ILogger<LedgerMerkleAnchorWorker> logger)
{
_queue = queue ?? throw new ArgumentNullException(nameof(queue));
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
_cryptoHash = cryptoHash ?? throw new ArgumentNullException(nameof(cryptoHash));
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_options = options?.Value.Merkle ?? throw new ArgumentNullException(nameof(options));
@@ -89,7 +93,7 @@ public sealed class LedgerMerkleAnchorWorker : BackgroundService
.ThenBy(e => e.RecordedAt)
.ToList();
var rootHash = MerkleTreeBuilder.ComputeRoot(orderedEvents.Select(e => e.MerkleLeafHash).ToArray());
var rootHash = MerkleTreeBuilder.ComputeRoot(_cryptoHash, orderedEvents.Select(e => e.MerkleLeafHash).ToArray());
var anchorId = Guid.NewGuid();
var windowStart = orderedEvents.First().RecordedAt;
var windowEnd = orderedEvents.Last().RecordedAt;

View File

@@ -1,12 +1,14 @@
using System.Security.Cryptography;
using System.Text;
using StellaOps.Cryptography;
namespace StellaOps.Findings.Ledger.Infrastructure.Merkle;
internal static class MerkleTreeBuilder
{
public static string ComputeRoot(IReadOnlyList<string> leafHashes)
public static string ComputeRoot(ICryptoHash cryptoHash, IReadOnlyList<string> leafHashes)
{
ArgumentNullException.ThrowIfNull(cryptoHash);
if (leafHashes.Count == 0)
{
throw new ArgumentException("At least one leaf hash is required to compute a Merkle root.", nameof(leafHashes));
@@ -18,13 +20,13 @@ internal static class MerkleTreeBuilder
while (currentLevel.Length > 1)
{
currentLevel = ComputeNextLevel(currentLevel);
currentLevel = ComputeNextLevel(cryptoHash, currentLevel);
}
return currentLevel[0];
}
private static string[] ComputeNextLevel(IReadOnlyList<string> level)
private static string[] ComputeNextLevel(ICryptoHash cryptoHash, IReadOnlyList<string> level)
{
var next = new string[(level.Count + 1) / 2];
var index = 0;
@@ -33,16 +35,15 @@ internal static class MerkleTreeBuilder
{
var left = level[i];
var right = i + 1 < level.Count ? level[i + 1] : level[i];
next[index++] = HashPair(left, right);
next[index++] = HashPair(cryptoHash, left, right);
}
return next;
}
private static string HashPair(string left, string right)
private static string HashPair(ICryptoHash cryptoHash, string left, string right)
{
var bytes = Encoding.UTF8.GetBytes(left + right);
var hashBytes = SHA256.HashData(bytes);
return Convert.ToHexString(hashBytes).ToLowerInvariant();
return cryptoHash.ComputeHashHexForPurpose(bytes, HashPurpose.Merkle);
}
}

View File

@@ -30,4 +30,8 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
</ItemGroup>
</Project>