b4a03b4baa
CalculationDriverProbe.Opts (Test-Connect) omitted AllowTrailingCommas and ReadCommentHandling that CalculationDriverFactoryExtensions.JsonOptions (spawn) and CalculationDriver.ReinitJsonOptions (in-place ApplyDelta) both set, so a config blob the real deploy path tolerates could fail Test-Connect as "invalid JSON" even though deploying it would succeed. Aligned the three option sets. Also adds CalculationDriverProbeTests.cs, which previously did not exist at all for this driver type's Test-Connect surface. Part of code-reviews/Driver.Calculation/findings.md (-003, -004).
73 lines
2.9 KiB
C#
73 lines
2.9 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Calculation.Tests;
|
|
|
|
/// <summary>
|
|
/// Unit tests for <see cref="CalculationDriverProbe"/> — the Calculation pseudo-driver's Test-Connect
|
|
/// probe (parse-only, since there is no backend to reach).
|
|
/// </summary>
|
|
public sealed class CalculationDriverProbeTests
|
|
{
|
|
private static readonly CalculationDriverProbe Sut = new();
|
|
|
|
[Fact]
|
|
public async Task Empty_config_json_fails()
|
|
{
|
|
var result = await Sut.ProbeAsync("", TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeFalse();
|
|
result.Message.ShouldNotBeNullOrWhiteSpace();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Malformed_json_fails()
|
|
{
|
|
var result = await Sut.ProbeAsync("not json", TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeFalse();
|
|
result.Message.ShouldNotBeNullOrWhiteSpace();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task A_config_with_no_rawTags_array_is_still_valid()
|
|
{
|
|
var result = await Sut.ProbeAsync("{}", TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeTrue(result.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task A_well_formed_rawTags_config_is_valid()
|
|
{
|
|
const string json = """{"rawTags":[{"rawPath":"calc/e/x","tagConfig":"{}","writeIdempotent":false}]}""";
|
|
var result = await Sut.ProbeAsync(json, TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeTrue(result.Message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The probe must not be STRICTER than the real spawn/reinit path: both
|
|
/// <c>CalculationDriverFactoryExtensions.JsonOptions</c> and <c>CalculationDriver.ReinitJsonOptions</c>
|
|
/// set <c>AllowTrailingCommas</c> + <c>ReadCommentHandling.Skip</c>. Before this pin the probe's own
|
|
/// options omitted both, so a config a real deploy would accept could fail Test-Connect as "invalid".
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task Tolerates_trailing_commas_like_the_real_spawn_and_reinit_paths()
|
|
{
|
|
const string json = """{"rawTags":[{"rawPath":"calc/e/x","tagConfig":"{}","writeIdempotent":false},],}""";
|
|
var result = await Sut.ProbeAsync(json, TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeTrue(result.Message);
|
|
}
|
|
|
|
/// <summary>Same parity claim for comments, which the spawn/reinit path also tolerates.</summary>
|
|
[Fact]
|
|
public async Task Tolerates_comments_like_the_real_spawn_and_reinit_paths()
|
|
{
|
|
const string json = """
|
|
{
|
|
// a hand-edited config comment
|
|
"rawTags": []
|
|
}
|
|
""";
|
|
var result = await Sut.ProbeAsync(json, TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
|
result.Ok.ShouldBeTrue(result.Message);
|
|
}
|
|
}
|