refactor!: rename the project from Monitor to MoShiro

Namespaces, assemblies, projects and directories, the solution, binaries,
images, systemd units, config paths, environment variables, protocol method
names, the media type and the raw chunk magic all move to MoShiro/moshiro.
Existing data and deployments are not compatible and must be recreated.
Also fix the architecture tests after the solution layout change and make
the update tests independent of their order.
This commit is contained in:
justme committed 2026-10-07 01:49:04 +08:00
1 parent 17b35223aa
commit 83e5120377
309 files changed
+1505 -1499

No files matched your search

@@ -1,7 +1,7 @@
using System.Net;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>积木的公共部分:环境、参数、把行切成列块交出去。</summary>
public abstract class BlockBase : IBlock
@@ -1,6 +1,6 @@
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 一种采集方法(Kind)的两个角色:拨号方(Probe)和监听方(Agent),以及它能不能作为目标任务(Agent 自己探测一个地址,没有对端)运行。
@@ -1,7 +1,7 @@
using System.Net.Sockets;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>批量传输的收发循环(两端共用)。</summary>
internal static class BulkIo
@@ -1,8 +1,8 @@
using System.Net;
using System.Net.Sockets;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 回显积木的行表(拨号方,行的主导方):发出时记 size、t1,回复到达时按序号回填 t4,到点把已经稳定的行切成列块。
@@ -1,9 +1,9 @@
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Authentication;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>什么也不做的监听方:connect 的另一端就是 TCP 监听器本身(接受连接、认证失败就关闭),不需要积木,但需要占一个流编号。</summary>
public sealed class IdleListener : BlockBase
@@ -1,8 +1,8 @@
using System.Diagnostics;
using System.Net;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 单向数据流(UDP train),监听方(Agent,行的主导方):按声明的码率均匀发包,发出的每个包 (seq, size, t_send) 记在按序号的记录里,
@@ -1,9 +1,9 @@
using System.Net;
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 数据面会话:<c>session_id</c> 和密钥(由点对点握手里的 ECDH 派生)。两端的数据面包都用它认证。
@@ -1,4 +1,4 @@
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>节点的单调时钟(微秒):t1…t4、t_send、t_recv 都用它;Probe 和 Agent 各自一个,块头里的时钟锚点把它对应到 UTC。</summary>
public sealed class MonoClock
@@ -1,6 +1,6 @@
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 一侧记录的行:只含这一侧拥有的列(见 <see cref="StreamSpec.ColumnsOf"/>),按连接键(通常是 <c>seq</c>)索引的环形缓冲,
@@ -1,4 +1,4 @@
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>一个运行中的积木:自己的取消令牌和后台任务。Probe 和 Agent 共用。</summary>
public sealed class RunningBlock : IDisposable
@@ -1,8 +1,8 @@
using System.Net;
using System.Text.Json;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>节点的本地硬上限(写在本机配置里,Backend 无法修改)。</summary>
public sealed class NodeLimits
@@ -1,8 +1,8 @@
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>Agent 单调时钟(微秒)与 UTC(毫秒)的对应关系:块头里的时钟锚点。</summary>
public readonly record struct ClockAnchor(long AgentMonoUs, long UtcMs);
@@ -1,8 +1,8 @@
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>Agent 一侧为合并保留的按键记录(由正在运行的积木提供)。</summary>
public interface IRecordSource
@@ -29,7 +29,7 @@ public static class FragmentMerger
StreamSpec? streamSpec = spec.FindStream(stream.Name);
if (streamSpec is null)
{
return Result<IReadOnlyList<RawStream>>.Fail(MonitorErrors.ValidationFailed, $"stream {stream.Name} is not declared by {spec.Id}");
return Result<IReadOnlyList<RawStream>>.Fail(MoShiroErrors.ValidationFailed, $"stream {stream.Name} is not declared by {spec.Id}");
}
Result<RawStream> merged = Join(streamSpec, stream, fragment.Header, records.Records(streamId, stream.Name));
@@ -71,7 +71,7 @@ public static class FragmentMerger
RawColumn? key = probe.Find(spec.Key);
if (key is null || probeColumns.Any(c => probe.Find(c.Name) is null))
{
return Result<RawStream>.Fail(MonitorErrors.ValidationFailed, $"a fragment of stream {spec.Name} needs the columns {string.Join(", ", new[] { spec.Key }.Concat(probeColumns.Select(c => c.Name)))}");
return Result<RawStream>.Fail(MoShiroErrors.ValidationFailed, $"a fragment of stream {spec.Name} needs the columns {string.Join(", ", new[] { spec.Key }.Concat(probeColumns.Select(c => c.Name)))}");
}
return spec.Driver == Side.Probe ? JoinOnProbeRows(spec, probe, key, agent) : JoinOnAgentRows(spec, probe, key, header, agent);
@@ -118,7 +118,7 @@ public static class FragmentMerger
{
if (!TryGetRange(header, out uint from, out uint to))
{
return Result<RawStream>.Fail(MonitorErrors.ValidationFailed, $"a fragment of stream {spec.Name} must declare its sequence range");
return Result<RawStream>.Fail(MoShiroErrors.ValidationFailed, $"a fragment of stream {spec.Name} must declare its sequence range");
}
// 行取自 Agent 的记录:范围内发出过的每一个包都有一行,Probe 没有报告到达的就是丢失
@@ -3,8 +3,8 @@
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="Monitor.Measurement.Tests" />
<InternalsVisibleTo Include="MoShiro.Measurement.Tests" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)../../BannedSymbols.Node.txt" />
<ProjectReference Include="..\Monitor.Protocol\Monitor.Protocol.csproj" />
<ProjectReference Include="..\MoShiro.Protocol\MoShiro.Protocol.csproj" />
</ItemGroup>
</Project>
@@ -5,9 +5,9 @@ using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>拨号方的一条数据面 TCP 连接(已经完成 TLS 和首帧认证)。</summary>
public sealed class TcpLink : IDisposable
@@ -1,8 +1,8 @@
using System.Buffers.Binary;
using System.Net.Sockets;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>内核对一条 TCP 连接的采样(Linux <c>TCP_INFO</c>)。</summary>
public readonly record struct TcpInfoSample(long SrttUs, long RttVarUs, long Cwnd, long TotalRetrans, long SegsOut, long BytesAcked);
@@ -2,9 +2,9 @@ using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>一个通过校验的 UDP 包,交给按 <c>stream_id</c> 登记的处理函数。处理函数在接收循环里同步执行,不能阻塞。</summary>
public readonly ref struct UdpDelivery
@@ -1,7 +1,7 @@
using System.Runtime.InteropServices;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 读出本机的系统名和架构,只用于在面板上展示。故意只取粗粒度的信息:
@@ -1,12 +1,12 @@
using System.Text;
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement;
namespace MoShiro.Measurement;
/// <summary>
/// 节点进程和宿主机更新器之间的文件交换(容器里 <c>/etc/monitor</c>,也就是数据目录):
/// 节点进程和宿主机更新器之间的文件交换(容器里 <c>/etc/moshiro</c>,也就是数据目录):
/// 节点把面板发来的清单和签名写进 <c>update/</c>,把「更新」请求写成 <c>update/apply.request</c>;更新器验签并更新,状态由宿主更新器写在只读挂载的 <c>update-status/status.json</c>。
/// 节点进程不执行任何命令,也不信任清单的内容(验签在宿主机上)。没有安装更新器时目录写不了或没人读,调用只是返回 false。
/// </summary>
@@ -88,7 +88,7 @@ public sealed class UpdateBridge
return null;
}
return JsonSerializer.Deserialize(File.ReadAllBytes(_statusFile), MonitorJsonContext.Default.UpdateStatus);
return JsonSerializer.Deserialize(File.ReadAllBytes(_statusFile), MoShiroJsonContext.Default.UpdateStatus);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or JsonException)
{
@@ -1,4 +1,4 @@
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
[Flags]
public enum Scope
@@ -1,4 +1,4 @@
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>
/// Kind 目录。新增一种采集方法 = 在这里加一个静态字段并放进 <see cref="All"/>;
@@ -1,7 +1,7 @@
using System.Globalization;
using System.Text.Json;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
public enum ParamType
{
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
[JsonConverter(typeof(ProbeIdJsonConverter))]
public readonly record struct ProbeId(string Value)
@@ -7,7 +7,7 @@
<ProjectReference Include="..\..\fleet\src\Fleet.Rpc\Fleet.Rpc.csproj" />
</ItemGroup>
<!--
构建信息:版本来自 $(Version),tag、提交、构建时间来自环境变量 MONITOR_TAG / MONITOR_COMMIT / MONITOR_BUILT_AT
构建信息:版本来自 $(Version),tag、提交、构建时间来自环境变量 MOSHIRO_TAG / MOSHIRO_COMMIT / MOSHIRO_BUILT_AT
(scripts/publish.sh 和 CI 会设置;本地开发不设置就是空,这样本地构建是可重复的、不会每次都重新编译)。
生成一个带常量的源文件,NativeAOT 下不用反射。
-->
@@ -16,14 +16,14 @@
<BuildInfoFile>$(IntermediateOutputPath)BuildInfo.g.cs</BuildInfoFile>
</PropertyGroup>
<ItemGroup>
<BuildInfoLine Include="namespace Monitor.Protocol%3B" />
<BuildInfoLine Include="namespace MoShiro.Protocol%3B" />
<BuildInfoLine Include="/// &lt;summary&gt;这个程序是什么时候、从哪个版本构建出来的(构建时生成)。&lt;/summary&gt;" />
<BuildInfoLine Include="public static class BuildInfo" />
<BuildInfoLine Include="{" />
<BuildInfoLine Include=" public const string Version = &quot;$(Version)&quot;%3B" />
<BuildInfoLine Include=" public const string Tag = &quot;$(MONITOR_TAG)&quot;%3B" />
<BuildInfoLine Include=" public const string Commit = &quot;$(MONITOR_COMMIT)&quot;%3B" />
<BuildInfoLine Include=" public const string BuiltAt = &quot;$(MONITOR_BUILT_AT)&quot;%3B" />
<BuildInfoLine Include=" public const string Tag = &quot;$(MOSHIRO_TAG)&quot;%3B" />
<BuildInfoLine Include=" public const string Commit = &quot;$(MOSHIRO_COMMIT)&quot;%3B" />
<BuildInfoLine Include=" public const string BuiltAt = &quot;$(MOSHIRO_BUILT_AT)&quot;%3B" />
<BuildInfoLine Include="}" />
</ItemGroup>
<WriteLinesToFile File="$(BuildInfoFile)" Lines="@(BuildInfoLine)" Overwrite="true" WriteOnlyWhenDifferent="true" />
@@ -1,9 +1,9 @@
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>Monitor 的错误码(在 Fleet 错误码之上扩展)。REST、JSON-RPC、OpenAPI 共用同一份。</summary>
public static class MonitorErrors
/// <summary>MoShiro 的错误码(在 Fleet 错误码之上扩展)。REST、JSON-RPC、OpenAPI 共用同一份。</summary>
public static class MoShiroErrors
{
public static readonly ErrorCode ValidationFailed = new("validation_failed");
public static readonly ErrorCode BudgetExceeded = new("budget_exceeded");
@@ -1,4 +1,4 @@
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
public static class ProtocolVersion
{
@@ -25,8 +25,8 @@ public static class ProtocolLimits
public const long MaxLineBudgetBitsPerSecond = 100_000;
}
/// <summary>二进制通道号(0–15 属于 Fleet,Monitor 从 16 开始)。</summary>
public static class MonitorChannels
/// <summary>二进制通道号(0–15 属于 Fleet,MoShiro 从 16 开始)。</summary>
public static class MoShiroChannels
{
/// <summary>Agent → Backend:RawChunk(发件箱)。</summary>
public const byte RawChunk = 16;
@@ -35,9 +35,9 @@ public static class MonitorChannels
public const byte ColumnBlock = 17;
}
public static class MonitorCapabilities
public static class MoShiroCapabilities
{
public const string Base = "monitor.v1";
public const string KindsPrefix = "monitor.kinds:";
public const string BlocksPrefix = "monitor.blocks:";
public const string Base = "moshiro.v1";
public const string KindsPrefix = "moshiro.kinds:";
public const string BlocksPrefix = "moshiro.blocks:";
}
@@ -1,4 +1,4 @@
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>CRC-32C(Castagnoli),RawChunk 的完整性校验。</summary>
public static class Crc32c
@@ -2,7 +2,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>Agent 单调时钟与 UTC 的锚点,以及 Probe 时钟相对 Agent 时钟的偏移估计。</summary>
public sealed class ChunkClock
@@ -3,18 +3,18 @@ using System.IO.Compression;
using System.Text.Json;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>
/// RawChunk 的编解码(Probe、Agent、Backend、离线工具共用同一份代码)。
/// 布局:<c>"MNRC" | u8 container_version | u32 crc32c(压缩数据) | Brotli( u32 header_len | header JSON | 各列数据 )</c>。
/// 布局:<c>"MSRC" | u8 container_version | u32 crc32c(压缩数据) | Brotli( u32 header_len | header JSON | 各列数据 )</c>。
/// 列数据:可空列先写有效位图,再写有效值;plain 为无符号 varint(有符号类型用 zigzag),delta 为与上一个有效值之差的 zigzag varint。
/// </summary>
public static class RawChunkCodec
{
private const int PrefixBytes = 4 + 1 + 4;
private static ReadOnlySpan<byte> Magic => "MNRC"u8;
private static ReadOnlySpan<byte> Magic => "MSRC"u8;
/// <summary>压缩之前的正文:<c>u32 header_len | header JSON | 各列数据</c>。布局变化时黄金字节测试会失败,提醒升级版本。</summary>
public static byte[] EncodeBody(RawChunk chunk)
@@ -40,7 +40,7 @@ public static class RawChunkCodec
header.Streams.Add(streamHeader);
}
byte[] headerJson = JsonSerializer.SerializeToUtf8Bytes(header, MonitorJsonContext.Default.RawChunkHeader);
byte[] headerJson = JsonSerializer.SerializeToUtf8Bytes(header, MoShiroJsonContext.Default.RawChunkHeader);
using var body = new MemoryStream();
Span<byte> length = stackalloc byte[4];
@@ -114,7 +114,7 @@ public static class RawChunkCodec
RawChunkHeader? header;
try
{
header = JsonSerializer.Deserialize(plain.AsSpan(4, (int)headerLength), MonitorJsonContext.Default.RawChunkHeader);
header = JsonSerializer.Deserialize(plain.AsSpan(4, (int)headerLength), MoShiroJsonContext.Default.RawChunkHeader);
}
catch (JsonException)
{
@@ -159,7 +159,7 @@ public static class RawChunkCodec
}
private static Result<RawChunk> Corrupt(string message) =>
Result<RawChunk>.Fail(MonitorErrors.RawCorrupt, message);
Result<RawChunk>.Fail(MoShiroErrors.RawCorrupt, message);
private static byte[]? Inflate(ReadOnlySpan<byte> payload)
{
@@ -1,4 +1,4 @@
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>按 <see cref="StreamSpec"/> 逐行构造一个 <see cref="RawStream"/>(用于测试、模拟器和离线工具,不用于节点热路径)。</summary>
public sealed class StreamBuilder
@@ -2,25 +2,25 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>monitor.* 方法名。新增方法 = 在这里定义名称和 params/result,再在组装处加一行 <c>.On(...)</c>。</summary>
public static class MonitorMethods
/// <summary>moshiro.* 方法名。新增方法 = 在这里定义名称和 params/result,再在组装处加一行 <c>.On(...)</c>。</summary>
public static class MoShiroMethods
{
public const string TestRun = "monitor.test.run";
public const string TestCancel = "monitor.test.cancel";
public const string ProbeDisconnect = "monitor.probe.disconnect";
public const string TestStatus = "monitor.test.status";
public const string Event = "monitor.event";
public const string Host = "monitor.host";
public const string UpdateOffer = "monitor.update.offer";
public const string UpdateApply = "monitor.update.apply";
public const string TestRun = "moshiro.test.run";
public const string TestCancel = "moshiro.test.cancel";
public const string ProbeDisconnect = "moshiro.probe.disconnect";
public const string TestStatus = "moshiro.test.status";
public const string Event = "moshiro.event";
public const string Host = "moshiro.host";
public const string UpdateOffer = "moshiro.update.offer";
public const string UpdateApply = "moshiro.update.apply";
// Probe ↔ Agent(点对点会话)
public const string Clock = "monitor.clock";
public const string TestPhase = "monitor.test.phase";
public const string TestPhaseEnd = "monitor.test.phase_end";
public const string TestAbort = "monitor.test.abort";
public const string Clock = "moshiro.clock";
public const string TestPhase = "moshiro.test.phase";
public const string TestPhaseEnd = "moshiro.test.phase_end";
public const string TestAbort = "moshiro.test.abort";
}
public static class AgentEventKinds
@@ -159,7 +159,7 @@ public sealed class ProbeAgentList
public List<AgentEndpoint> Agents { get; set; } = [];
}
/// <summary>注册元数据(Monitor 定义,经 Fleet 的 <c>meta</c> 字段带上来)。</summary>
/// <summary>注册元数据(MoShiro 定义,经 Fleet 的 <c>meta</c> 字段带上来)。</summary>
public sealed class AgentEnrollMeta
{
[JsonPropertyName("probe_tcp_port")]
@@ -220,7 +220,7 @@ public sealed class PlatformInfo
}
/// <summary>
/// 面板给节点的更新清单(<c>monitor.update.offer</c>):<c>manifest</c> 是发布清单的原始文本,<c>signature</c> 是 base64 的签名。
/// 面板给节点的更新清单(<c>moshiro.update.offer</c>):<c>manifest</c> 是发布清单的原始文本,<c>signature</c> 是 base64 的签名。
/// 节点只是把它们原样放进数据目录;验签、拉取、重启都由宿主机上的更新器完成(节点进程不执行任何命令,也不信任清单的内容)。
/// </summary>
public sealed class UpdateOfferParams
@@ -436,7 +436,7 @@ public sealed class LineTaskSet
public List<int> TcpPorts { get; set; } = [];
}
/// <summary><c>monitor.clock</c>:Probe 用它估计与 Agent 单调时钟的偏移(对称往返假设)。</summary>
/// <summary><c>moshiro.clock</c>:Probe 用它估计与 Agent 单调时钟的偏移(对称往返假设)。</summary>
public sealed class ClockParams
{
[JsonPropertyName("probe_mono_us")]
@@ -543,4 +543,4 @@ public static class FragmentKeys
[JsonSerializable(typeof(AgentHelloMeta))]
[JsonSerializable(typeof(AgentHeartbeatExtra))]
[JsonSerializable(typeof(RawChunkHeader))]
public sealed partial class MonitorJsonContext : JsonSerializerContext;
public sealed partial class MoShiroJsonContext : JsonSerializerContext;
@@ -3,7 +3,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>Task = { id, scope, kind, target, params, schedule, enabled }。参数已经按 ParamSpec 校验并补全默认值。</summary>
public sealed class TaskSpec
@@ -79,9 +79,9 @@ public static class TaskSchedule
{
return minutes >= 60
? Result<int?>.Ok(minutes)
: Result<int?>.Fail(MonitorErrors.ValidationFailed, "every:N requires N >= 60 minutes");
: Result<int?>.Fail(MoShiroErrors.ValidationFailed, "every:N requires N >= 60 minutes");
}
return Result<int?>.Fail(MonitorErrors.ValidationFailed, "schedule must be continuous, once or every:<minutes>");
return Result<int?>.Fail(MoShiroErrors.ValidationFailed, "schedule must be continuous, once or every:<minutes>");
}
}
@@ -2,7 +2,7 @@ using System.Buffers.Binary;
using System.Security.Cryptography;
using Fleet.Core;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
/// <summary>
/// 数据面的 TCP 连接(Fleet 之外的线格式)。连接都由 Probe 发起;TLS 是可选的(ClientHello 以 0x16 开头,
@@ -1,7 +1,7 @@
using System.Buffers.Binary;
using System.Security.Cryptography;
namespace Monitor.Protocol;
namespace MoShiro.Protocol;
public enum UdpPacketType : byte
{
@@ -1,8 +1,8 @@
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Measurement.Tests;
namespace MoShiro.Measurement.Tests;
public sealed class MeasurementTests
{
@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit.v3" />
<ProjectReference Include="..\..\Monitor.Measurement\Monitor.Measurement.csproj" />
<ProjectReference Include="..\..\MoShiro.Measurement\MoShiro.Measurement.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
@@ -1,4 +1,4 @@
namespace Monitor.Measurement.Tests;
namespace MoShiro.Measurement.Tests;
public sealed class PlatformDetectorTests
{
@@ -1,8 +1,8 @@
using System.Text.Json;
using Fleet.Core;
using Monitor.Protocol;
using MoShiro.Protocol;
namespace Monitor.Protocol.Tests;
namespace MoShiro.Protocol.Tests;
public sealed class CatalogTests
{
@@ -101,8 +101,8 @@ public sealed class CatalogTests
Tasks = [new TaskSpec { Id = new TaskId("tsk_1"), Kind = "udp_echo", Params = new Dictionary<string, JsonElement> { ["rate_hz"] = Json("10") } }],
Peers = [new PeerSpec { ProbeId = new ProbeId("prb_1"), PublicKey = "AAAA" }],
};
string text = JsonSerializer.Serialize(set, MonitorJsonContext.Default.TaskSet);
TaskSet back = JsonSerializer.Deserialize(text, MonitorJsonContext.Default.TaskSet)!;
string text = JsonSerializer.Serialize(set, MoShiroJsonContext.Default.TaskSet);
TaskSet back = JsonSerializer.Deserialize(text, MoShiroJsonContext.Default.TaskSet)!;
Assert.Contains("\"id\":\"tsk_1\"", text);
Assert.Equal(7, back.Version);
@@ -114,7 +114,7 @@ public sealed class CatalogTests
[Fact]
public void AgentEnrollMeta_ToleratesUnknownFields_AndKeepsDefaults()
{
AgentEnrollMeta meta = JsonSerializer.Deserialize("{\"kinds\":[\"udp_echo\"],\"future\":1}", MonitorJsonContext.Default.AgentEnrollMeta)!;
AgentEnrollMeta meta = JsonSerializer.Deserialize("{\"kinds\":[\"udp_echo\"],\"future\":1}", MoShiroJsonContext.Default.AgentEnrollMeta)!;
Assert.Equal(7443, meta.ProbeTcpPort);
Assert.Equal(["udp_echo"], meta.Kinds);
}
@@ -122,7 +122,7 @@ public sealed class CatalogTests
[Fact]
public void ErrorCodes_AreSnakeCase()
{
foreach (System.Reflection.FieldInfo field in typeof(MonitorErrors).GetFields())
foreach (System.Reflection.FieldInfo field in typeof(MoShiroErrors).GetFields())
{
string value = ((ErrorCode)field.GetValue(null)!).Value;
Assert.Matches("^[a-z]+(_[a-z]+)*$", value);
@@ -5,8 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit.v3" />
<ProjectReference Include="..\..\Monitor.Protocol\Monitor.Protocol.csproj" />
<ProjectReference Include="..\..\..\tests\Monitor.TestSupport\Monitor.TestSupport.csproj" />
<ProjectReference Include="..\..\MoShiro.Protocol\MoShiro.Protocol.csproj" />
<ProjectReference Include="..\..\..\tests\MoShiro.TestSupport\MoShiro.TestSupport.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
@@ -1,10 +1,10 @@
using System.Buffers.Binary;
using System.IO.Compression;
using Fleet.Core;
using Monitor.Protocol;
using Monitor.TestSupport;
using MoShiro.Protocol;
using MoShiro.TestSupport;
namespace Monitor.Protocol.Tests;
namespace MoShiro.Protocol.Tests;
public sealed class RawChunkCodecTests
{
@@ -103,7 +103,7 @@ public sealed class RawChunkCodecTests
byte[] badCrc = (byte[])good.Clone();
badCrc[^1] ^= 0xFF;
Assert.Equal(MonitorErrors.RawCorrupt, RawChunkCodec.Decode(badMagic).Error.Code);
Assert.Equal(MoShiroErrors.RawCorrupt, RawChunkCodec.Decode(badMagic).Error.Code);
Assert.Contains("version", RawChunkCodec.Decode(badVersion).Error.Message);
Assert.Contains("crc", RawChunkCodec.Decode(badCrc).Error.Message);
Assert.False(RawChunkCodec.Decode(good.AsSpan(0, good.Length / 2)).IsSuccess);
@@ -190,7 +190,7 @@ public sealed class RawChunkCodecTests
private static byte[] Wrap(byte[] payload)
{
byte[] result = new byte[9 + payload.Length];
"MNRC"u8.CopyTo(result);
"MSRC"u8.CopyTo(result);
result[4] = ProtocolVersion.Container;
BinaryPrimitives.WriteUInt32LittleEndian(result.AsSpan(5), Crc32c.Compute(payload));
payload.CopyTo(result, 9);