Skip to content

Commit 80702f7

Browse files
committed
Ensure we do not block forever waiting for message listener thread to complete when the server sends a disconnect message, or the message listener thread never actually started. Fixes issue #2591.
Refactored creating of key exchange algorithm to allow unit tests without encyption and decryption. Added tests for KeyExchangeDhGroupExchangeRequest and IgnoreMessage. Added large set of tests for Session in both connected and disconnected mode. Remove SshData.ReadInt64() and SshData.Write(long). Fixes issue #2579.
1 parent 8f9d4ea commit 80702f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2555
-339
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using Moq;
7+
8+
namespace Renci.SshNet.Tests.Classes
9+
{
10+
[TestClass]
11+
public class ClientAuthenticationTest
12+
{
13+
private ClientAuthentication _clientAuthentication;
14+
15+
[TestInitialize]
16+
public void Init()
17+
{
18+
_clientAuthentication = new ClientAuthentication();
19+
}
20+
21+
[TestMethod]
22+
public void AuthenticateShouldThrowArgumentNullExceptionWhenConnectionInfoIsNull()
23+
{
24+
IConnectionInfoInternal connectionInfo = null;
25+
var session = new Mock<ISession>(MockBehavior.Strict).Object;
26+
27+
try
28+
{
29+
_clientAuthentication.Authenticate(connectionInfo, session);
30+
Assert.Fail();
31+
}
32+
catch (ArgumentNullException ex)
33+
{
34+
Assert.IsNull(ex.InnerException);
35+
Assert.AreEqual("connectionInfo", ex.ParamName);
36+
}
37+
}
38+
39+
[TestMethod]
40+
public void AuthenticateShouldThrowArgumentNullExceptionWhenSessionIsNull()
41+
{
42+
var connectionInfo = new Mock<IConnectionInfoInternal>(MockBehavior.Strict).Object;
43+
ISession session = null;
44+
45+
try
46+
{
47+
_clientAuthentication.Authenticate(connectionInfo, session);
48+
Assert.Fail();
49+
}
50+
catch (ArgumentNullException ex)
51+
{
52+
Assert.IsNull(ex.InnerException);
53+
Assert.AreEqual("session", ex.ParamName);
54+
}
55+
}
56+
}
57+
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
using System;
2-
using Microsoft.VisualStudio.TestTools.UnitTesting;
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
32
using Moq;
4-
using Moq.Protected;
5-
using Renci.SshNet.Common;
63
using Renci.SshNet.Tests.Common;
74

85
namespace Renci.SshNet.Tests.Classes

Renci.SshClient/Renci.SshNet.Tests/Classes/Common/SshConnectionExceptionTest.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,6 @@ public void SshConnectionExceptionConstructorTest3()
6060
Assert.Inconclusive("TODO: Implement code to verify target");
6161
}
6262

63-
/// <summary>
64-
///A test for SshConnectionException Constructor
65-
///</summary>
66-
[TestMethod()]
67-
public void SshConnectionExceptionConstructorTest4()
68-
{
69-
string message = string.Empty; // TODO: Initialize to an appropriate value
70-
Exception innerException = null; // TODO: Initialize to an appropriate value
71-
SshConnectionException target = new SshConnectionException(message, innerException);
72-
Assert.Inconclusive("TODO: Implement code to verify target");
73-
}
74-
7563
/// <summary>
7664
///A test for GetObjectData
7765
///</summary>

Renci.SshClient/Renci.SshNet.Tests/Classes/ConnectionInfoTest.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Globalization;
22
using System.Net;
33
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Moq;
45
using Renci.SshNet.Tests.Common;
56
using Renci.SshNet.Tests.Properties;
67
using System;
@@ -323,20 +324,23 @@ public void ConstructorShouldThrowArgumentNullExceptionWhenAuthenticationMethods
323324

324325
[TestMethod]
325326
[TestCategory("ConnectionInfo")]
326-
public void AuthenticateShouldThrowArgumentNullExceptionWhenSessionIsNull()
327+
public void AuthenticateShouldThrowArgumentNullExceptionWhenServiceFactoryIsNull()
327328
{
328-
var ret = new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, ProxyTypes.None,
329+
var connectionInfo = new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, ProxyTypes.None,
329330
Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD,
330331
new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME));
332+
var session = new Mock<ISession>(MockBehavior.Strict).Object;
333+
IServiceFactory serviceFactory = null;
331334

332335
try
333336
{
334-
ret.Authenticate(null);
337+
connectionInfo.Authenticate(session, serviceFactory);
338+
Assert.Fail();
335339
}
336340
catch (ArgumentNullException ex)
337341
{
338342
Assert.IsNull(ex.InnerException);
339-
Assert.AreEqual("session", ex.ParamName);
343+
Assert.AreEqual("serviceFactory", ex.ParamName);
340344
}
341345
}
342346
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Moq;
3+
using Renci.SshNet.Common;
4+
using Renci.SshNet.Tests.Properties;
5+
6+
namespace Renci.SshNet.Tests.Classes
7+
{
8+
[TestClass]
9+
public class ConnectionInfoTest_Authenticate_Failure
10+
{
11+
private Mock<IServiceFactory> _serviceFactoryMock;
12+
private Mock<IClientAuthentication> _clientAuthenticationMock;
13+
private Mock<ISession> _sessionMock;
14+
private ConnectionInfo _connectionInfo;
15+
private SshAuthenticationException _authenticationException;
16+
private SshAuthenticationException _actualException;
17+
18+
[TestInitialize]
19+
public void Init()
20+
{
21+
Arrange();
22+
Act();
23+
}
24+
25+
protected void Arrange()
26+
{
27+
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
28+
_clientAuthenticationMock = new Mock<IClientAuthentication>(MockBehavior.Strict);
29+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
30+
31+
_connectionInfo = new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, ProxyTypes.None,
32+
Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD,
33+
new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME));
34+
_authenticationException = new SshAuthenticationException();
35+
36+
_serviceFactoryMock.Setup(p => p.CreateClientAuthentication()).Returns(_clientAuthenticationMock.Object);
37+
_clientAuthenticationMock.Setup(p => p.Authenticate(_connectionInfo, _sessionMock.Object))
38+
.Throws(_authenticationException);
39+
}
40+
41+
protected void Act()
42+
{
43+
try
44+
{
45+
_connectionInfo.Authenticate(_sessionMock.Object, _serviceFactoryMock.Object);
46+
}
47+
catch (SshAuthenticationException ex)
48+
{
49+
_actualException = ex;
50+
}
51+
}
52+
53+
[TestMethod]
54+
public void AuthenticateShouldHaveThrownSshAuthenticationException()
55+
{
56+
Assert.IsNotNull(_actualException);
57+
Assert.AreSame(_authenticationException, _actualException);
58+
}
59+
60+
[TestMethod]
61+
public void IsAuthenticatedShouldReturnFalse()
62+
{
63+
Assert.IsFalse(_connectionInfo.IsAuthenticated);
64+
}
65+
66+
[TestMethod]
67+
public void CreateClientAuthenticationOnServiceFactoryShouldBeInvokedOnce()
68+
{
69+
_serviceFactoryMock.Verify(p => p.CreateClientAuthentication(), Times.Once);
70+
}
71+
72+
[TestMethod]
73+
public void AuthenticateOnClientAuthenticationShouldBeInvokedOnce()
74+
{
75+
_clientAuthenticationMock.Verify(p => p.Authenticate(_connectionInfo, _sessionMock.Object), Times.Once);
76+
}
77+
}
78+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Moq;
3+
using Renci.SshNet.Tests.Properties;
4+
5+
namespace Renci.SshNet.Tests.Classes
6+
{
7+
[TestClass]
8+
public class ConnectionInfoTest_Authenticate_Success
9+
{
10+
private Mock<IServiceFactory> _serviceFactoryMock;
11+
private Mock<IClientAuthentication> _clientAuthenticationMock;
12+
private Mock<ISession> _sessionMock;
13+
private ConnectionInfo _connectionInfo;
14+
15+
[TestInitialize]
16+
public void Init()
17+
{
18+
Arrange();
19+
Act();
20+
}
21+
22+
protected void Arrange()
23+
{
24+
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
25+
_clientAuthenticationMock = new Mock<IClientAuthentication>(MockBehavior.Strict);
26+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
27+
28+
_connectionInfo = new ConnectionInfo(Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, ProxyTypes.None,
29+
Resources.HOST, int.Parse(Resources.PORT), Resources.USERNAME, Resources.PASSWORD,
30+
new KeyboardInteractiveAuthenticationMethod(Resources.USERNAME));
31+
32+
_serviceFactoryMock.Setup(p => p.CreateClientAuthentication()).Returns(_clientAuthenticationMock.Object);
33+
_clientAuthenticationMock.Setup(p => p.Authenticate(_connectionInfo, _sessionMock.Object));
34+
}
35+
36+
protected void Act()
37+
{
38+
_connectionInfo.Authenticate(_sessionMock.Object, _serviceFactoryMock.Object);
39+
}
40+
41+
[TestMethod]
42+
public void IsAuthenticatedShouldReturnTrue()
43+
{
44+
Assert.IsTrue(_connectionInfo.IsAuthenticated);
45+
}
46+
47+
[TestMethod]
48+
public void CreateClientAuthenticationOnServiceFactoryShouldBeInvokedOnce()
49+
{
50+
_serviceFactoryMock.Verify(p => p.CreateClientAuthentication(), Times.Once);
51+
}
52+
53+
[TestMethod]
54+
public void AuthenticateOnClientAuthenticationShouldBeInvokedOnce()
55+
{
56+
_clientAuthenticationMock.Verify(p => p.Authenticate(_connectionInfo, _sessionMock.Object), Times.Once);
57+
}
58+
}
59+
}
Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,95 @@
1-
using Renci.SshNet.Messages.Transport;
1+
using System;
2+
using System.Linq;
3+
using Renci.SshNet.Common;
4+
using Renci.SshNet.Messages.Transport;
25
using Microsoft.VisualStudio.TestTools.UnitTesting;
3-
using System;
4-
using Renci.SshNet.Tests.Common;
56

67
namespace Renci.SshNet.Tests.Classes.Messages.Transport
78
{
8-
/// <summary>
9-
///This is a test class for IgnoreMessageTest and is intended
10-
///to contain all IgnoreMessageTest Unit Tests
11-
///</summary>
12-
[TestClass()]
13-
public class IgnoreMessageTest : TestBase
9+
[TestClass]
10+
public class IgnoreMessageTest
1411
{
15-
/// <summary>
16-
///A test for IgnoreMessage Constructor
17-
///</summary>
18-
[TestMethod()]
19-
public void IgnoreMessageConstructorTest()
12+
private Random _random;
13+
private byte[] _data;
14+
15+
[TestInitialize]
16+
public void Init()
17+
{
18+
_random = new Random();
19+
_data = new byte[_random.Next(1, 10)];
20+
_random.NextBytes(_data);
21+
}
22+
23+
[TestMethod]
24+
public void DefaultConstructor()
25+
{
26+
var target = new IgnoreMessage();
27+
Assert.IsNotNull(target.Data);
28+
Assert.AreEqual(0, target.Data.Length);
29+
}
30+
31+
[TestMethod]
32+
public void Constructor_Data()
33+
{
34+
var target = new IgnoreMessage(_data);
35+
Assert.AreSame(_data, target.Data);
36+
}
37+
38+
[TestMethod]
39+
public void Constructor_Data_ShouldThrowArgumentNullExceptionWhenDataIsNull()
2040
{
21-
IgnoreMessage target = new IgnoreMessage();
22-
Assert.Inconclusive("TODO: Implement code to verify target");
41+
byte[] data = null;
42+
43+
try
44+
{
45+
new IgnoreMessage(data);
46+
Assert.Fail();
47+
}
48+
catch (ArgumentNullException ex)
49+
{
50+
Assert.IsNull(ex.InnerException);
51+
Assert.AreEqual("data", ex.ParamName);
52+
}
2353
}
2454

25-
/// <summary>
26-
///A test for IgnoreMessage Constructor
27-
///</summary>
28-
[TestMethod()]
29-
public void IgnoreMessageConstructorTest1()
55+
[TestMethod]
56+
public void GetBytes()
3057
{
31-
byte[] data = null; // TODO: Initialize to an appropriate value
32-
IgnoreMessage target = new IgnoreMessage(data);
33-
Assert.Inconclusive("TODO: Implement code to verify target");
58+
var request = new IgnoreMessage(_data);
59+
60+
var bytes = request.GetBytes();
61+
62+
var expectedBytesLength = 0;
63+
expectedBytesLength += 1; // Type
64+
expectedBytesLength += 4; // Data length
65+
expectedBytesLength += _data.Length; // Data
66+
67+
Assert.AreEqual(expectedBytesLength, bytes.Length);
68+
69+
var sshDataStream = new SshDataStream(bytes);
70+
71+
Assert.AreEqual(IgnoreMessage.MessageNumber, sshDataStream.ReadByte());
72+
Assert.AreEqual((uint) _data.Length, sshDataStream.ReadUInt32());
73+
74+
var actualData = new byte[_data.Length];
75+
sshDataStream.Read(actualData, 0, actualData.Length);
76+
Assert.IsTrue(_data.SequenceEqual(actualData));
77+
78+
Assert.IsTrue(sshDataStream.IsEndOfData);
79+
}
80+
81+
[TestMethod]
82+
public void Load()
83+
{
84+
var ignoreMessage = new IgnoreMessage(_data);
85+
var bytes = ignoreMessage.GetBytes();
86+
var target = new IgnoreMessage();
87+
88+
target.Load(bytes);
89+
90+
Assert.IsNotNull(target.Data);
91+
Assert.AreEqual(_data.Length, target.Data.Length);
92+
Assert.IsTrue(target.Data.SequenceEqual(_data));
3493
}
3594
}
3695
}

0 commit comments

Comments
 (0)