Skip to content

Commit

Permalink
Throw exception if --teamcity is specified but the extension is not p…
Browse files Browse the repository at this point in the history
…resent
  • Loading branch information
CharliePoole committed Nov 27, 2024
1 parent d238d33 commit de2add5
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 25 deletions.
2 changes: 1 addition & 1 deletion build.cake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Load the recipe
#load nuget:?package=NUnit.Cake.Recipe&version=1.2.0
#load nuget:?package=NUnit.Cake.Recipe&version=1.2.1-dev00002
// Comment out above line and uncomment below for local tests of recipe changes
//#load ../NUnit.Cake.Recipe/recipe/*.cake

Expand Down
73 changes: 50 additions & 23 deletions src/NUnitConsole/nunit3-console.tests/ConsoleRunnerTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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;
Expand All @@ -14,25 +15,43 @@ namespace NUnit.ConsoleRunner.Tests
{
class ConsoleRunnerTests
{
private ITestEngine _testEngine;
private IResultService _resultService;

[SetUp]
public void Setup()
{
_testEngine = Substitute.For<ITestEngine>();
_resultService = new FakeResultService();

_testEngine.Services.GetService<IResultService>().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<IService, IExtensionService>());
((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<NUnitEngineException>(() => { consoleRunner.Execute(); });
Assert.That(ex, Has.Message.EqualTo("The path specified in --result TestResult.xml could not be written to"));
}
var ex = Assert.Throws<NUnitEngineException>(() => { 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<NUnitEngineException>(
() => 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
Expand All @@ -43,25 +62,33 @@ public string[] Formats

public IResultWriter GetResultWriter(string format, object[] args)
{
return new FakeResultWriter();
return new FakeResultWriter(this);
}
}

internal class FakeResultWriter : IResultWriter
{
public void CheckWritability(string outputPath)
class FakeResultWriter : IResultWriter
{
throw new UnauthorizedAccessException();
}
private FakeResultService _service;

public void WriteResultFile(XmlNode resultNode, string outputPath)
{
throw new System.NotImplementedException();
}
public FakeResultWriter(FakeResultService service)
{
_service = service;
}

public void WriteResultFile(XmlNode resultNode, TextWriter writer)
{
throw new System.NotImplementedException();
public void CheckWritability(string outputPath)
{
if (_service.ThrowsUnauthorizedAccessException)
throw new UnauthorizedAccessException();
}

public void WriteResultFile(XmlNode resultNode, string outputPath)
{
throw new System.NotImplementedException();
}

public void WriteResultFile(XmlNode resultNode, TextWriter writer)
{
throw new System.NotImplementedException();
}
}
}
}
16 changes: 15 additions & 1 deletion src/NUnitConsole/nunit3-console/ConsoleRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

public static readonly int OK = 0;
public static readonly int INVALID_ARG = -1;
public static readonly int INVALID_ASSEMBLY = -2;
Expand Down Expand Up @@ -58,8 +61,19 @@ public ConsoleRunner(ITestEngine engine, ConsoleOptions options, ExtendedTextWri
_filterService = _engine.Services.GetService<ITestFilterService>();
_extensionService = _engine.Services.GetService<IExtensionService>();

// 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);
}

/// <summary>
Expand Down

0 comments on commit de2add5

Please sign in to comment.