Files
scadaproj/ZB.MOM.WW.LocalDb/tests/ZB.MOM.WW.LocalDb.Tests/LocalDbSchemaTests.cs
T

127 lines
3.7 KiB
C#

using Microsoft.Data.Sqlite;
using ZB.MOM.WW.LocalDb.Internal;
namespace ZB.MOM.WW.LocalDb.Tests;
public sealed class LocalDbSchemaTests : IDisposable
{
private readonly string _path = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".db");
public void Dispose()
{
SqliteConnection.ClearAllPools();
if (File.Exists(_path))
File.Delete(_path);
}
private SqliteConnection Open()
{
var conn = new SqliteConnection($"Data Source={_path}");
conn.Open();
return conn;
}
private static long ScalarLong(SqliteConnection conn, string sql)
{
using var cmd = conn.CreateCommand();
cmd.CommandText = sql;
return Convert.ToInt64(cmd.ExecuteScalar());
}
private static string ScalarString(SqliteConnection conn, string sql)
{
using var cmd = conn.CreateCommand();
cmd.CommandText = sql;
return (string)cmd.ExecuteScalar()!;
}
[Fact]
public void EnsureCreated_CreatesAllObjects()
{
using var conn = Open();
LocalDbSchema.EnsureCreated(conn);
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table'";
var tables = new List<string>();
using (var reader = cmd.ExecuteReader())
while (reader.Read())
tables.Add(reader.GetString(0));
foreach (var expected in new[]
{
"__localdb_meta", "__localdb_oplog", "__localdb_peer_state",
"__localdb_row_version", "__localdb_applying", "__localdb_dead_letter"
})
Assert.Contains(expected, tables);
Assert.Equal(1, ScalarLong(conn,
"SELECT count(*) FROM sqlite_master WHERE type='index' AND name='__localdb_oplog_hlc'"));
}
[Fact]
public void EnsureCreated_IsIdempotent()
{
using var conn = Open();
LocalDbSchema.EnsureCreated(conn);
LocalDbSchema.EnsureCreated(conn);
Assert.Equal(1, ScalarLong(conn, "SELECT COUNT(*) FROM __localdb_meta"));
Assert.Equal(1, ScalarLong(conn, "SELECT COUNT(*) FROM __localdb_applying"));
Assert.Equal(1, ScalarLong(conn, "SELECT COUNT(*) FROM __localdb_peer_state"));
}
[Fact]
public void Meta_NodeId_MintedOnceAndStable()
{
string first;
using (var conn = Open())
{
LocalDbSchema.EnsureCreated(conn);
first = ScalarString(conn, "SELECT node_id FROM __localdb_meta WHERE id=1");
}
using (var conn = Open())
{
LocalDbSchema.EnsureCreated(conn);
var second = ScalarString(conn, "SELECT node_id FROM __localdb_meta WHERE id=1");
Assert.Equal(first, second);
}
Assert.True(Guid.TryParse(first, out _));
}
[Fact]
public void Applying_SeededWithZeroRow()
{
using var conn = Open();
LocalDbSchema.EnsureCreated(conn);
Assert.Equal(0, ScalarLong(conn, "SELECT applying FROM __localdb_applying WHERE id=1"));
}
[Fact]
public void ReadMeta_ReturnsNodeIdAndHighWater()
{
using var conn = Open();
LocalDbSchema.EnsureCreated(conn);
var (nodeId, highWater) = LocalDbSchema.ReadMeta(conn);
Assert.True(Guid.TryParse(nodeId, out _));
Assert.Equal(0, highWater);
}
[Fact]
public void FlushHlcHighWater_RoundTrips()
{
using var conn = Open();
LocalDbSchema.EnsureCreated(conn);
LocalDbSchema.FlushHlcHighWater(conn, 123_456_789L);
var (_, highWater) = LocalDbSchema.ReadMeta(conn);
Assert.Equal(123_456_789L, highWater);
}
}