using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.Cip; using ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.Logix; namespace ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.Tests.Logix; // No template exchange exists in the golden captures (ab_server has no Template Object), so these // are layout tests against the brief / CIP spec. public sealed class TemplateObjectServicesTests { [Fact] public void Get_attributes_request() => Convert.ToHexString(TemplateObjectServices.GetAttributes(0x0123)).ShouldBe( "0303" + "206C2500" + "2301" + "0400" + "0400" + "0500" + "0200" + "0100"); [Fact] public void Parse_attributes() { var reply = CipReply.Parse(Convert.FromHexString("83000000" + "0400" + "0400" + "0000" + "2A000000" + "0500" + "0000" + "18000000" + "0200" + "0000" + "0300" + "0100" + "0000" + "CE0F")); var a = TemplateObjectServices.ParseAttributes(reply); a.ShouldBe(new TemplateAttributes(42, 24, 3, 0x0FCE)); } [Fact] public void Parse_attributes_nonzero_attribute_status_throws() { var reply = CipReply.Parse(Convert.FromHexString("83000000" + "0100" + "0400" + "0100" + "2A000000")); Should.Throw(() => TemplateObjectServices.ParseAttributes(reply)); } [Fact] public void Read_template_request() => Convert.ToHexString(TemplateObjectServices.ReadTemplate(0x0123, 0x20, 0x1F4)).ShouldBe( "4C03" + "206C2500" + "2301" + "20000000" + "F401"); [Fact] public void Read_more_follows_status_0x06() { TemplateObjectServices.ReadHasMore(new CipReply(0x4C, 0x06, [], ReadOnlyMemory.Empty)).ShouldBeTrue(); TemplateObjectServices.ReadHasMore(new CipReply(0x4C, 0x00, [], ReadOnlyMemory.Empty)).ShouldBeFalse(); } [Fact] public void Decoder_buffer_header() { var buf = TemplateObjectServices.BuildDecoderBuffer(0x0123, new TemplateAttributes(42, 24, 3, 0x0FCE), [0xAA, 0xBB]); Convert.ToHexString(buf).ShouldBe("2301" + "2A000000" + "18000000" + "0300" + "CE0F" + "AABB"); } }