Skip to content

Commit

Permalink
FIX AggregatingConnectorEventQueue was aggregating non contiguous bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-domenichini committed Jan 15, 2024
1 parent a2d3989 commit 3c7e4bc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using ProtoBuf;
using SmartIOT.Connector.Core.Events;
using SmartIOT.Connector.Core.Events;

namespace SmartIOT.Connector.Core.Connector;

Expand Down Expand Up @@ -34,10 +33,10 @@ public class AggregatingConnectorEventQueue : AggregatingQueue<CompositeConnecto

if (e1.Tag == e2.Tag)
{
if (e1.Data != null && e2.Data != null && e1.Data.Length > 0 && e2.Data.Length > 0)
if (DataIntersects(item1, item2))
{
int startOffset = Math.Min(e1.StartOffset, e2.StartOffset);
int endOffset = Math.Max(e1.StartOffset + e1.Data.Length, e2.StartOffset + e2.Data.Length);
int endOffset = Math.Max(e1.StartOffset + e1.Data!.Length, e2.StartOffset + e2.Data!.Length);
int length = endOffset - startOffset;
byte[] data = new byte[length];

Expand Down Expand Up @@ -68,10 +67,10 @@ public class AggregatingConnectorEventQueue : AggregatingQueue<CompositeConnecto
var e1 = item1.TagScheduleEvent;
var e2 = item2.TagScheduleEvent;

if (e1.Tag == e2.Tag && e1.Data != null && e2.Data != null && e1.Data.Length > 0 && e2.Data.Length > 0)
if (e1.Tag == e2.Tag && DataIntersects(item1, item2))
{
int startOffset = Math.Min(e1.StartOffset, e2.StartOffset);
int endOffset = Math.Max(e1.StartOffset + e1.Data.Length, e2.StartOffset + e2.Data.Length);
int endOffset = Math.Max(e1.StartOffset + e1.Data!.Length, e2.StartOffset + e2.Data!.Length);
int length = endOffset - startOffset;
byte[] data = new byte[length];

Expand All @@ -92,6 +91,14 @@ public class AggregatingConnectorEventQueue : AggregatingQueue<CompositeConnecto
return null;
}

private bool DataIntersects(TagScheduleEventArgs a, TagScheduleEventArgs b)
{
return a.TagScheduleEvent?.Data is not null && b.TagScheduleEvent?.Data is not null
&& a.TagScheduleEvent.Data.Length > 0 && b.TagScheduleEvent.Data.Length > 0
&& a.TagScheduleEvent.StartOffset < b.TagScheduleEvent.StartOffset + b.TagScheduleEvent.Data.Length
&& a.TagScheduleEvent.StartOffset + a.TagScheduleEvent.Data.Length > b.TagScheduleEvent.StartOffset;
}

private CompositeConnectorEvent? AggregateDeviceStatusEvents(object? sender, DeviceStatusEventArgs item1, DeviceStatusEventArgs item2)
{
if (item1.DeviceStatusEvent.Device == item2.DeviceStatusEvent.Device)
Expand Down
1 change: 0 additions & 1 deletion SmartIOT.Connector.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
docker-push-app.bat = docker-push-app.bat
docker-run-app.bat = docker-run-app.bat
dotnet-build-and-push.bat = dotnet-build-and-push.bat
.github\workflows\dotnet-develop.yml = .github\workflows\dotnet-develop.yml
.github\workflows\dotnet-master.yml = .github\workflows\dotnet-master.yml
.github\workflows\dotnet-prerelease.yml = .github\workflows\dotnet-prerelease.yml
.github\workflows\dotnet-release.yml = .github\workflows\dotnet-release.yml
Expand Down
56 changes: 56 additions & 0 deletions Tests/SmartIOT.Connector.Core.Tests/ConnectorEventQueueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,60 @@ public void Test_not_aggregating_tagRead()

Assert.Null(queue.PopOrDefault());
}

[Fact]
public void Test_not_aggregating_tagRead_on_no_intersection()
{
Model.Device device = new Model.Device(new Conf.DeviceConfiguration());
Model.Tag t20 = new Model.Tag(new Conf.TagConfiguration("DB20", Conf.TagType.READ, 10, 100, 1));

var driver = new MockDeviceDriver(device);

var queue = new AggregatingConnectorEventQueue();

Assert.Null(queue.PopOrDefault());

byte[] data1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, };
byte[] data2 = new byte[] { 11, 12, 13, 14, 15, 16, 17, 18 };
byte[] data3 = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28 };

queue.Push(CompositeConnectorEvent.TagRead((null, new TagScheduleEventArgs(driver, TagScheduleEvent.BuildTagData(device, t20, 0, data1, false)))));
queue.Push(CompositeConnectorEvent.TagRead((null, new TagScheduleEventArgs(driver, TagScheduleEvent.BuildTagData(device, t20, 10, data2, false)))));
queue.Push(CompositeConnectorEvent.TagRead((null, new TagScheduleEventArgs(driver, TagScheduleEvent.BuildTagData(device, t20, 20, data3, false)))));

var e = queue.PopOrDefault();
Assert.NotNull(e?.TagReadScheduleEvent);
TagScheduleEvent te = e!.TagReadScheduleEvent!.Value.args.TagScheduleEvent;
Assert.Equal(device, te.Device);
Assert.Equal(t20, te.Tag);
Assert.Equal(0, te.ErrorNumber);
Assert.Null(te.Description);
Assert.NotNull(te.Data);
Assert.Equal(8, te.Data!.Length);
Assert.Equal(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, te.Data);

e = queue.PopOrDefault();
Assert.NotNull(e?.TagReadScheduleEvent);
te = e!.TagReadScheduleEvent!.Value.args.TagScheduleEvent;
Assert.Equal(device, te.Device);
Assert.Equal(t20, te.Tag);
Assert.Equal(0, te.ErrorNumber);
Assert.Null(te.Description);
Assert.NotNull(te.Data);
Assert.Equal(8, te.Data!.Length);
Assert.Equal(new byte[] { 11, 12, 13, 14, 15, 16, 17, 18 }, te.Data);

e = queue.PopOrDefault();
Assert.NotNull(e?.TagReadScheduleEvent);
te = e!.TagReadScheduleEvent!.Value.args.TagScheduleEvent;
Assert.Equal(device, te.Device);
Assert.Equal(t20, te.Tag);
Assert.Equal(0, te.ErrorNumber);
Assert.Null(te.Description);
Assert.NotNull(te.Data);
Assert.Equal(8, te.Data!.Length);
Assert.Equal(new byte[] { 21, 22, 23, 24, 25, 26, 27, 28 }, te.Data);

Assert.Null(queue.PopOrDefault());
}
}

0 comments on commit 3c7e4bc

Please sign in to comment.