Skip to content

Commit 14b654d

Browse files
committed
Introduce a partial success limit.
Added first batch of tests.
1 parent 9e5ed68 commit 14b654d

File tree

19 files changed

+1210
-135
lines changed

19 files changed

+1210
-135
lines changed

src/Renci.SshNet.Tests/Classes/ClientAuthenticationTest.cs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,64 @@ public class ClientAuthenticationTest
1212
[TestInitialize]
1313
public void Init()
1414
{
15-
_clientAuthentication = new ClientAuthentication();
15+
_clientAuthentication = new ClientAuthentication(1);
1616
}
1717

18+
[TestMethod]
19+
public void Ctor_PartialSuccessLimit_Zero()
20+
{
21+
const int partialSuccessLimit = 0;
22+
23+
try
24+
{
25+
new ClientAuthentication(partialSuccessLimit);
26+
Assert.Fail();
27+
}
28+
catch (ArgumentOutOfRangeException ex)
29+
{
30+
Assert.IsNull(ex.InnerException);
31+
Assert.AreEqual(string.Format("Cannot be less than one.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
32+
Assert.AreEqual("partialSuccessLimit", ex.ParamName);
33+
}
34+
}
35+
36+
[TestMethod]
37+
public void Ctor_PartialSuccessLimit_Negative()
38+
{
39+
var partialSuccessLimit = new Random().Next(int.MinValue, -1);
40+
41+
try
42+
{
43+
new ClientAuthentication(partialSuccessLimit);
44+
Assert.Fail();
45+
}
46+
catch (ArgumentOutOfRangeException ex)
47+
{
48+
Assert.IsNull(ex.InnerException);
49+
Assert.AreEqual(string.Format("Cannot be less than one.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
50+
Assert.AreEqual("partialSuccessLimit", ex.ParamName);
51+
}
52+
}
53+
54+
[TestMethod]
55+
public void Ctor_PartialSuccessLimit_One()
56+
{
57+
const int partialSuccessLimit = 1;
58+
59+
var clientAuthentication = new ClientAuthentication(partialSuccessLimit);
60+
Assert.AreEqual(partialSuccessLimit, clientAuthentication.PartialSuccessLimit);
61+
}
62+
63+
[TestMethod]
64+
public void Ctor_PartialSuccessLimit_MaxValue()
65+
{
66+
const int partialSuccessLimit = int.MaxValue;
67+
68+
var clientAuthentication = new ClientAuthentication(partialSuccessLimit);
69+
Assert.AreEqual(partialSuccessLimit, clientAuthentication.PartialSuccessLimit);
70+
}
71+
72+
1873
[TestMethod]
1974
public void AuthenticateShouldThrowArgumentNullExceptionWhenConnectionInfoIsNull()
2075
{

src/Renci.SshNet.Tests/Classes/ClientAuthenticationTestBase.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public abstract class ClientAuthenticationTestBase : TestBase
1313
internal Mock<IAuthenticationMethod> PasswordAuthenticationMethodMock { get; private set; }
1414
internal Mock<IAuthenticationMethod> PublicKeyAuthenticationMethodMock { get; private set; }
1515
internal Mock<IAuthenticationMethod> KeyboardInteractiveAuthenticationMethodMock { get; private set; }
16-
internal ClientAuthentication ClientAuthentication { get; private set; }
16+
17+
protected abstract void SetupData();
1718

1819
protected void CreateMocks()
1920
{
@@ -27,18 +28,20 @@ protected void CreateMocks()
2728

2829
protected abstract void SetupMocks();
2930

31+
protected virtual void Arrange()
32+
{
33+
SetupData();
34+
CreateMocks();
35+
SetupMocks();
36+
}
37+
3038
protected abstract void Act();
3139

32-
protected override void OnInit()
40+
protected sealed override void OnInit()
3341
{
3442
base.OnInit();
3543

36-
// Arrange
37-
CreateMocks();
38-
SetupMocks();
39-
ClientAuthentication = new ClientAuthentication();
40-
41-
// Act
44+
Arrange();
4245
Act();
4346
}
4447

src/Renci.SshNet.Tests/Classes/ClientAuthenticationTest_Failure_SingleList_AuthenticationMethodFailed.cs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ namespace Renci.SshNet.Tests.Classes
88
[TestClass]
99
public class ClientAuthenticationTest_Failure_SingleList_AuthenticationMethodFailed : ClientAuthenticationTestBase
1010
{
11+
private int _partialSuccessLimit;
12+
private ClientAuthentication _clientAuthentication;
1113
private SshAuthenticationException _actualException;
1214

15+
protected override void SetupData()
16+
{
17+
_partialSuccessLimit = 1;
18+
}
19+
1320
protected override void SetupMocks()
1421
{
1522
var seq = new MockSequence();
@@ -21,23 +28,26 @@ protected override void SetupMocks()
2128
ConnectionInfoMock.InSequence(seq).Setup(p => p.CreateNoneAuthenticationMethod())
2229
.Returns(NoneAuthenticationMethodMock.Object);
2330

24-
NoneAuthenticationMethodMock.InSequence(seq).Setup(p => p.Authenticate(SessionMock.Object))
25-
.Returns(AuthenticationResult.Failure);
26-
ConnectionInfoMock.InSequence(seq).Setup(p => p.AuthenticationMethods)
27-
.Returns(new List<IAuthenticationMethod>
28-
{
29-
PublicKeyAuthenticationMethodMock.Object,
30-
PasswordAuthenticationMethodMock.Object
31-
});
3231
NoneAuthenticationMethodMock.InSequence(seq)
33-
.Setup(p => p.AllowedAuthentications)
34-
.Returns(new[] { "password" });
32+
.Setup(p => p.Authenticate(SessionMock.Object))
33+
.Returns(AuthenticationResult.Failure);
34+
ConnectionInfoMock.InSequence(seq)
35+
.Setup(p => p.AuthenticationMethods)
36+
.Returns(new List<IAuthenticationMethod>
37+
{
38+
PublicKeyAuthenticationMethodMock.Object,
39+
PasswordAuthenticationMethodMock.Object
40+
});
41+
NoneAuthenticationMethodMock.InSequence(seq)
42+
.Setup(p => p.AllowedAuthentications)
43+
.Returns(new[] { "password" });
3544

3645
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
3746
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
3847

39-
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Authenticate(SessionMock.Object))
40-
.Returns(AuthenticationResult.Failure);
48+
PasswordAuthenticationMethodMock.InSequence(seq)
49+
.Setup(p => p.Authenticate(SessionMock.Object))
50+
.Returns(AuthenticationResult.Failure);
4151
// obtain name for inclusion in SshAuthenticationException
4252
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
4353

@@ -46,11 +56,18 @@ protected override void SetupMocks()
4656
SessionMock.InSequence(seq).Setup(p => p.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"));
4757
}
4858

59+
protected override void Arrange()
60+
{
61+
base.Arrange();
62+
63+
_clientAuthentication = new ClientAuthentication(_partialSuccessLimit);
64+
}
65+
4966
protected override void Act()
5067
{
5168
try
5269
{
53-
ClientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
70+
_clientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
5471
Assert.Fail();
5572
}
5673
catch (SshAuthenticationException ex)

src/Renci.SshNet.Tests/Classes/ClientAuthenticationTest_Failure_SingleList_AuthenticationMethodNotConfigured.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ namespace Renci.SshNet.Tests.Classes
88
[TestClass]
99
public class ClientAuthenticationTest_Failure_SingleList_AuthenticationMethodNotSupported : ClientAuthenticationTestBase
1010
{
11+
private int _partialSuccessLimit;
12+
private ClientAuthentication _clientAuthentication;
1113
private SshAuthenticationException _actualException;
1214

15+
protected override void SetupData()
16+
{
17+
_partialSuccessLimit = 1;
18+
}
19+
1320
protected override void SetupMocks()
1421
{
1522
var seq = new MockSequence();
@@ -39,11 +46,18 @@ protected override void SetupMocks()
3946
SessionMock.InSequence(seq).Setup(p => p.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"));
4047
}
4148

49+
protected override void Arrange()
50+
{
51+
base.Arrange();
52+
53+
_clientAuthentication = new ClientAuthentication(_partialSuccessLimit);
54+
}
55+
4256
protected override void Act()
4357
{
4458
try
4559
{
46-
ClientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
60+
_clientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
4761
Assert.Fail();
4862
}
4963
catch (SshAuthenticationException ex)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
3+
namespace Renci.SshNet.Tests.Classes
4+
{
5+
[TestClass]
6+
public class ClientAuthenticationTest_Success_MultiList_AllAllowedAuthenticationsHaveReachedPartialSuccessLimit
7+
{
8+
[TestMethod]
9+
public void Test()
10+
{
11+
Assert.Fail();
12+
}
13+
}
14+
}

src/Renci.SshNet.Tests/Classes/ClientAuthenticationTest_Success_MultiList_DifferentAllowedAuthenticationsAfterPartialSuccess.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ namespace Renci.SshNet.Tests.Classes
77
[TestClass]
88
public class ClientAuthenticationTest_Success_MultiList_DifferentAllowedAuthenticationsAfterPartialSuccess : ClientAuthenticationTestBase
99
{
10+
private int _partialSuccessLimit;
11+
private ClientAuthentication _clientAuthentication;
12+
13+
protected override void SetupData()
14+
{
15+
_partialSuccessLimit = 1;
16+
}
17+
1018
protected override void SetupMocks()
1119
{
1220
var seq = new MockSequence();
@@ -47,9 +55,16 @@ protected override void SetupMocks()
4755
SessionMock.InSequence(seq).Setup(p => p.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"));
4856
}
4957

58+
protected override void Arrange()
59+
{
60+
base.Arrange();
61+
62+
_clientAuthentication = new ClientAuthentication(_partialSuccessLimit);
63+
}
64+
5065
protected override void Act()
5166
{
52-
ClientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
67+
_clientAuthentication.Authenticate(ConnectionInfoMock.Object, SessionMock.Object);
5368
}
5469
}
5570
}

0 commit comments

Comments
 (0)