Reformat / cleanup
All checks were successful
NuGet Publish / build-and-pack (push) Successful in 46s
NuGet Publish / publish-to-gitea (push) Successful in 56s

This commit is contained in:
Joseph Doherty
2026-02-21 08:10:36 -05:00
parent 4c6aaa5a3f
commit a70d8befae
176 changed files with 50555 additions and 49587 deletions

View File

@@ -1,5 +1,6 @@
using System.Buffers.Binary;
using System.IO.Compression;
using System.Text;
using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Core.Compression;
using ZB.MOM.WW.CBDD.Core.Storage;
@@ -10,12 +11,12 @@ namespace ZB.MOM.WW.CBDD.Tests;
public class CompressionCorruptionTests
{
/// <summary>
/// Verifies corrupted compressed payload checksum triggers invalid data errors.
/// Verifies corrupted compressed payload checksum triggers invalid data errors.
/// </summary>
[Fact]
public void Read_WithBadChecksum_ShouldThrowInvalidData()
{
var dbPath = NewDbPath();
string dbPath = NewDbPath();
var options = CompressionEnabledOptions();
try
@@ -23,7 +24,7 @@ public class CompressionCorruptionTests
using var db = new TestDbContext(dbPath, options);
var id = InsertCheckpointAndCorrupt(db, header =>
{
var currentChecksum = BinaryPrimitives.ReadUInt32LittleEndian(header.Slice(12, 4));
uint currentChecksum = BinaryPrimitives.ReadUInt32LittleEndian(header.Slice(12, 4));
BinaryPrimitives.WriteUInt32LittleEndian(header.Slice(12, 4), currentChecksum + 1);
});
@@ -38,21 +39,19 @@ public class CompressionCorruptionTests
}
/// <summary>
/// Verifies invalid original length metadata triggers invalid data errors.
/// Verifies invalid original length metadata triggers invalid data errors.
/// </summary>
[Fact]
public void Read_WithBadOriginalLength_ShouldThrowInvalidData()
{
var dbPath = NewDbPath();
string dbPath = NewDbPath();
var options = CompressionEnabledOptions();
try
{
using var db = new TestDbContext(dbPath, options);
var id = InsertCheckpointAndCorrupt(db, header =>
{
BinaryPrimitives.WriteInt32LittleEndian(header.Slice(4, 4), -1);
});
var id = InsertCheckpointAndCorrupt(db,
header => { BinaryPrimitives.WriteInt32LittleEndian(header.Slice(4, 4), -1); });
var ex = Should.Throw<InvalidDataException>(() => db.Users.FindById(id));
ex.Message.ShouldContain("decompress");
@@ -64,21 +63,19 @@ public class CompressionCorruptionTests
}
/// <summary>
/// Verifies oversized declared decompressed length enforces safety guardrails.
/// Verifies oversized declared decompressed length enforces safety guardrails.
/// </summary>
[Fact]
public void Read_WithOversizedDeclaredLength_ShouldEnforceGuardrail()
{
var dbPath = NewDbPath();
var options = CompressionEnabledOptions(maxDecompressedSizeBytes: 2048);
string dbPath = NewDbPath();
var options = CompressionEnabledOptions(2048);
try
{
using var db = new TestDbContext(dbPath, options);
var id = InsertCheckpointAndCorrupt(db, header =>
{
BinaryPrimitives.WriteInt32LittleEndian(header.Slice(4, 4), 2049);
});
var id = InsertCheckpointAndCorrupt(db,
header => { BinaryPrimitives.WriteInt32LittleEndian(header.Slice(4, 4), 2049); });
var ex = Should.Throw<InvalidDataException>(() => db.Users.FindById(id));
ex.Message.ShouldContain("invalid decompressed length");
@@ -91,12 +88,12 @@ public class CompressionCorruptionTests
}
/// <summary>
/// Verifies invalid codec identifiers in compressed headers trigger invalid data errors.
/// Verifies invalid codec identifiers in compressed headers trigger invalid data errors.
/// </summary>
[Fact]
public void Read_WithInvalidCodecId_ShouldThrowInvalidData()
{
var dbPath = NewDbPath();
string dbPath = NewDbPath();
var options = CompressionEnabledOptions();
try
@@ -128,7 +125,7 @@ public class CompressionCorruptionTests
db.SaveChanges();
db.ForceCheckpoint();
var (pageId, slot, _) = FindFirstCompressedSlot(db.Storage);
(uint pageId, var slot, _) = FindFirstCompressedSlot(db.Storage);
((slot.Flags & SlotFlags.HasOverflow) != 0).ShouldBeFalse();
var page = new byte[db.Storage.PageSize];
@@ -152,7 +149,7 @@ public class CompressionCorruptionTests
for (ushort slotIndex = 0; slotIndex < header.SlotCount; slotIndex++)
{
var slotOffset = SlottedPageHeader.Size + (slotIndex * SlotEntry.Size);
int slotOffset = SlottedPageHeader.Size + slotIndex * SlotEntry.Size;
var slot = SlotEntry.ReadFrom(buffer.AsSpan(slotOffset, SlotEntry.Size));
if ((slot.Flags & SlotFlags.Deleted) != 0)
continue;
@@ -178,11 +175,9 @@ public class CompressionCorruptionTests
};
}
private delegate void HeaderMutator(Span<byte> header);
private static string BuildPayload(int approxLength)
{
var builder = new System.Text.StringBuilder(approxLength + 256);
var builder = new StringBuilder(approxLength + 256);
var i = 0;
while (builder.Length < approxLength)
{
@@ -196,14 +191,18 @@ public class CompressionCorruptionTests
}
private static string NewDbPath()
=> Path.Combine(Path.GetTempPath(), $"compression_corruption_{Guid.NewGuid():N}.db");
{
return Path.Combine(Path.GetTempPath(), $"compression_corruption_{Guid.NewGuid():N}.db");
}
private static void CleanupFiles(string dbPath)
{
var walPath = Path.ChangeExtension(dbPath, ".wal");
string walPath = Path.ChangeExtension(dbPath, ".wal");
var markerPath = $"{dbPath}.compact.state";
if (File.Exists(dbPath)) File.Delete(dbPath);
if (File.Exists(walPath)) File.Delete(walPath);
if (File.Exists(markerPath)) File.Delete(markerPath);
}
}
private delegate void HeaderMutator(Span<byte> header);
}