Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.
This commit is contained in:
109
tests/CBDD.Tests/CompactionWalCoordinationTests.cs
Normal file
109
tests/CBDD.Tests/CompactionWalCoordinationTests.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using ZB.MOM.WW.CBDD.Bson;
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Shared;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests;
|
||||
|
||||
public class CompactionWalCoordinationTests
|
||||
{
|
||||
[Fact]
|
||||
public void OfflineCompact_ShouldCheckpointAndLeaveWalEmpty()
|
||||
{
|
||||
var dbPath = NewDbPath();
|
||||
var markerPath = $"{dbPath}.compact.state";
|
||||
|
||||
try
|
||||
{
|
||||
using var db = new TestDbContext(dbPath);
|
||||
for (var i = 0; i < 80; i++)
|
||||
{
|
||||
db.Users.Insert(new User { Name = $"wal-compact-{i:D3}", Age = i });
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
db.Storage.GetWalSize().ShouldBeGreaterThan(0);
|
||||
|
||||
var stats = db.Compact(new CompactionOptions
|
||||
{
|
||||
EnableTailTruncation = true,
|
||||
NormalizeFreeList = true,
|
||||
DefragmentSlottedPages = true
|
||||
});
|
||||
|
||||
stats.OnlineMode.ShouldBeFalse();
|
||||
db.Storage.GetWalSize().ShouldBe(0);
|
||||
File.Exists(markerPath).ShouldBeFalse();
|
||||
|
||||
db.Users.Count().ShouldBe(80);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupFiles(dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Compact_AfterWalRecovery_ShouldKeepDataDurable()
|
||||
{
|
||||
var dbPath = NewDbPath();
|
||||
var walPath = Path.ChangeExtension(dbPath, ".wal");
|
||||
var expected = new List<(ObjectId Id, string Name)>();
|
||||
|
||||
try
|
||||
{
|
||||
using (var writer = new TestDbContext(dbPath))
|
||||
{
|
||||
for (var i = 0; i < 48; i++)
|
||||
{
|
||||
var name = $"recoverable-{i:D3}";
|
||||
var id = writer.Users.Insert(new User { Name = name, Age = i % 13 });
|
||||
expected.Add((id, name));
|
||||
}
|
||||
|
||||
writer.SaveChanges();
|
||||
writer.Storage.GetWalSize().ShouldBeGreaterThan(0);
|
||||
}
|
||||
|
||||
new FileInfo(walPath).Length.ShouldBeGreaterThan(0);
|
||||
|
||||
using (var recovered = new TestDbContext(dbPath))
|
||||
{
|
||||
recovered.Users.Count().ShouldBe(expected.Count);
|
||||
|
||||
foreach (var item in expected)
|
||||
{
|
||||
recovered.Users.FindById(item.Id)!.Name.ShouldBe(item.Name);
|
||||
}
|
||||
|
||||
recovered.SaveChanges();
|
||||
recovered.Compact();
|
||||
recovered.Storage.GetWalSize().ShouldBe(0);
|
||||
}
|
||||
|
||||
using (var verify = new TestDbContext(dbPath))
|
||||
{
|
||||
verify.Users.Count().ShouldBe(expected.Count);
|
||||
foreach (var item in expected)
|
||||
{
|
||||
verify.Users.FindById(item.Id)!.Name.ShouldBe(item.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
CleanupFiles(dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static string NewDbPath()
|
||||
=> Path.Combine(Path.GetTempPath(), $"compaction_wal_{Guid.NewGuid():N}.db");
|
||||
|
||||
private static void CleanupFiles(string dbPath)
|
||||
{
|
||||
var 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user