SftpClientTest.Upload.cs 16 KB

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