80 lines
3.6 KiB
C#
80 lines
3.6 KiB
C#
using System.Net;
|
|
using System.Text.Json.Nodes;
|
|
using MoShiro.Backend.Application;
|
|
using MoShiro.Protocol;
|
|
using MoShiro.TestSupport;
|
|
|
|
namespace MoShiro.Backend.Tests;
|
|
|
|
/// <summary>定时重启:默认开、北京时间 04:30;节点连上时补发,管理端改了设置马上群发,关掉就发空。</summary>
|
|
public sealed class ScheduleTests : IClassFixture<BackendFixture>
|
|
{
|
|
private readonly BackendFixture _backend;
|
|
|
|
public ScheduleTests(BackendFixture backend)
|
|
{
|
|
_backend = backend;
|
|
}
|
|
|
|
private async Task PatchAsync(JsonObject settings)
|
|
{
|
|
using HttpResponseMessage response = await _backend.Admin.PatchAsync("/api/admin/settings", BackendFixture.Json(settings, "application/merge-patch+json"));
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
private static Task<bool> LastIs(AgentSimulator agent, string? restartAt) =>
|
|
Task.FromResult(agent.Schedules.ToArray() is { Length: > 0 } all && all[^1].RestartAt == restartAt);
|
|
|
|
[Fact]
|
|
public void Format_WritesTheOffsetTheNodeParses()
|
|
{
|
|
Assert.Equal("04:30+08:00", ScheduleService.Format(4, 30, 480));
|
|
Assert.Equal("00:00+00:00", ScheduleService.Format(0, 0, 0));
|
|
Assert.Equal("23:05-05:30", ScheduleService.Format(23, 5, -330));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ANewNode_GetsTheDefaultSchedule_AndLaterChangesAreBroadcast()
|
|
{
|
|
await using AgentSimulator agent = await _backend.ConnectAgentAsync();
|
|
await BackendFixture.EventuallyAsync(() => LastIs(agent, "04:30+08:00"), because: "defaults: on, 04:30 Beijing time, sent right after hello");
|
|
|
|
try
|
|
{
|
|
await PatchAsync(new JsonObject { ["fleet.restart_hour"] = 3, ["fleet.restart_minute"] = 5, ["fleet.restart_utc_offset_minutes"] = 0 });
|
|
await BackendFixture.EventuallyAsync(() => LastIs(agent, "03:05+00:00"), because: "a changed time is pushed to online nodes");
|
|
|
|
await PatchAsync(new JsonObject { ["fleet.restart_enabled"] = false });
|
|
await BackendFixture.EventuallyAsync(() => LastIs(agent, null), because: "switching it off sends an empty schedule");
|
|
|
|
// 关着的时候新连上的节点也拿到「关」
|
|
await using AgentSimulator late = await _backend.ConnectAgentAsync();
|
|
await BackendFixture.EventuallyAsync(() => LastIs(late, null), because: "a node connecting while it is off is told so");
|
|
}
|
|
finally
|
|
{
|
|
await PatchAsync(new JsonObject { ["fleet.restart_enabled"] = true, ["fleet.restart_hour"] = 4, ["fleet.restart_minute"] = 30, ["fleet.restart_utc_offset_minutes"] = 480 });
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task BadValues_AreRefused()
|
|
{
|
|
using HttpResponseMessage response = await _backend.Admin.PatchAsync("/api/admin/settings",
|
|
BackendFixture.Json(new JsonObject { ["fleet.restart_hour"] = 24, ["fleet.restart_minute"] = 60, ["fleet.restart_utc_offset_minutes"] = 900 }, "application/merge-patch+json"));
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DefaultLineTemplates_IncludeTheConnectTimings()
|
|
{
|
|
using HttpResponseMessage response = await _backend.Admin.GetAsync("/api/admin/tasks");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
JsonArray items = JsonNode.Parse(await response.Content.ReadAsStringAsync())!["items"]!.AsArray();
|
|
string[] kinds = [.. items.Select(i => i!["kind"]!.GetValue<string>())];
|
|
Assert.Contains("tcp_connect", kinds);
|
|
Assert.Contains("quic_ping", kinds);
|
|
Assert.Contains("tcp_ping", kinds);
|
|
}
|
|
}
|