diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index e784069..2aeccc5 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -30,54 +30,43 @@ name: SonarCloud analysis on: push: - branches: [ "master" ] + branches: ["master"] pull_request: - branches: [ "master" ] + branches: ["master"] workflow_dispatch: permissions: - pull-requests: read # allows SonarCloud to decorate PRs with analysis results + pull-requests: read jobs: sonar-check: name: Sonar Check - runs-on: windows-latest # безпечно для будь-яких .NET проектів + runs-on: windows-latest steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } - uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' + dotnet-version: "8.0.x" - # 1) BEGIN: SonarScanner for .NET - name: SonarScanner Begin run: | dotnet tool install --global dotnet-sonarscanner echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH - dotnet sonarscanner begin ` - /k:"ppanchen_NetSdrClient" ` - /o:"ppanchen" ` - /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` - /d:sonar.cs.opencover.reportsPaths="**/coverage.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 + dotnet sonarscanner begin /k:"friezze_ReengineeringCourse" /o:"friezze" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.cs.opencover.reportsPaths="**/coverage.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 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 - # 3) END: SonarScanner + + - name: Tests with coverage (OpenCover) + shell: pwsh + run: dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build /p:CollectCoverage=true /p:CoverletOutput=TestResults/coverage.xml /p:CoverletOutputFormat=opencover + - name: SonarScanner End run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" shell: pwsh diff --git a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs index 0d69b4d..438dfaf 100644 --- a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs +++ b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs @@ -16,6 +16,8 @@ public static class NetSdrMessageHelper private const short _msgControlItemLength = 2; //2 byte, 16 bit private const short _msgSequenceNumberLength = 2; //2 byte, 16 bit + + public enum MsgTypes { SetControlItem, diff --git a/NetSdrClientApp/NetSdrClient.cs b/NetSdrClientApp/NetSdrClient.cs index b0a7c05..fbd8d3e 100644 --- a/NetSdrClientApp/NetSdrClient.cs +++ b/NetSdrClientApp/NetSdrClient.cs @@ -14,8 +14,8 @@ namespace NetSdrClientApp { public class NetSdrClient { - private ITcpClient _tcpClient; - private IUdpClient _udpClient; + private readonly ITcpClient _tcpClient; + private readonly IUdpClient _udpClient; public bool IQStarted { get; set; } @@ -66,7 +66,7 @@ public async Task StartIQAsync() return; } -; var iqDataMode = (byte)0x80; + var iqDataMode = (byte)0x80; var start = (byte)0x02; var fifo16bitCaptureMode = (byte)0x01; var n = (byte)1; @@ -114,9 +114,9 @@ public async Task ChangeFrequencyAsync(long hz, int channel) await SendTcpRequest(msg); } - private void _udpClient_MessageReceived(object? sender, byte[] e) + private static void _udpClient_MessageReceived(object? sender, byte[] e) { - NetSdrMessageHelper.TranslateMessage(e, out MsgTypes type, out ControlItemCodes code, out ushort sequenceNum, out byte[] body); + NetSdrMessageHelper.TranslateMessage(e, out _, out _, out _, out byte[] body); var samples = NetSdrMessageHelper.GetSamples(16, body); Console.WriteLine($"Samples recieved: " + body.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}")); @@ -153,7 +153,7 @@ private async Task SendTcpRequest(byte[] msg) private void _tcpClient_MessageReceived(object? sender, byte[] e) { - //TODO: add Unsolicited messages handling here + //NOTE: add Unsolicited messages handling here if (responseTaskSource != null) { responseTaskSource.SetResult(e); diff --git a/NetSdrClientApp/Networking/TcpClientWrapper.cs b/NetSdrClientApp/Networking/TcpClientWrapper.cs index 1f37e2e..abdab76 100644 --- a/NetSdrClientApp/Networking/TcpClientWrapper.cs +++ b/NetSdrClientApp/Networking/TcpClientWrapper.cs @@ -84,18 +84,10 @@ public async Task SendMessageAsync(byte[] data) } } - public async Task SendMessageAsync(string str) + public Task SendMessageAsync(string str) { var data = Encoding.UTF8.GetBytes(str); - if (Connected && _stream != null && _stream.CanWrite) - { - Console.WriteLine($"Message sent: " + data.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}")); - await _stream.WriteAsync(data, 0, data.Length); - } - else - { - throw new InvalidOperationException("Not connected to a server."); - } + return SendMessageAsync(data); } private async Task StartListeningAsync() @@ -136,5 +128,4 @@ private async Task StartListeningAsync() } } } - -} +} \ No newline at end of file diff --git a/NetSdrClientApp/Networking/UdpClientWrapper.cs b/NetSdrClientApp/Networking/UdpClientWrapper.cs index 31e0b79..3c12217 100644 --- a/NetSdrClientApp/Networking/UdpClientWrapper.cs +++ b/NetSdrClientApp/Networking/UdpClientWrapper.cs @@ -61,16 +61,7 @@ public void StopListening() public void Exit() { - try - { - _cts?.Cancel(); - _udpClient?.Close(); - Console.WriteLine("Stopped listening for UDP messages."); - } - catch (Exception ex) - { - Console.WriteLine($"Error while stopping: {ex.Message}"); - } + StopListening(); } public override int GetHashCode() diff --git a/NetSdrClientAppTests/ArchitectureTests.cs b/NetSdrClientAppTests/ArchitectureTests.cs new file mode 100644 index 0000000..dec06fc --- /dev/null +++ b/NetSdrClientAppTests/ArchitectureTests.cs @@ -0,0 +1,24 @@ +using NetArchTest.Rules; +using NUnit.Framework; +using NetSdrClientApp.Networking; + +namespace NetSdrClientAppTests +{ + public class ArchitectureTests + { + [Test] + public void Messages_ShouldNotDependOn_Networking() + { + // Arrange + var result = Types.InAssembly(typeof(TcpClientWrapper).Assembly) + .That() + .ResideInNamespace("NetSdrClientApp.Messages") + .ShouldNot() + .HaveDependencyOn("NetSdrClientApp.Networking") + .GetResult(); + + // Assert + Assert.That(result.IsSuccessful, Is.True, "Messages namespace has a prohibited dependency on Networking."); + } + } +} \ No newline at end of file diff --git a/NetSdrClientAppTests/NetSdrClientAppTests.csproj b/NetSdrClientAppTests/NetSdrClientAppTests.csproj index 3cbc46a..728eebf 100644 --- a/NetSdrClientAppTests/NetSdrClientAppTests.csproj +++ b/NetSdrClientAppTests/NetSdrClientAppTests.csproj @@ -11,8 +11,13 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/NetSdrClientAppTests/NetSdrClientTests.cs b/NetSdrClientAppTests/NetSdrClientTests.cs index ad00c4f..6032648 100644 --- a/NetSdrClientAppTests/NetSdrClientTests.cs +++ b/NetSdrClientAppTests/NetSdrClientTests.cs @@ -116,4 +116,62 @@ public async Task StopIQTest() } //TODO: cover the rest of the NetSdrClient code here + [Test] + public async Task StartIQAsync_CalledTwice_ExecutesTwice() + { + // Arrange + await ConnectAsyncTest(); + + // Act + await _client.StartIQAsync(); + await _client.StartIQAsync(); + + // Assert + _updMock.Verify(udp => udp.StartListeningAsync(), Times.Exactly(2)); + } + + [Test] + public async Task StopIQAsync_CalledTwice_ExecutesTwice() + { + // Arrange + await ConnectAsyncTest(); + + // Act + await _client.StopIQAsync(); + await _client.StopIQAsync(); + + // Assert + _updMock.Verify(udp => udp.StopListening(), Times.Exactly(2)); + } + + [Test] + public void Disconect_CalledTwice_ExecutesTwice() + { + // Act + _client.Disconect(); + _client.Disconect(); + + // Assert + _tcpMock.Verify(tcp => tcp.Disconnect(), Times.Exactly(2)); + } + + [Test] + public async Task StartIQAsync_NeverCalls_TcpDisconnect() + { + // Act + await _client.StartIQAsync(); + + // Assert + _tcpMock.Verify(tcp => tcp.Disconnect(), Times.Never); + } + + [Test] + public async Task StopIQAsync_NeverCalls_TcpDisconnect() + { + // Act + await _client.StopIQAsync(); + + // Assert + _tcpMock.Verify(tcp => tcp.Disconnect(), Times.Never); + } } diff --git a/README.md b/README.md index b3a9029..b09ef7d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,57 @@ [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) + +## Тут все пов'язане з виконанням самих лаб +# 1 +![Чек сонарклауда з форка репозиторія](image.png) +![Бейджі](image-1.png) +Лінк на коміт +''' +https://github.com/friezze/ReengineeringCourse/commit/2534516c319a38d4aecd5d70a4e93c086961300 +''' + +# 2 + +До змін +![alt text](image-2.png) +Після +![alt text](image-3.png) +Може здатися дивним що їх стало більше але скоріше за все це тому що пофіксився білдер через зміни в які я лив в мейн і мерджив в гілку але сонар аналізував пуши в мейн а тік злиття. Але у будьякому випадку 8 фіксед. + +# 3 +До а якщо бути точним одразу після включення ковередж +![alt text](image-5.png) +Після(пушу тестів нових) +![alt text](image-6.png) + +# 4 +До + +![alt text](image-4.png) + +Після + +![alt text](image-7.png) + +Важливо зауважити що завдяки зменьшенню дублікатів піднявся і тест коверед бо коду стало банально меньше + +![alt text](image-8.png) + +# 5 + +Це так виглядає після додання порушення прав архітектури і самого порушення. +![alt text](image-9.png) + + +![alt text](image-10.png) + +Після виправлення + +![alt text](image-11.png) + + + Цей репозиторій використовується для курсу **реінжиніринг ПЗ**. Мета — провести комплексний реінжиніринг спадкового коду NetSdrClient, включаючи рефакторинг архітектури, покращення якості коду, впровадження сучасних практик розробки та автоматизацію процесів контролю якості через CI/CD пайплайни. diff --git a/image-1.png b/image-1.png new file mode 100644 index 0000000..7f7452d Binary files /dev/null and b/image-1.png differ diff --git a/image-10.png b/image-10.png new file mode 100644 index 0000000..dd73204 Binary files /dev/null and b/image-10.png differ diff --git a/image-11.png b/image-11.png new file mode 100644 index 0000000..d0bc53d Binary files /dev/null and b/image-11.png differ diff --git a/image-2.png b/image-2.png new file mode 100644 index 0000000..7c9f7ab Binary files /dev/null and b/image-2.png differ diff --git a/image-3.png b/image-3.png new file mode 100644 index 0000000..d50e72f Binary files /dev/null and b/image-3.png differ diff --git a/image-4.png b/image-4.png new file mode 100644 index 0000000..8bb1a03 Binary files /dev/null and b/image-4.png differ diff --git a/image-5.png b/image-5.png new file mode 100644 index 0000000..1f473da Binary files /dev/null and b/image-5.png differ diff --git a/image-6.png b/image-6.png new file mode 100644 index 0000000..ff2e9bf Binary files /dev/null and b/image-6.png differ diff --git a/image-7.png b/image-7.png new file mode 100644 index 0000000..e21f162 Binary files /dev/null and b/image-7.png differ diff --git a/image-8.png b/image-8.png new file mode 100644 index 0000000..1b32640 Binary files /dev/null and b/image-8.png differ diff --git a/image-9.png b/image-9.png new file mode 100644 index 0000000..c41bc24 Binary files /dev/null and b/image-9.png differ diff --git a/image.png b/image.png new file mode 100644 index 0000000..6b49fb0 Binary files /dev/null and b/image.png differ