SessionTest_Connected.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. using System;
  2. using System.Linq;
  3. using System.Text.RegularExpressions;
  4. using System.Threading;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using Moq;
  7. using Renci.SshNet.Messages.Transport;
  8. namespace Renci.SshNet.Tests.Classes
  9. {
  10. [TestClass]
  11. public class SessionTest_Connected : SessionTest_ConnectedBase
  12. {
  13. private IgnoreMessage _ignoreMessage;
  14. protected override void SetupData()
  15. {
  16. base.SetupData();
  17. var data = new byte[10];
  18. Random.NextBytes(data);
  19. _ignoreMessage = new IgnoreMessage(data);
  20. }
  21. protected override void Act()
  22. {
  23. }
  24. [TestMethod]
  25. public void ClientVersionIsRenciSshNet()
  26. {
  27. Assert.IsTrue(Regex.IsMatch(
  28. Session.ClientVersion,
  29. // Ends with e.g. 2024.1.1 plus some optional metadata not containing '-'
  30. @"^SSH-2\.0-Renci\.SshNet\.SshClient\.\d{4}\.\d+\.\d+(_[a-zA-Z0-9_\.]+)?$"));
  31. }
  32. [TestMethod]
  33. public void IncludeStrictKexPseudoAlgorithmInInitKex()
  34. {
  35. Assert.IsTrue(FirstKexReceived.Wait(1000));
  36. Assert.IsTrue(ServerBytesReceivedRegister.Count > 0);
  37. var kexInitMessage = new KeyExchangeInitMessage();
  38. kexInitMessage.Load(ServerBytesReceivedRegister[0], 4 + 1 + 1, ServerBytesReceivedRegister[0].Length - 4 - 1 - 1);
  39. Assert.IsTrue(kexInitMessage.KeyExchangeAlgorithms.Contains("kex-strict-c-v00@openssh.com"));
  40. }
  41. [TestMethod]
  42. public void ShouldNotIncludeStrictKexPseudoAlgorithmInSubsequentKex()
  43. {
  44. Assert.IsTrue(FirstKexReceived.Wait(1000));
  45. using var subsequentKexReceived = new ManualResetEventSlim();
  46. bool kexContainsPseudoAlg = true;
  47. ServerListener.BytesReceived += ServerListener_BytesReceived;
  48. void ServerListener_BytesReceived(byte[] bytesReceived, System.Net.Sockets.Socket socket)
  49. {
  50. if (bytesReceived.Length > 5 && bytesReceived[5] == 20)
  51. {
  52. // SSH_MSG_KEXINIT = 20
  53. var kexInitMessage = new KeyExchangeInitMessage();
  54. kexInitMessage.Load(bytesReceived, 6, bytesReceived.Length - 6);
  55. kexContainsPseudoAlg = kexInitMessage.KeyExchangeAlgorithms.Contains("kex-strict-c-v00@openssh.com");
  56. subsequentKexReceived.Set();
  57. }
  58. }
  59. Session.SendMessage(Session.ClientInitMessage);
  60. Assert.IsTrue(subsequentKexReceived.Wait(1000));
  61. Assert.IsFalse(kexContainsPseudoAlg);
  62. ServerListener.BytesReceived -= ServerListener_BytesReceived;
  63. }
  64. [TestMethod]
  65. public void ConnectionInfoShouldReturnConnectionInfoPassedThroughConstructor()
  66. {
  67. Assert.AreSame(ConnectionInfo, Session.ConnectionInfo);
  68. }
  69. [TestMethod]
  70. public void IsConnectedShouldReturnTrue()
  71. {
  72. Assert.IsTrue(Session.IsConnected);
  73. }
  74. [TestMethod]
  75. public void SendMessageShouldSendPacketToServer()
  76. {
  77. Thread.Sleep(100);
  78. ServerBytesReceivedRegister.Clear();
  79. Session.SendMessage(_ignoreMessage);
  80. // give session time to process message
  81. Thread.Sleep(100);
  82. Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
  83. }
  84. [TestMethod]
  85. public void SessionIdShouldReturnExchangeHashCalculatedFromKeyExchangeInitMessage()
  86. {
  87. Assert.IsNotNull(Session.SessionId);
  88. Assert.AreSame(SessionId, Session.SessionId);
  89. }
  90. [TestMethod]
  91. public void ServerVersionShouldNotReturnNull()
  92. {
  93. Assert.IsNotNull(Session.ServerVersion);
  94. Assert.AreEqual("SSH-2.0-OurServerStub", Session.ServerVersion);
  95. }
  96. [TestMethod]
  97. public void WaitOnHandle_WaitHandle_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull()
  98. {
  99. const WaitHandle waitHandle = null;
  100. try
  101. {
  102. Session.WaitOnHandle(waitHandle);
  103. Assert.Fail();
  104. }
  105. catch (ArgumentNullException ex)
  106. {
  107. Assert.IsNull(ex.InnerException);
  108. Assert.AreEqual("waitHandle", ex.ParamName);
  109. }
  110. }
  111. [TestMethod]
  112. public void WaitOnHandle_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull()
  113. {
  114. const WaitHandle waitHandle = null;
  115. var timeout = TimeSpan.FromMinutes(5);
  116. try
  117. {
  118. Session.WaitOnHandle(waitHandle, timeout);
  119. Assert.Fail();
  120. }
  121. catch (ArgumentNullException ex)
  122. {
  123. Assert.IsNull(ex.InnerException);
  124. Assert.AreEqual("waitHandle", ex.ParamName);
  125. }
  126. }
  127. [TestMethod]
  128. public void ISession_ConnectionInfoShouldReturnConnectionInfoPassedThroughConstructor()
  129. {
  130. var session = (ISession)Session;
  131. Assert.AreSame(ConnectionInfo, session.ConnectionInfo);
  132. }
  133. [TestMethod]
  134. public void ISession_MessageListenerCompletedShouldNotBeSignaled()
  135. {
  136. var session = (ISession)Session;
  137. Assert.IsNotNull(session.MessageListenerCompleted);
  138. Assert.IsFalse(session.MessageListenerCompleted.WaitOne(0));
  139. }
  140. [TestMethod]
  141. public void ISession_SendMessageShouldSendPacketToServer()
  142. {
  143. Thread.Sleep(100);
  144. var session = (ISession)Session;
  145. ServerBytesReceivedRegister.Clear();
  146. session.SendMessage(_ignoreMessage);
  147. // give session time to process message
  148. Thread.Sleep(100);
  149. Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
  150. }
  151. [TestMethod]
  152. public void ISession_TrySendMessageShouldSendPacketToServerAndReturnTrue()
  153. {
  154. Thread.Sleep(100);
  155. var session = (ISession)Session;
  156. ServerBytesReceivedRegister.Clear();
  157. var actual = session.TrySendMessage(new IgnoreMessage());
  158. // give session time to process message
  159. Thread.Sleep(100);
  160. Assert.IsTrue(actual);
  161. Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
  162. }
  163. [TestMethod]
  164. public void ISession_WaitOnHandleShouldThrowArgumentNullExceptionWhenWaitHandleIsNull()
  165. {
  166. const WaitHandle waitHandle = null;
  167. var session = (ISession)Session;
  168. try
  169. {
  170. session.WaitOnHandle(waitHandle);
  171. Assert.Fail();
  172. }
  173. catch (ArgumentNullException ex)
  174. {
  175. Assert.IsNull(ex.InnerException);
  176. Assert.AreEqual("waitHandle", ex.ParamName);
  177. }
  178. }
  179. [TestMethod]
  180. public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnSuccessIfWaitHandleIsSignaled()
  181. {
  182. var session = (ISession)Session;
  183. var waitHandle = new ManualResetEvent(true);
  184. var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0));
  185. Assert.AreEqual(WaitResult.Success, result);
  186. }
  187. [TestMethod]
  188. public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnTimedOutIfWaitHandleIsNotSignaled()
  189. {
  190. var session = (ISession)Session;
  191. var waitHandle = new ManualResetEvent(false);
  192. var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0));
  193. Assert.AreEqual(WaitResult.TimedOut, result);
  194. }
  195. [TestMethod]
  196. public void ISession_TryWait_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull()
  197. {
  198. var session = (ISession)Session;
  199. const WaitHandle waitHandle = null;
  200. try
  201. {
  202. _ = session.TryWait(waitHandle, Timeout.InfiniteTimeSpan);
  203. Assert.Fail();
  204. }
  205. catch (ArgumentNullException ex)
  206. {
  207. Assert.IsNull(ex.InnerException);
  208. Assert.AreEqual("waitHandle", ex.ParamName);
  209. }
  210. }
  211. [TestMethod]
  212. public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnSuccessIfWaitHandleIsSignaled()
  213. {
  214. var session = (ISession)Session;
  215. var waitHandle = new ManualResetEvent(true);
  216. var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0), out var exception);
  217. Assert.AreEqual(WaitResult.Success, result);
  218. Assert.IsNull(exception);
  219. }
  220. [TestMethod]
  221. public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnTimedOutIfWaitHandleIsNotSignaled()
  222. {
  223. var session = (ISession)Session;
  224. var waitHandle = new ManualResetEvent(false);
  225. var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0), out var exception);
  226. Assert.AreEqual(WaitResult.TimedOut, result);
  227. Assert.IsNull(exception);
  228. }
  229. [TestMethod]
  230. public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull()
  231. {
  232. var session = (ISession)Session;
  233. const WaitHandle waitHandle = null;
  234. Exception exception = null;
  235. try
  236. {
  237. session.TryWait(waitHandle, Timeout.InfiniteTimeSpan, out exception);
  238. Assert.Fail();
  239. }
  240. catch (ArgumentNullException ex)
  241. {
  242. Assert.IsNull(ex.InnerException);
  243. Assert.AreEqual("waitHandle", ex.ParamName);
  244. Assert.IsNull(exception);
  245. }
  246. }
  247. [TestMethod]
  248. public void ClientSocketShouldBeConnected()
  249. {
  250. Assert.IsNotNull(ClientSocket);
  251. Assert.IsTrue(ClientSocket.Connected);
  252. }
  253. [TestMethod]
  254. public void CreateConnectorOnServiceFactoryShouldHaveBeenInvokedOnce()
  255. {
  256. ServiceFactoryMock.Verify(p => p.CreateConnector(ConnectionInfo, SocketFactoryMock.Object), Times.Once());
  257. }
  258. [TestMethod]
  259. public void ConnectorOnConnectorShouldHaveBeenInvokedOnce()
  260. {
  261. ConnectorMock.Verify(p => p.Connect(ConnectionInfo), Times.Once());
  262. }
  263. }
  264. }