SftpClientTest.Upload.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using Renci.SshNet.Common;
  3. using Renci.SshNet.Sftp;
  4. using Renci.SshNet.Tests.Common;
  5. using Renci.SshNet.Tests.Properties;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Threading;
  10. namespace Renci.SshNet.Tests.Classes
  11. {
  12. /// <summary>
  13. /// Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
  14. /// </summary>
  15. public partial class SftpClientTest : TestBase
  16. {
  17. [TestMethod]
  18. [TestCategory("Sftp")]
  19. public void Test_Sftp_Upload_And_Download_1MB_File()
  20. {
  21. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  22. {
  23. sftp.Connect();
  24. string uploadedFileName = Path.GetTempFileName();
  25. string remoteFileName = Path.GetRandomFileName();
  26. this.CreateTestFile(uploadedFileName, 1);
  27. // Calculate has value
  28. var uploadedHash = CalculateMD5(uploadedFileName);
  29. using (var file = File.OpenRead(uploadedFileName))
  30. {
  31. sftp.UploadFile(file, remoteFileName);
  32. }
  33. string downloadedFileName = Path.GetTempFileName();
  34. using (var file = File.OpenWrite(downloadedFileName))
  35. {
  36. sftp.DownloadFile(remoteFileName, file);
  37. }
  38. var downloadedHash = CalculateMD5(downloadedFileName);
  39. sftp.DeleteFile(remoteFileName);
  40. File.Delete(uploadedFileName);
  41. File.Delete(downloadedFileName);
  42. sftp.Disconnect();
  43. Assert.AreEqual(uploadedHash, downloadedHash);
  44. }
  45. }
  46. [TestMethod]
  47. [TestCategory("Sftp")]
  48. [ExpectedException(typeof(SftpPermissionDeniedException))]
  49. public void Test_Sftp_Upload_Forbidden()
  50. {
  51. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  52. {
  53. sftp.Connect();
  54. string uploadedFileName = Path.GetTempFileName();
  55. string remoteFileName = "/root/1";
  56. this.CreateTestFile(uploadedFileName, 1);
  57. using (var file = File.OpenRead(uploadedFileName))
  58. {
  59. sftp.UploadFile(file, remoteFileName);
  60. }
  61. sftp.Disconnect();
  62. }
  63. }
  64. [TestMethod]
  65. [TestCategory("Sftp")]
  66. public void Test_Sftp_Multiple_Async_Upload_And_Download_10Files_5MB_Each()
  67. {
  68. var maxFiles = 10;
  69. var maxSize = 5;
  70. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  71. {
  72. sftp.Connect();
  73. var testInfoList = new Dictionary<string, TestInfo>();
  74. for (int i = 0; i < maxFiles; i++)
  75. {
  76. var testInfo = new TestInfo();
  77. testInfo.UploadedFileName = Path.GetTempFileName();
  78. testInfo.DownloadedFileName = Path.GetTempFileName();
  79. testInfo.RemoteFileName = Path.GetRandomFileName();
  80. this.CreateTestFile(testInfo.UploadedFileName, maxSize);
  81. // Calculate hash value
  82. testInfo.UploadedHash = CalculateMD5(testInfo.UploadedFileName);
  83. testInfoList.Add(testInfo.RemoteFileName, testInfo);
  84. }
  85. var uploadWaitHandles = new List<WaitHandle>();
  86. // Start file uploads
  87. foreach (var remoteFile in testInfoList.Keys)
  88. {
  89. var testInfo = testInfoList[remoteFile];
  90. testInfo.UploadedFile = File.OpenRead(testInfo.UploadedFileName);
  91. testInfo.UploadResult = sftp.BeginUploadFile(testInfo.UploadedFile,
  92. remoteFile,
  93. null,
  94. null) as SftpUploadAsyncResult;
  95. uploadWaitHandles.Add(testInfo.UploadResult.AsyncWaitHandle);
  96. }
  97. // Wait for upload to finish
  98. bool uploadCompleted = false;
  99. while (!uploadCompleted)
  100. {
  101. // Assume upload completed
  102. uploadCompleted = true;
  103. foreach (var testInfo in testInfoList.Values)
  104. {
  105. var sftpResult = testInfo.UploadResult;
  106. if (!testInfo.UploadResult.IsCompleted)
  107. {
  108. uploadCompleted = false;
  109. }
  110. }
  111. Thread.Sleep(500);
  112. }
  113. // End file uploads
  114. foreach (var remoteFile in testInfoList.Keys)
  115. {
  116. var testInfo = testInfoList[remoteFile];
  117. sftp.EndUploadFile(testInfo.UploadResult);
  118. testInfo.UploadedFile.Dispose();
  119. }
  120. // Start file downloads
  121. var downloadWaitHandles = new List<WaitHandle>();
  122. foreach (var remoteFile in testInfoList.Keys)
  123. {
  124. var testInfo = testInfoList[remoteFile];
  125. testInfo.DownloadedFile = File.OpenWrite(testInfo.DownloadedFileName);
  126. testInfo.DownloadResult = sftp.BeginDownloadFile(remoteFile,
  127. testInfo.DownloadedFile,
  128. null,
  129. null) as SftpDownloadAsyncResult;
  130. downloadWaitHandles.Add(testInfo.DownloadResult.AsyncWaitHandle);
  131. }
  132. // Wait for download to finish
  133. bool downloadCompleted = false;
  134. while (!downloadCompleted)
  135. {
  136. // Assume download completed
  137. downloadCompleted = true;
  138. foreach (var testInfo in testInfoList.Values)
  139. {
  140. var sftpResult = testInfo.DownloadResult;
  141. if (!testInfo.DownloadResult.IsCompleted)
  142. {
  143. downloadCompleted = false;
  144. }
  145. }
  146. Thread.Sleep(500);
  147. }
  148. var hashMatches = true;
  149. var uploadDownloadSizeOk = true;
  150. // End file downloads
  151. foreach (var remoteFile in testInfoList.Keys)
  152. {
  153. var testInfo = testInfoList[remoteFile];
  154. sftp.EndDownloadFile(testInfo.DownloadResult);
  155. testInfo.DownloadedFile.Dispose();
  156. testInfo.DownloadedHash = CalculateMD5(testInfo.DownloadedFileName);
  157. if (!(testInfo.UploadResult.UploadedBytes > 0 && testInfo.DownloadResult.DownloadedBytes > 0 && testInfo.DownloadResult.DownloadedBytes == testInfo.UploadResult.UploadedBytes))
  158. {
  159. uploadDownloadSizeOk = false;
  160. }
  161. if (!testInfo.DownloadedHash.Equals(testInfo.UploadedHash))
  162. {
  163. hashMatches = false;
  164. }
  165. }
  166. // Clean up after test
  167. foreach (var remoteFile in testInfoList.Keys)
  168. {
  169. var testInfo = testInfoList[remoteFile];
  170. sftp.DeleteFile(remoteFile);
  171. File.Delete(testInfo.UploadedFileName);
  172. File.Delete(testInfo.DownloadedFileName);
  173. }
  174. sftp.Disconnect();
  175. Assert.IsTrue(hashMatches, "Hash does not match");
  176. Assert.IsTrue(uploadDownloadSizeOk, "Uploaded and downloaded bytes does not match");
  177. }
  178. }
  179. // TODO: Split this test into multiple tests
  180. [TestMethod]
  181. [TestCategory("Sftp")]
  182. [Description("Test that delegates passed to BeginUploadFile, BeginDownloadFile and BeginListDirectory are actually called.")]
  183. public void Test_Sftp_Ensure_Async_Delegates_Called_For_BeginFileUpload_BeginFileDownload_BeginListDirectory()
  184. {
  185. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  186. {
  187. sftp.Connect();
  188. string remoteFileName = Path.GetRandomFileName();
  189. string localFileName = Path.GetRandomFileName();
  190. bool uploadDelegateCalled = false;
  191. bool downloadDelegateCalled = false;
  192. bool listDirectoryDelegateCalled = false;
  193. IAsyncResult asyncResult;
  194. // Test for BeginUploadFile.
  195. CreateTestFile(localFileName, 1);
  196. using (var fileStream = File.OpenRead(localFileName))
  197. {
  198. asyncResult = sftp.BeginUploadFile(fileStream, remoteFileName, delegate(IAsyncResult ar)
  199. {
  200. sftp.EndUploadFile(ar);
  201. uploadDelegateCalled = true;
  202. }, null);
  203. while (!asyncResult.IsCompleted)
  204. {
  205. Thread.Sleep(500);
  206. }
  207. }
  208. File.Delete(localFileName);
  209. Assert.IsTrue(uploadDelegateCalled, "BeginUploadFile");
  210. // Test for BeginDownloadFile.
  211. asyncResult = null;
  212. using (var fileStream = File.OpenWrite(localFileName))
  213. {
  214. asyncResult = sftp.BeginDownloadFile(remoteFileName, fileStream, delegate(IAsyncResult ar)
  215. {
  216. sftp.EndDownloadFile(ar);
  217. downloadDelegateCalled = true;
  218. }, null);
  219. while (!asyncResult.IsCompleted)
  220. {
  221. Thread.Sleep(500);
  222. }
  223. }
  224. File.Delete(localFileName);
  225. Assert.IsTrue(downloadDelegateCalled, "BeginDownloadFile");
  226. // Test for BeginListDirectory.
  227. asyncResult = null;
  228. asyncResult = sftp.BeginListDirectory(sftp.WorkingDirectory, delegate(IAsyncResult ar)
  229. {
  230. sftp.EndListDirectory(ar);
  231. listDirectoryDelegateCalled = true;
  232. }, null);
  233. while (!asyncResult.IsCompleted)
  234. {
  235. Thread.Sleep(500);
  236. }
  237. Assert.IsTrue(listDirectoryDelegateCalled, "BeginListDirectory");
  238. }
  239. }
  240. [TestMethod]
  241. [TestCategory("Sftp")]
  242. [Description("Test passing null to BeginUploadFile")]
  243. [ExpectedException(typeof(ArgumentNullException))]
  244. public void Test_Sftp_BeginUploadFile_StreamIsNull()
  245. {
  246. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  247. {
  248. sftp.Connect();
  249. sftp.BeginUploadFile(null, "aaaaa", null, null);
  250. sftp.Disconnect();
  251. }
  252. }
  253. [TestMethod]
  254. [TestCategory("Sftp")]
  255. [Description("Test passing null to BeginUploadFile")]
  256. [ExpectedException(typeof(ArgumentException))]
  257. public void Test_Sftp_BeginUploadFile_FileNameIsWhiteSpace()
  258. {
  259. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  260. {
  261. sftp.Connect();
  262. sftp.BeginUploadFile(new MemoryStream(), " ", null, null);
  263. sftp.Disconnect();
  264. }
  265. }
  266. [TestMethod]
  267. [TestCategory("Sftp")]
  268. [Description("Test passing null to BeginUploadFile")]
  269. [ExpectedException(typeof(ArgumentException))]
  270. public void Test_Sftp_BeginUploadFile_FileNameIsNull()
  271. {
  272. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  273. {
  274. sftp.Connect();
  275. sftp.BeginUploadFile(new MemoryStream(), null, null, null);
  276. sftp.Disconnect();
  277. }
  278. }
  279. [TestMethod]
  280. [TestCategory("Sftp")]
  281. [ExpectedException(typeof(ArgumentException))]
  282. public void Test_Sftp_EndUploadFile_Invalid_Async_Handle()
  283. {
  284. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  285. {
  286. sftp.Connect();
  287. var async1 = sftp.BeginListDirectory("/", null, null);
  288. var filename = Path.GetTempFileName();
  289. this.CreateTestFile(filename, 100);
  290. var async2 = sftp.BeginUploadFile(File.OpenRead(filename), "test", null, null);
  291. sftp.EndUploadFile(async1);
  292. }
  293. }
  294. }
  295. }