SshCommandTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. using System.Diagnostics;
  2. using Renci.SshNet.Common;
  3. namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
  4. {
  5. /// <summary>
  6. /// Represents SSH command that can be executed.
  7. /// </summary>
  8. [TestClass]
  9. public class SshCommandTest : IntegrationTestBase
  10. {
  11. [TestMethod]
  12. public void Test_Run_SingleCommand()
  13. {
  14. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  15. {
  16. #region Example SshCommand RunCommand Result
  17. client.Connect();
  18. var testValue = Guid.NewGuid().ToString();
  19. using var command = client.RunCommand(string.Format("echo {0}", testValue));
  20. var result = command.Result;
  21. result = result.Substring(0, result.Length - 1); // Remove \n character returned by command
  22. client.Disconnect();
  23. #endregion
  24. Assert.AreEqual(testValue, result);
  25. }
  26. }
  27. [TestMethod]
  28. public void Test_Execute_SingleCommand()
  29. {
  30. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  31. {
  32. #region Example SshCommand CreateCommand Execute
  33. client.Connect();
  34. var testValue = Guid.NewGuid().ToString();
  35. var command = string.Format("echo -n {0}", testValue);
  36. using var cmd = client.CreateCommand(command);
  37. var result = cmd.Execute();
  38. client.Disconnect();
  39. #endregion
  40. Assert.AreEqual(testValue, result);
  41. }
  42. }
  43. [TestMethod]
  44. [Timeout(5000)]
  45. public void Test_CancelAsync_Unfinished_Command()
  46. {
  47. using var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password);
  48. client.Connect();
  49. var testValue = Guid.NewGuid().ToString();
  50. using var cmd = client.CreateCommand($"sleep 15s; echo {testValue}");
  51. var asyncResult = cmd.BeginExecute();
  52. cmd.CancelAsync();
  53. Assert.ThrowsException<OperationCanceledException>(() => cmd.EndExecute(asyncResult));
  54. Assert.IsTrue(asyncResult.IsCompleted);
  55. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(0));
  56. Assert.AreEqual(string.Empty, cmd.Result);
  57. Assert.AreEqual("TERM", cmd.ExitSignal);
  58. Assert.IsNull(cmd.ExitStatus);
  59. }
  60. [TestMethod]
  61. [Timeout(5000)]
  62. public async Task Test_CancelAsync_Kill_Unfinished_Command()
  63. {
  64. using var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password);
  65. client.Connect();
  66. var testValue = Guid.NewGuid().ToString();
  67. using var cmd = client.CreateCommand($"sleep 15s; echo {testValue}");
  68. var asyncResult = cmd.BeginExecute();
  69. Task<string> executeTask = Task.Factory.FromAsync(asyncResult, cmd.EndExecute);
  70. cmd.CancelAsync(forceKill: true);
  71. await Assert.ThrowsExceptionAsync<OperationCanceledException>(() => executeTask);
  72. Assert.IsTrue(asyncResult.IsCompleted);
  73. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(0));
  74. Assert.AreEqual(string.Empty, cmd.Result);
  75. Assert.AreEqual("KILL", cmd.ExitSignal);
  76. Assert.IsNull(cmd.ExitStatus);
  77. }
  78. [TestMethod]
  79. public void Test_CancelAsync_Finished_Command()
  80. {
  81. using var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password);
  82. client.Connect();
  83. var testValue = Guid.NewGuid().ToString();
  84. using var cmd = client.CreateCommand($"echo -n {testValue}");
  85. var asyncResult = cmd.BeginExecute();
  86. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
  87. cmd.CancelAsync(); // Should not throw
  88. Assert.AreEqual(testValue, cmd.EndExecute(asyncResult)); // Should not throw
  89. cmd.CancelAsync(); // Should not throw
  90. Assert.IsTrue(asyncResult.IsCompleted);
  91. Assert.AreEqual(testValue, cmd.Result);
  92. Assert.AreEqual(0, cmd.ExitStatus);
  93. Assert.IsNull(cmd.ExitSignal);
  94. }
  95. [TestMethod]
  96. public void Test_Execute_ExtendedOutputStream()
  97. {
  98. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  99. {
  100. #region Example SshCommand CreateCommand Execute ExtendedOutputStream
  101. client.Connect();
  102. using var cmd = client.CreateCommand("echo 12345; echo 654321 >&2");
  103. using var reader = new StreamReader(cmd.ExtendedOutputStream);
  104. Assert.AreEqual("12345\n", cmd.Execute());
  105. Assert.AreEqual("654321\n", reader.ReadToEnd());
  106. client.Disconnect();
  107. #endregion
  108. }
  109. }
  110. [TestMethod]
  111. public void Test_Execute_Timeout()
  112. {
  113. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  114. {
  115. #region Example SshCommand CreateCommand Execute CommandTimeout
  116. client.Connect();
  117. using var cmd = client.CreateCommand("sleep 10s");
  118. cmd.CommandTimeout = TimeSpan.FromSeconds(2);
  119. Assert.ThrowsException<SshOperationTimeoutException>(cmd.Execute);
  120. client.Disconnect();
  121. #endregion
  122. }
  123. }
  124. [TestMethod]
  125. public void Test_Execute_InvalidCommand()
  126. {
  127. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  128. {
  129. client.Connect();
  130. using var cmd = client.CreateCommand(";");
  131. cmd.Execute();
  132. if (string.IsNullOrEmpty(cmd.Error))
  133. {
  134. Assert.Fail("Operation should fail");
  135. }
  136. Assert.IsTrue(cmd.ExitStatus > 0);
  137. client.Disconnect();
  138. }
  139. }
  140. [TestMethod]
  141. public void Test_Execute_InvalidCommand_Then_Execute_ValidCommand()
  142. {
  143. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  144. {
  145. client.Connect();
  146. using var cmd = client.CreateCommand(";");
  147. cmd.Execute();
  148. if (string.IsNullOrEmpty(cmd.Error))
  149. {
  150. Assert.Fail("Operation should fail");
  151. }
  152. Assert.IsTrue(cmd.ExitStatus > 0);
  153. var result = ExecuteTestCommand(client);
  154. client.Disconnect();
  155. Assert.IsTrue(result);
  156. }
  157. }
  158. [TestMethod]
  159. public void Test_Execute_Command_Reconnect_Execute_Command()
  160. {
  161. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  162. {
  163. client.Connect();
  164. var result = ExecuteTestCommand(client);
  165. Assert.IsTrue(result);
  166. client.Disconnect();
  167. client.Connect();
  168. result = ExecuteTestCommand(client);
  169. Assert.IsTrue(result);
  170. client.Disconnect();
  171. }
  172. }
  173. [TestMethod]
  174. public void Test_Execute_Command_ExitStatus()
  175. {
  176. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  177. {
  178. client.Connect();
  179. using var cmd = client.RunCommand("exit 128");
  180. Assert.AreEqual(128, cmd.ExitStatus);
  181. Assert.IsNull(cmd.ExitSignal);
  182. }
  183. }
  184. [TestMethod]
  185. public void Test_Execute_Command_Asynchronously()
  186. {
  187. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  188. {
  189. client.Connect();
  190. using var callbackCalled = new ManualResetEventSlim();
  191. using var cmd = client.CreateCommand("sleep 2s; echo 'test'");
  192. var asyncResult = cmd.BeginExecute(new AsyncCallback((s) =>
  193. {
  194. callbackCalled.Set();
  195. }), state: null);
  196. while (!asyncResult.IsCompleted)
  197. {
  198. Thread.Sleep(100);
  199. }
  200. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(0));
  201. cmd.EndExecute(asyncResult);
  202. Assert.AreEqual("test\n", cmd.Result);
  203. Assert.IsTrue(callbackCalled.Wait(TimeSpan.FromSeconds(1)));
  204. client.Disconnect();
  205. }
  206. }
  207. [TestMethod]
  208. public void Test_Execute_Command_Asynchronously_With_Error()
  209. {
  210. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  211. {
  212. client.Connect();
  213. using var cmd = client.CreateCommand("sleep 2s; ;");
  214. var asyncResult = cmd.BeginExecute(null, null);
  215. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
  216. cmd.EndExecute(asyncResult);
  217. Assert.IsFalse(string.IsNullOrEmpty(cmd.Error));
  218. client.Disconnect();
  219. }
  220. }
  221. [TestMethod]
  222. public void Test_Execute_Command_Asynchronously_With_Callback_On_Different_Thread()
  223. {
  224. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  225. {
  226. client.Connect();
  227. var currentThreadId = Thread.CurrentThread.ManagedThreadId;
  228. int callbackThreadId = 0;
  229. using var callbackCalled = new ManualResetEventSlim();
  230. using var cmd = client.CreateCommand("sleep 2s; echo 'test'");
  231. var asyncResult = cmd.BeginExecute(new AsyncCallback((s) =>
  232. {
  233. callbackThreadId = Thread.CurrentThread.ManagedThreadId;
  234. callbackCalled.Set();
  235. }), null);
  236. cmd.EndExecute(asyncResult);
  237. Assert.IsTrue(callbackCalled.Wait(TimeSpan.FromSeconds(1)));
  238. Assert.AreNotEqual(currentThreadId, callbackThreadId);
  239. client.Disconnect();
  240. }
  241. }
  242. /// <summary>
  243. /// Tests for Issue 563.
  244. /// </summary>
  245. [WorkItem(563), TestMethod]
  246. public void Test_Execute_Command_Same_Object_Different_Commands()
  247. {
  248. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  249. {
  250. client.Connect();
  251. using var cmd = client.CreateCommand("echo 12345");
  252. cmd.Execute();
  253. Assert.AreEqual("12345\n", cmd.Result);
  254. cmd.Execute("echo 23456");
  255. Assert.AreEqual("23456\n", cmd.Result);
  256. client.Disconnect();
  257. }
  258. }
  259. [TestMethod]
  260. public void Test_Get_Result_Without_Execution()
  261. {
  262. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  263. {
  264. client.Connect();
  265. using var cmd = client.CreateCommand("ls -l");
  266. Assert.AreEqual(string.Empty, cmd.Result);
  267. Assert.AreEqual(string.Empty, cmd.Error);
  268. client.Disconnect();
  269. }
  270. }
  271. [WorkItem(703), TestMethod]
  272. public void Test_EndExecute_Before_BeginExecute()
  273. {
  274. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  275. {
  276. client.Connect();
  277. using var cmd = client.CreateCommand("ls -l");
  278. Assert.ThrowsException<ArgumentNullException>(() => cmd.EndExecute(null));
  279. client.Disconnect();
  280. }
  281. }
  282. /// <summary>
  283. ///A test for BeginExecute
  284. ///</summary>
  285. [TestMethod()]
  286. public void BeginExecuteTest()
  287. {
  288. string expected = "123\n";
  289. string result;
  290. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  291. {
  292. #region Example SshCommand CreateCommand BeginExecute IsCompleted EndExecute
  293. client.Connect();
  294. using var cmd = client.CreateCommand("sleep 2s;echo 123"); // Perform long running task
  295. var asynch = cmd.BeginExecute();
  296. Assert.IsTrue(asynch.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
  297. result = cmd.EndExecute(asynch);
  298. client.Disconnect();
  299. #endregion
  300. Assert.IsNotNull(asynch);
  301. Assert.AreEqual(expected, result);
  302. }
  303. }
  304. [TestMethod]
  305. public void Test_MultipleThread_100_MultipleConnections()
  306. {
  307. try
  308. {
  309. var options = new ParallelOptions()
  310. {
  311. MaxDegreeOfParallelism = 8
  312. };
  313. Parallel.For(0, 100, options,
  314. () =>
  315. {
  316. var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password);
  317. client.Connect();
  318. return client;
  319. },
  320. (int counter, ParallelLoopState pls, SshClient client) =>
  321. {
  322. var result = ExecuteTestCommand(client);
  323. Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter));
  324. Assert.IsTrue(result);
  325. return client;
  326. },
  327. (SshClient client) =>
  328. {
  329. client.Disconnect();
  330. client.Dispose();
  331. }
  332. );
  333. }
  334. catch (Exception exp)
  335. {
  336. Assert.Fail(exp.ToString());
  337. }
  338. }
  339. [TestMethod]
  340. public void Test_MultipleThread_100_MultipleSessions()
  341. {
  342. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  343. {
  344. client.Connect();
  345. Parallel.For(0, 100,
  346. (counter) =>
  347. {
  348. var result = ExecuteTestCommand(client);
  349. Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter));
  350. Assert.IsTrue(result);
  351. }
  352. );
  353. client.Disconnect();
  354. }
  355. }
  356. [TestMethod]
  357. public void Test_ExecuteAsync_Dispose_CommandFinishes()
  358. {
  359. using (var client = new SshClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
  360. {
  361. client.Connect();
  362. var cmd = client.CreateCommand("sleep 5s");
  363. var asyncResult = cmd.BeginExecute(null, null);
  364. cmd.Dispose();
  365. Assert.IsTrue(asyncResult.AsyncWaitHandle.WaitOne(0));
  366. Assert.ThrowsException<ObjectDisposedException>(() => cmd.EndExecute(asyncResult));
  367. }
  368. }
  369. private static bool ExecuteTestCommand(SshClient s)
  370. {
  371. var testValue = Guid.NewGuid().ToString();
  372. var command = string.Format("echo -n {0}", testValue);
  373. using var cmd = s.CreateCommand(command);
  374. var result = cmd.Execute();
  375. return result.Equals(testValue);
  376. }
  377. }
  378. }