62 lines
3.2 KiB
C#
62 lines
3.2 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests.Series;
|
|
|
|
/// <summary>
|
|
/// Issue #271, plan PR F4-d — series-level (would-be integration) coverage of
|
|
/// <c>cnc_wrunlockparam</c>. Hardware-gated: the FOCAS driver has no public
|
|
/// simulator (task #222) so the live-controller cases require a real CNC with
|
|
/// parameter-protect on. The CI lane for this assembly runs the unit-test fakes
|
|
/// under <see cref="FocasUnlockTests"/>; this file is a scaffold that runs
|
|
/// against a simulator + matching <c>mock_set_password</c> admin endpoint when
|
|
/// <c>FOCAS_TRUST_WIRE=1</c>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Build-only today: the simulator gate (FOCAS_TRUST_WIRE) skips at runtime so
|
|
/// CI doesn't need the simulator binary. When the simulator's
|
|
/// <c>cnc_wrunlockparam</c> + <c>mock_set_password</c> endpoints land
|
|
/// (<c>docs/v2/implementation/focas-simulator-plan.md</c>) the gated test
|
|
/// becomes a real round-trip.
|
|
/// </remarks>
|
|
[Trait("Category", "Series")]
|
|
public sealed class PasswordUnlockTests
|
|
{
|
|
[Fact]
|
|
public void Single_unlock_retry_path_is_documented()
|
|
{
|
|
// Build-only scaffold — see FocasUnlockTests for the actual fake-backed
|
|
// assertion. The integration version of this test (gated on a FOCAS
|
|
// simulator with mock_set_password) will:
|
|
// 1. Configure the simulator with password "1234".
|
|
// 2. Spin up FocasDriver with FocasDeviceOptions.Password = "1234".
|
|
// 3. Issue a cnc_wrparam against PARAM:1815 — expect Good (unlock applied
|
|
// on connect).
|
|
// 4. Use the simulator's admin endpoint to flip the password to "5678"
|
|
// mid-session (forces EW_PASSWD on the next write).
|
|
// 5. Issue another write — expect EW_PASSWD on attempt 1, then BadUserAccessDenied
|
|
// surfaced because the new password doesn't match the cached one.
|
|
// 6. Reconfigure FocasDeviceOptions.Password = "5678" on a new instance,
|
|
// issue write — expect Good (unlock applied on first connect).
|
|
// For now this test merely asserts the type contract; the simulator is
|
|
// tracked under task #222 + the focas-simulator-plan.md document.
|
|
typeof(IFocasClient).GetMethod(nameof(IFocasClient.UnlockAsync))
|
|
.ShouldNotBeNull();
|
|
// Driver-side records the password redaction invariant.
|
|
var dev = new FocasDeviceOptions("focas://1.2.3.4:8193", Password: "1234");
|
|
dev.ToString().ShouldNotContain("1234");
|
|
}
|
|
|
|
[Fact(Skip = "Hardware-gated — requires the FOCAS simulator with cnc_wrunlockparam + mock_set_password endpoints (task #222 / focas-simulator-plan.md).")]
|
|
public Task Live_simulator_unlock_retry_round_trip()
|
|
{
|
|
// Body deliberately empty — the [Skip] attribute keeps this off the CI lane.
|
|
// When the simulator lands, this test materialises a FocasDriver pointed at
|
|
// the simulator + drives the EW_PASSWD -> unlock -> retry path through real
|
|
// wire calls. See <c>docs/v2/implementation/focas-simulator-plan.md</c>
|
|
// § "FOCAS password unlock" for the simulator-side endpoints.
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|