fix(ab): share status map + libplctag orphan release, harden confinement guard, pin width-mismatch + DefaultTransport wiring (#568 #569 #580 #585)
- Ab.Transport: AbOpcUaStatusMap is the single AbStatus->OPC UA table; AbCip/AbLegacy mappers delegate. - Remove dead MapCipGeneralStatus / MapPcccStatus / AbLegacy MapException (+ tests). - LibplctagOrphanRelease is one source file (Ab.LibplctagShared) compiled into both drivers. - LibplctagConfinementGuardTests: tokenising comment/literal stripper, block comments, csproj PackageReference guard. - LibplctagStatusTranslationTests: real LibPlcTagException round trip, WrapSync/Wrap OCE pass-through, adapter routes decode via WrapSync. - AbCipTypeMismatchTests: libplctag width-mismatch path (BadTypeMismatch, handle kept, no Degraded, warn once). - Host: AddAbCipDriverDefaults extension + Program.cs source pin for Drivers:AbCip:DefaultTransport. - docs/drivers/AbCip.md: layout rows + benign Degraded-after-outage note. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+22
-2
@@ -32,8 +32,7 @@ public sealed class AbCipDriverDefaultsOptionsTests
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging();
|
||||
services.AddSingleton<ISecretResolver>(new StubSecretResolver());
|
||||
services.AddValidatedOptions<AbCipDriverDefaultsOptions, AbCipDriverDefaultsOptionsValidator>(
|
||||
configuration, AbCipDriverDefaultsOptions.SectionName);
|
||||
services.AddAbCipDriverDefaults(configuration);
|
||||
services.AddOtOpcUaDriverFactories();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
@@ -48,6 +47,27 @@ public sealed class AbCipDriverDefaultsOptionsTests
|
||||
private static AbCipDriver Create(ServiceProvider sp, string json) =>
|
||||
(AbCipDriver)sp.GetRequiredService<DriverFactoryRegistry>().TryGet(DriverTypeNames.AbCip)!("drv-i1", json);
|
||||
|
||||
/// <summary>
|
||||
/// #585 composition-root pin: <c>Program.cs</c> is top-level statements and cannot be booted in a unit test, so
|
||||
/// the registration lives in <see cref="AbCipDriverDefaultsRegistration.AddAbCipDriverDefaults"/> (which every
|
||||
/// test here builds through) and this asserts Program.cs still CALLS it. Deleting the call silently ignores an
|
||||
/// operator's <c>Drivers:AbCip:DefaultTransport</c> pin — every behaviour test above would stay green.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Program_registers_the_node_default_transport()
|
||||
{
|
||||
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "ZB.MOM.WW.OtOpcUa.slnx"))) dir = dir.Parent;
|
||||
dir.ShouldNotBeNull();
|
||||
var program = File.ReadAllText(Path.Combine(dir.FullName, "src", "Server", "ZB.MOM.WW.OtOpcUa.Host", "Program.cs"));
|
||||
|
||||
System.Text.RegularExpressions.Regex.IsMatch(
|
||||
program, @"^builder\.Services\s*\.\s*AddAbCipDriverDefaults\(\s*builder\.Configuration\s*\)\s*;",
|
||||
System.Text.RegularExpressions.RegexOptions.Multiline)
|
||||
.ShouldBeTrue("Program.cs must call builder.Services.AddAbCipDriverDefaults(builder.Configuration), unconditionally " +
|
||||
"(at top level, not inside an if (hasDriver/hasAdmin) block — the probe on admin nodes needs it too)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Absent_section_defaults_to_Native()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user