test(heidenhain): live gate asserts integer tool leaves keep their runtime type (#867)

Verified read-only on Hermle59 and Hermle70 (iTNC 530): Tool/Number Int64, Tool/Index and Tool/AxisCode Int32.

Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
This commit is contained in:
Joseph Doherty
2026-11-11 13:36:13 -05:00
parent c63233b654
commit 1059eb7885
@@ -85,4 +85,38 @@ public sealed class HeidenhainLiveIntegrationTests
TestContext.Current.SendDiagnosticMessage($"{tags[i].RawPath} = {values[i].Value} (0x{values[i].StatusCode:X8})");
values[0].StatusCode.ShouldBe(HeidenhainStatus.Good);
}
/// <summary>#867: integer tool leaves must reach clients with their declared runtime type, not Double.</summary>
[Fact]
public async Task Real_control_tool_leaves_keep_integer_types()
{
Assert.SkipWhen(string.IsNullOrWhiteSpace(Host), "HEIDENHAIN_LSV2_HOST not set — real-controller gate skipped.");
var ct = TestContext.Current.CancellationToken;
var tags = new[] { TestTags.Raw("Tool/Number"), TestTags.Raw("Tool/Index"), TestTags.Raw("Tool/AxisCode") };
var options = new HeidenhainDriverOptions
{
Devices = [new HeidenhainDeviceOptions { Host = Host!, Port = Port, DeviceName = "dev1" }],
RawTags = tags,
Access = new HeidenhainAccessOptions { InspectPassword = Environment.GetEnvironmentVariable("OTOPCUA_HEIDENHAIN_INSPECT_PASSWORD") is { Length: > 0 } ? "env:OTOPCUA_HEIDENHAIN_INSPECT_PASSWORD" : null },
};
await using var driver = new HeidenhainDriver(options, "live");
await driver.InitializeAsync("{}", ct);
await driver.SubscribeAsync(tags.Select(t => t.RawPath).ToList(), TimeSpan.FromSeconds(1), ct);
var deadline = DateTime.UtcNow.AddSeconds(30);
IReadOnlyList<Core.Abstractions.DataValueSnapshot> values;
do
{
await Task.Delay(500, ct);
values = await driver.ReadAsync(tags.Select(t => t.RawPath).ToList(), ct);
} while (values.Any(v => v.StatusCode != HeidenhainStatus.Good) && DateTime.UtcNow < deadline);
var expected = new[] { typeof(long), typeof(int), typeof(int) };
for (var i = 0; i < tags.Length; i++)
{
TestContext.Current.SendDiagnosticMessage($"{tags[i].RawPath} = {values[i].Value} ({values[i].Value?.GetType().Name}) (0x{values[i].StatusCode:X8})");
if (values[i].StatusCode == HeidenhainStatus.Good)
values[i].Value!.GetType().ShouldBe(expected[i]);
}
values.Count(v => v.StatusCode == HeidenhainStatus.Good).ShouldBeGreaterThan(0);
}
}