From 0bf571e28ef15e4bac5e04be8d07be6d4ad35cb1 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sat, 21 Dec 2024 08:14:14 -0800 Subject: [PATCH] Port issue 1507 from 3.19 release --- .../ConsoleRunnerTests.cs | 51 +++++++++++++++---- .../nunit4-console/ConsoleRunner.cs | 19 ++++++- .../nunit4-netcore-console/ConsoleRunner.cs | 19 ++++++- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/NUnitConsole/nunit4-console.tests/ConsoleRunnerTests.cs b/src/NUnitConsole/nunit4-console.tests/ConsoleRunnerTests.cs index 7e177c9ac..01c080344 100644 --- a/src/NUnitConsole/nunit4-console.tests/ConsoleRunnerTests.cs +++ b/src/NUnitConsole/nunit4-console.tests/ConsoleRunnerTests.cs @@ -1,9 +1,11 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; +using System.Collections.Generic; using System.IO; using System.Xml; using NSubstitute; +using NUnit.ConsoleRunner; using NUnit.ConsoleRunner.Options; using NUnit.Engine; using NUnit.Engine.Extensibility; @@ -14,27 +16,46 @@ namespace NUnit.ConsoleRunner { class ConsoleRunnerTests { + private ITestEngine _testEngine; + private IResultService _resultService; + + [SetUp] + public void SetUp() + { + _testEngine = Substitute.For(); + _resultService = new FakeResultService(); + + _testEngine.Services.GetService().Returns(_resultService); + } + [Test] public void ThrowsNUnitEngineExceptionWhenTestResultsAreNotWriteable() { - using (var testEngine = new TestEngine()) - { - testEngine.Services.Add(new FakeResultService()); - testEngine.Services.Add(new TestFilterService()); - testEngine.Services.Add(Substitute.For()); + ((FakeResultService)_resultService).ThrowsUnauthorizedAccessException = true; - var consoleRunner = new ConsoleRunner(testEngine, ConsoleMocks.Options("mock-assembly.dll"), new ColorConsoleWriter()); + var consoleRunner = new ConsoleRunner(_testEngine, ConsoleMocks.Options("mock-assembly.dll"), new ColorConsoleWriter()); - var ex = Assert.Throws(() => { consoleRunner.Execute(); }); - Assert.That(ex, Has.Message.EqualTo("The path specified in --result TestResult.xml could not be written to")); - } + var ex = Assert.Throws(() => { consoleRunner.Execute(); }); + Assert.That(ex, Has.Message.EqualTo("The path specified in --result TestResult.xml could not be written to")); + } + + [Test] + public void ThrowsNUnitExceptionWhenTeamcityOptionIsSpecifiedButNotAvailable() + { + var ex = Assert.Throws( + () => new ConsoleRunner(_testEngine, ConsoleMocks.Options("mock-assembly.dll", "--teamcity"), new ColorConsoleWriter())); + + Assert.That(ex, Has.Message.Contains("teamcity")); } } internal class FakeResultService : Service, IResultService { + public bool ThrowsUnauthorizedAccessException; + public string[] Formats { + get { return new[] { "nunit3" }; @@ -43,15 +64,23 @@ public string[] Formats public IResultWriter GetResultWriter(string format, object[] args) { - return new FakeResultWriter(); + return new FakeResultWriter(this); } } internal class FakeResultWriter : IResultWriter { + private FakeResultService _service; + + public FakeResultWriter(FakeResultService service) + { + _service = service; + } + public void CheckWritability(string outputPath) { - throw new UnauthorizedAccessException(); + if (_service.ThrowsUnauthorizedAccessException) + throw new UnauthorizedAccessException(); } public void WriteResultFile(XmlNode resultNode, string outputPath) diff --git a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs index 25ce55535..7bdc21d99 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs +++ b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs @@ -25,6 +25,9 @@ public class ConsoleRunner // ourselves so as to stay in that range. private const int MAXIMUM_RETURN_CODE_ALLOWED = 100; // In case we are running on Unix + private const string EVENT_LISTENER_EXTENSION_PATH = "/NUnit/Engine/TypeExtensions/ITestEventListener"; + private const string TEAMCITY_EVENT_LISTENER = "NUnit.Engine.Listeners.TeamCityEventListener"; + private const string INDENT4 = " "; private const string INDENT6 = " "; private const string INDENT8 = " "; @@ -62,12 +65,24 @@ public ConsoleRunner(ITestEngine engine, ConsoleOptions options, ExtendedTextWri _filterService = _engine.Services.GetService(); _extensionService = _engine.Services.GetService(); + // TODO: Exit with error if any of the services are not found + + if (_options.TeamCity) + { + bool teamcityInstalled = false; + foreach (var node in _extensionService.GetExtensionNodes(EVENT_LISTENER_EXTENSION_PATH)) + if (teamcityInstalled = node.TypeName == TEAMCITY_EVENT_LISTENER) + break; + + if (!teamcityInstalled) throw new NUnitEngineException("Option --teamcity specified but the extension is not installed."); + } + // Enable TeamCityEventListener immediately, before the console is redirected - _extensionService?.EnableExtension("NUnit.Engine.Listeners.TeamCityEventListener", _options.TeamCity); + _extensionService.EnableExtension("NUnit.Engine.Listeners.TeamCityEventListener", _options.TeamCity); } /// - /// Executes tests according to the provided commandline options. + /// Executes tests according to the provided command-line options. /// /// public int Execute() diff --git a/src/NUnitConsole/nunit4-netcore-console/ConsoleRunner.cs b/src/NUnitConsole/nunit4-netcore-console/ConsoleRunner.cs index 25ce55535..7bdc21d99 100644 --- a/src/NUnitConsole/nunit4-netcore-console/ConsoleRunner.cs +++ b/src/NUnitConsole/nunit4-netcore-console/ConsoleRunner.cs @@ -25,6 +25,9 @@ public class ConsoleRunner // ourselves so as to stay in that range. private const int MAXIMUM_RETURN_CODE_ALLOWED = 100; // In case we are running on Unix + private const string EVENT_LISTENER_EXTENSION_PATH = "/NUnit/Engine/TypeExtensions/ITestEventListener"; + private const string TEAMCITY_EVENT_LISTENER = "NUnit.Engine.Listeners.TeamCityEventListener"; + private const string INDENT4 = " "; private const string INDENT6 = " "; private const string INDENT8 = " "; @@ -62,12 +65,24 @@ public ConsoleRunner(ITestEngine engine, ConsoleOptions options, ExtendedTextWri _filterService = _engine.Services.GetService(); _extensionService = _engine.Services.GetService(); + // TODO: Exit with error if any of the services are not found + + if (_options.TeamCity) + { + bool teamcityInstalled = false; + foreach (var node in _extensionService.GetExtensionNodes(EVENT_LISTENER_EXTENSION_PATH)) + if (teamcityInstalled = node.TypeName == TEAMCITY_EVENT_LISTENER) + break; + + if (!teamcityInstalled) throw new NUnitEngineException("Option --teamcity specified but the extension is not installed."); + } + // Enable TeamCityEventListener immediately, before the console is redirected - _extensionService?.EnableExtension("NUnit.Engine.Listeners.TeamCityEventListener", _options.TeamCity); + _extensionService.EnableExtension("NUnit.Engine.Listeners.TeamCityEventListener", _options.TeamCity); } /// - /// Executes tests according to the provided commandline options. + /// Executes tests according to the provided command-line options. /// /// public int Execute()