using AVEVA.Historian.Client.Protocol; using AVEVA.Historian.Client.Wcf; namespace AVEVA.Historian.Client.Tests; public sealed class WcfRuntimeParameterProtocolTests { // GETRP pRequestBuff captured from the native client for GetRuntimeParameter("HistorianVersion") // via scripts/Capture-RuntimeParam.ps1 + instrument-wcf-writemessage: // 54 67 01 00 signature(0x6754) + version(1) // 01 00 00 00 name count = 1 // 10 00 00 00 char count = 16 // UTF-16LE "HistorianVersion" private const string CaptureRequestHex = "54670100010000001000000048006900730074006F007200690061006E00560065007200730069006F006E00"; // GETRP pResponseBuff captured from the paired GETRPResponse (instrument-wcf-readmessage): // 01 00 version = 1 // 01 00 00 00 result count = 1 // 43 CRetVariant type 0x43 (VT_BSTR) // 1A 00 payload length = 26 (= charCount field + string bytes) // 0C 00 char count = 12 // UTF-16LE "20,0,000,000" private const string CaptureResponseHex = "010001000000431A000C00320030002C0030002C003000300030002C00300030003000"; [Fact] public void SerializeRequestMatchesInstrumentedNativeRequestBuffer() { byte[] actual = HistorianRuntimeParameterProtocol.SerializeRequest("HistorianVersion"); Assert.Equal(Convert.FromHexString(CaptureRequestHex), actual); } [Fact] public void ParseSingleStringResultReadsTheCapturedResponseValue() { byte[] response = Convert.FromHexString(CaptureResponseHex); string? value = HistorianRuntimeParameterProtocol.ParseSingleStringResult(response); Assert.Equal("20,0,000,000", value); } [Fact] public void ParseSingleStringResultReturnsNullForZeroResultCount() { // version(1) + result count(0) byte[] empty = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00]; Assert.Null(HistorianRuntimeParameterProtocol.ParseSingleStringResult(empty)); } [Fact] public void ParseSingleStringResultThrowsForUncapturedVariantType() { // version(1) + count(1) + a non-string variant marker (0x03, VT_I4 — not captured). byte[] buffer = [0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00]; Assert.Throws( () => HistorianRuntimeParameterProtocol.ParseSingleStringResult(buffer)); } }