c5df43d594
v2-ci / unit-tests (push) Has been cancelled
The Lane H2 remediation made Periodic(100 ms) the options-class default, but appsettings.json, docker-dev and Program.cs's bad-value fallback all used PerEntry, so effective behaviour never changed and the docs contradicted the shipped config. The options default is now PerEntry; Periodic stays opt-in (<= CommitIntervalMs of crash loss in exchange for throughput). Program.cs now uses ContinuousHistorizationOptions.ResolveCommitMode() so the fallback shares the single DefaultCommitMode constant. docs/Historian.md updated. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
83 lines
3.9 KiB
C#
83 lines
3.9 KiB
C#
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
using ZB.MOM.WW.OtOpcUa.Runtime.Historian;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Historian;
|
|
|
|
/// <summary>
|
|
/// Verifies <see cref="ContinuousHistorizationOptions.Validate"/> self-gates on <c>Enabled</c> and
|
|
/// warns (warn-only, never blocks startup) on the two gated misconfigurations: a blank
|
|
/// <c>OutboxPath</c> while enabled, and a non-positive <c>CommitIntervalMs</c> under
|
|
/// <c>Periodic</c> commit mode. No warning text carries a secret value.
|
|
/// </summary>
|
|
public sealed class ContinuousHistorizationOptionsTests
|
|
{
|
|
/// <summary>A disabled recorder yields no warnings regardless of the other knobs.</summary>
|
|
[Fact]
|
|
public void Disabled_no_warnings()
|
|
=> Assert.Empty(new ContinuousHistorizationOptions { Enabled = false }.Validate());
|
|
|
|
/// <summary>An enabled recorder with a blank outbox directory warns about <c>OutboxPath</c>.</summary>
|
|
[Fact]
|
|
public void Enabled_requires_outbox_path()
|
|
=> Assert.Contains(
|
|
new ContinuousHistorizationOptions { Enabled = true, OutboxPath = "" }.Validate(),
|
|
m => m.Contains("OutboxPath"));
|
|
|
|
/// <summary>Periodic commit mode with a non-positive interval warns about <c>CommitIntervalMs</c>.</summary>
|
|
[Fact]
|
|
public void Periodic_requires_positive_interval()
|
|
=> Assert.Contains(
|
|
new ContinuousHistorizationOptions
|
|
{
|
|
Enabled = true,
|
|
OutboxPath = "x",
|
|
CommitMode = "Periodic",
|
|
CommitIntervalMs = 0,
|
|
}.Validate(),
|
|
m => m.Contains("CommitIntervalMs"));
|
|
|
|
[Fact]
|
|
public void Unparseable_commit_mode_falls_back_to_the_options_default()
|
|
{
|
|
var defaults = new ContinuousHistorizationOptions();
|
|
Assert.Equal(HistorizationCommitMode.PerEntry, defaults.ResolveCommitMode());
|
|
Assert.Equal(ContinuousHistorizationOptions.DefaultCommitMode, new ContinuousHistorizationOptions { CommitMode = "garbage" }.ResolveCommitMode());
|
|
Assert.Equal(Enum.Parse<HistorizationCommitMode>(defaults.CommitMode), new ContinuousHistorizationOptions { CommitMode = "garbage" }.ResolveCommitMode());
|
|
Assert.Equal(HistorizationCommitMode.Periodic, new ContinuousHistorizationOptions { CommitMode = "periodic" }.ResolveCommitMode());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pins the shipped defaults, which are a tuned set rather than arbitrary numbers: the drain is
|
|
/// bounded-parallel over an in-memory peek (so a wide <c>DrainBatchSize</c> is cheap and a narrow
|
|
/// one lets the outbox fill during a gateway hiccup), <c>Capacity</c> is the #538 disk backstop,
|
|
/// and <c>MaxWriteAttempts</c> is the #538 poison-tag budget. The shipped
|
|
/// <c>appsettings.json</c> restates these values, so a silent drift between the two is exactly
|
|
/// what this test exists to catch.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Defaults_are_the_documented_batch_era_values()
|
|
{
|
|
var options = new ContinuousHistorizationOptions();
|
|
|
|
Assert.Equal("PerEntry", options.CommitMode); // matches appsettings.json, docker-dev and the bad-value fallback (lmxopcua#776)
|
|
Assert.Equal(100, options.CommitIntervalMs);
|
|
Assert.Equal(1024, options.DrainBatchSize);
|
|
Assert.Equal(8, options.DrainConcurrency);
|
|
Assert.Equal(500_000, options.Capacity);
|
|
Assert.Equal(5, options.MaxWriteAttempts);
|
|
Assert.True(options.CaptureWhilePrimaryUnreachable); // Gitea #672
|
|
}
|
|
|
|
/// <summary>A fully-configured enabled recorder produces no warnings.</summary>
|
|
[Fact]
|
|
public void Valid_config_is_clean()
|
|
=> Assert.Empty(
|
|
new ContinuousHistorizationOptions
|
|
{
|
|
Enabled = true,
|
|
OutboxPath = "/var/lib/otopcua/historization",
|
|
CommitMode = "PerEntry",
|
|
}.Validate());
|
|
}
|