using System.Reflection; using MessagePack; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Shared.Contracts; namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Shared.Tests; [Trait("Category", "Unit")] public sealed class ContractRoundTripTests { /// /// Every MessagePack contract in the Shared project must round-trip. Byte-for-byte equality /// on re-serialization proves the contract is deterministic — critical for the Hello /// version-negotiation hash and for debugging wire dumps. /// [Fact] public void All_MessagePackObject_contracts_round_trip_byte_for_byte() { var contractTypes = typeof(Hello).Assembly.GetTypes() .Where(t => t.GetCustomAttribute() is not null) .ToList(); contractTypes.Count.ShouldBeGreaterThan(15, "scan should find all contracts"); foreach (var type in contractTypes) { var instance = Activator.CreateInstance(type); var bytes1 = MessagePackSerializer.Serialize(type, instance); var hydrated = MessagePackSerializer.Deserialize(type, bytes1); var bytes2 = MessagePackSerializer.Serialize(type, hydrated); bytes2.ShouldBe(bytes1, $"{type.Name} did not round-trip byte-for-byte"); } } [Fact] public void Hello_default_reports_current_protocol_version() { var h = new Hello { PeerName = "Proxy", SharedSecret = "x" }; h.ProtocolMajor.ShouldBe(Hello.CurrentMajor); h.ProtocolMinor.ShouldBe(Hello.CurrentMinor); } [Fact] public void OpenSessionRequest_round_trips_values() { var req = new OpenSessionRequest { DriverInstanceId = "gal-1", DriverConfigJson = "{\"x\":1}" }; var bytes = MessagePackSerializer.Serialize(req); var hydrated = MessagePackSerializer.Deserialize(bytes); hydrated.DriverInstanceId.ShouldBe("gal-1"); hydrated.DriverConfigJson.ShouldBe("{\"x\":1}"); } [Fact] public void Contracts_reference_only_BCL_and_MessagePack() { var asm = typeof(Hello).Assembly; var references = asm.GetReferencedAssemblies() .Select(n => n.Name!) .Where(n => !n.StartsWith("System.") && n != "mscorlib" && n != "netstandard") .ToList(); // Only MessagePack should appear outside BCL — no System.Text.Json, no EF, no AspNetCore. references.ShouldAllBe(n => n == "MessagePack" || n == "MessagePack.Annotations"); } }