forked from imurvai/brickcontroller2
-
Notifications
You must be signed in to change notification settings - Fork 4
Add unit tests for CaDA RaceCar rev1 and rev2 datagram encoding #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADatagramTestsBase.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using BrickController2.DeviceManagement; | ||
| using BrickController2.DeviceManagement.CaDA; | ||
| using BrickController2.PlatformServices.BluetoothLE; | ||
| using Moq; | ||
| using System; | ||
|
|
||
| namespace BrickController2.Tests.DeviceManagement.CaDA; | ||
|
|
||
| public abstract class CaDADatagramTestsBase | ||
| { | ||
| protected const byte AppIdentifier1 = 0x61; // This is the first byte of a randomly chosen AppIdentifier for unit testing | ||
| protected const byte AppIdentifier2 = 0x62; // This is the second byte of a randomly chosen AppIdentifier for unit testing | ||
| protected const byte AppIdentifier3 = 0x63; // This is the third byte of a randomly chosen AppIdentifier for unit testing | ||
|
|
||
| protected static readonly byte[] AppIdentifier = [AppIdentifier1, AppIdentifier2, AppIdentifier3]; | ||
|
|
||
| /// <summary> | ||
| /// This class is a test implementation of the ICaDAPlatformService interface that simulates the behavior of the TryGetRfPayload method for testing purposes. | ||
| /// It always returns true and sets the rfPayload to the rawData provided. | ||
| /// </summary> | ||
| protected class TestCaDAPlatformService : ICaDAPlatformService | ||
| { | ||
| public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) | ||
| { | ||
| rfPayload = rawData; | ||
| return true; // Simulate success | ||
| } | ||
| } | ||
|
|
||
| protected readonly Mock<IBluetoothLEService> _bluetoothLEService = new(MockBehavior.Strict); | ||
| protected readonly Mock<ICaDADeviceManager> _manager = new(MockBehavior.Strict); | ||
| protected readonly TestCaDAPlatformService _cadaPlatformService = new(); | ||
| internal readonly Mock<IDeviceRepository> _deviceRepository = new(MockBehavior.Strict); | ||
| protected readonly MessageEncoderFactory _messageEncoderFactory; | ||
| protected readonly Mock<Random> _random = new(MockBehavior.Strict); | ||
|
|
||
| protected CaDADatagramTestsBase() | ||
| { | ||
| _manager.Setup(x => x.GetAppId()).Returns(AppIdentifier); | ||
| _random.Setup(x => x.Next(ushort.MinValue, ushort.MaxValue)).Returns(0); // mock random number generation to always return 0 for testing | ||
| _messageEncoderFactory = new MessageEncoderFactory(_manager.Object, _cadaPlatformService, _random.Object); | ||
| } | ||
| } | ||
205 changes: 205 additions & 0 deletions
205
...kController2/BrickController2.Tests/DeviceManagement/CaDA/CaDARaceCarRev1DatagramTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| using BrickController2.DeviceManagement.CaDA; | ||
| using FluentAssertions; | ||
| using System; | ||
| using Xunit; | ||
|
|
||
| namespace BrickController2.Tests.DeviceManagement.CaDA; | ||
|
|
||
| public sealed class CaDARaceCarRev1DatagramTests : CaDADatagramTestsBase | ||
| { | ||
| private const byte PayloadIdentifier1 = 0x75; | ||
| private const byte PayloadIdentifier2 = 0x13; | ||
| private const byte MockedRandomValue1 = 0xf4; | ||
| private const byte MockedRandomValue2 = 0xf4; | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the payload identifiers are correctly set in the connect datagram for each device address. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef })] | ||
| [InlineData(new byte[] { 0x12, 0x34, 0x56 })] | ||
| public void TryGetTelegram_ConnectDatagram_PayloadIdentifier(byte[] deviceAddress) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| device.TryGetTelegram(true, out byte[] payload).Should().BeTrue(); | ||
| payload[0].Should().Be(PayloadIdentifier1); | ||
| payload[1].Should().Be(PayloadIdentifier2); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the AppIdentifier is correctly included in the connect datagram payload for each device address. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef })] | ||
| [InlineData(new byte[] { 0x12, 0x34, 0x35 })] | ||
| public void TryGetTelegram_ConnectDatagram_AppIdentifier(byte[] deviceAddress) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| device.TryGetTelegram(true, out byte[] payload).Should().BeTrue(); | ||
| payload[5].Should().Be(AppIdentifier1); | ||
| payload[6].Should().Be(AppIdentifier2); | ||
| payload[7].Should().Be(AppIdentifier3); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the payload identifiers are correctly set in the connect datagram for each device address. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef })] | ||
| [InlineData(new byte[] { 0x12, 0x34, 0x35 })] | ||
| public void TryGetTelegram_CommandDatagram_PayloadIdentifier(byte[] deviceAddress) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| device.TryGetTelegram(false, out byte[] payload).Should().BeTrue(); | ||
| payload[0].Should().Be(PayloadIdentifier1); | ||
| payload[1].Should().Be(PayloadIdentifier2); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the AppIdentifier is correctly included in the connect datagram payload for each device address. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef })] | ||
| [InlineData(new byte[] { 0x12, 0x34, 0x35 })] | ||
| public void TryGetTelegram_CommandDatagram_AppIdentifier(byte[] deviceAddress) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| device.TryGetTelegram(false, out byte[] payload).Should().BeTrue(); | ||
| payload[5].Should().Be(AppIdentifier1); | ||
| payload[6].Should().Be(AppIdentifier2); | ||
| payload[7].Should().Be(AppIdentifier3); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Tests that setting an illegal channel index throws an ArgumentOutOfRangeException. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef })] | ||
| [InlineData(new byte[] { 0x12, 0x34, 0x35 })] | ||
| public void TryGetTelegram_CommandDatagram_SetIllegalChannel(byte[] deviceAddress) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| Action action = () => device.SetOutput(device.NumberOfChannels, 0); | ||
|
|
||
| action.Should().Throw<ArgumentOutOfRangeException>(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the command datagram payload is correctly constructed based on the set output values for multiple devices, ensuring that each device's payload is independent of the others. | ||
| /// </summary> | ||
| [Fact] | ||
| public void TryGetTelegram_CommandDatagram_InstanceInteraction() | ||
| { | ||
| byte[] deviceAddress1 = [0xab, 0xcd, 0xef]; | ||
| byte[] scanData1 = [0x00, 0x00, 0x00, 0x00, deviceAddress1[0], deviceAddress1[1], deviceAddress1[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device1 = new CaDARaceCar("CaDARaceCar1", BitConverter.ToString(deviceAddress1).ToLower(), scanData1, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| float[] setValues1 = [1.0f, 1.0f, 0.0f]; | ||
| byte[] expectedPayload1 = [ | ||
| PayloadIdentifier1, PayloadIdentifier2, | ||
| deviceAddress1[0], deviceAddress1[1], deviceAddress1[2], | ||
| AppIdentifier1, AppIdentifier2, AppIdentifier3, | ||
| MockedRandomValue1, MockedRandomValue2, // mocked random values | ||
| 0xc9, 0x1a, 0x21, 0xc9, 0xc9, 0xc9]; | ||
|
|
||
| byte[] deviceAddress2 = [0x12, 0x34, 0x56]; | ||
| byte[] scanData2 = [0x00, 0x00, 0x00, 0x00, deviceAddress2[0], deviceAddress2[1], deviceAddress2[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device2 = new CaDARaceCar("CaDARaceCar2", BitConverter.ToString(deviceAddress2).ToLower(), scanData2, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| float[] setValues2 = [-1.0f, -1.0f, 0.0f]; | ||
| byte[] expectedPayload2 = [ | ||
| PayloadIdentifier1, PayloadIdentifier2, | ||
| deviceAddress2[0], deviceAddress2[1], deviceAddress2[2], | ||
| AppIdentifier1, AppIdentifier2, AppIdentifier3, | ||
| MockedRandomValue1, MockedRandomValue2, // mocked random values | ||
| 0x1a, 0xc9, 0x21, 0xc9, 0xc9, 0xc9]; | ||
|
|
||
| byte[] deviceAddress3 = [0x78, 0x90, 0xab]; | ||
| byte[] scanData3 = [0x00, 0x00, 0x00, 0x00, deviceAddress3[0], deviceAddress3[1], deviceAddress3[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
|
|
||
| CaDARaceCar device3 = new CaDARaceCar("CaDARaceCar3", BitConverter.ToString(deviceAddress3).ToLower(), scanData3, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| float[] setValues3 = [1.0f, -1.0f, 1.0f]; | ||
| byte[] expectedPayload3 = [ | ||
| PayloadIdentifier1, PayloadIdentifier2, | ||
| deviceAddress3[0], deviceAddress3[1], deviceAddress3[2], | ||
| AppIdentifier1, AppIdentifier2, AppIdentifier3, | ||
| MockedRandomValue1, MockedRandomValue2, // mocked random values | ||
| 0xc9, 0xc9, 0x1a, 0xc9, 0xc9, 0xc9]; | ||
|
|
||
| // Set the output values for the device | ||
| for (int i = 0; i < device1.NumberOfChannels; i++) | ||
| { | ||
| device1.SetOutput(i, setValues1[i]); | ||
| device2.SetOutput(i, setValues2[i]); | ||
| device3.SetOutput(i, setValues3[i]); | ||
| } | ||
|
|
||
| // Get the command datagram payload | ||
| device1.TryGetTelegram(false, out byte[] payload1).Should().BeTrue(); | ||
| device2.TryGetTelegram(false, out byte[] payload2).Should().BeTrue(); | ||
| device3.TryGetTelegram(false, out byte[] payload3).Should().BeTrue(); | ||
|
|
||
| payload1.Should().BeEquivalentTo(expectedPayload1); | ||
| payload2.Should().BeEquivalentTo(expectedPayload2); | ||
| payload3.Should().BeEquivalentTo(expectedPayload3); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This test checks that the command datagram payload is correctly constructed based on the set output values for each device address. | ||
| /// </summary> | ||
| /// <param name="deviceAddress">The address of the device to test.</param> | ||
| /// <param name="setValues">The set values for each channel.</param> | ||
| /// <param name="expectedPayload">The expected payload for the command datagram.</param> | ||
| [Theory] | ||
| [InlineData(new byte[] { 0xab, 0xcd, 0xef }, new float[] { 0.0f, 0.0f, 0.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x21, 0x21, 0x21, 0xc9, 0xc9, 0xc9 })] // all channels neutral | ||
| [InlineData(new byte[] { 0xcd, 0xef, 0xab }, new float[] { 1.0f, 0.0f, 0.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0xc9, 0x21, 0x21, 0xc9, 0xc9, 0xc9 })] // channel 1 maximum, others neutral | ||
| [InlineData(new byte[] { 0xef, 0xab, 0xcd }, new float[] { 0.0f, 1.0f, 0.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x21, 0x1a, 0x21, 0xc9, 0xc9, 0xc9 })] // channel 2 maximum, others neutral | ||
| [InlineData(new byte[] { 0x11, 0x22, 0x33 }, new float[] { 0.0f, 0.0f, 1.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x21, 0x21, 0x1a, 0xc9, 0xc9, 0xc9 })] // channel 3 maximum, others neutral | ||
| [InlineData(new byte[] { 0x22, 0x33, 0x44 }, new float[] { -1.0f, 0.0f, 0.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x1a, 0x21, 0x21, 0xc9, 0xc9, 0xc9 })] // channel 1 minimum, others neutral | ||
| [InlineData(new byte[] { 0x33, 0x44, 0x55 }, new float[] { 0.0f, -1.0f, 0.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x21, 0xc9, 0x21, 0xc9, 0xc9, 0xc9 })] // channel 2 minimum, others neutral | ||
| [InlineData(new byte[] { 0x44, 0x55, 0x66 }, new float[] { 0.0f, 0.0f, -1.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x21, 0x21, 0xc9, 0xc9, 0xc9, 0xc9 })] // channel 3 minimum, others neutral | ||
| [InlineData(new byte[] { 0x55, 0x66, 0x77 }, new float[] { 9.0f, 9.0f, 9.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0xc9, 0x1a, 0x1a, 0xc9, 0xc9, 0xc9 })] // all channels above maximum, should be clamped to maximum | ||
| [InlineData(new byte[] { 0x66, 0x77, 0x88 }, new float[] { -9.0f, -9.0f, -9.0f }, new byte[] { PayloadIdentifier1, PayloadIdentifier2, 0x00, 0x00, 0x00, AppIdentifier1, AppIdentifier2, AppIdentifier3, MockedRandomValue1, MockedRandomValue2, 0x1a, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9 })] // all channels below minimum, should be clamped to minimum | ||
| public void TryGetTelegram_CommandDatagram_Payload(byte[] deviceAddress, float[] setValues, byte[] expectedPayload) | ||
| { | ||
| byte[] scanData = [0x00, 0x00, 0x00, 0x00, deviceAddress[0], deviceAddress[1], deviceAddress[2], AppIdentifier1, AppIdentifier2, AppIdentifier3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; | ||
| CaDARaceCar device = new CaDARaceCar("CaDARaceCar", BitConverter.ToString(deviceAddress).ToLower(), scanData, _deviceRepository.Object, _bluetoothLEService.Object, _messageEncoderFactory); | ||
|
|
||
| deviceAddress.CopyTo(expectedPayload, 2); // Copy device address to expectedPayload at index 2 | ||
|
|
||
| // Set the output values for the device | ||
| for (int i = 0; i < device.NumberOfChannels; i++) | ||
| { | ||
| device.SetOutput(i, setValues[i]); | ||
| } | ||
|
|
||
| // Get the command datagram payload | ||
| device.TryGetTelegram(false, out byte[] payload).Should().BeTrue(); | ||
|
|
||
| // Check that the payload matches the expected values | ||
| payload.Should().BeEquivalentTo(expectedPayload); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not proper unit test as you are using already tested
MessageEncoderFactory. The way you have composed this setup is more integration test than the unit test.TEsts for
TryGetTelegrammethod should just test that encoder is properly called and the mothed itself returns its mocked value.