fix(alarms): fetch/poll ceilings; truncation-semantics docs; log-format conformance
This commit is contained in:
@@ -57,6 +57,51 @@ public sealed class MxAccessStaSessionTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The alarm poll cadence comes from the launcher-set environment
|
||||
/// variable; a missing, unparseable, or out-of-range value must fall
|
||||
/// back to the 500 ms default rather than throw. The ceiling matters as
|
||||
/// much as the floor: <see cref="int.MaxValue"/> milliseconds is ~24
|
||||
/// days, which silently disables alarm polling altogether.
|
||||
/// </summary>
|
||||
/// <param name="environmentValue">Raw environment value under test.</param>
|
||||
/// <param name="expectedMilliseconds">Expected resolved cadence, in milliseconds.</param>
|
||||
[Theory]
|
||||
[InlineData(null, 500)]
|
||||
[InlineData("", 500)]
|
||||
[InlineData("not-a-number", 500)]
|
||||
[InlineData("0", 500)]
|
||||
[InlineData("-1", 500)]
|
||||
[InlineData("99", 500)]
|
||||
[InlineData("100", 100)]
|
||||
[InlineData("250", 250)]
|
||||
[InlineData("3600000", 3600000)]
|
||||
[InlineData("3600001", 500)]
|
||||
[InlineData("2147483647", 500)]
|
||||
public void ResolveAlarmPollInterval_WithEnvironmentValue_FallsBackToDefaultWhenOutOfRange(
|
||||
string? environmentValue,
|
||||
int expectedMilliseconds)
|
||||
{
|
||||
string? original = Environment.GetEnvironmentVariable(
|
||||
MxAccessStaSession.AlarmPollIntervalEnvironmentVariableName);
|
||||
try
|
||||
{
|
||||
Environment.SetEnvironmentVariable(
|
||||
MxAccessStaSession.AlarmPollIntervalEnvironmentVariableName,
|
||||
environmentValue);
|
||||
|
||||
Assert.Equal(
|
||||
TimeSpan.FromMilliseconds(expectedMilliseconds),
|
||||
MxAccessStaSession.ResolveAlarmPollInterval());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.SetEnvironmentVariable(
|
||||
MxAccessStaSession.AlarmPollIntervalEnvironmentVariableName,
|
||||
original);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that StartAsync creates the MXAccess COM object and attaches the event sink on the STA thread.
|
||||
/// </summary>
|
||||
|
||||
@@ -496,6 +496,11 @@ public sealed class WnWrapAlarmConsumerXmlTests
|
||||
[InlineData("63", 1024)]
|
||||
[InlineData("64", 64)]
|
||||
[InlineData("4096", 4096)]
|
||||
[InlineData("65536", 65536)]
|
||||
// Above the ceiling: the x86 worker materializes the whole reply as one
|
||||
// BSTR plus an XmlDocument, so an unbounded cap is an OOM on the STA.
|
||||
[InlineData("65537", 1024)]
|
||||
[InlineData("2147483647", 1024)]
|
||||
public void ResolveMaxAlarmsPerFetch_WithEnvironmentValue_FallsBackToDefaultWhenUnusable(
|
||||
string? environmentValue,
|
||||
int expected)
|
||||
@@ -518,6 +523,32 @@ public sealed class WnWrapAlarmConsumerXmlTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A galaxy parked above the cap truncates on every poll, so the
|
||||
/// warning must be throttled: two truncated polls inside one interval
|
||||
/// produce exactly one line, and the next one only after the full
|
||||
/// interval has elapsed.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void ShouldWarnTruncation_ThrottlesConsecutiveTruncatedPollsToOneWarningPerInterval()
|
||||
{
|
||||
// Seeded so the very first truncated poll always warns.
|
||||
const long NeverWarned = -60_000;
|
||||
|
||||
// Poll 1 at t=0: warns, and records t=0 as the last warning.
|
||||
Assert.True(WnWrapAlarmConsumer.ShouldWarnTruncation(0, NeverWarned));
|
||||
|
||||
// Poll 2 half a second later (the default cadence): suppressed.
|
||||
Assert.False(WnWrapAlarmConsumer.ShouldWarnTruncation(500, 0));
|
||||
|
||||
// Still suppressed just shy of the interval...
|
||||
Assert.False(WnWrapAlarmConsumer.ShouldWarnTruncation(59_999, 0));
|
||||
|
||||
// ...and allowed again exactly on it.
|
||||
Assert.True(WnWrapAlarmConsumer.ShouldWarnTruncation(60_000, 0));
|
||||
Assert.True(WnWrapAlarmConsumer.ShouldWarnTruncation(120_000, 60_000));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a well-formed ALARM_RECORDS payload with
|
||||
/// <paramref name="count"/> distinct alarms. GUIDs are the dashless
|
||||
|
||||
Reference in New Issue
Block a user