6b385441c1
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>
62 lines
2.8 KiB
C#
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.
|
|
}
|
|
}
|