From 89891804b77e88bc245109c634639f4198850240 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Wed, 17 Dec 2025 13:41:38 +0200 Subject: [PATCH 1/8] Added unit test project, action and status badge to TechnitiumLibrary --- .github/workflows/unit-testing.yml | 41 +++++++++++++++++++ README.md | 4 ++ TechnitiumLibrary.UnitTests/MSTestSettings.cs | 3 ++ .../TechnitiumLibrary.UnitTests.csproj | 15 +++++++ TechnitiumLibrary.sln | 10 ++++- TechnitiumLibrary/Base32.cs | 2 +- TechnitiumLibrary/CollectionExtensions.cs | 2 +- 7 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/unit-testing.yml create mode 100644 TechnitiumLibrary.UnitTests/MSTestSettings.cs create mode 100644 TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj diff --git a/.github/workflows/unit-testing.yml b/.github/workflows/unit-testing.yml new file mode 100644 index 00000000..11ef5256 --- /dev/null +++ b/.github/workflows/unit-testing.yml @@ -0,0 +1,41 @@ +name: Unit testing (Windows / MSBuild) + +on: + workflow_dispatch: + push: + branches: ["master"] + pull_request: + branches: ["master"] + schedule: + - cron: "0 0 * * 0" # weekly, Sunday 00:00 UTC + +permissions: + contents: read + +jobs: + test: + runs-on: windows-latest + + env: + SOLUTION_NAME: TechnitiumLibrary.sln + BUILD_CONFIGURATION: Debug + + steps: + - uses: actions/checkout@v4 + + - name: Install .NET 9 SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1 + + - name: Restore + run: msbuild ${{ env.SOLUTION_NAME }} /t:Restore + + - name: Build + run: msbuild ${{ env.SOLUTION_NAME }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION }} + + - name: Test (msbuild) + run: msbuild TechnitiumLibrary.Tests\TechnitiumLibrary.Tests.csproj /t:Test /p:Configuration=${{ env.BUILD_CONFIGURATION }} \ No newline at end of file diff --git a/README.md b/README.md index b329873a..ad146a6c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # TechnitiumLibrary A library for .net based applications. + +## Quality Assurance + +[![Unit testing (Windows / MSBuild)](https://github.com/TechnitiumSoftware/TechnitiumLibrary/actions/workflows/unit-testing.yml/badge.svg)](https://github.com/TechnitiumSoftware/TechnitiumLibrary/actions/workflows/unit-testing.yml) \ No newline at end of file diff --git a/TechnitiumLibrary.UnitTests/MSTestSettings.cs b/TechnitiumLibrary.UnitTests/MSTestSettings.cs new file mode 100644 index 00000000..e466aa12 --- /dev/null +++ b/TechnitiumLibrary.UnitTests/MSTestSettings.cs @@ -0,0 +1,3 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj new file mode 100644 index 00000000..81e42102 --- /dev/null +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + latest + disable + enable + true + + + + + + + diff --git a/TechnitiumLibrary.sln b/TechnitiumLibrary.sln index 9cbcda3e..0b02129c 100644 --- a/TechnitiumLibrary.sln +++ b/TechnitiumLibrary.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31912.275 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TechnitiumLibrary.IO", "TechnitiumLibrary.IO\TechnitiumLibrary.IO.csproj", "{E0BA5456-FEAA-4380-92BB-6B1C4BC3DC70}" EndProject @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechnitiumLibrary", "Techni EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechnitiumLibrary.Security.OTP", "TechnitiumLibrary.Security.OTP\TechnitiumLibrary.Security.OTP.csproj", "{72AF4EB6-EB81-4655-9998-8BF24B304614}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechnitiumLibrary.UnitTests", "TechnitiumLibrary.UnitTests\TechnitiumLibrary.UnitTests.csproj", "{D0CD41D8-E5F0-4EEF-81E3-587A2A877C49}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +77,10 @@ Global {72AF4EB6-EB81-4655-9998-8BF24B304614}.Debug|Any CPU.Build.0 = Debug|Any CPU {72AF4EB6-EB81-4655-9998-8BF24B304614}.Release|Any CPU.ActiveCfg = Release|Any CPU {72AF4EB6-EB81-4655-9998-8BF24B304614}.Release|Any CPU.Build.0 = Release|Any CPU + {D0CD41D8-E5F0-4EEF-81E3-587A2A877C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0CD41D8-E5F0-4EEF-81E3-587A2A877C49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0CD41D8-E5F0-4EEF-81E3-587A2A877C49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0CD41D8-E5F0-4EEF-81E3-587A2A877C49}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TechnitiumLibrary/Base32.cs b/TechnitiumLibrary/Base32.cs index e5d6b8b2..464590e3 100644 --- a/TechnitiumLibrary/Base32.cs +++ b/TechnitiumLibrary/Base32.cs @@ -317,4 +317,4 @@ public static byte[] FromBase32HexString(string data) #endregion } -} +} \ No newline at end of file diff --git a/TechnitiumLibrary/CollectionExtensions.cs b/TechnitiumLibrary/CollectionExtensions.cs index 91a04cd1..539f8dc4 100644 --- a/TechnitiumLibrary/CollectionExtensions.cs +++ b/TechnitiumLibrary/CollectionExtensions.cs @@ -112,4 +112,4 @@ public static int GetArrayHashCode(this IReadOnlyCollection value) return hashCode; } } -} +} \ No newline at end of file From 13d11648dc9b9883951c55c60a525a4e0ec05bc4 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Mon, 12 Jan 2026 22:45:36 +0200 Subject: [PATCH 2/8] Added unit tests --- .../WindowsFirewallTests.cs | 55 +++++++++++++++++++ .../TechnitiumLibrary.UnitTests.csproj | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs new file mode 100644 index 00000000..152737b9 --- /dev/null +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs @@ -0,0 +1,55 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using TechnitiumLibrary.Net.Firewall; + +namespace TechnitiumLibrary.UnitTests.TechnitiumLibrary.Net.Firewall +{ + [TestClass] + public sealed class WindowsFirewallPublicTests + { + [TestMethod] + public void AddPort_ShouldThrow_WhenUnsupportedProtocol() + { + // Protocol ICMPv4 cannot be added using AddPort + Assert.ThrowsExactly(() => WindowsFirewall.AddPort("bad", Protocol.ICMPv4, port: 55, enable: true)); + } + + [TestMethod] + public void RemovePort_ShouldThrow_WhenUnsupportedProtocol() + { + // RemovePort validates only TCP, UDP, ANY + Assert.ThrowsExactly(() => WindowsFirewall.RemovePort(Protocol.IGMP, 123)); + } + + [TestMethod] + public void PortExists_ShouldThrow_WhenUnsupportedProtocol() + { + Assert.ThrowsExactly(() => WindowsFirewall.PortExists(Protocol.IGMP, 44)); + } + + [TestMethod] + public void RuleExistsVista_ShouldReturnDoesNotExist_WhenInputsClearlyNotMatchingAnything() + { + // Since firewall is not guaranteed to have this rule, + // safest expected response is DoesNotExists. + RuleStatus result = WindowsFirewall.RuleExistsVista( + name: "__Definitely_Not_A_Real_Rule__", + applicationPath: "__Fake__"); + + Assert.AreEqual(RuleStatus.DoesNotExists, result); + } + + [TestMethod] + public void ApplicationExists_ShouldReturnDoesNotExist_WhenApplicationIsNotRegistered() + { + // Public observable guarantee: + // if the system has no such application entry → DoesNotExists + + const string fakePath = "C:\\DefinitelyNotExisting\\app.exe"; + + RuleStatus status = WindowsFirewall.ApplicationExists(fakePath); + + Assert.AreEqual(RuleStatus.DoesNotExists, status); + } + } +} diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj index 81e42102..744a928c 100644 --- a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.UnitTests.csproj @@ -9,7 +9,7 @@ - + From 9fd7bbdc21c2b21e797f0147c823e0309a070d28 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Wed, 28 Jan 2026 21:40:46 +0200 Subject: [PATCH 3/8] Downgraded solution version Signed-off-by: Zafer Balkan --- TechnitiumLibrary.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TechnitiumLibrary.sln b/TechnitiumLibrary.sln index 0b02129c..bfc3298a 100644 --- a/TechnitiumLibrary.sln +++ b/TechnitiumLibrary.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.1.11312.151 d18.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TechnitiumLibrary.IO", "TechnitiumLibrary.IO\TechnitiumLibrary.IO.csproj", "{E0BA5456-FEAA-4380-92BB-6B1C4BC3DC70}" EndProject From de1e1fe200b9b75cb5a7bee915206f2757adf1cb Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Thu, 29 Jan 2026 10:20:55 +0200 Subject: [PATCH 4/8] Fixed workflow --- .github/workflows/unit-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-testing.yml b/.github/workflows/unit-testing.yml index 11ef5256..74c7a992 100644 --- a/.github/workflows/unit-testing.yml +++ b/.github/workflows/unit-testing.yml @@ -38,4 +38,4 @@ jobs: run: msbuild ${{ env.SOLUTION_NAME }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION }} - name: Test (msbuild) - run: msbuild TechnitiumLibrary.Tests\TechnitiumLibrary.Tests.csproj /t:Test /p:Configuration=${{ env.BUILD_CONFIGURATION }} \ No newline at end of file + run: msbuild TechnitiumLibrary.UnitTests\TechnitiumLibrary.UnitTests.csproj /t:Test /p:Configuration=${{ env.BUILD_CONFIGURATION }} \ No newline at end of file From 4187fb2e7828c564685c77de58b52bdc6b531e15 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Thu, 29 Jan 2026 10:31:59 +0200 Subject: [PATCH 5/8] Fixed test class name --- .../TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs index 152737b9..0698db87 100644 --- a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs @@ -5,7 +5,7 @@ namespace TechnitiumLibrary.UnitTests.TechnitiumLibrary.Net.Firewall { [TestClass] - public sealed class WindowsFirewallPublicTests + public sealed class WindowsFirewallTests { [TestMethod] public void AddPort_ShouldThrow_WhenUnsupportedProtocol() From 30db6c10a0aa9a25a5970785ac4b397585cb0bb5 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Thu, 29 Jan 2026 10:40:36 +0200 Subject: [PATCH 6/8] Updated workflow file --- .github/workflows/unit-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-testing.yml b/.github/workflows/unit-testing.yml index 74c7a992..5fbbae8e 100644 --- a/.github/workflows/unit-testing.yml +++ b/.github/workflows/unit-testing.yml @@ -29,7 +29,7 @@ jobs: dotnet-version: 9.0.x - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1 + uses: microsoft/setup-msbuild@v2 - name: Restore run: msbuild ${{ env.SOLUTION_NAME }} /t:Restore From 64efaf9746c600286482fd66b6d756a04cf46f3b Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Tue, 3 Feb 2026 19:25:27 +0200 Subject: [PATCH 7/8] Added OSCondition --- .../TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs index 0698db87..65da7f1e 100644 --- a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs @@ -8,6 +8,7 @@ namespace TechnitiumLibrary.UnitTests.TechnitiumLibrary.Net.Firewall public sealed class WindowsFirewallTests { [TestMethod] + [OSCondition(OperatingSystems.Windows)] public void AddPort_ShouldThrow_WhenUnsupportedProtocol() { // Protocol ICMPv4 cannot be added using AddPort @@ -15,6 +16,7 @@ public void AddPort_ShouldThrow_WhenUnsupportedProtocol() } [TestMethod] + [OSCondition(OperatingSystems.Windows)] public void RemovePort_ShouldThrow_WhenUnsupportedProtocol() { // RemovePort validates only TCP, UDP, ANY @@ -22,12 +24,14 @@ public void RemovePort_ShouldThrow_WhenUnsupportedProtocol() } [TestMethod] + [OSCondition(OperatingSystems.Windows)] public void PortExists_ShouldThrow_WhenUnsupportedProtocol() { Assert.ThrowsExactly(() => WindowsFirewall.PortExists(Protocol.IGMP, 44)); } [TestMethod] + [OSCondition(OperatingSystems.Windows)] public void RuleExistsVista_ShouldReturnDoesNotExist_WhenInputsClearlyNotMatchingAnything() { // Since firewall is not guaranteed to have this rule, @@ -40,6 +44,7 @@ public void RuleExistsVista_ShouldReturnDoesNotExist_WhenInputsClearlyNotMatchin } [TestMethod] + [OSCondition(OperatingSystems.Windows)] public void ApplicationExists_ShouldReturnDoesNotExist_WhenApplicationIsNotRegistered() { // Public observable guarantee: From 47cf1f69155b2879220a07f7209e00e52aae2932 Mon Sep 17 00:00:00 2001 From: Zafer Balkan Date: Tue, 3 Feb 2026 19:25:44 +0200 Subject: [PATCH 8/8] Added copyright --- .../WindowsFirewallTests.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs index 65da7f1e..e5a90545 100644 --- a/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs +++ b/TechnitiumLibrary.UnitTests/TechnitiumLibrary.Net.Firewall/WindowsFirewallTests.cs @@ -1,4 +1,24 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +/* +Technitium Library +Copyright (C) 2026 Shreyas Zare (shreyas@technitium.com) +Copyright (C) 2026 Zafer Balkan (zafer@zaferbalkan.com) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +*/ + +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using TechnitiumLibrary.Net.Firewall;