Strengthen live event-read test: assert well-formed parsed events
ReadEventsAsync verified to return real, parsed events against the local 2020 server (e.g. User.Write with 18 properties) — the row parser (HistorianEventRowProtocol v9) is wired and works. The prior test only asserted NotNull with a stale "row format not yet decoded" comment. - Renamed to ReadEventsAsync_AgainstLocalHistorian_ReturnsWellFormedEvents. - Widened the window to 30 days (robust against a quiet recent window). - Asserts NotEmpty + per-event well-formedness (non-empty Type, non-null Properties, EventTimeUtc within the queried window) — matching the ReadRawAsync test's NotEmpty style. - Documents the known limitation: enumeration stops at the first benign `type=4 code=85` soft-terminal, so this verifies parsing correctness rather than exhaustive retrieval (draining all rows needs the code-85 decode, a capture task). Passes live (1 event over 30 days). Non-live unit suite unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -211,7 +211,7 @@ public sealed class HistorianClientIntegrationTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ReadEventsAsync_AgainstLocalHistorian_DoesNotThrow()
|
public async Task ReadEventsAsync_AgainstLocalHistorian_ReturnsWellFormedEvents()
|
||||||
{
|
{
|
||||||
string? host = Environment.GetEnvironmentVariable("HISTORIAN_HOST");
|
string? host = Environment.GetEnvironmentVariable("HISTORIAN_HOST");
|
||||||
if (string.IsNullOrWhiteSpace(host) || !string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase) || !OperatingSystem.IsWindows())
|
if (string.IsNullOrWhiteSpace(host) || !string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase) || !OperatingSystem.IsWindows())
|
||||||
@@ -227,18 +227,28 @@ public sealed class HistorianClientIntegrationTests
|
|||||||
});
|
});
|
||||||
|
|
||||||
DateTime endUtc = DateTime.UtcNow;
|
DateTime endUtc = DateTime.UtcNow;
|
||||||
DateTime startUtc = endUtc - TimeSpan.FromDays(7);
|
DateTime startUtc = endUtc - TimeSpan.FromDays(30);
|
||||||
|
|
||||||
// The event-row WCF wire format is not yet decoded; this test verifies the chain
|
// The full chain (ValCl + Open2 + Retr.IsOriginalAllowed + Retr.StartEventQuery +
|
||||||
// (ValCl + Open2 + Retr.IsOriginalAllowed + Retr.StartEventQuery) reaches the server
|
// GetNextEventQueryResultBuffer + HistorianEventRowProtocol.Parse) returns real, parsed
|
||||||
// without throwing. An empty event list is acceptable until row parsing is wired.
|
// events. Requires the local store to hold events in the window — System-Platform
|
||||||
|
// alarm/user-write events are present on a working Historian. NOTE: enumeration currently
|
||||||
|
// stops at the first benign `type=4 code=85` soft-terminal, so this verifies parsing
|
||||||
|
// correctness rather than exhaustive retrieval (decoding code 85 to drain all rows is a
|
||||||
|
// separate capture task).
|
||||||
List<AVEVA.Historian.Client.Models.HistorianEvent> events = [];
|
List<AVEVA.Historian.Client.Models.HistorianEvent> events = [];
|
||||||
await foreach (AVEVA.Historian.Client.Models.HistorianEvent evt in client.ReadEventsAsync(startUtc, endUtc, CancellationToken.None))
|
await foreach (AVEVA.Historian.Client.Models.HistorianEvent evt in client.ReadEventsAsync(startUtc, endUtc, CancellationToken.None))
|
||||||
{
|
{
|
||||||
events.Add(evt);
|
events.Add(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.NotNull(events);
|
Assert.NotEmpty(events);
|
||||||
|
Assert.All(events, evt =>
|
||||||
|
{
|
||||||
|
Assert.False(string.IsNullOrWhiteSpace(evt.Type)); // e.g. "User.Write", "Alarm.Set"
|
||||||
|
Assert.NotNull(evt.Properties);
|
||||||
|
Assert.InRange(evt.EventTimeUtc, startUtc - TimeSpan.FromDays(1), endUtc + TimeSpan.FromDays(1));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
Reference in New Issue
Block a user