Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.
This commit is contained in:
131
tests/CBDD.Tests/AsyncTests.cs
Executable file
131
tests/CBDD.Tests/AsyncTests.cs
Executable file
@@ -0,0 +1,131 @@
|
||||
using ZB.MOM.WW.CBDD.Core;
|
||||
using ZB.MOM.WW.CBDD.Core.Collections;
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Core.Transactions;
|
||||
using ZB.MOM.WW.CBDD.Shared;
|
||||
using Xunit;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests;
|
||||
|
||||
public class AsyncTests : IDisposable
|
||||
{
|
||||
private readonly string _dbPath;
|
||||
|
||||
public AsyncTests()
|
||||
{
|
||||
_dbPath = Path.Combine(Path.GetTempPath(), $"cbdd_async_{Guid.NewGuid()}.db");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (File.Exists(_dbPath)) File.Delete(_dbPath);
|
||||
if (File.Exists(Path.ChangeExtension(_dbPath, ".wal"))) File.Delete(Path.ChangeExtension(_dbPath, ".wal"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Async_Transaction_Commit_Should_Persist_Data()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
|
||||
using (var db = new Shared.TestDbContext(_dbPath))
|
||||
{
|
||||
using (var txn = await db.BeginTransactionAsync(ct))
|
||||
{
|
||||
db.AsyncDocs.Insert(new AsyncDoc { Id = 1, Name = "Async1" });
|
||||
db.AsyncDocs.Insert(new AsyncDoc { Id = 2, Name = "Async2" });
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify with new storage engine instance
|
||||
using var db2 = new Shared.TestDbContext(_dbPath);
|
||||
var doc1 = db2.AsyncDocs.FindById(1);
|
||||
doc1.ShouldNotBeNull();
|
||||
doc1.Name.ShouldBe("Async1");
|
||||
|
||||
var doc2 = db2.AsyncDocs.FindById(2);
|
||||
doc2.ShouldNotBeNull();
|
||||
doc2.Name.ShouldBe("Async2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Async_Transaction_Rollback_Should_Discard_Data()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
|
||||
using var db = new Shared.TestDbContext(_dbPath);
|
||||
using (var txn = await db.BeginTransactionAsync(ct))
|
||||
{
|
||||
db.AsyncDocs.Insert(new AsyncDoc { Id = 3, Name = "RollbackMe" });
|
||||
}
|
||||
|
||||
var doc = db.AsyncDocs.FindById(3);
|
||||
doc.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Bulk_Async_Insert_Should_Persist_Data()
|
||||
{
|
||||
using var db = new Shared.TestDbContext(_dbPath);
|
||||
var docs = Enumerable.Range(1, 100).Select(i => new AsyncDoc { Id = i + 5000, Name = $"Bulk{i}" });
|
||||
|
||||
var ids = await db.AsyncDocs.InsertBulkAsync(docs);
|
||||
|
||||
ids.Count.ShouldBe(100);
|
||||
|
||||
var doc50 = db.AsyncDocs.FindById(5050);
|
||||
doc50.ShouldNotBeNull();
|
||||
doc50.Name.ShouldBe("Bulk50");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Bulk_Async_Update_Should_Persist_Changes()
|
||||
{
|
||||
using var db = new Shared.TestDbContext(_dbPath);
|
||||
// 1. Insert 100 docs
|
||||
var docs = Enumerable.Range(1, 100).Select(i => new AsyncDoc { Id = i + 6000, Name = $"Original{i}" }).ToList();
|
||||
await db.AsyncDocs.InsertBulkAsync(docs);
|
||||
|
||||
// 2. Update all docs
|
||||
foreach (var doc in docs)
|
||||
{
|
||||
doc.Name = $"Updated{doc.Id - 6000}";
|
||||
}
|
||||
|
||||
var count = await db.AsyncDocs.UpdateBulkAsync(docs);
|
||||
|
||||
count.ShouldBe(100);
|
||||
|
||||
// 3. Verify updates
|
||||
var doc50 = db.AsyncDocs.FindById(6050);
|
||||
doc50.ShouldNotBeNull();
|
||||
doc50.Name.ShouldBe("Updated50");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task High_Concurrency_Async_Commits()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
|
||||
using var db = new Shared.TestDbContext(Path.Combine(Path.GetTempPath(), $"cbdd_async_concurrency_{Guid.NewGuid()}.db"));
|
||||
int threadCount = 2;
|
||||
int docsPerThread = 50;
|
||||
|
||||
var tasks = Enumerable.Range(0, threadCount).Select(async i =>
|
||||
{
|
||||
// Test mix of implicit and explicit transactions
|
||||
for (int j = 0; j < docsPerThread; j++)
|
||||
{
|
||||
int id = (i * docsPerThread) + j + 8000;
|
||||
await db.AsyncDocs.InsertAsync(new AsyncDoc { Id = id, Name = $"Thread{i}_Doc{j}" });
|
||||
}
|
||||
});
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
// Verify count
|
||||
var count = db.AsyncDocs.Scan(_ => true).Count();
|
||||
count.ShouldBe(threadCount * docsPerThread);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user