From 338936ace5e9f370dc20e6944df228dff2499470 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Thu, 2 Jan 2025 10:17:09 +0100 Subject: [PATCH] Improve unit tests, cleanup --- ClientMsg.cs | 54 +----------------- ControlCore.csproj | 4 +- ModelUrlMsg.cs | 56 +++---------------- NameMsg.cs | 63 +++++---------------- NetworkIdMsg.cs | 32 +---------- Participant.cs | 133 ++++++++++----------------------------------- SiteServer.cs | 19 ++++--- ThingMsg.cs | 63 ++++----------------- test/UnitTest1.cs | 13 +++-- test/test.csproj | 4 +- 10 files changed, 89 insertions(+), 352 deletions(-) diff --git a/ClientMsg.cs b/ClientMsg.cs index 56f5063..d924b17 100644 --- a/ClientMsg.cs +++ b/ClientMsg.cs @@ -9,7 +9,7 @@ namespace Passer.Control.Core { this.networkId = networkId; } - public ClientMsg(byte[] buffer) : base(buffer) { + public ClientMsg(byte[] buffer) { this.networkId = buffer[1]; } @@ -19,57 +19,5 @@ namespace Passer.Control.Core { buffer[ix++] = networkId; return ClientMsg.length; } - public override void Deserialize(byte[] buffer) { - base.Deserialize(buffer); - uint ix = 0; - networkId = buffer[ix]; - } - - public static async Task Receive(Stream dataStream, Participant client, byte packetSize) { - if (packetSize != length) - return false; - - byte[] buffer = await Receive(dataStream, packetSize); - ClientMsg msg = new(buffer); - - if (client.networkId == 0) { - // client.networkId = (byte)(Participant.clients.Count); - // NetworkIdMsg.Send(client, client.networkId); - client.messageQueue.Enqueue(msg); - } - else if (msg.networkId == 0) { - // NetworkIdMsg.Send(client, client.networkId); - client.messageQueue.Enqueue(msg); - } - - return true; - } - - public static byte Serialized(byte[] buffer, byte networkId) { - byte ix = 0; - buffer[ix++] = ClientMsg.Id; - buffer[ix++] = networkId; - return ix; - } - public static bool SendTo(Participant participant, byte networkId) { - if (participant == null) - return false; - - byte ix = 0; - participant.buffer[ix++] = ClientMsg.Id; - participant.buffer[ix++] = networkId; - - return participant.SendBuffer(ix); - } - public static bool Publish(Participant participant, byte networkId) { - if (participant == null) - return false; - - byte ix = 0; - participant.buffer[ix++] = ClientMsg.Id; - participant.buffer[ix++] = networkId; - - return participant.PublishBuffer(ix); - } } } \ No newline at end of file diff --git a/ControlCore.csproj b/ControlCore.csproj index b63b20c..9f3c622 100644 --- a/ControlCore.csproj +++ b/ControlCore.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/ModelUrlMsg.cs b/ModelUrlMsg.cs index 47e99e7..aae6301 100644 --- a/ModelUrlMsg.cs +++ b/ModelUrlMsg.cs @@ -17,7 +17,14 @@ namespace Passer.Control.Core { this.thingId = thingId; this.url = url; } - public ModelUrlMsg(byte[] buffer) : base(buffer) { } + public ModelUrlMsg(byte[] buffer) { + byte ix = 1; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + + int strlen = buffer[ix++]; + url = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); + } public override byte Serialize(ref byte[] buffer) { byte ix = 0; @@ -30,54 +37,7 @@ namespace Passer.Control.Core { buffer[ix++] = (byte)url[urlIx]; return ix; } - public override void Deserialize(byte[] buffer) { - byte ix = 0; - this.networkId = buffer[ix++]; - this.thingId = buffer[ix++]; - int strlen = buffer[ix++]; - url = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); - } - public static bool Send(Participant client, Thing thing) { - if (string.IsNullOrEmpty(thing.modelUrl)) - return true; // nothing sent, but still a success! - - ModelUrlMsg msg = new(thing.networkId, thing.id, thing.modelUrl); - return SendMsg(client, msg); - } - public static bool Send(Participant client, byte networkId, byte thingId, string modelUrl) { - if (string.IsNullOrEmpty(modelUrl)) - return true; // nothing sent, but still a success! - - ModelUrlMsg msg = new(networkId, thingId, modelUrl); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Participant client, byte packetSize) { - byte[] buffer = await Receive(dataStream, packetSize); - ModelUrlMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - - public static bool SendTo(Participant participant, Thing thing) { - if (participant == null || thing == null || thing.modelUrl == null) - return false; - - byte urlLength = (byte)thing.modelUrl.Length; - if (participant.buffer.Length < 3 + urlLength) - return false; - - byte ix = 0; - participant.buffer[ix++] = ModelUrlMsg.Id; - participant.buffer[ix++] = participant.networkId; - participant.buffer[ix++] = thing.id; // Thing Id - - participant.buffer[ix++] = urlLength; - for (int urlIx = 0; urlIx < urlLength; urlIx++) - participant.buffer[ix++] = (byte)thing.modelUrl[urlIx]; - - return participant.SendBuffer(ix); - } } } \ No newline at end of file diff --git a/NameMsg.cs b/NameMsg.cs index 18b3d5b..04802aa 100644 --- a/NameMsg.cs +++ b/NameMsg.cs @@ -18,63 +18,28 @@ namespace Passer.Control.Core { this.thingId = thingId; this.name = name; } - public NameMsg(byte[] buffer) : base(buffer) { } - - public override byte Serialize(ref byte[] buffer) { - byte ix = 0; - buffer[ix++] = NameMsg.Id; - buffer[ix++] = this.networkId; - buffer[ix++] = this.thingId; - buffer[ix++] = (byte)this.name.Length; - for (int nameIx = 0; nameIx < this.name.Length; nameIx++) - buffer[ix++] = (byte)this.name[nameIx]; - return ix; - } - public override void Deserialize(byte[] buffer) { - byte ix = 0; + public NameMsg(byte[] buffer) { + byte ix = 1; this.networkId = buffer[ix++]; this.thingId = buffer[ix++]; int strlen = buffer[ix++]; this.name = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); } - public static bool Send(Participant client, Thing thing) { - if (string.IsNullOrEmpty(thing.name)) - return true; // nothing sent, but still a success! - - NameMsg msg = new(thing.networkId, thing.id, thing.name); - return SendMsg(client, msg); - } - //public static bool Send(Client client, byte networkId, byte thingId, string name) - //{ - // NameMsg msg = new(networkId, thingId, name); - // return SendMsg(client, msg); - //} - public static async Task Receive(Stream dataStream, Participant client, byte packetSize) { - byte[] buffer = await Receive(dataStream, packetSize); - NameMsg msg = new(buffer); - - client.messageQueue.Enqueue(msg); - return true; - } - - public static bool SendTo(Participant participant, Thing thing) { - if (participant == null || thing == null || thing.name == null) - return false; - - byte nameLength = (byte)thing.name.Length; - if (participant.buffer.Length < 3 + nameLength) - return false; - + public override byte Serialize(ref byte[] buffer) { byte ix = 0; - participant.buffer[ix++] = NameMsg.Id; - participant.buffer[ix++] = participant.networkId; - participant.buffer[ix++] = thing.id; - participant.buffer[ix++] = nameLength; - for (int nameIx = 0; nameIx < nameLength; nameIx++) - participant.buffer[ix++] = (byte)thing.name[nameIx]; + buffer[ix++] = NameMsg.Id; + buffer[ix++] = this.networkId; + buffer[ix++] = this.thingId; - return participant.SendBuffer(ix); + int nameLength = 0; + if (this.name != null) + nameLength = this.name.Length; + + buffer[ix++] = (byte)nameLength; + for (int nameIx = 0; nameIx < nameLength; nameIx++) + buffer[ix++] = (byte)this.name[nameIx]; + return ix; } } diff --git a/NetworkIdMsg.cs b/NetworkIdMsg.cs index c730c40..6b65913 100644 --- a/NetworkIdMsg.cs +++ b/NetworkIdMsg.cs @@ -8,7 +8,7 @@ namespace Passer.Control.Core { public NetworkIdMsg(byte networkId) { this.networkId = networkId; } - public NetworkIdMsg(byte[] buffer) : base(buffer) { + public NetworkIdMsg(byte[] buffer) { this.networkId = buffer[1]; } @@ -17,36 +17,6 @@ namespace Passer.Control.Core { buffer[1] = this.networkId; return NetworkIdMsg.length; } - public override void Deserialize(byte[] buffer) { - uint ix = 1; - this.networkId = buffer[ix]; - } - - public static bool Send(Participant client, byte networkId) { - NetworkIdMsg msg = new(networkId); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Participant client, byte packetSize) { - if (packetSize != length) - return false; - - byte[] buffer = await Receive(dataStream, packetSize); - NetworkIdMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - - public static bool SendTo(Participant participant, byte networkId) { - if (participant == null) - return false; - - byte ix = 0; - participant.buffer[ix++] = NetworkIdMsg.Id; - participant.buffer[ix++] = networkId; - - return participant.SendBuffer(ix); - - } } } \ No newline at end of file diff --git a/Participant.cs b/Participant.cs index 697c825..ae99883 100644 --- a/Participant.cs +++ b/Participant.cs @@ -14,7 +14,6 @@ namespace Passer.Control.Core { public string ipAddress = "0.0.0.0"; public string broadcastIpAddress = "255.255.255.255"; public int port; - // public Stream dataStream; public byte[] buffer = new byte[256]; @@ -42,7 +41,6 @@ namespace Passer.Control.Core { #region Init public Participant() { - // this.dataStream = new EchoStream(); others.Add(this); } @@ -63,7 +61,6 @@ namespace Passer.Control.Core { public Participant(UdpClient udpClient, int port) : this() { this.udpClient = udpClient; this.port = port; - //this.dataStream = new EchoStream(); //clients.Add(this); } @@ -71,27 +68,19 @@ namespace Passer.Control.Core { #region Update - protected async void ReceiveUDP(IAsyncResult result) { + protected void ReceiveUDP(IAsyncResult result) { if (udpClient == null || this.endPoint == null) return; - try { - // Console.WriteLine($"{this.name} received"); - byte[] data = udpClient.EndReceive(result, ref this.endPoint); - // This does not yet take multi-packet messages into account! + byte[] data = udpClient.EndReceive(result, ref this.endPoint); + // This does not yet take multi-packet messages into account! - Participant remoteParticipant = this.GetParticipant(endPoint.Address.ToString(), endPoint.Port); - if (remoteParticipant == null) { - remoteParticipant = this.AddParticipant(endPoint.Address.ToString(), endPoint.Port); - } - await ReceiveData(data, remoteParticipant); - // this.dataStream.WriteByte((byte)data.Length); - // this.dataStream.Write(data, 0, data.Length); - //Task task = Task.Run(() => ReceiveData()); - } - catch (Exception _) { - Console.WriteLine("connection error"); + Participant remoteParticipant = this.GetParticipant(endPoint.Address.ToString(), endPoint.Port); + if (remoteParticipant == null) { + remoteParticipant = this.AddParticipant(endPoint.Address.ToString(), endPoint.Port); } + ReceiveData(data, remoteParticipant); + udpClient.BeginReceive(new AsyncCallback(result => ReceiveUDP(result)), null); } @@ -102,17 +91,17 @@ namespace Passer.Control.Core { public virtual void Update(long currentTimeMs) { if (currentTimeMs > this.nextPublishMe) { this.Publish(new ClientMsg(this.networkId)); - Console.WriteLine($"{this.name} Sent ClientMsg {this.networkId}"); + // Console.WriteLine($"{this.name} Sent ClientMsg {this.networkId}"); this.nextPublishMe = currentTimeMs + Participant.publishInterval; } - for (int ix = 0; ix < this.others.Count; ix++) { - Participant client = this.others[ix]; - if (client == null) - continue; + // for (int ix = 0; ix < this.others.Count; ix++) { + // Participant client = this.others[ix]; + // if (client == null) + // continue; - this.ProcessMessages(client); - } + // this.ProcessMessages(client); + // } Thing.UpdateAll(currentTimeMs); } @@ -121,6 +110,7 @@ namespace Passer.Control.Core { #region Send public void SendThingInfo(Thing thing) { + Console.WriteLine("Send thing info"); this.Send(new ThingMsg(this.networkId, thing)); this.Send(new NameMsg(this.networkId, thing)); this.Send(new ModelUrlMsg(this.networkId, thing)); @@ -131,7 +121,7 @@ namespace Passer.Control.Core { if (bufferSize <= 0) return true; - Console.WriteLine($"msg to {endPoint.Address.ToString()} {endPoint.Port}"); + // Console.WriteLine($"msg to {endPoint.Address.ToString()} {endPoint.Port}"); this.udpClient?.Send(this.buffer, bufferSize, this.endPoint); return true; } @@ -168,46 +158,31 @@ namespace Passer.Control.Core { #region Receive - // public async Task ReceiveData_old() { - // while (true) { - // byte packetSize = (byte)this.dataStream.ReadByte(); - // if (packetSize != 0xFF) - // await ReceiveData(this.dataStream, this, packetSize); - // // else timeout - // } - // } - - // public static async Task ReceiveData(Stream dataStream, Participant client, byte packetSize) { - public async Task ReceiveData(byte[] data, Participant remoteParticipant) { - // byte msgId = (byte)dataStream.ReadByte(); + public void ReceiveData(byte[] data, Participant remoteParticipant) { byte msgId = data[0]; if (msgId == 0xFF) { // Timeout return; } - // Console.WriteLine($"R {msgId} from {remoteParticipant.ipAddress}"); - bool result = false; switch (msgId) { case ClientMsg.Id: // 0xA0 / 160 - //result = await ClientMsg.Receive(dataStream, client, packetSize); - this.ProcessClientMsg(remoteParticipant, new ClientMsg(data)); + this.Process(remoteParticipant, new ClientMsg(data)); break; case NetworkIdMsg.Id: // 0xA1 / 161 - //result = await NetworkIdMsg.Receive(dataStream, client, packetSize); - this.ProcessNetworkIdMsg(remoteParticipant, new NetworkIdMsg(data)); + this.Process(remoteParticipant, new NetworkIdMsg(data)); break; case InvestigateMsg.Id: // 0x81 // result = await InvestigateMsg.Receive(dataStream, client, packetSize); break; case ThingMsg.id: // 0x80 / 128 - // result = await ThingMsg.Receive(dataStream, client, packetSize); + this.Process(new ThingMsg(data)); break; case NameMsg.Id: // 0x91 / 145 - // result = await NameMsg.Receive(dataStream, client, packetSize); + this.Process(new NameMsg(data)); break; case ModelUrlMsg.Id: // 0x90 / 144 - // result = await ModelUrlMsg.Receive(dataStream, client, packetSize); + this.Process(new ModelUrlMsg(data)); break; case PoseMsg.Id: // 0x10 / 16 // result = await PoseMsg.Receive(dataStream, client, packetSize); @@ -224,82 +199,34 @@ namespace Passer.Control.Core { default: break; } - // if (result == false) { - // packetSize = msgId; // skip 1 byte, msgId is possibly a packet size byte - // await ReceiveData(dataStream, client, packetSize); - // } } #endregion #region Process - public virtual void ProcessMessages(Participant remoteParticipant) { - while (this.messageQueue.TryDequeue(out IMessage msg)) - ProcessMessage(remoteParticipant, msg); - } + protected virtual void Process(Participant sender, ClientMsg msg) { } - public void ProcessMessage(Participant remoteParticipant, IMessage msg) { - switch (msg) { - case ClientMsg clientMsg: - ProcessClientMsg(remoteParticipant, clientMsg); - break; - case NetworkIdMsg networkId: - ProcessNetworkIdMsg(remoteParticipant, networkId); - break; - case InvestigateMsg investigate: - ProcessInvestigateMsg(investigate); - break; - case ThingMsg thing: - ProcessThingMsg(thing); - break; - case NameMsg name: - //UnityEngine.Debug.Log($"Name [{name.networkId}/{name.thingId}] {name.name}"); - ProcessNameMsg(name); - break; - case ModelUrlMsg modelUrl: - ProcessModelUrlMsg(modelUrl); - break; - case PoseMsg pose: - ProcessPoseMsg(pose); - break; - case CustomMsg custom: - ProcessCustomMsg(custom); - break; - case TextMsg text: - ProcessTextMsg(text); - break; - case DestroyMsg destroy: - ProcessDestroyMsg(destroy); - break; - default: - return; - } - ForwardMessage(msg); - } - - protected virtual void ProcessClientMsg(Participant sender, ClientMsg msg) { } - - protected virtual void ProcessNetworkIdMsg(Participant sender, NetworkIdMsg msg) { + protected virtual void Process(Participant sender, NetworkIdMsg msg) { Console.WriteLine($"{this.name} receive network id {this.networkId} {msg.networkId}"); if (this.networkId != msg.networkId) { this.networkId = msg.networkId; foreach (Thing thing in Thing.GetAllThings()) - this.SendThingInfo(thing); + sender.SendThingInfo(thing); } } - protected virtual void ProcessInvestigateMsg(InvestigateMsg msg) { } + protected virtual void Process(InvestigateMsg msg) { } - protected virtual void ProcessThingMsg(ThingMsg msg) { + protected virtual void Process(ThingMsg msg) { Console.WriteLine($"received thing {msg.thingId}"); } - protected virtual void ProcessNameMsg(NameMsg msg) { + protected virtual void Process(NameMsg msg) { Console.WriteLine($"received name {msg.name}"); } - protected virtual void ProcessModelUrlMsg(ModelUrlMsg msg) { + protected virtual void Process(ModelUrlMsg msg) { Console.WriteLine($"received name {msg.url}"); } diff --git a/SiteServer.cs b/SiteServer.cs index 52c90c7..d4d4e19 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -5,7 +5,7 @@ namespace Passer.Control.Core { public class SiteServer : Participant { - public SiteServer(int port) { + public SiteServer(int port = 7681) { this.ipAddress = "0.0.0.0"; this.port = port; this.endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), 0); // for sending, but should not be used really... @@ -16,21 +16,24 @@ namespace Passer.Control.Core { } public override void Update(long currentTimeMs) { - for (int ix = 0; ix < this.others.Count; ix++) { - Participant client = this.others[ix]; - if (client == null) - continue; + // for (int ix = 0; ix < this.others.Count; ix++) { + // Participant client = this.others[ix]; + // if (client == null) + // continue; - this.ProcessMessages(client); - } + // this.ProcessMessages(client); + // } Thing.UpdateAll(currentTimeMs); } - protected override void ProcessClientMsg(Participant sender, ClientMsg msg) { + protected override void Process(Participant sender, ClientMsg msg) { if (msg.networkId == 0) { Console.WriteLine($"{this.name} received New Client -> {sender.networkId}"); sender.Send(new NetworkIdMsg(sender.networkId)); } } + + protected override void Process(Participant sender, NetworkIdMsg msg) { + } } } \ No newline at end of file diff --git a/ThingMsg.cs b/ThingMsg.cs index 382fc8b..aefcf1b 100644 --- a/ThingMsg.cs +++ b/ThingMsg.cs @@ -12,7 +12,10 @@ namespace Passer.Control.Core { this.networkId = networkId; this.thingId = thing.id; this.thingType = thing.type; - this.parentId = thing.parent.id; + if (thing.parent != null) + this.parentId = thing.parent.id; + else + this.parentId = 0; } public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { this.networkId = networkId; @@ -20,7 +23,13 @@ namespace Passer.Control.Core { this.thingType = thingType; this.parentId = parentId; } - public ThingMsg(byte[] buffer) : base(buffer) { } + public ThingMsg(byte[] buffer) { + uint ix = 0; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + this.thingType = buffer[ix++]; + this.parentId = buffer[ix]; + } public override byte Serialize(ref byte[] buffer) { byte ix = 0; @@ -31,56 +40,6 @@ namespace Passer.Control.Core { buffer[ix++] = this.parentId; return ThingMsg.length; } - public override void Deserialize(byte[] buffer) { - uint ix = 0; - this.networkId = buffer[ix++]; - this.thingId = buffer[ix++]; - this.thingType = buffer[ix++]; - this.parentId = buffer[ix]; - } - - public static bool Send(Participant client, Thing thing) { - ThingMsg msg = new(thing.networkId, thing.id, thing.type, thing.parent.id); - return SendMsg(client, msg); - } - //public static bool Send(Client client, byte networkId, byte thingId, byte thingType, byte parentId) - //{ - // ThingMsg msg = new(networkId, thingId, thingType, parentId); - // //UnityEngine.Debug.Log($"Send thing [{msg.networkId}/{msg.thingId}]"); - // return SendMsg(client, msg); - //} - public static async Task Receive(Stream dataStream, Participant client, byte packetSize) { - if (packetSize != length) - return false; - - byte[] buffer = await Receive(dataStream, packetSize); - ThingMsg msg = new(buffer); - //UnityEngine.Debug.Log($"Receive thing [{msg.networkId}/{msg.thingId}]"); - - // Do no process poses with nwid == 0 (== local) - //if (msg.networkId == 0) - // return true; - - client.messageQueue.Enqueue(msg); - return true; - } - - public static bool SendTo(Participant participant, Thing thing) { - if (participant == null || thing == null) - return false; - - byte ix = 0; - participant.buffer[ix++] = ThingMsg.id; - participant.buffer[ix++] = participant.networkId; - participant.buffer[ix++] = thing.id; - participant.buffer[ix++] = thing.type; - if (thing.parent != null) - participant.buffer[ix++] = thing.parent.id; - else - participant.buffer[ix++] = 0; - - return participant.SendBuffer(ix); - } } } \ No newline at end of file diff --git a/test/UnitTest1.cs b/test/UnitTest1.cs index f369c56..1051a4f 100644 --- a/test/UnitTest1.cs +++ b/test/UnitTest1.cs @@ -1,7 +1,10 @@ -namespace test; +using System; +using NUnit.Framework; using Passer.Control.Core; +namespace ControlCore.test; + public class Tests { [SetUp] public void Setup() { @@ -46,7 +49,7 @@ public class Tests { long milliseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long startTime = milliseconds; - while (milliseconds < startTime + 7000) { + while (milliseconds < startTime + 1000) { siteServer.Update(milliseconds); participant.Update(milliseconds); @@ -54,11 +57,12 @@ public class Tests { milliseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } - Assert.Pass(); + Assert.That(participant.networkId, Is.EqualTo(1)); } [Test] public void Test_ThingMsg() { + SiteServer siteServer = new(); Participant participant = new("127.0.0.1"); Thing thing = new() { name = "First Thing", @@ -68,12 +72,13 @@ public class Tests { long milliseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long startTime = milliseconds; while (milliseconds < startTime + 7000) { + siteServer.Update(milliseconds); participant.Update(milliseconds); Thread.Sleep(100); milliseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } - Assert.Pass(); + Assert.That(participant.networkId, Is.EqualTo(1)); } } diff --git a/test/test.csproj b/test/test.csproj index 6da79b7..b0f97b9 100644 --- a/test/test.csproj +++ b/test/test.csproj @@ -11,8 +11,8 @@ - - + +