Files
MoShiro/backend/tests/MoShiro.Backend.Tests/LinkRuntimeTests.cs
T
justme 57acecdb86
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline was successful
ci/woodpecker/push/e2e Pipeline failed
web: show how long a line has been out of contact
The Backend now keeps the time since a link's control layer was last up, because retries move the control state in and out of backoff and its own timestamp keeps resetting. The overview exposes it as control_down_since and the card shows it next to the lost-contact notice.
2026-10-21 17:16:09 +08:00

29 lines
1.2 KiB
C#

using MoShiro.Backend.Application;
using MoShiro.Protocol;
namespace MoShiro.Backend.Tests;
public sealed class LinkRuntimeTests
{
private static LinkHealth Health(ControlState state) => new() { ListenerId = "agt_l", Control = { State = state } };
[Fact]
public void DownSince_StaysAtTheFirstLostReport_AndClearsWhenTheControlLinkIsUp()
{
var runtime = new LinkRuntime();
runtime.Replace("agt_d", 1_000, [Health(ControlState.Up)]);
Assert.Null(runtime.Get("agt_d", "agt_l", IpVersions.V4)!.DownSinceMs);
runtime.Replace("agt_d", 2_000, [Health(ControlState.Backoff)]);
runtime.Replace("agt_d", 3_000, [Health(ControlState.Dialing)]); // 重试期间状态在退避和拨号之间来回,失联的起点不变
runtime.Replace("agt_d", 4_000, [Health(ControlState.Backoff)]);
Assert.Equal(2_000, runtime.Get("agt_d", "agt_l", IpVersions.V4)!.DownSinceMs);
runtime.MarkDialerOffline("agt_d", 5_000);
Assert.Equal(2_000, runtime.Get("agt_d", "agt_l", IpVersions.V4)!.DownSinceMs);
runtime.Replace("agt_d", 6_000, [Health(ControlState.Up)]);
Assert.Null(runtime.Get("agt_d", "agt_l", IpVersions.V4)!.DownSinceMs);
}
}