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]
|
||||
public async Task ReadEventsAsync_AgainstLocalHistorian_DoesNotThrow()
|
||||
public async Task ReadEventsAsync_AgainstLocalHistorian_ReturnsWellFormedEvents()
|
||||
{
|
||||
string? host = Environment.GetEnvironmentVariable("HISTORIAN_HOST");
|
||||
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 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
|
||||
// (ValCl + Open2 + Retr.IsOriginalAllowed + Retr.StartEventQuery) reaches the server
|
||||
// without throwing. An empty event list is acceptable until row parsing is wired.
|
||||
// The full chain (ValCl + Open2 + Retr.IsOriginalAllowed + Retr.StartEventQuery +
|
||||
// GetNextEventQueryResultBuffer + HistorianEventRowProtocol.Parse) returns real, parsed
|
||||
// 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 = [];
|
||||
await foreach (AVEVA.Historian.Client.Models.HistorianEvent evt in client.ReadEventsAsync(startUtc, endUtc, CancellationToken.None))
|
||||
{
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user