test(grpc): write-reuse + read-on-write-session probe (one-vs-two-kind decider)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using AVEVA.Historian.Client.Grpc;
|
using AVEVA.Historian.Client.Grpc;
|
||||||
using AVEVA.Historian.Client.Models;
|
using AVEVA.Historian.Client.Models;
|
||||||
|
using AVEVA.Historian.Client.Wcf;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace AVEVA.Historian.Client.Tests;
|
namespace AVEVA.Historian.Client.Tests;
|
||||||
@@ -110,8 +111,70 @@ public sealed class HandshakeReuseSpikeTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (A) WRITE REUSE VALIDITY: one externally-opened 0x401 (write-enabled) session, N writes on it via
|
||||||
|
// RunWriteOnSession — NO Create()/handshake per write. If the server rejects reusing a write session,
|
||||||
|
// write #2 throws -> RED finding. Both succeed -> GREEN (write-reuse is sound). Bounded writes to the
|
||||||
|
// sandbox tag ONLY; latency LOGGED, success ASSERTED.
|
||||||
|
[Fact]
|
||||||
|
public void WriteEnabledSession_RunsTwoWrites_AllSucceed()
|
||||||
|
{
|
||||||
|
if (!TryGetWriteEnv(out string host, out string sandboxTag)) return;
|
||||||
|
HistorianClientOptions options = BuildOptions(host);
|
||||||
|
using HistorianGrpcConnection connection = HistorianGrpcChannelFactory.Create(options);
|
||||||
|
HistorianGrpcHandshake.Session session = OpenWriteSession(options, connection);
|
||||||
|
var writer = new HistorianGrpcHistoricalWriteOrchestrator(options);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
|
bool ok = writer.RunWriteOnSession(connection, session, sandboxTag,
|
||||||
|
new[] { new HistorianHistoricalValue(DateTime.UtcNow.AddSeconds(-i), 1.0 + i, OpcQuality: 192) },
|
||||||
|
CancellationToken.None);
|
||||||
|
sw.Stop();
|
||||||
|
_output.WriteLine($"reused-write[{i}] = {sw.ElapsedMilliseconds} ms, ok={ok}");
|
||||||
|
Assert.True(ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (B) READ-ON-WRITE-SESSION PROBE: can a 0x401 (write-enabled) session ALSO serve a raw read? Decides
|
||||||
|
// the pool shape — ONE-KIND (a single write-enabled session serves both reads and writes) vs TWO-KIND
|
||||||
|
// (separate read 0x402 / write 0x401 sessions). The kind is LOGGED, never asserted; any failure is
|
||||||
|
// swallowed (a rejection is itself the finding, not a test failure). READ-ONLY here.
|
||||||
|
[Fact]
|
||||||
|
public void WriteEnabledSession_AlsoServesRead_RecordsKind()
|
||||||
|
{
|
||||||
|
if (!TryGetWriteEnv(out string host, out string sandboxTag)) return;
|
||||||
|
HistorianClientOptions options = BuildOptions(host);
|
||||||
|
using HistorianGrpcConnection connection = HistorianGrpcChannelFactory.Create(options);
|
||||||
|
HistorianGrpcHandshake.Session session = OpenWriteSession(options, connection);
|
||||||
|
(DateTime startUtc, DateTime endUtc) = LastSevenDays();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<HistorianSample> rows = new HistorianGrpcReadOrchestrator(options)
|
||||||
|
.RunRawQueryOnSession(connection, session.ClientHandle, sandboxTag, startUtc, endUtc, 8, CancellationToken.None);
|
||||||
|
_output.WriteLine($"read-on-0x401 -> OK (rows={rows.Count}) => ONE-KIND pool (write-enabled serves reads)");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_output.WriteLine($"read-on-0x401 -> FAILED ({ex.GetType().Name}) => TWO-KIND pool (separate read/write)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- helpers ---
|
// --- helpers ---
|
||||||
|
|
||||||
|
private static bool TryGetWriteEnv(out string host, out string sandboxTag)
|
||||||
|
{
|
||||||
|
host = Environment.GetEnvironmentVariable("HISTORIAN_GRPC_HOST") ?? "";
|
||||||
|
sandboxTag = Environment.GetEnvironmentVariable("HISTORIAN_WRITE_SANDBOX_TAG") ?? "";
|
||||||
|
return !string.IsNullOrWhiteSpace(host)
|
||||||
|
&& !string.IsNullOrWhiteSpace(sandboxTag)
|
||||||
|
&& !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HISTORIAN_USER"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HistorianGrpcHandshake.Session OpenWriteSession(HistorianClientOptions o, HistorianGrpcConnection c)
|
||||||
|
=> HistorianGrpcHandshake.OpenSession(c, o, CancellationToken.None,
|
||||||
|
connectionMode: HistorianWcfAuthChainHelper.NativeIntegratedWriteEnabledConnectionMode);
|
||||||
|
|
||||||
private static bool TryGetEnv(out string host, out string tag)
|
private static bool TryGetEnv(out string host, out string tag)
|
||||||
{
|
{
|
||||||
host = Environment.GetEnvironmentVariable("HISTORIAN_GRPC_HOST") ?? "";
|
host = Environment.GetEnvironmentVariable("HISTORIAN_GRPC_HOST") ?? "";
|
||||||
|
|||||||
Reference in New Issue
Block a user