Files
histsdk/tests/AVEVA.Historian.Client.Tests/HistorianWcfRevisionProbeTests.cs
Joseph Doherty 6b385441c1 D2 follow-up: RTag2 doesn't cascade client identity to Trx
Tested hypothesis (1) from the plan: add RTag2(CM_EVENT tag id) to the
priming chain before AddNonStreamValuesBegin2.

Result:
- RTag2 itself succeeds: returns 25-byte response
  (01000000000100000001EE39C30EDCDC010100000000000000), no error buffer.
- But AddNonStreamValuesBegin2 still fails with the same
  04 33 00 00 00 (UnknownClient = 51) for all four handle formats.

So RTag2 on /Hist isn't the cross-service registration trigger we need
for /Trx. Plan doc updated with the result + next-session ordered
probes (try IStorageServiceContract, then IL walk CClientCommon,
then server-side decompile as last resort).

Probe orchestrator now also performs the RTag2 step so the test gives
one-shot diagnostic visibility of both calls.

178/178 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 02:54:52 -04:00

62 lines
2.8 KiB
C#

using System.Runtime.Versioning;
using AVEVA.Historian.Client;
using AVEVA.Historian.Client.Models;
using AVEVA.Historian.Client.Wcf;
using Xunit.Abstractions;
namespace AVEVA.Historian.Client.Tests;
/// <remarks>
/// Probes the SDK-direct WCF revision-write path (D2 new path). Calls
/// <c>AddNonStreamValuesBegin</c> through <see cref="HistorianWcfRevisionOrchestrator"/>
/// against the live local Historian and surfaces what the server returns. The
/// underlying native wrapper is gated client-side by err 129 TagNotFoundInCache;
/// this test bypasses the wrapper entirely and asks the SERVER directly. Gated on
/// HISTORIAN_HOST=localhost; skips otherwise.
/// </remarks>
[SupportedOSPlatform("windows")]
public sealed class HistorianWcfRevisionProbeTests
{
private readonly ITestOutputHelper _output;
public HistorianWcfRevisionProbeTests(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public async Task AddNonStreamValuesBegin_ProbeReturnsServerResult()
{
string? host = Environment.GetEnvironmentVariable("HISTORIAN_HOST");
if (string.IsNullOrWhiteSpace(host) || !string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase) || !OperatingSystem.IsWindows())
{
return;
}
HistorianClientOptions options = new()
{
Host = host,
IntegratedSecurity = true,
Transport = HistorianTransport.LocalPipe,
};
HistorianWcfRevisionOrchestrator orchestrator = new(options);
HistorianRevisionProbeResult result = await orchestrator.ProbeBeginAsync(CancellationToken.None);
_output.WriteLine($"OpenSucceeded: {result.OpenSucceeded}");
_output.WriteLine($"ClientHandle: {result.ClientHandle}");
_output.WriteLine($"StorageSessionId: {result.StorageSessionId}");
_output.WriteLine($"TrxInterfaceVersion: {result.TrxInterfaceVersion} (rc={result.TrxInterfaceVersionReturnCode}) ex={result.TrxInterfaceVersionException}");
_output.WriteLine($"RTag2Succeeded: {result.RTag2Succeeded} OutHex={result.RTag2OutHex} ErrHex={result.RTag2ErrorHex} Ex={result.RTag2Exception}");
_output.WriteLine($"BeginSucceeded: {result.BeginSucceeded}");
_output.WriteLine($"BeginTransactionId: {result.BeginTransactionId}");
foreach (HistorianRevisionBeginAttempt attempt in result.BeginAttempts)
{
_output.WriteLine($" attempt[{attempt.HandleLabel}] handle={attempt.HandleSent} ok={attempt.Succeeded} tx={attempt.TransactionId} err={attempt.ErrorHex} ex={attempt.Exception}");
}
Assert.True(result.OpenSucceeded, "Auth chain failed; revision probe never reached the Trx endpoint.");
// Don't assert BeginSucceeded — we're surfacing whatever the server says, not requiring success.
}
}