Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.

This commit is contained in:
Joseph Doherty
2026-02-20 12:54:07 -05:00
commit b8ed5ec500
214 changed files with 101452 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
using System.IO.Compression;
using ZB.MOM.WW.CBDD.Core.Compression;
using ZB.MOM.WW.CBDD.Core.Storage;
using ZB.MOM.WW.CBDD.Shared;
namespace ZB.MOM.WW.CBDD.Tests;
public class MaintenanceDiagnosticsAndMigrationTests
{
[Fact]
public void DiagnosticsApis_ShouldReturnPageUsageCompressionAndFragmentationData()
{
var dbPath = NewDbPath();
try
{
var options = new CompressionOptions
{
EnableCompression = true,
MinSizeBytes = 0,
MinSavingsPercent = 0,
Codec = CompressionCodec.Brotli,
Level = CompressionLevel.Fastest
};
using var db = new TestDbContext(dbPath, options);
for (var i = 0; i < 40; i++)
{
db.Users.Insert(new User
{
Name = BuildPayload(i, 9000),
Age = i
});
}
db.SaveChanges();
db.ForceCheckpoint();
var byType = db.GetPageUsageByPageType();
byType.Count.ShouldBeGreaterThan(0);
byType.Any(x => x.PageType == PageType.Data && x.PageCount > 0).ShouldBeTrue();
var byCollection = db.GetPageUsageByCollection();
byCollection.Any(x => x.CollectionName.Equals("users", StringComparison.OrdinalIgnoreCase)).ShouldBeTrue();
var compressionByCollection = db.GetCompressionRatioByCollection();
var usersCompression = compressionByCollection.First(x => x.CollectionName.Equals("users", StringComparison.OrdinalIgnoreCase));
usersCompression.DocumentCount.ShouldBeGreaterThan(0);
usersCompression.BytesBeforeCompression.ShouldBeGreaterThan(0);
usersCompression.BytesAfterCompression.ShouldBeGreaterThan(0);
var freeList = db.GetFreeListSummary();
freeList.PageCount.ShouldBeGreaterThan(0u);
var fragmentation = db.GetFragmentationMap();
fragmentation.Pages.Count.ShouldBeGreaterThan(0);
}
finally
{
CleanupFiles(dbPath);
}
}
[Fact]
public void MigrateCompression_DryRunAndApply_ShouldReturnDeterministicStatsAndPreserveData()
{
var dbPath = NewDbPath();
try
{
using var db = new TestDbContext(dbPath, CompressionOptions.Default);
var ids = new List<ZB.MOM.WW.CBDD.Bson.ObjectId>();
for (var i = 0; i < 60; i++)
{
ids.Add(db.Users.Insert(new User
{
Name = BuildPayload(i, 12000),
Age = i % 17
}));
}
db.SaveChanges();
db.ForceCheckpoint();
var dryRun = db.MigrateCompression(new CompressionMigrationOptions
{
DryRun = true,
Codec = CompressionCodec.Deflate,
Level = CompressionLevel.Fastest,
MinSizeBytes = 0,
MinSavingsPercent = 0,
IncludeCollections = ["users"]
});
dryRun.DryRun.ShouldBeTrue();
dryRun.DocumentsScanned.ShouldBeGreaterThan(0);
dryRun.BytesBefore.ShouldBeGreaterThan(0);
dryRun.BytesEstimatedAfter.ShouldBeGreaterThan(0);
var apply = db.MigrateCompression(new CompressionMigrationOptions
{
DryRun = false,
Codec = CompressionCodec.Deflate,
Level = CompressionLevel.Fastest,
MinSizeBytes = 0,
MinSavingsPercent = 0,
IncludeCollections = ["users"]
});
apply.DryRun.ShouldBeFalse();
apply.DocumentsScanned.ShouldBeGreaterThan(0);
foreach (var id in ids)
{
var user = db.Users.FindById(id);
user.ShouldNotBeNull();
user!.Name.Length.ShouldBeGreaterThan(1000);
}
}
finally
{
CleanupFiles(dbPath);
}
}
private static string BuildPayload(int seed, int approxLength)
{
var builder = new System.Text.StringBuilder(approxLength + 128);
var i = 0;
while (builder.Length < approxLength)
{
builder.Append("diag-migrate-");
builder.Append(seed.ToString("D4"));
builder.Append('-');
builder.Append(i.ToString("D6"));
builder.Append('|');
i++;
}
return builder.ToString();
}
private static string NewDbPath()
=> Path.Combine(Path.GetTempPath(), $"maint_diag_migrate_{Guid.NewGuid():N}.db");
private static void CleanupFiles(string dbPath)
{
var walPath = Path.ChangeExtension(dbPath, ".wal");
var markerPath = $"{dbPath}.compact.state";
var tempPath = $"{dbPath}.compact.tmp";
var backupPath = $"{dbPath}.compact.bak";
if (File.Exists(dbPath)) File.Delete(dbPath);
if (File.Exists(walPath)) File.Delete(walPath);
if (File.Exists(markerPath)) File.Delete(markerPath);
if (File.Exists(tempPath)) File.Delete(tempPath);
if (File.Exists(backupPath)) File.Delete(backupPath);
}
}