From f3aa7c929117734b3c83105342716597578fc1d8 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 05:55:15 +0100 Subject: [PATCH 01/23] build: re-create the bug by building on windows --- .github/workflows/dotnet.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a7c2739..e97a041 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -5,7 +5,7 @@ on: branches: [ main ] pull_request: branches: [ main ] - + env: packageVersionPrefix: ${{ '0.0.' }} packageVersionSuffixForFeatureBranch: ${{ '-alpha' }} @@ -13,12 +13,15 @@ env: jobs: build-and-test: - runs-on: ubuntu-latest + strategy: + matrix: + # os: [ macos-latest, ubuntu-latest, windows-latest ] + os: [ windows-latest ] + runs-on: ${{ matrix.os }} name: Build and test - steps: - uses: actions/checkout@v2 - + - name: Setup environment variables (main branch) if: github.ref == 'refs/heads/main' run: echo "packageVersion=${{ env.packageVersionPrefix }}${{ github.run_number }}${{ env.packageVersionSuffixForMainBranch }}" >> $GITHUB_ENV @@ -54,7 +57,7 @@ jobs: - name: Test NuGet package run: ./smoketest.sh working-directory: RemoteControlledProcess.Nupkg.Tests - + - name: Generate coverage reports run: reportgenerator "-reports:RemoteControlledProcess.Acceptance.Tests/TestResults/*.xml;RemoteControlledProcess.Unit.Tests/TestResults/*.xml" \ "-targetdir:report" \ @@ -78,9 +81,9 @@ jobs: publish-reports: runs-on: ubuntu-latest name: Publish coverage reports - + needs: build-and-test - + steps: # the repository is required by codeclimate-action - uses: actions/checkout@v2 @@ -90,7 +93,7 @@ jobs: with: name: coverage-reports path: coverage-reports - + - name: Publish coverage report to coveralls.io uses: coverallsapp/github-action@master with: @@ -107,7 +110,7 @@ jobs: publish-nuget: runs-on: ubuntu-latest name: Publish NuGet package - + needs: publish-reports steps: @@ -116,7 +119,7 @@ jobs: with: name: nuget-package path: nuget-package - + - name: Identify package version run: cat nuget-package/VERSION.txt >> $GITHUB_ENV From 4185ba367c79f4f5898706b54cc368bbff4ab271 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 06:19:41 +0100 Subject: [PATCH 02/23] build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e97a041..7e27faa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,6 +46,9 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + - name: Test with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' From ca6033788d08b087cb1ed5ad45525349f3a14b65 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 06:41:27 +0100 Subject: [PATCH 03/23] chore: add logging to unit test failing under windows --- .../ExceptionReporterExtensionTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs index 290ea6d..74c17eb 100644 --- a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs +++ b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs @@ -2,12 +2,16 @@ using Microsoft.Extensions.Logging; using Moq; using Xunit; +using Xunit.Abstractions; namespace RemoteControlledProcess.Unit.Tests { public class ExceptionReporterExtensionTests { private const string ExceptionMessage = "Exception generated for test purpose"; + private ITestOutputHelper _testOutputHelper; + + public ExceptionReporterExtensionTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; [Theory] [InlineData(0, @@ -30,6 +34,12 @@ public void Write_CalledInCatchBlock_WrittenMessagesMatch(int invocationIndex, s // Assert var actualMessage = (string)writerMock.Invocations[invocationIndex].Arguments[0]; + + _testOutputHelper.WriteLine("===== Expected Message Regex:"); + _testOutputHelper.WriteLine($"\"{expectedMessageRegex}\""); + _testOutputHelper.WriteLine("===== Actual Message:"); + _testOutputHelper.WriteLine($"\"{actualMessage}\""); + Assert.Matches(expectedMessageRegex, actualMessage); } @@ -54,6 +64,17 @@ public void Log_CalledInCatchBlock_LogsCriticalMessageWithExpectedRegex() "Unhandled exception in .*RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs:[0-9]+"; var actualLogLevel = (LogLevel)loggerMock.Invocations[0].Arguments[0]; var actualMessage = loggerMock.Invocations[0].Arguments[2].ToString(); + + _testOutputHelper.WriteLine("===== Expected Message Regex:"); + _testOutputHelper.WriteLine($"\"{expectedMessageRegex}\""); + _testOutputHelper.WriteLine("===== Actual Message:"); + _testOutputHelper.WriteLine($"\"{actualMessage}\""); + + _testOutputHelper.WriteLine("===== Expected LogLevel:"); + _testOutputHelper.WriteLine($"\"{LogLevel.Critical}\""); + _testOutputHelper.WriteLine("===== Actual LogLevel:"); + _testOutputHelper.WriteLine($"\"{actualLogLevel}\""); + Assert.Equal(LogLevel.Critical, actualLogLevel); Assert.Matches(expectedMessageRegex, actualMessage); } From 760f3e97364ea7cfb24a3dd5dfeec866dbeb97eb Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 06:53:48 +0100 Subject: [PATCH 04/23] fix: consider the windows path separator - backslash - in test expectation regex --- .../ExceptionReporterExtensionTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs index 74c17eb..e9b227e 100644 --- a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs +++ b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs @@ -15,7 +15,7 @@ public class ExceptionReporterExtensionTests [Theory] [InlineData(0, - "Unhandled exception in .*RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs:[0-9]+")] + @"Unhandled exception in .*RemoteControlledProcess\.Unit\.Tests[\/\\]ExceptionReporterExtensionTests\.cs:[0-9]+")] [InlineData(1, ExceptionMessage)] public void Write_CalledInCatchBlock_WrittenMessagesMatch(int invocationIndex, string expectedMessageRegex) { @@ -61,7 +61,7 @@ public void Log_CalledInCatchBlock_LogsCriticalMessageWithExpectedRegex() // Assert var expectedMessageRegex = - "Unhandled exception in .*RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs:[0-9]+"; + @"Unhandled exception in .*RemoteControlledProcess\.Unit\.Tests[\/\\]ExceptionReporterExtensionTests\.cs:[0-9]+"; var actualLogLevel = (LogLevel)loggerMock.Invocations[0].Arguments[0]; var actualMessage = loggerMock.Invocations[0].Arguments[2].ToString(); From 306fc6b60766aecf52fd48b8ac07520e591993d3 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 06:58:57 +0100 Subject: [PATCH 05/23] revert: chore: add logging to unit test failing under windows --- .../ExceptionReporterExtensionTests.cs | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs index e9b227e..6391db6 100644 --- a/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs +++ b/RemoteControlledProcess.Unit.Tests/ExceptionReporterExtensionTests.cs @@ -2,16 +2,12 @@ using Microsoft.Extensions.Logging; using Moq; using Xunit; -using Xunit.Abstractions; namespace RemoteControlledProcess.Unit.Tests { public class ExceptionReporterExtensionTests { private const string ExceptionMessage = "Exception generated for test purpose"; - private ITestOutputHelper _testOutputHelper; - - public ExceptionReporterExtensionTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; [Theory] [InlineData(0, @@ -34,12 +30,6 @@ public void Write_CalledInCatchBlock_WrittenMessagesMatch(int invocationIndex, s // Assert var actualMessage = (string)writerMock.Invocations[invocationIndex].Arguments[0]; - - _testOutputHelper.WriteLine("===== Expected Message Regex:"); - _testOutputHelper.WriteLine($"\"{expectedMessageRegex}\""); - _testOutputHelper.WriteLine("===== Actual Message:"); - _testOutputHelper.WriteLine($"\"{actualMessage}\""); - Assert.Matches(expectedMessageRegex, actualMessage); } @@ -64,17 +54,6 @@ public void Log_CalledInCatchBlock_LogsCriticalMessageWithExpectedRegex() @"Unhandled exception in .*RemoteControlledProcess\.Unit\.Tests[\/\\]ExceptionReporterExtensionTests\.cs:[0-9]+"; var actualLogLevel = (LogLevel)loggerMock.Invocations[0].Arguments[0]; var actualMessage = loggerMock.Invocations[0].Arguments[2].ToString(); - - _testOutputHelper.WriteLine("===== Expected Message Regex:"); - _testOutputHelper.WriteLine($"\"{expectedMessageRegex}\""); - _testOutputHelper.WriteLine("===== Actual Message:"); - _testOutputHelper.WriteLine($"\"{actualMessage}\""); - - _testOutputHelper.WriteLine("===== Expected LogLevel:"); - _testOutputHelper.WriteLine($"\"{LogLevel.Critical}\""); - _testOutputHelper.WriteLine("===== Actual LogLevel:"); - _testOutputHelper.WriteLine($"\"{actualLogLevel}\""); - Assert.Equal(LogLevel.Critical, actualLogLevel); Assert.Matches(expectedMessageRegex, actualMessage); } From f7a00ab50268b8c649bc86bbcd23581d77926a8f Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 17 Feb 2021 06:59:13 +0100 Subject: [PATCH 06/23] revert: build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7e27faa..e97a041 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,9 +46,6 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - - name: Test with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' From 695c1d47cf48dd22fe44313c8ad43c7a22cb9aa4 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 06:15:56 +0100 Subject: [PATCH 07/23] test(acceptance): enhance logging --- RemoteControlledProcess/ProcessWrapper.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/RemoteControlledProcess/ProcessWrapper.cs b/RemoteControlledProcess/ProcessWrapper.cs index e328e8f..225902a 100644 --- a/RemoteControlledProcess/ProcessWrapper.cs +++ b/RemoteControlledProcess/ProcessWrapper.cs @@ -233,8 +233,10 @@ private void WaitForProcessExit() { TestOutputHelper?.WriteLine("Waiting for process to shutdown ..."); _process.WaitForExit(2000); - TestOutputHelper?.WriteLine($"Process {_appProjectName} has " + (_process.HasExited ? "" : "NOT ") + - "completed."); + + var processDescription = IsCoverletEnabled ? $"coverlet({_appProjectName})" : _appProjectName; + var conditionalNot = _process.HasExited ? "" : "NOT "; + TestOutputHelper?.WriteLine($"Process {processDescription} has {conditionalNot}completed."); } public void ForceTermination() From b3b50af67f36d426ef381d31ccc13b200da408ca Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 06:20:56 +0100 Subject: [PATCH 08/23] build: separate unit tests run from acceptance test run --- .github/workflows/dotnet.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e97a041..ef0457c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -45,9 +45,12 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - - name: Test with coverage - run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' + + - name: Run unit tests with coverage + run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Unit.Tests/RemoteControlledProcess.Unit.Tests.csproj + + - name: Run acceptance tests with coverage + run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Acceptance.Tests/RemoteControlledProcess.Acceptance.Tests.csproj - name: Build NuGet package run: | From b1b0366d4e4c6f249200b37604b82bcfb5a3c20e Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 06:21:10 +0100 Subject: [PATCH 09/23] build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ef0457c..8ebdcda 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,6 +46,9 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + - name: Run unit tests with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Unit.Tests/RemoteControlledProcess.Unit.Tests.csproj From 940c9ecc134db9a5d7e5201858480cbde602ba5d Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 07:01:13 +0100 Subject: [PATCH 10/23] revert: build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 8ebdcda..ef0457c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,9 +46,6 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - - name: Run unit tests with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Unit.Tests/RemoteControlledProcess.Unit.Tests.csproj From 74c726992f5de3e5dbfb8b78460b8e015691953d Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 07:01:31 +0100 Subject: [PATCH 11/23] revert: build: separate unit tests run from acceptance test run --- .github/workflows/dotnet.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ef0457c..e97a041 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -45,12 +45,9 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - - name: Run unit tests with coverage - run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Unit.Tests/RemoteControlledProcess.Unit.Tests.csproj - - - name: Run acceptance tests with coverage - run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Acceptance.Tests/RemoteControlledProcess.Acceptance.Tests.csproj + + - name: Test with coverage + run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' - name: Build NuGet package run: | From 6c717b0ccd78a9f3a86417a31b0538c832a57378 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 18 Feb 2021 07:02:13 +0100 Subject: [PATCH 12/23] test: test output of taskkill on windows --- .../GlobalSuppressions.cs | 6 +++ ...oteControlledProcess.Taskkill.Tests.csproj | 26 ++++++++++ .../TaskkillTests.cs | 47 +++++++++++++++++++ RemoteControlledProcess.sln | 14 ++++++ 4 files changed, 93 insertions(+) create mode 100644 RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs create mode 100644 RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj create mode 100644 RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs diff --git a/RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs b/RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs new file mode 100644 index 0000000..f8cd5cc --- /dev/null +++ b/RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs @@ -0,0 +1,6 @@ +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( + "Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", + Justification = "Unit test naming follows https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html", + Scope = "namespaceanddescendants", Target = "RemoteControlledProcess.Taskkill.Tests")] \ No newline at end of file diff --git a/RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj b/RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj new file mode 100644 index 0000000..9631cee --- /dev/null +++ b/RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj @@ -0,0 +1,26 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs b/RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs new file mode 100644 index 0000000..6f8564f --- /dev/null +++ b/RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs @@ -0,0 +1,47 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; +using Xunit; +using Xunit.Abstractions; + +namespace RemoteControlledProcess.Taskkill.Tests +{ + public class TaskkillTests + { + private ITestOutputHelper _testOutputHelper; + + public TaskkillTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; + + [Fact] + public void RunTaskkillProcess_OnWindows_ShowsProcessOutput() + { + string processName; + string arguments; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + processName = "taskkill"; + arguments = "/?"; + } + else + { + processName = "kill"; + arguments = "-l"; + } + + var processStartInfo = new ProcessStartInfo(processName) + { + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + Arguments = arguments + }; + + var process = new Process { StartInfo = processStartInfo }; + process.Start(); + process.WaitForExit(30000); + + _testOutputHelper.WriteLine($"Process produced the following output: \"{process.StandardOutput.ReadToEnd()}\""); + } + } +} diff --git a/RemoteControlledProcess.sln b/RemoteControlledProcess.sln index 6fe1f85..95cfa78 100644 --- a/RemoteControlledProcess.sln +++ b/RemoteControlledProcess.sln @@ -32,6 +32,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RemoteControlledProcess.Nup EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteControlledProcess.Unit.Tests", "RemoteControlledProcess.Unit.Tests\RemoteControlledProcess.Unit.Tests.csproj", "{7BC3300D-4599-409C-9839-A69E6E66CD7F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteControlledProcess.Taskkill.Tests", "RemoteControlledProcess.Taskkill.Tests\RemoteControlledProcess.Taskkill.Tests.csproj", "{288D6EDE-DC2C-4EE7-A3BA-7FE605865413}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -90,6 +92,18 @@ Global {7BC3300D-4599-409C-9839-A69E6E66CD7F}.Release|x64.Build.0 = Release|Any CPU {7BC3300D-4599-409C-9839-A69E6E66CD7F}.Release|x86.ActiveCfg = Release|Any CPU {7BC3300D-4599-409C-9839-A69E6E66CD7F}.Release|x86.Build.0 = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|Any CPU.Build.0 = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|x64.ActiveCfg = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|x64.Build.0 = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|x86.ActiveCfg = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Debug|x86.Build.0 = Debug|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|Any CPU.ActiveCfg = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|Any CPU.Build.0 = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|x64.ActiveCfg = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|x64.Build.0 = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|x86.ActiveCfg = Release|Any CPU + {288D6EDE-DC2C-4EE7-A3BA-7FE605865413}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From e4d775fc360ddd2cc169aacaafc806e22647502b Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 05:41:28 +0100 Subject: [PATCH 13/23] test(acceptance): deactivate acceptance tests temporarily --- .../Features/CorrectUsage.feature | 4 ++++ .../Features/SaveReportBeneathCurrentProject.feature | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature b/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature index 338a385..d1f741b 100644 --- a/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature +++ b/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature @@ -4,12 +4,14 @@ Feature: Correct Usage As a test developer using ProcessWrapper I want to know how ProcessWrapper shall be used + @Ignore Scenario: Correct usage: 1 application with coverlet enabled Given 1 application is running with coverlet 'enabled' When a TERM signal is sent to all applications Then all applications shut down And the reported total line coverage is greater 0% + @Ignore Scenario: Correct usage: 2 applications, 1 has coverlet enabled, 1 has coverlet disabled Given 1 application is running with coverlet 'enabled' And 1 application is running with coverlet 'disabled' @@ -17,12 +19,14 @@ Feature: Correct Usage Then all applications shut down And the reported total line coverage is greater 0% + @Ignore Scenario: Correct usage: 2 applications, both have coverlet disabled Given 2 applications are running with coverlet 'disabled' When a TERM signal is sent to all applications Then all applications shut down And the log is free of exception messages + @Ignore Scenario: Wrong usage: 2 applications, both have coverlet enabled Given 2 applications are running with coverlet 'enabled' When a TERM signal is sent to all applications diff --git a/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature b/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature index d660744..e7e9346 100644 --- a/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature +++ b/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature @@ -3,7 +3,8 @@ Feature: Save Report Beneath Current Project In order to have a clean project structure As a developer using the NuGet package I want generated coverage reports to be stored in the TestResults folder of the current project - + + @Ignore Scenario: Generate coverage report in TestResults folder of current project Given the number of coverage reports in the TestResults folder is known And 1 application is running with coverlet 'enabled' From 8a90eb0df2750033135a3a17e8218030062dfe21 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 05:47:47 +0100 Subject: [PATCH 14/23] build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e97a041..7812f9d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -54,6 +54,9 @@ jobs: dotnet pack RemoteControlledProcess/RemoteControlledProcess.csproj /p:PackageVersion=${{ env.packageVersion }} echo "packageVersion=${{ env.packageVersion }}" > RemoteControlledProcess/bin/Debug/VERSION.txt + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + - name: Test NuGet package run: ./smoketest.sh working-directory: RemoteControlledProcess.Nupkg.Tests From 554ef15c4ee5f4dde52de8ba899e20db82838266 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 05:53:54 +0100 Subject: [PATCH 15/23] build: setup tmate debugging session --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7812f9d..7e27faa 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,6 +46,9 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + - name: Test with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' @@ -54,9 +57,6 @@ jobs: dotnet pack RemoteControlledProcess/RemoteControlledProcess.csproj /p:PackageVersion=${{ env.packageVersion }} echo "packageVersion=${{ env.packageVersion }}" > RemoteControlledProcess/bin/Debug/VERSION.txt - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - - name: Test NuGet package run: ./smoketest.sh working-directory: RemoteControlledProcess.Nupkg.Tests From 5060bc0da3acd072faec4a0858ed43008c1b49f4 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:14:01 +0100 Subject: [PATCH 16/23] revert: build: setup tmate debugging session --- .github/workflows/dotnet.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7e27faa..e97a041 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,9 +46,6 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - - name: Test with coverage run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' From 3958f8de1a6ecf7d56e4834c551a376f2b0af6ab Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:16:05 +0100 Subject: [PATCH 17/23] test: run all tests sequentially --- .github/workflows/dotnet.yml | 4 ++-- RemoteControlledProcess.Tests.proj | 5 +++++ RemoteControlledProcess.sln | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 RemoteControlledProcess.Tests.proj diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e97a041..d541811 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -46,8 +46,8 @@ jobs: - name: Build run: dotnet build --configuration Debug --no-restore - - name: Test with coverage - run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' + - name: Run tests sequentially with coverage + run: dotnet test --no-restore --verbosity normal /p:BuildInParallel=false /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Tests.proj - name: Build NuGet package run: | diff --git a/RemoteControlledProcess.Tests.proj b/RemoteControlledProcess.Tests.proj new file mode 100644 index 0000000..66e162d --- /dev/null +++ b/RemoteControlledProcess.Tests.proj @@ -0,0 +1,5 @@ + + + + + diff --git a/RemoteControlledProcess.sln b/RemoteControlledProcess.sln index 95cfa78..7428d9f 100644 --- a/RemoteControlledProcess.sln +++ b/RemoteControlledProcess.sln @@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{86E95D10-0 run-application.bat = run-application.bat run-application.sh = run-application.sh Nuget-OfficialOnly.config = Nuget-OfficialOnly.config + RemoteControlledProcess.Tests.proj = RemoteControlledProcess.Tests.proj EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RemoteControlledProcess.Application", "RemoteControlledProcess.Application\RemoteControlledProcess.Application.csproj", "{5122B0AC-FAD4-44F4-B372-C5A6AED29E22}" From 280180c6dbd365bc39e231c5a5741c8a082136b3 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:19:23 +0100 Subject: [PATCH 18/23] build: fix failed dotnet restore and dotnet build add "RemoteControlledProcess.sln" as a parameter to the dotnet command. This resolves the ambiguity between the .sln and a .proj file --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d541811..1eae9a1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,10 +41,10 @@ jobs: dotnet tool install --global dotnet-reportgenerator-globaltool - name: Install dependencies - run: dotnet restore + run: dotnet restore RemoteControlledProcess.sln - name: Build - run: dotnet build --configuration Debug --no-restore + run: dotnet build --configuration Debug --no-restore RemoteControlledProcess.sln - name: Run tests sequentially with coverage run: dotnet test --no-restore --verbosity normal /p:BuildInParallel=false /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Tests.proj From c08809f19b7693391d38a4b3ad3438b93281e868 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:27:10 +0100 Subject: [PATCH 19/23] test(smoketest): fix when run unter windows --- .../Features/SmokeTests.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RemoteControlledProcess.Acceptance.Tests/Features/SmokeTests.cs b/RemoteControlledProcess.Acceptance.Tests/Features/SmokeTests.cs index 28ed0dc..9d08668 100644 --- a/RemoteControlledProcess.Acceptance.Tests/Features/SmokeTests.cs +++ b/RemoteControlledProcess.Acceptance.Tests/Features/SmokeTests.cs @@ -1,9 +1,14 @@ using Xunit; +using Xunit.Abstractions; namespace RemoteControlledProcess.Acceptance.Tests.Features { public class SmokeTests { + private readonly ITestOutputHelper _testOutputHelper; + + public SmokeTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; + /// /// SmokeTest used to verify that the NuGet package has been created correctly. /// @@ -18,8 +23,10 @@ public void SmokeTest() processWrapper.Start(); processWrapper.ShutdownGracefully(); processWrapper.ForceTermination(); + var output = processWrapper.ReadOutput(); - Assert.Contains("STOP", output); + _testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); + Assert.Contains("Process ID", output); } } } \ No newline at end of file From 00c5e84b3d8e76f88fee5d9743f0f32d28a9c37f Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:47:33 +0100 Subject: [PATCH 20/23] revert: test(acceptance): deactivate acceptance tests temporarily --- .../Features/CorrectUsage.feature | 4 ---- .../Features/SaveReportBeneathCurrentProject.feature | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature b/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature index d1f741b..338a385 100644 --- a/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature +++ b/RemoteControlledProcess.Acceptance.Tests/Features/CorrectUsage.feature @@ -4,14 +4,12 @@ Feature: Correct Usage As a test developer using ProcessWrapper I want to know how ProcessWrapper shall be used - @Ignore Scenario: Correct usage: 1 application with coverlet enabled Given 1 application is running with coverlet 'enabled' When a TERM signal is sent to all applications Then all applications shut down And the reported total line coverage is greater 0% - @Ignore Scenario: Correct usage: 2 applications, 1 has coverlet enabled, 1 has coverlet disabled Given 1 application is running with coverlet 'enabled' And 1 application is running with coverlet 'disabled' @@ -19,14 +17,12 @@ Feature: Correct Usage Then all applications shut down And the reported total line coverage is greater 0% - @Ignore Scenario: Correct usage: 2 applications, both have coverlet disabled Given 2 applications are running with coverlet 'disabled' When a TERM signal is sent to all applications Then all applications shut down And the log is free of exception messages - @Ignore Scenario: Wrong usage: 2 applications, both have coverlet enabled Given 2 applications are running with coverlet 'enabled' When a TERM signal is sent to all applications diff --git a/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature b/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature index e7e9346..d660744 100644 --- a/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature +++ b/RemoteControlledProcess.Acceptance.Tests/Features/SaveReportBeneathCurrentProject.feature @@ -3,8 +3,7 @@ Feature: Save Report Beneath Current Project In order to have a clean project structure As a developer using the NuGet package I want generated coverage reports to be stored in the TestResults folder of the current project - - @Ignore + Scenario: Generate coverage report in TestResults folder of current project Given the number of coverage reports in the TestResults folder is known And 1 application is running with coverlet 'enabled' From e6b32e0b7a37bb27b7e8edcaa723496a93125ff3 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:49:12 +0100 Subject: [PATCH 21/23] test(consumer): create consumer driven tests for kill and taskkill system calls --- .../GlobalSuppressions.cs | 2 +- .../KillTests.cs | 44 +++++++++++++++++++ ...trolledProcess.ConsumerDriven.Tests.csproj | 0 .../TaskkillTests.cs | 26 +++++------ RemoteControlledProcess.sln | 2 +- 5 files changed, 58 insertions(+), 16 deletions(-) rename {RemoteControlledProcess.Taskkill.Tests => RemoteControlledProcess.ConsumerDriven.Tests}/GlobalSuppressions.cs (91%) create mode 100644 RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs rename RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj => RemoteControlledProcess.ConsumerDriven.Tests/RemoteControlledProcess.ConsumerDriven.Tests.csproj (100%) rename {RemoteControlledProcess.Taskkill.Tests => RemoteControlledProcess.ConsumerDriven.Tests}/TaskkillTests.cs (63%) diff --git a/RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs b/RemoteControlledProcess.ConsumerDriven.Tests/GlobalSuppressions.cs similarity index 91% rename from RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs rename to RemoteControlledProcess.ConsumerDriven.Tests/GlobalSuppressions.cs index f8cd5cc..5883ae2 100644 --- a/RemoteControlledProcess.Taskkill.Tests/GlobalSuppressions.cs +++ b/RemoteControlledProcess.ConsumerDriven.Tests/GlobalSuppressions.cs @@ -3,4 +3,4 @@ [assembly: SuppressMessage( "Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Justification = "Unit test naming follows https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html", - Scope = "namespaceanddescendants", Target = "RemoteControlledProcess.Taskkill.Tests")] \ No newline at end of file + Scope = "namespaceanddescendants", Target = "RemoteControlledProcess.ConsumerDriven.Tests")] \ No newline at end of file diff --git a/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs b/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs new file mode 100644 index 0000000..a71a5dc --- /dev/null +++ b/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs @@ -0,0 +1,44 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; +using Xunit; +using Xunit.Abstractions; + +namespace RemoteControlledProcess.ConsumerDriven.Tests +{ + public class KillTests + { + private readonly ITestOutputHelper _testOutputHelper; + + public KillTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; + + [Fact] + public void RunKillProcess_NotOnWindows_ShowsProcessOutput() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + _testOutputHelper.WriteLine($"Windows OS detected. Skipping test RunKillProcess_NotOnWindows_ShowsProcessOutput."); + return; + } + + var processName = "kill"; + var arguments = "-l"; + + var processStartInfo = new ProcessStartInfo(processName) + { + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + Arguments = arguments + }; + + var process = new Process { StartInfo = processStartInfo }; + process.Start(); + process.WaitForExit(30000); + + var output = process.StandardOutput.ReadToEnd(); + _testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); + Assert.Contains("term", output); + } + } +} diff --git a/RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj b/RemoteControlledProcess.ConsumerDriven.Tests/RemoteControlledProcess.ConsumerDriven.Tests.csproj similarity index 100% rename from RemoteControlledProcess.Taskkill.Tests/RemoteControlledProcess.Taskkill.Tests.csproj rename to RemoteControlledProcess.ConsumerDriven.Tests/RemoteControlledProcess.ConsumerDriven.Tests.csproj diff --git a/RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs b/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs similarity index 63% rename from RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs rename to RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs index 6f8564f..5ab20e7 100644 --- a/RemoteControlledProcess.Taskkill.Tests/TaskkillTests.cs +++ b/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs @@ -3,31 +3,26 @@ using Xunit; using Xunit.Abstractions; -namespace RemoteControlledProcess.Taskkill.Tests +namespace RemoteControlledProcess.ConsumerDriven.Tests { public class TaskkillTests { private ITestOutputHelper _testOutputHelper; public TaskkillTests(ITestOutputHelper testOutputHelper) => _testOutputHelper = testOutputHelper; - + [Fact] public void RunTaskkillProcess_OnWindows_ShowsProcessOutput() { - string processName; - string arguments; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - processName = "taskkill"; - arguments = "/?"; - } - else - { - processName = "kill"; - arguments = "-l"; + _testOutputHelper.WriteLine($"Non-Windows OS detected. Skipping test RunTaskkillProcess_OnWindows_ShowsProcessOutput."); + return; } + var processName = "taskkill"; + var arguments = "/?"; + var processStartInfo = new ProcessStartInfo(processName) { UseShellExecute = false, @@ -41,7 +36,10 @@ public void RunTaskkillProcess_OnWindows_ShowsProcessOutput() process.Start(); process.WaitForExit(30000); - _testOutputHelper.WriteLine($"Process produced the following output: \"{process.StandardOutput.ReadToEnd()}\""); + var output = process.StandardOutput.ReadToEnd(); + _testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); + Assert.Contains("TASKKILL", output); + Assert.Contains("/PID", output); } } } diff --git a/RemoteControlledProcess.sln b/RemoteControlledProcess.sln index 7428d9f..f32a93c 100644 --- a/RemoteControlledProcess.sln +++ b/RemoteControlledProcess.sln @@ -33,7 +33,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RemoteControlledProcess.Nup EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteControlledProcess.Unit.Tests", "RemoteControlledProcess.Unit.Tests\RemoteControlledProcess.Unit.Tests.csproj", "{7BC3300D-4599-409C-9839-A69E6E66CD7F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteControlledProcess.Taskkill.Tests", "RemoteControlledProcess.Taskkill.Tests\RemoteControlledProcess.Taskkill.Tests.csproj", "{288D6EDE-DC2C-4EE7-A3BA-7FE605865413}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteControlledProcess.ConsumerDriven.Tests", "RemoteControlledProcess.ConsumerDriven.Tests\RemoteControlledProcess.ConsumerDriven.Tests.csproj", "{288D6EDE-DC2C-4EE7-A3BA-7FE605865413}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 121b4b7c70e6ea0ef82efb088837580e7a252982 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 06:56:51 +0100 Subject: [PATCH 22/23] refactor(consumer driven tests): extract ProcessRunner class --- .../KillTests.cs | 20 ++----------- .../ProcessRunner.cs | 29 +++++++++++++++++++ .../TaskkillTests.cs | 18 +----------- 3 files changed, 32 insertions(+), 35 deletions(-) create mode 100644 RemoteControlledProcess.ConsumerDriven.Tests/ProcessRunner.cs diff --git a/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs b/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs index a71a5dc..fba8a7e 100644 --- a/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs +++ b/RemoteControlledProcess.ConsumerDriven.Tests/KillTests.cs @@ -20,24 +20,8 @@ public void RunKillProcess_NotOnWindows_ShowsProcessOutput() return; } - var processName = "kill"; - var arguments = "-l"; - - var processStartInfo = new ProcessStartInfo(processName) - { - UseShellExecute = false, - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - Arguments = arguments - }; - - var process = new Process { StartInfo = processStartInfo }; - process.Start(); - process.WaitForExit(30000); - - var output = process.StandardOutput.ReadToEnd(); - _testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); + var output = ProcessRunner.RunProcess("kill", "-l", _testOutputHelper); + Assert.Contains("term", output); } } diff --git a/RemoteControlledProcess.ConsumerDriven.Tests/ProcessRunner.cs b/RemoteControlledProcess.ConsumerDriven.Tests/ProcessRunner.cs new file mode 100644 index 0000000..513aba3 --- /dev/null +++ b/RemoteControlledProcess.ConsumerDriven.Tests/ProcessRunner.cs @@ -0,0 +1,29 @@ +using System.Diagnostics; +using Xunit.Abstractions; + +namespace RemoteControlledProcess.ConsumerDriven.Tests +{ + public static class ProcessRunner + { + public static string RunProcess(string processName, string arguments, ITestOutputHelper testOutputHelper) + { + var processStartInfo = new ProcessStartInfo(processName) + { + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + Arguments = arguments + }; + + var process = new Process { StartInfo = processStartInfo }; + process.Start(); + process.WaitForExit(30000); + + var output = process.StandardOutput.ReadToEnd(); + testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); + + return output; + } + } +} \ No newline at end of file diff --git a/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs b/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs index 5ab20e7..06cdf83 100644 --- a/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs +++ b/RemoteControlledProcess.ConsumerDriven.Tests/TaskkillTests.cs @@ -20,24 +20,8 @@ public void RunTaskkillProcess_OnWindows_ShowsProcessOutput() return; } - var processName = "taskkill"; - var arguments = "/?"; + var output = ProcessRunner.RunProcess("taskkill", "/?", _testOutputHelper); - var processStartInfo = new ProcessStartInfo(processName) - { - UseShellExecute = false, - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - Arguments = arguments - }; - - var process = new Process { StartInfo = processStartInfo }; - process.Start(); - process.WaitForExit(30000); - - var output = process.StandardOutput.ReadToEnd(); - _testOutputHelper.WriteLine($"Process produced the following output: \"{output}\""); Assert.Contains("TASKKILL", output); Assert.Contains("/PID", output); } From e7e7e52278110a1a9b8919c8d02ccc30a249fc83 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Fri, 19 Feb 2021 07:02:39 +0100 Subject: [PATCH 23/23] docs: add explanation for serializing tests --- .github/workflows/dotnet.yml | 4 ++++ RemoteControlledProcess/ProcessWrapper.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 1eae9a1..7b72446 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -47,6 +47,10 @@ jobs: run: dotnet build --configuration Debug --no-restore RemoteControlledProcess.sln - name: Run tests sequentially with coverage + # By default tests run in parallel. + # Coverlet instrumentation requires running tests sequentially. + # Thus, using a separate project and the /p:BuildInParallel switch to serialize the test runs + # See also: https://github.com/nunit/nunit3-vs-adapter/issues/657 run: dotnet test --no-restore --verbosity normal /p:BuildInParallel=false /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput='./TestResults/coverage.cobertura.xml' RemoteControlledProcess.Tests.proj - name: Build NuGet package diff --git a/RemoteControlledProcess/ProcessWrapper.cs b/RemoteControlledProcess/ProcessWrapper.cs index 225902a..662197e 100644 --- a/RemoteControlledProcess/ProcessWrapper.cs +++ b/RemoteControlledProcess/ProcessWrapper.cs @@ -8,6 +8,8 @@ namespace RemoteControlledProcess { + // TODO: Double check whether serializing tests is really required - see dotnet.yml + public sealed class ProcessWrapper : IDisposable { private readonly string _appDir;