Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
78707e8
upload files
VlasenkoMykola Apr 24, 2026
60c9c61
adjust files
VlasenkoMykola Apr 24, 2026
b19eabb
adjust files
VlasenkoMykola Apr 25, 2026
68ff125
adjust files
VlasenkoMykola Apr 25, 2026
b5ed302
suppress warnings
VlasenkoMykola Apr 25, 2026
5ae0494
fix: make _tcpClient and _udpClient readonly
VlasenkoMykola Apr 28, 2026
10526db
fix: make _host and _port readonly
VlasenkoMykola Apr 28, 2026
2cec185
fix: remove empty statement and unused variables
VlasenkoMykola Apr 28, 2026
cafd14b
fix: move IUdpClient and UdpClientWrapper into named namespace
VlasenkoMykola Apr 30, 2026
02988d4
fix: dispose CancellationTokenSource before reassignment
VlasenkoMykola Apr 30, 2026
3575ca7
fix: remove unused ex variables in catch blocks
VlasenkoMykola Apr 30, 2026
1284888
fix: add meaningful message to ArgumentOutOfRangeException
VlasenkoMykola Apr 30, 2026
ad7b4cf
added new tests
VlasenkoMykola May 3, 2026
acbf2f5
adjust file
VlasenkoMykola May 3, 2026
73895a6
adjust file
VlasenkoMykola May 3, 2026
d882148
adjust file
VlasenkoMykola May 3, 2026
26437be
fix: added int cast
VlasenkoMykola May 4, 2026
a7e5c26
refactor: remove duplicate code in UdpClientWrapper and TcpClientWrapper
VlasenkoMykola May 4, 2026
863f47b
lab 5 architecture test, red commit
VlasenkoMykola May 9, 2026
f572bc1
adjust files
VlasenkoMykola May 10, 2026
0901a19
lab 5 dummy commit to trigger github actions after red commit
VlasenkoMykola May 10, 2026
6965a95
lab 5 green commit
VlasenkoMykola May 10, 2026
977277a
lab 6: implement echo server tests
VlasenkoMykola May 16, 2026
e90a8a8
lab 6 upload the current sln file
VlasenkoMykola May 17, 2026
106f942
lab 7 update vulnerable dependencies
VlasenkoMykola May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
30 changes: 17 additions & 13 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,32 @@ jobs:
dotnet tool install --global dotnet-sonarscanner
echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH
dotnet sonarscanner begin `
/k:"ppanchen_NetSdrClient" `
/o:"ppanchen" `
/k:"VlasenkoMykola_ReengineeringCourse" `
/o:"vlasenkomykola" `
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.xml" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" `
/d:sonar.cpd.cs.minimumTokens=40 `
/d:sonar.cpd.cs.minimumLines=5 `
/d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml `
/d:sonar.qualitygate.wait=true
/d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml
shell: pwsh
# 2) BUILD & TEST
- name: Restore
run: dotnet restore NetSdrClient.sln
- name: Build
run: dotnet build NetSdrClient.sln -c Release --no-restore
#- name: Tests with coverage (OpenCover)
# run: |
# dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build `
# /p:CollectCoverage=true `
# /p:CoverletOutput=TestResults/coverage.xml `
# /p:CoverletOutputFormat=opencover
# shell: pwsh
- name: Tests with coverage (OpenCover)
run: |
dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build `
/p:CollectCoverage=true `
/p:CoverletOutput=TestResults/coverage `
/p:CoverletOutputFormat=opencover
dotnet test EchoServerTests/EchoServerTests.csproj -c Release --no-build `
/p:CollectCoverage=true `
/p:CoverletOutput=TestResults/coverage `
/p:CoverletOutputFormat=opencover
shell: pwsh
# 3) END: SonarScanner
- name: SonarScanner End
if: always()
run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
shell: pwsh
shell: pwsh
176 changes: 176 additions & 0 deletions EchoServerTests/EchoServerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using EchoTcpServer;

namespace EchoServerTests
{
public class EchoServerHandleClientTests
{
[Test]
public async Task HandleClientAsync_EchoesSingleMessage()
{
// Arrange
var input = new byte[] { 0x48, 0x65, 0x6C, 0x6C, 0x6F }; // "Hello"
using var stream = new MemoryStream();
stream.Write(input, 0, input.Length);
stream.Position = 0;

// Act
await EchoServer.HandleClientAsync(stream, CancellationToken.None);

// Assert — read back what was written after the original input
var result = stream.ToArray();
var echoed = result.Skip(input.Length).ToArray();
Assert.That(echoed, Is.EqualTo(input));
}

[Test]
public async Task HandleClientAsync_EchoesMultipleChunks()
{
// Arrange — simulate two sequential writes by concatenating data
var chunk1 = new byte[] { 0x01, 0x02, 0x03 };
var chunk2 = new byte[] { 0x04, 0x05 };
var combined = chunk1.Concat(chunk2).ToArray();

using var stream = new MemoryStream();
stream.Write(combined, 0, combined.Length);
stream.Position = 0;

// Act
await EchoServer.HandleClientAsync(stream, CancellationToken.None);

// Assert
var result = stream.ToArray();
var echoed = result.Skip(combined.Length).ToArray();
Assert.That(echoed, Is.EqualTo(combined));
}

[Test]
public async Task HandleClientAsync_EmptyStream_WritesNothing()
{
// Arrange
using var stream = new MemoryStream();
// Empty — nothing to read

// Act
await EchoServer.HandleClientAsync(stream, CancellationToken.None);

// Assert
Assert.That(stream.Length, Is.EqualTo(0));
}

[Test]
public async Task HandleClientAsync_RespectsLargePayload()
{
// Arrange — 4KB payload
var input = new byte[4096];
new Random(42).NextBytes(input);

using var stream = new MemoryStream();
stream.Write(input, 0, input.Length);
stream.Position = 0;

// Act
await EchoServer.HandleClientAsync(stream, CancellationToken.None);

// Assert
var result = stream.ToArray();
var echoed = result.Skip(input.Length).ToArray();
Assert.That(echoed, Is.EqualTo(input));
}
}

public class UdpTimedSenderBuildMessageTests
{
[Test]
public void BuildMessage_HasCorrectHeader()
{
// Arrange
ushort seq = 1;
var samples = new byte[] { 0xAA, 0xBB };

// Act
var msg = UdpTimedSender.BuildMessage(seq, samples);

// Assert — first two bytes are the fixed header
Assert.That(msg[0], Is.EqualTo(0x04));
Assert.That(msg[1], Is.EqualTo(0x84));
}

[Test]
public void BuildMessage_HasCorrectSequenceNumber()
{
// Arrange
ushort seq = 0x0A0B;
var samples = new byte[] { 0xFF };

// Act
var msg = UdpTimedSender.BuildMessage(seq, samples);

// Assert — bytes 2-3 are the little-endian sequence number
var parsedSeq = BitConverter.ToUInt16(msg, 2);
Assert.That(parsedSeq, Is.EqualTo(seq));
}

[Test]
public void BuildMessage_HasCorrectTotalLength()
{
// Arrange
ushort seq = 5;
var samples = new byte[1024];

// Act
var msg = UdpTimedSender.BuildMessage(seq, samples);

// Assert — 2 header + 2 seq + 1024 samples = 1028
Assert.That(msg.Length, Is.EqualTo(2 + 2 + 1024));
}

[Test]
public void BuildMessage_ContainsSamplesAtEnd()
{
// Arrange
ushort seq = 1;
var samples = new byte[] { 0x11, 0x22, 0x33 };

// Act
var msg = UdpTimedSender.BuildMessage(seq, samples);

// Assert — last 3 bytes match samples
var tail = msg.Skip(4).ToArray();
Assert.That(tail, Is.EqualTo(samples));
}

[Test]
public void BuildMessage_EmptySamples_ReturnsHeaderAndSeqOnly()
{
// Arrange
ushort seq = 0;
var samples = Array.Empty<byte>();

// Act
var msg = UdpTimedSender.BuildMessage(seq, samples);

// Assert — only header + seq = 4 bytes
Assert.That(msg.Length, Is.EqualTo(4));
}
}

public class EchoServerConstructorTests
{
[Test]
public void Constructor_DoesNotThrow()
{
// Act & Assert
Assert.DoesNotThrow(() => new EchoServer(0));
}

[Test]
public void Stop_AfterConstruction_DoesNotThrow()
{
// Arrange
var server = new EchoServer(0);

// Act & Assert — stopping without starting should not crash
Assert.DoesNotThrow(() => server.Stop());
}
}
}
29 changes: 29 additions & 0 deletions EchoServerTests/EchoServerTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="coverlet.msbuild" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\EchoTcpServer\EchoServer.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>

</Project>
Loading