ПЗС, Примачук Максим
Підключення SonarCloud і CI
Створено новий репозиторій на основі репозиторію курсу та підключено SonarCloud, вимкнено автоматичний аналіз.
Посилання – https://github.com/m4xym/NetSDR_Lab.git
Перший PR (m4xym/NetSDR_Lab#2) – не пройшов перевірку через недостатнє покриття коду та ризики безпеки, пов’язані з використанням ${{ secrets.SONAR_TOKEN }} безпосередньо в блоці run (sonarcloud.yml)
Code Smells через PR + “gated merge”
Виявлено та виправлено 6 нових Code smells (Mantainability):
-
Make '_sampleWriter' 'readonly'. Fields that are only assigned in the constructor should be "readonly" https://github.com/m4xym/NetSDR_Lab/commit/7a581ea95651b465146e14e95d0946a234ba1ee8
-
Cannot convert null literal to non-nullable reference type. https://github.com/m4xym/NetSDR_Lab/commit/edea573f091dcbd044110bfeaf5def14b119c7af
-
Non-nullable event 'UnsolicitedMessageReceived' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the event as nullable. https://github.com/m4xym/NetSDR_Lab/commit/f1e6ef1a45b5b058cf224b84d20bdcd3000a73c0
-
Remove the unused local variable 'code', 'sequenceNum', 'body'. https://github.com/m4xym/NetSDR_Lab/commit/da7a11f287afc9bd4d9f5024ab24a8be5e3facc5
Результат:
Тести та покриття
Поточне покриття – 0%.
Додано 6 unit тестів (PR m4xym/NetSDR_Lab#5 ):
- ConnectAsync_WhenAlreadyConnected_DoesNotConnectOrSend Перевіряє, чи виклик методу connect для вже активного з'єднання безпечно достроково завершується.
- StopIQAsync_NoConnection_DoesNotSendRequest Гарантує, що якщо застосунок намагається зупинити потік даних IQ під час відключення, метод коректно завершується без викидання помилок або спроб передачі команд через неактивний мережевий сокет.
- ChangeFrequencyAsync_ValidInputs_SendsCorrectMessage Підтверджує основну функціональність методу налаштування частоти. Перевіряє, що передача конкретної частоти в герцах та індексу каналу успішно упаковує корисне навантаження та передає його до потоку TCP.
- TcpClient_UnsolicitedMessage_RaisesUnsolicitedMessageReceivedEvent Тестує логіку маршрутизації TCP. Вводить імітовану фонову трансляцію з апаратного забезпечення та перевіряє, що подія - UnsolicitedMessageReceived успішно передається до програми, замість виконання завдання з очікуючим наказом.
- UdpClient_MessageReceived_CallsSampleWriterWithSamples Перевіряє працездатність парсера даних шляхом введення в UDP-потік імітованого корисного навантаження у вигляді байтів IQ перевіряється, чи NetSdrMessageHelper успішно перетворює корисне навантаження та передає отримані зразки повністю в пам'яті до роз'єднаного інтерфейсу ISampleWriter.
- ChangeFrequencyAsync_WhenNotConnected_HandlesNullResponseGracefully Перевіряє асинхронні механізми безпеки. Якщо команда запускається без активного з'єднання, базовий SendTcpRequest припиняється і повертає null.
Покриття становить 81.38%:
Дублікати через SonarCloud
Поточний рівень дублікатів коду становить 9.8%:
Дублікати виявлено у файлах:
-
TcpClientWrapper.cs — дублювання (14 %) Причина: 2 перевантаження для SendMessageAsync (одне приймає byte[], а інше – sting). Виправлення: щоб перевантаження для string перетворює корисне навантаження, а потім негайно передає його до перевантаження для byte[].
-
Дублювання в UdpClientWrapper.cs (28%) Причина: Методи StopListening() та Exit() містять ідентичний блок try/catch, логіку скасування, закриття сокета та ведення журналу в консолі. Виправлення: Exit() викликає StopListening().
Знижено Дублювання коду до 0%:
Архітектурні правила (NetArchTest)
Додано 2 тести для перевірки архітектури
-
Ізоляція доменної логіки (Messages_ShouldNot_DependOn_Networking) – Розділення відповідальності: тест гарантує, що простір імен Messages (де відбувається парсинг байтів та бізнес-логіка) є повністю незалежним. Він перевіряє, що парсер нічого не знає про інфраструктуру (Networking). Це захищає ядро програми: ми можемо змінити механізм роботи сокетів, не торкаючись логіки обробки самих повідомлень.
-
Інверсія залежностей (ClientApp_Should_DependOn_Interfaces...) – Принцип інверсії залежностей: тест забороняє головному класу NetSdrClient напряму створювати або залежати від конкретних класів (наприклад, TcpClientWrapper). Він змушує клас працювати виключно через абстракції (ITcpClient). Завдяки цьому ми зберігаємо можливість легко підміняти реальні мережеві виклики на моки (Mocks) під час тестування.
Для перевірки тестів додано тимчасовий демонстраційний метод BadArchitectureMethod у класі NetSdrMessageHelper, який навмисно створює жорстку прив'язку між незалежними модулями. Знаходячись у просторі імен Messages (який має відповідати лише за чисту логіку парсингу), він ініціалізує клас TcpClientWrapper з простору імен Networking.
Його наявність у коді гарантовано порушує правило ізоляції доменної логіки. Завдання цього методу – викликати спрацьовування NetArchTest.Rules, "завалити" збірку (зробити PR червоним).
Провал тесту Messages_ShouldNot_DependOn_Networking ламає збірку:
Виправлення (видалено BadArchitectureMethod):
Безпечний рефакторинг під тести
Поточне покриття EchoServer – 0%.
Рефакторинг EchoServer:
- Підтримка порту 0: якщо передати серверу значення 0, ОС автоматично призначить вільний тимчасовий порт. Logger: функція Console.WriteLine замінюється вбудованим Action, що дозволяє тестам фіксувати або приховувати записи в журналі.
- Розмежування функціональних блоків: логіка виведення інформації винесена в клас ProcessStreamAsync, який приймає стандартний потік.
Тести:
- StartAsync_AssignsDynamicPort_AndSetsIsRunningToTrue – Коректність ініціалізації сервера та правильну роботу з динамічними портами ОС: передає порт 0 під час створення сервера, що змушує ОС автоматично знайти та призначити будь-який вільний порт. Потім він перевіряє, що стан сервера IsRunning стає true, фактичний порт оновлюється на число більше за 0, а логер фіксує повідомлення про успішний старт. Це повністю усуває проблему "Address already in use", коли тести падають через зайнятий жорстко заданий порт (наприклад, 5000).
- Stop_SafeShutDownServer – Безпечне завершення роботи мережевого слухача: запускає сервер у фоновій задачі, дає йому час на ініціалізацію, а потім викликає метод Stop(). Він перевіряє, що внутрішній CancellationToken успішно скасовує очікування нових клієнтів, статус IsRunning змінюється на false, а процес зупинки не викидає фатальних винятків і фіксується у логах.
- Server_ReceivesAndEchoesDataCorrectly – здатність сервера приймати та повертати (Echo) байти без втрат: запускає сервер, після чого створює тестовий TcpClient та підключається до 127.0.0.1 на динамічно виділений порт. Тест відправляє текстовий рядок ("Hello, Echo Server!"), перетворений на масив байтів. Далі він вичитує відповідь із потоку та застосовує Assert для перевірки того, що отримана кількість байтів і сам текст збігаються до символу. Додатково перевіряється, чи логер зафіксував факт підключення клієнта та обсяг повернутих даних.
Покриття нового коду становить 82.76%:
Оновлення залежностей
Список залежностей:
У налаштуваннях увімкнено Dependency graph + Dependabot alerts.
- PR на оновлення coverlet.collector (m4xym/NetSDR_Lab#13)
У нових версіях Coverlet часто змінюється спосіб взаємодії з JIT-компілятором. Оновлення в цьому випадку може призвести до «фантомного» падіння покриття, коли показник покриття, що становив 80%, раптово впаде до 0%, оскільки інструментарій не зміг інтегруватися у структуру конкретного збірника. Версії Coverlet часто прив’язані до конкретних версій MSBuild. Істотний перехід на нову версію може вимагати оновленої версії .NET SDK для збірки або на GitHub Actions runner.
- PR на оновлення Microsoft.NET.Test.Sdk (m4xym/NetSDR_Lab#14)
Test SDK керує процесом виявлення тестів та інтеграцією з виконавцем. Значні зміни в цій частині можуть іноді спричиняти проблеми з виявленням тестів у Visual Studio або в певних адаптерах тестів CI/CD, якщо змінюється внутрішній протокол зв’язку виконавця.
-
PR на оновлення NUnit.Analyzers (m4xym/NetSDR_Lab#16)
-
PR на оновлення NUnit (m4xym/NetSDR_Lab#15)
Чистий проєкт і gated build
Статус проєкту:
- Coverage - 89.6%
- Duplications - 0%
- 1 Security Hotspots
Виправлено Security Hotspot "Make sure that using this pseudorandom number generator is safe here." (PR m4xym/NetSDR_Lab#21)
Увімкнено правила Require a pull request before merging та Require status checks to pass (Sonar Check)
Правило не дозволяє злиття до закінчення перевірки:















