using Shouldly;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.Driver.S7.Cli.Tests;
///
/// Driver.S7.Cli-011: the subscribe command's OnDataChange handler must
/// serialize its console writes through a lock so that overlapping poll ticks (which
/// arrive on a background thread) cannot interleave partial lines on the output stream.
/// Mirrors the pattern from the Modbus CLI subscribe command.
///
[Trait("Category", "Unit")]
public sealed class SubscribeCommandWriteLockTests
{
private static readonly string CommandsDir = LocateCommandsDir();
///
/// Verifies that SubscribeCommand uses a lock in the OnDataChange handler to
/// prevent interleaved console writes from overlapping poll ticks.
///
[Fact]
public void SubscribeCommand_OnDataChange_uses_write_lock()
{
// Driver.S7.Cli-011: the handler writes via console.Output.WriteLine on a
// background poll thread; concurrent ticks must be serialised with a lock
// to prevent partial-line interleaving.
var source = File.ReadAllText(Path.Combine(CommandsDir, "SubscribeCommand.cs"));
source.ShouldContain("lock (writeLock)");
}
private static string LocateCommandsDir()
{
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("Could not find solution root (ZB.MOM.WW.OtOpcUa.slnx).");
return Path.Combine(
dir!.FullName, "src", "Drivers", "Cli", "ZB.MOM.WW.OtOpcUa.Driver.S7.Cli", "Commands");
}
}