Skip to content

Commit

Permalink
Merge pull request #110 from AutomatedArchitecture/feature/invalid-pa…
Browse files Browse the repository at this point in the history
…ssword-tfs

Feature: invalid password tfs
  • Loading branch information
lprichar committed Dec 3, 2017
2 parents c4a517e + 8b803d9 commit cea52c5
Show file tree
Hide file tree
Showing 109 changed files with 161 additions and 375,841 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -108,3 +108,5 @@ Desktop.ini

Releases/Updates
/SirenOfShame.Extruder/Services/MySosOnlineService.cs
.vs/
packages/
15 changes: 8 additions & 7 deletions SirenOfShame.Test.Unit/Service/TeamCityBuildStatusTest.cs
Expand Up @@ -29,18 +29,19 @@ public class FakeTeamCityService : TeamCityService
public class TeamCityBuildStatusTest
{
[Test]
[ExpectedException(typeof(ServerUnavailableException))]
public void ServerIsDoingACleanup()
{
FakeTeamCityService teamCityService = new FakeTeamCityService();
BuildDefinitionSetting buildDefinitionSetting = new BuildDefinitionSetting();
XDocument xDoc = TeamCityResources.TeamCityServerCleanup;
teamCityService.GetBuildStatusAndCommentsFromXDocumentFake(
"fakeurl",
"username",
"password",
buildDefinitionSetting,
xDoc);
Assert.Throws<ServerUnavailableException>(() =>
teamCityService.GetBuildStatusAndCommentsFromXDocumentFake(
"fakeurl",
"username",
"password",
buildDefinitionSetting,
xDoc)
);
}
}
}
14 changes: 10 additions & 4 deletions SirenOfShame.Test.Unit/SirenOfShame.Test.Unit.csproj
Expand Up @@ -36,21 +36,26 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Moq">
<HintPath>..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
<Reference Include="Moq, Version=4.7.145.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.7.145\lib\net45\Moq.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
<Reference Include="nunit.framework, Version=3.9.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.9.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
Expand Down Expand Up @@ -84,6 +89,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources\TeamCity\TeamCityResources.cs" />
<Compile Include="Services\TfsRestServiceTest.cs" />
<Compile Include="TfsRestServices\TfsRestWatcherTest.cs" />
<Compile Include="Watcher\WebClientXmlTest.cs" />
<EmbeddedResource Include="Resources\JenkinsPassingBuild.xml">
<SubType>Designer</SubType>
Expand Down
117 changes: 117 additions & 0 deletions SirenOfShame.Test.Unit/TfsRestServices/TfsRestWatcherTest.cs
@@ -0,0 +1,117 @@
using System.Collections.Generic;
using System.Net;
using Moq;
using NUnit.Framework;
using SirenOfShame.Lib.Exceptions;
using SirenOfShame.Lib.Settings;
using SirenOfShame.Lib.Watcher;
using TfsRestServices;

namespace SirenOfShame.Test.Unit.TfsRestServices
{
public class MyTfsRestWatcher : TfsRestWatcher
{
private readonly IEnumerable<BuildDefinitionSetting> _buildDefinitions;

public MyTfsRestWatcher(TfsRestService tfsRestService, IEnumerable<BuildDefinitionSetting> buildDefinitions, CiEntryPointSetting ciEntryPointSetting) : base(null, null)
{
_buildDefinitions = buildDefinitions;
_service = tfsRestService;
CiEntryPointSetting = ciEntryPointSetting;
}

protected override IEnumerable<BuildDefinitionSetting> GetAllWatchedBuildDefinitions()
{
return _buildDefinitions;
}

public IList<BuildStatus> MyGetBuildStatus()
{
return GetBuildStatus();
}
}

[TestFixture]
public class TfsRestWatcherTest
{
[Test]
public void GivenNullUrlInCiEntryPointSetting_WhenGettingBuildStatus_ThenSosException()
{
// arrange
var ciEntryPointSetting = new CiEntryPointSetting();
var tfsRestWatcher = new MyTfsRestWatcher(null, new BuildDefinitionSetting[] { }, ciEntryPointSetting);

// act
Assert.Throws<SosException>(() => tfsRestWatcher.MyGetBuildStatus(), "TFS URL is null or empty")
;
}

[Test]
public void GivenWebExceptionRemoteNameCouldNotBeResolved_WhenGettingBuildStatus_ThenServerUnavailableException()
{
// arrange
var buildDefinitionSettings = new[] {new BuildDefinitionSetting()};
var tfsRestService = new Mock<TfsRestService>();
var ciEntryPointSetting = new CiEntryPointSetting { Url = "url" };
tfsRestService.Setup(i => i.GetBuildsStatuses(ciEntryPointSetting, buildDefinitionSettings))
.ThrowsAsync(new WebException("The remote name could not be resolved:"));
var tfsRestWatcher = new MyTfsRestWatcher(tfsRestService.Object, buildDefinitionSettings, ciEntryPointSetting);

// assert & act
Assert.Throws<ServerUnavailableException>(() =>
tfsRestWatcher.MyGetBuildStatus()
);
}

[Test]
public void GivenWebExceptionUnableConnectRemoteServer_WhenGettingBuildStatus_ThenServerUnavailableException()
{
// arrange
var buildDefinitionSettings = new[] {new BuildDefinitionSetting()};
var tfsRestService = new Mock<TfsRestService>();
var ciEntryPointSetting = new CiEntryPointSetting { Url = "url" };
tfsRestService.Setup(i => i.GetBuildsStatuses(ciEntryPointSetting, buildDefinitionSettings))
.ThrowsAsync(new WebException("Unable to connect to the remote server"));
var tfsRestWatcher = new MyTfsRestWatcher(tfsRestService.Object, buildDefinitionSettings, ciEntryPointSetting);

// assert & act
Assert.Throws<ServerUnavailableException>(() =>
tfsRestWatcher.MyGetBuildStatus()
);
}

[Test]
public void GivenHttpRequestException_WhenGettingBuildStatus_ThenServerUnavailableException()
{
// arrange
var buildDefinitionSettings = new[] {new BuildDefinitionSetting()};
var tfsRestService = new Mock<TfsRestService>();
var ciEntryPointSetting = new CiEntryPointSetting { Url = "url" };
tfsRestService.Setup(i => i.GetBuildsStatuses(ciEntryPointSetting, buildDefinitionSettings))
.ThrowsAsync(new System.Net.Http.HttpRequestException("Unable to connect to the remote server"));
var tfsRestWatcher = new MyTfsRestWatcher(tfsRestService.Object, buildDefinitionSettings, ciEntryPointSetting);

// assert & act
Assert.Throws<ServerUnavailableException>(() =>
tfsRestWatcher.MyGetBuildStatus()
);
}

[Test]
public void GivenHttpRequestExceptionWith401InMessage_WhenGettingBuildStatus_ThenInvalidCredentialsException()
{
// arrange
var buildDefinitionSettings = new[] { new BuildDefinitionSetting() };
var tfsRestService = new Mock<TfsRestService>();
var ciEntryPointSetting = new CiEntryPointSetting { Url = "url" };
tfsRestService.Setup(i => i.GetBuildsStatuses(ciEntryPointSetting, buildDefinitionSettings))
.ThrowsAsync(new System.Net.Http.HttpRequestException("Response status code does not indicate success: 401 (Unauthorized)."));
var tfsRestWatcher = new MyTfsRestWatcher(tfsRestService.Object, buildDefinitionSettings, ciEntryPointSetting);

// assert & act
Assert.Throws<InvalidCredentialsException>(() =>
tfsRestWatcher.MyGetBuildStatus()
);
}
}
}
2 changes: 1 addition & 1 deletion SirenOfShame.Test.Unit/Watcher/RulesEngineTest.cs
Expand Up @@ -482,7 +482,7 @@ public void BuildNameChanges_BuildSettingsNameIsUpdated()
}

[Test]
[Ignore]
[Ignore("I don't remember why")]
public void TwoBuildsBackToBack_SystemFindsFirstResultForReputation()
{
var rulesEngine = new RulesEngineWrapper();
Expand Down
5 changes: 3 additions & 2 deletions SirenOfShame.Test.Unit/packages.config
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="4.2.1" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Moq" version="4.0.10827" targetFramework="net40" />
<package id="Moq" version="4.7.145" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net45" />
<package id="NUnit" version="2.6.3" targetFramework="net40" />
<package id="NUnit" version="3.9.0" targetFramework="net45" />
</packages>
2 changes: 1 addition & 1 deletion TfsRestServices/TfsRestService.cs
Expand Up @@ -69,7 +69,7 @@ private async Task<List<TfsRestBuildDefinition>> GetBuildDefinitions(TfsConnecti
return result;
}

public async Task<IEnumerable<TfsRestBuildStatus>> GetBuildsStatuses(CiEntryPointSetting ciEntryPointSetting, BuildDefinitionSetting[] watchedBuildDefinitions)
public virtual async Task<IEnumerable<TfsRestBuildStatus>> GetBuildsStatuses(CiEntryPointSetting ciEntryPointSetting, BuildDefinitionSetting[] watchedBuildDefinitions)
{
var connection = new TfsConnectionDetails(ciEntryPointSetting);
var buildDefinitionsByProjectCollection = watchedBuildDefinitions.GroupBy(bd => bd.Parent);
Expand Down
25 changes: 19 additions & 6 deletions TfsRestServices/TfsRestWatcher.cs
Expand Up @@ -13,7 +13,7 @@ namespace TfsRestServices
public class TfsRestWatcher : WatcherBase
{
private readonly TfsRestCiEntryPoint _tfsRestCiEntryPoint;
private readonly TfsRestService _service;
protected TfsRestService _service;

public TfsRestWatcher(SirenOfShameSettings settings, TfsRestCiEntryPoint tfsRestCiEntryPoint) : base(settings)
{
Expand All @@ -34,6 +34,12 @@ protected override IList<BuildStatus> GetBuildStatus()
}
catch (AggregateException ex)
{
var anyInvalidCredentials = ex.InnerExceptions.Any(IsInvalidCredentials);
if (anyInvalidCredentials)
{
throw new InvalidCredentialsException();
}

var anyServerUnavailable = ex.InnerExceptions.Any(IsServerUnavailable);
if (anyServerUnavailable)
{
Expand All @@ -58,13 +64,20 @@ protected override IList<BuildStatus> GetBuildStatus()
}
}

private static bool IsInvalidCredentials(Exception ex)
{
if (ex is HttpRequestException httpRequestException)
{
return httpRequestException.Message.Contains("401");
}
return false;
}

private static bool IsServerUnavailable(Exception ex)
{
var webException = ex as WebException;
if (webException != null)
if (ex is WebException webException)
return IsServerUnavailable(webException);
var httpRequestException = ex as HttpRequestException;
if (httpRequestException != null)
if (ex is HttpRequestException httpRequestException)
return IsServerUnavailable(httpRequestException);
// SocketException?
return false;
Expand All @@ -84,7 +97,7 @@ private static bool IsServerUnavailable(WebException ex)
ex.Message.Contains("Unable to connect to the remote server");
}

private IEnumerable<BuildDefinitionSetting> GetAllWatchedBuildDefinitions()
protected virtual IEnumerable<BuildDefinitionSetting> GetAllWatchedBuildDefinitions()
{
var activeBuildDefinitionSettings = CiEntryPointSetting.BuildDefinitionSettings.Where(bd => bd.Active && bd.BuildServer == _tfsRestCiEntryPoint.Name);
return activeBuildDefinitionSettings;
Expand Down
Binary file not shown.

0 comments on commit cea52c5

Please sign in to comment.