UploadDownloadFileTest.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using Renci.SshNet.Common;
  7. using Renci.SshNet.Tests.Properties;
  8. using System.IO;
  9. using System.Security.Cryptography;
  10. using Renci.SshNet.Sftp;
  11. using System.Threading;
  12. namespace Renci.SshNet.Tests.SftpClientTests
  13. {
  14. [TestClass]
  15. public class UploadDownloadFileTest
  16. {
  17. [TestInitialize()]
  18. public void CleanCurrentFolder()
  19. {
  20. using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  21. {
  22. client.Connect();
  23. client.RunCommand("rm -rf *");
  24. client.Disconnect();
  25. }
  26. }
  27. [TestMethod]
  28. [TestCategory("Sftp")]
  29. public void Test_Sftp_Upload_And_Download_1MB_File()
  30. {
  31. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  32. {
  33. sftp.Connect();
  34. string uploadedFileName = Path.GetTempFileName();
  35. string remoteFileName = Path.GetRandomFileName();
  36. this.CreateTestFile(uploadedFileName, 1);
  37. // Calculate has value
  38. var uploadedHash = CalculateMD5(uploadedFileName);
  39. using (var file = File.OpenRead(uploadedFileName))
  40. {
  41. sftp.UploadFile(file, remoteFileName);
  42. }
  43. string downloadedFileName = Path.GetTempFileName();
  44. using (var file = File.OpenWrite(downloadedFileName))
  45. {
  46. sftp.DownloadFile(remoteFileName, file);
  47. }
  48. var downloadedHash = CalculateMD5(downloadedFileName);
  49. sftp.DeleteFile(remoteFileName);
  50. File.Delete(uploadedFileName);
  51. File.Delete(downloadedFileName);
  52. sftp.Disconnect();
  53. Assert.AreEqual(uploadedHash, downloadedHash);
  54. }
  55. }
  56. [TestMethod]
  57. [TestCategory("Sftp")]
  58. [ExpectedException(typeof(SftpPermissionDeniedException))]
  59. public void Test_Sftp_Upload_Forbidden()
  60. {
  61. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  62. {
  63. sftp.Connect();
  64. string uploadedFileName = Path.GetTempFileName();
  65. string remoteFileName = "/root/1";
  66. this.CreateTestFile(uploadedFileName, 1);
  67. using (var file = File.OpenRead(uploadedFileName))
  68. {
  69. sftp.UploadFile(file, remoteFileName);
  70. }
  71. sftp.Disconnect();
  72. }
  73. }
  74. [TestMethod]
  75. [TestCategory("Sftp")]
  76. [ExpectedException(typeof(SftpPermissionDeniedException))]
  77. public void Test_Sftp_Download_Forbidden()
  78. {
  79. if (Resources.USERNAME == "root")
  80. Assert.Fail("Must not run this test as root!");
  81. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  82. {
  83. sftp.Connect();
  84. string remoteFileName = "/root/.profile";
  85. using (var ms = new MemoryStream())
  86. {
  87. sftp.DownloadFile(remoteFileName, ms);
  88. }
  89. sftp.Disconnect();
  90. }
  91. }
  92. [TestMethod]
  93. [TestCategory("Sftp")]
  94. [ExpectedException(typeof(SftpPathNotFoundException))]
  95. public void Test_Sftp_Download_File_Not_Exists()
  96. {
  97. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  98. {
  99. sftp.Connect();
  100. string remoteFileName = "/xxx/eee/yyy";
  101. using (var ms = new MemoryStream())
  102. {
  103. sftp.DownloadFile(remoteFileName, ms);
  104. }
  105. sftp.Disconnect();
  106. }
  107. }
  108. [TestMethod]
  109. [TestCategory("Sftp")]
  110. public void Test_Sftp_Multiple_Async_Upload_And_Download_10Files_5MB_Each()
  111. {
  112. var maxFiles = 10;
  113. var maxSize = 5;
  114. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  115. {
  116. sftp.Connect();
  117. var testInfoList = new Dictionary<string, TestInfo>();
  118. for (int i = 0; i < maxFiles; i++)
  119. {
  120. var testInfo = new TestInfo();
  121. testInfo.UploadedFileName = Path.GetTempFileName();
  122. testInfo.DownloadedFileName = Path.GetTempFileName();
  123. testInfo.RemoteFileName = Path.GetRandomFileName();
  124. this.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. bool 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. bool 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. if (!(testInfo.UploadResult.UploadedBytes > 0 && testInfo.DownloadResult.DownloadedBytes > 0 && testInfo.DownloadResult.DownloadedBytes == testInfo.UploadResult.UploadedBytes))
  202. {
  203. uploadDownloadSizeOk = false;
  204. }
  205. if (!testInfo.DownloadedHash.Equals(testInfo.UploadedHash))
  206. {
  207. hashMatches = false;
  208. }
  209. }
  210. // Clean up after test
  211. foreach (var remoteFile in testInfoList.Keys)
  212. {
  213. var testInfo = testInfoList[remoteFile];
  214. sftp.DeleteFile(remoteFile);
  215. File.Delete(testInfo.UploadedFileName);
  216. File.Delete(testInfo.DownloadedFileName);
  217. }
  218. sftp.Disconnect();
  219. Assert.IsTrue(hashMatches, "Hash does not match");
  220. Assert.IsTrue(uploadDownloadSizeOk, "Uploaded and downloaded bytes does not match");
  221. }
  222. }
  223. [TestMethod]
  224. [TestCategory("Sftp")]
  225. [Description("Test that delegates passed to BeginUploadFile, BeginDownloadFile and BeginListDirectory are actually called.")]
  226. public void Test_Sftp_Ensure_Async_Delegates_Called_For_BeginFileUpload_BeginFileDownload_BeginListDirectory()
  227. {
  228. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  229. {
  230. sftp.Connect();
  231. string remoteFileName = Path.GetRandomFileName();
  232. string localFileName = Path.GetRandomFileName();
  233. bool uploadDelegateCalled = false;
  234. bool downloadDelegateCalled = false;
  235. bool listDirectoryDelegateCalled = false;
  236. IAsyncResult asyncResult;
  237. // Test for BeginUploadFile.
  238. CreateTestFile(localFileName, 1);
  239. using (var fileStream = File.OpenRead(localFileName))
  240. {
  241. asyncResult = sftp.BeginUploadFile(fileStream, remoteFileName, delegate(IAsyncResult ar)
  242. {
  243. sftp.EndUploadFile(ar);
  244. uploadDelegateCalled = true;
  245. }, null);
  246. while (!asyncResult.IsCompleted)
  247. {
  248. Thread.Sleep(500);
  249. }
  250. }
  251. File.Delete(localFileName);
  252. Assert.IsTrue(uploadDelegateCalled, "BeginUploadFile");
  253. // Test for BeginDownloadFile.
  254. asyncResult = null;
  255. using (var fileStream = File.OpenWrite(localFileName))
  256. {
  257. asyncResult = sftp.BeginDownloadFile(remoteFileName, fileStream, delegate(IAsyncResult ar)
  258. {
  259. sftp.EndDownloadFile(ar);
  260. downloadDelegateCalled = true;
  261. }, null);
  262. while (!asyncResult.IsCompleted)
  263. {
  264. Thread.Sleep(500);
  265. }
  266. }
  267. File.Delete(localFileName);
  268. Assert.IsTrue(downloadDelegateCalled, "BeginDownloadFile");
  269. // Test for BeginListDirectory.
  270. asyncResult = null;
  271. asyncResult = sftp.BeginListDirectory(sftp.WorkingDirectory, delegate(IAsyncResult ar)
  272. {
  273. sftp.EndListDirectory(ar);
  274. listDirectoryDelegateCalled = true;
  275. }, null);
  276. while (!asyncResult.IsCompleted)
  277. {
  278. Thread.Sleep(500);
  279. }
  280. Assert.IsTrue(listDirectoryDelegateCalled, "BeginListDirectory");
  281. }
  282. }
  283. [TestMethod]
  284. [TestCategory("Sftp")]
  285. [Description("Test passing null to BeginUploadFile")]
  286. [ExpectedException(typeof(ArgumentNullException))]
  287. public void Test_Sftp_BeginUploadFile_StreamIsNull()
  288. {
  289. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  290. {
  291. sftp.Connect();
  292. sftp.BeginUploadFile(null, "aaaaa", null, null);
  293. sftp.Disconnect();
  294. }
  295. }
  296. [TestMethod]
  297. [TestCategory("Sftp")]
  298. [Description("Test passing null to BeginUploadFile")]
  299. [ExpectedException(typeof(ArgumentException))]
  300. public void Test_Sftp_BeginUploadFile_FileNameIsWhiteSpace()
  301. {
  302. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  303. {
  304. sftp.Connect();
  305. sftp.BeginUploadFile(new MemoryStream(), " ", null, null);
  306. sftp.Disconnect();
  307. }
  308. }
  309. [TestMethod]
  310. [TestCategory("Sftp")]
  311. [Description("Test passing null to BeginUploadFile")]
  312. [ExpectedException(typeof(ArgumentException))]
  313. public void Test_Sftp_BeginUploadFile_FileNameIsNull()
  314. {
  315. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  316. {
  317. sftp.Connect();
  318. sftp.BeginUploadFile(new MemoryStream(), null, null, null);
  319. sftp.Disconnect();
  320. }
  321. }
  322. [TestMethod]
  323. [TestCategory("Sftp")]
  324. [Description("Test passing null to BeginDownloadFile")]
  325. [ExpectedException(typeof(ArgumentNullException))]
  326. public void Test_Sftp_BeginDownloadFile_StreamIsNull()
  327. {
  328. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  329. {
  330. sftp.Connect();
  331. sftp.BeginDownloadFile("aaaa", null, null, null);
  332. sftp.Disconnect();
  333. }
  334. }
  335. [TestMethod]
  336. [TestCategory("Sftp")]
  337. [Description("Test passing null to BeginDownloadFile")]
  338. [ExpectedException(typeof(ArgumentException))]
  339. public void Test_Sftp_BeginDownloadFile_FileNameIsWhiteSpace()
  340. {
  341. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  342. {
  343. sftp.Connect();
  344. sftp.BeginDownloadFile(" ", new MemoryStream(), null, null);
  345. sftp.Disconnect();
  346. }
  347. }
  348. [TestMethod]
  349. [TestCategory("Sftp")]
  350. [Description("Test passing null to BeginDownloadFile")]
  351. [ExpectedException(typeof(ArgumentException))]
  352. public void Test_Sftp_BeginDownloadFile_FileNameIsNull()
  353. {
  354. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  355. {
  356. sftp.Connect();
  357. sftp.BeginDownloadFile(null, new MemoryStream(), null, null);
  358. sftp.Disconnect();
  359. }
  360. }
  361. [TestMethod]
  362. [TestCategory("Sftp")]
  363. [ExpectedException(typeof(ArgumentException))]
  364. public void Test_Sftp_EndUploadFile_Invalid_Async_Handle()
  365. {
  366. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  367. {
  368. sftp.Connect();
  369. var async1 = sftp.BeginListDirectory("/", null, null);
  370. var filename = Path.GetTempFileName();
  371. this.CreateTestFile(filename, 100);
  372. var async2 = sftp.BeginUploadFile(File.OpenRead(filename), "test", null, null);
  373. sftp.EndUploadFile(async1);
  374. }
  375. }
  376. [TestMethod]
  377. [TestCategory("Sftp")]
  378. [ExpectedException(typeof(ArgumentException))]
  379. public void Test_Sftp_EndDownloadFile_Invalid_Async_Handle()
  380. {
  381. using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
  382. {
  383. sftp.Connect();
  384. var filename = Path.GetTempFileName();
  385. this.CreateTestFile(filename, 1);
  386. sftp.UploadFile(File.OpenRead(filename), "test123");
  387. var async1 = sftp.BeginListDirectory("/", null, null);
  388. var async2 = sftp.BeginDownloadFile("test123", new MemoryStream(), null, null);
  389. sftp.EndDownloadFile(async1);
  390. }
  391. }
  392. /// <summary>
  393. /// Creates the test file.
  394. /// </summary>
  395. /// <param name="fileName">Name of the file.</param>
  396. /// <param name="size">Size in megabytes.</param>
  397. private void CreateTestFile(string fileName, int size)
  398. {
  399. using (var testFile = File.Create(fileName))
  400. {
  401. var random = new Random();
  402. for (int i = 0; i < 1024 * size; i++)
  403. {
  404. var buffer = new byte[1024];
  405. random.NextBytes(buffer);
  406. testFile.Write(buffer, 0, buffer.Length);
  407. }
  408. }
  409. }
  410. protected static string CalculateMD5(string fileName)
  411. {
  412. using (FileStream file = new FileStream(fileName, FileMode.Open))
  413. {
  414. MD5 md5 = new MD5CryptoServiceProvider();
  415. byte[] retVal = md5.ComputeHash(file);
  416. file.Close();
  417. StringBuilder sb = new StringBuilder();
  418. for (int i = 0; i < retVal.Length; i++)
  419. {
  420. sb.Append(retVal[i].ToString("x2"));
  421. }
  422. return sb.ToString();
  423. }
  424. }
  425. /// <summary>
  426. /// Helper class to help with upload and download testing
  427. /// </summary>
  428. private class TestInfo
  429. {
  430. public string RemoteFileName { get; set; }
  431. public string UploadedFileName { get; set; }
  432. public string DownloadedFileName { get; set; }
  433. //public ulong UploadedBytes { get; set; }
  434. //public ulong DownloadedBytes { get; set; }
  435. public FileStream UploadedFile { get; set; }
  436. public FileStream DownloadedFile { get; set; }
  437. public string UploadedHash { get; set; }
  438. public string DownloadedHash { get; set; }
  439. public SftpUploadAsyncResult UploadResult { get; set; }
  440. public SftpDownloadAsyncResult DownloadResult { get; set; }
  441. }
  442. }
  443. }