using ZB.MOM.WW.ScadaBridge.AuditLog.Site; namespace ZB.MOM.WW.ScadaBridge.AuditLog.Tests.Site; /// /// Eager startup validation for /// (arch-review 08 round 2 NF4). The site hot-path writer's channel/batch/flush /// knobs must be positive or the background writer task cannot make progress; /// an empty DatabasePath would leave the SQLite writer with nowhere to go. /// BacklogPollIntervalSeconds is deliberately NOT validated — a /// non-positive value has a documented fall-back-to-30s contract. /// public class SqliteAuditWriterOptionsValidatorTests { [Fact] public void DefaultOptions_AreValid() { var validator = new SqliteAuditWriterOptionsValidator(); Assert.True(validator.Validate(null, new SqliteAuditWriterOptions()).Succeeded); } [Fact] public void EmptyDatabasePath_Fails() { var validator = new SqliteAuditWriterOptionsValidator(); var result = validator.Validate(null, new SqliteAuditWriterOptions { DatabasePath = "" }); Assert.False(result.Succeeded); Assert.Contains(result.Failures!, f => f.Contains(nameof(SqliteAuditWriterOptions.DatabasePath), StringComparison.Ordinal)); } [Fact] public void ZeroChannelCapacity_Fails() { var validator = new SqliteAuditWriterOptionsValidator(); var result = validator.Validate(null, new SqliteAuditWriterOptions { ChannelCapacity = 0 }); Assert.False(result.Succeeded); Assert.Contains(result.Failures!, f => f.Contains(nameof(SqliteAuditWriterOptions.ChannelCapacity), StringComparison.Ordinal)); } [Fact] public void ZeroBatchSize_Fails() { var validator = new SqliteAuditWriterOptionsValidator(); var result = validator.Validate(null, new SqliteAuditWriterOptions { BatchSize = 0 }); Assert.False(result.Succeeded); Assert.Contains(result.Failures!, f => f.Contains(nameof(SqliteAuditWriterOptions.BatchSize), StringComparison.Ordinal)); } [Fact] public void ZeroFlushInterval_Fails() { var validator = new SqliteAuditWriterOptionsValidator(); var result = validator.Validate(null, new SqliteAuditWriterOptions { FlushIntervalMs = 0 }); Assert.False(result.Succeeded); Assert.Contains(result.Failures!, f => f.Contains(nameof(SqliteAuditWriterOptions.FlushIntervalMs), StringComparison.Ordinal)); } [Theory] [InlineData(0)] [InlineData(-1)] public void NonPositiveBacklogPollInterval_StillValid(int value) { // Documented fall-back-to-30s contract — must NOT be rejected. var validator = new SqliteAuditWriterOptionsValidator(); Assert.True(validator.Validate(null, new SqliteAuditWriterOptions { BacklogPollIntervalSeconds = value }).Succeeded); } }