112 lines
4.0 KiB
C#
Executable File
112 lines
4.0 KiB
C#
Executable File
using ZB.MOM.WW.CBDD.Bson;
|
|
using ZB.MOM.WW.CBDD.Core.Collections;
|
|
using ZB.MOM.WW.CBDD.Core.Indexing;
|
|
using ZB.MOM.WW.CBDD.Core.Storage;
|
|
using ZB.MOM.WW.CBDD.Core.Transactions;
|
|
using ZB.MOM.WW.CBDD.Shared;
|
|
using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.CBDD.Tests;
|
|
|
|
public class MetadataPersistenceTests : IDisposable
|
|
{
|
|
private readonly string _dbPath;
|
|
private readonly string _walPath;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MetadataPersistenceTests"/> class.
|
|
/// </summary>
|
|
public MetadataPersistenceTests()
|
|
{
|
|
_dbPath = Path.Combine(Path.GetTempPath(), $"docdb_meta_{Guid.NewGuid()}.db");
|
|
_walPath = Path.ChangeExtension(_dbPath, ".wal");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests index definitions are persisted and reloaded.
|
|
/// </summary>
|
|
[Fact]
|
|
public void IndexDefinitions_ArePersisted_AndReloaded()
|
|
{
|
|
// 1. Create index in first session
|
|
using (var storage = new StorageEngine(_dbPath, PageFileConfig.Default))
|
|
{
|
|
// Disable auto-checkpoint to ensure cleaner test tracing, though not strictly required
|
|
var mapper = new ZB_MOM_WW_CBDD_Shared_UserMapper();
|
|
var indexManager = new CollectionIndexManager<ObjectId, User>(storage, mapper, nameof(User));
|
|
|
|
// Create 2 indexes
|
|
indexManager.CreateIndex(u => u.Age, "idx_age");
|
|
indexManager.CreateIndex(u => u.Name, unique: true); // name auto-generated
|
|
}
|
|
|
|
// 2. Re-open storage and verify indexes exist
|
|
using (var storage = new StorageEngine(_dbPath, PageFileConfig.Default))
|
|
{
|
|
var mapper = new ZB_MOM_WW_CBDD_Shared_UserMapper();
|
|
// Assuming Page 1 was allocated above in clean DB
|
|
var indexManager = new CollectionIndexManager<ObjectId, User>(storage, mapper, nameof(User));
|
|
|
|
var indexes = indexManager.GetAllIndexes().ToList();
|
|
|
|
indexes.Count.ShouldBe(2);
|
|
|
|
var ageIdx = indexManager.GetIndex("idx_age");
|
|
ageIdx.ShouldNotBeNull();
|
|
ageIdx.Definition.IsUnique.ShouldBeFalse();
|
|
ageIdx.Definition.PropertyPaths.Count().ShouldBe(1);
|
|
ageIdx.Definition.PropertyPaths[0].ShouldBe("Age");
|
|
|
|
// Check auto-generated name index
|
|
var nameIdx = indexes.FirstOrDefault(i => i.Definition.PropertyPaths[0] == "Name");
|
|
nameIdx.ShouldNotBeNull();
|
|
nameIdx.Definition.IsUnique.ShouldBeTrue();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests ensure index does not recreate if index exists.
|
|
/// </summary>
|
|
[Fact]
|
|
public void EnsureIndex_DoesNotRecreate_IfIndexExists()
|
|
{
|
|
// 1. Create index
|
|
using (var context = new Shared.TestDbContext(_dbPath))
|
|
{
|
|
context.Users.EnsureIndex(u => u.Age);
|
|
}
|
|
|
|
// 2. Re-open and EnsureIndex again - should be fast/no-op
|
|
using (var context = new Shared.TestDbContext(_dbPath))
|
|
{
|
|
var mapper = new ZB_MOM_WW_CBDD_Shared_UserMapper();
|
|
|
|
// Use reflection or diagnostic to check if it triggered rebuild?
|
|
// Currently hard to verify "no rebuild" without logs or mocking.
|
|
// But we can verify it doesn't throw and index is still valid.
|
|
|
|
var idx = context.Users.EnsureIndex(u => u.Age);
|
|
idx.ShouldNotBeNull();
|
|
|
|
// Verify functioning
|
|
using var txn = context.BeginTransaction();
|
|
context.Users.Insert(new User { Name = "Bob", Age = 50 });
|
|
txn.Commit();
|
|
|
|
// Should find it via index
|
|
var results = context.Users.Find(u => u.Age == 50).ToList();
|
|
results.Count().ShouldBe(1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disposes the resources used by this instance.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if (File.Exists(_dbPath)) File.Delete(_dbPath);
|
|
if (File.Exists(_walPath)) File.Delete(_walPath);
|
|
}
|
|
}
|