114 lines
3.4 KiB
C#
Executable File
114 lines
3.4 KiB
C#
Executable File
using ZB.MOM.WW.CBDD.Core;
|
|
using ZB.MOM.WW.CBDD.Core.Storage;
|
|
using ZB.MOM.WW.CBDD.Core.Collections;
|
|
using ZB.MOM.WW.CBDD.Core.Indexing;
|
|
using ZB.MOM.WW.CBDD.Bson;
|
|
using Xunit;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using ZB.MOM.WW.CBDD.Shared;
|
|
|
|
namespace ZB.MOM.WW.CBDD.Tests
|
|
{
|
|
public class ScanTests : IDisposable
|
|
{
|
|
private readonly string _testFile;
|
|
private readonly Shared.TestDbContext _db;
|
|
|
|
public ScanTests()
|
|
{
|
|
_testFile = Path.Combine(Path.GetTempPath(), $"scan_tests_{Guid.NewGuid()}.db");
|
|
if (File.Exists(_testFile)) File.Delete(_testFile);
|
|
var wal = Path.ChangeExtension(_testFile, ".wal");
|
|
if (File.Exists(wal)) File.Delete(wal);
|
|
|
|
_db = new Shared.TestDbContext(_testFile);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_db.Dispose();
|
|
if (File.Exists(_testFile)) File.Delete(_testFile);
|
|
var wal = Path.ChangeExtension(_testFile, ".wal");
|
|
if (File.Exists(wal)) File.Delete(wal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Scan_FindsMatchingDocuments()
|
|
{
|
|
// Arrange
|
|
_db.Users.Insert(new User { Name = "Alice", Age = 30 });
|
|
_db.Users.Insert(new User { Name = "Bob", Age = 25 });
|
|
_db.Users.Insert(new User { Name = "Charlie", Age = 35 });
|
|
_db.SaveChanges();
|
|
|
|
// Act: Find users older than 28
|
|
var results = _db.Users.Scan(reader => ParseAge(reader) > 28).ToList();
|
|
|
|
// Assert
|
|
results.Count.ShouldBe(2);
|
|
results.ShouldContain(d => d.Name == "Alice");
|
|
results.ShouldContain(d => d.Name == "Charlie");
|
|
}
|
|
|
|
[Fact]
|
|
public void Repro_Insert_Loop_Hang()
|
|
{
|
|
// Reproduce hang reported by user at 501 documents
|
|
int count = 600;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
_db.Users.Insert(new User { Name = $"User_{i}", Age = i });
|
|
}
|
|
_db.SaveChanges();
|
|
}
|
|
|
|
[Fact]
|
|
public void ParallelScan_FindsMatchingDocuments()
|
|
{
|
|
// Arrange
|
|
int count = 1000;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
_db.Users.Insert(new User { Name = $"User_{i}", Age = i });
|
|
}
|
|
_db.SaveChanges();
|
|
|
|
// Act: Find users with Age >= 500
|
|
// Parallelism 2 to force partitioning
|
|
var results = _db.Users.ParallelScan(reader => ParseAge(reader) >= 500, degreeOfParallelism: 2).ToList();
|
|
|
|
// Assert
|
|
results.Count.ShouldBe(500);
|
|
}
|
|
|
|
private int ParseAge(BsonSpanReader reader)
|
|
{
|
|
try
|
|
{
|
|
reader.ReadDocumentSize();
|
|
while (reader.Remaining > 0)
|
|
{
|
|
var type = reader.ReadBsonType();
|
|
if (type == 0) break; // End of doc
|
|
|
|
var name = reader.ReadElementHeader();
|
|
|
|
if (name == "age")
|
|
{
|
|
return reader.ReadInt32();
|
|
}
|
|
else
|
|
{
|
|
reader.SkipValue(type);
|
|
}
|
|
}
|
|
}
|
|
catch { return -1; }
|
|
return -1;
|
|
}
|
|
}
|
|
}
|