ScpClientTest_Upload_FileInfoAndPath_Success.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using Microsoft.VisualStudio.TestTools.UnitTesting;
  8. using Moq;
  9. using Renci.SshNet.Channels;
  10. using Renci.SshNet.Common;
  11. namespace Renci.SshNet.Tests.Classes
  12. {
  13. [TestClass]
  14. public class ScpClientTest_Upload_FileInfoAndPath_Success
  15. {
  16. private Mock<IServiceFactory> _serviceFactoryMock;
  17. private Mock<ISession> _sessionMock;
  18. private Mock<IChannelSession> _channelSessionMock;
  19. private Mock<PipeStream> _pipeStreamMock;
  20. private ConnectionInfo _connectionInfo;
  21. private ScpClient _scpClient;
  22. private FileInfo _fileInfo;
  23. private string _path;
  24. private int _bufferSize;
  25. private byte[] _fileContent;
  26. private string _fileName;
  27. private int _fileSize;
  28. private IList<ScpUploadEventArgs> _uploadingRegister;
  29. [TestInitialize]
  30. public void Setup()
  31. {
  32. Arrange();
  33. Act();
  34. }
  35. [TestCleanup]
  36. public void Cleanup()
  37. {
  38. if (_fileName != null)
  39. {
  40. File.Delete(_fileName);
  41. _fileName = null;
  42. }
  43. }
  44. protected void Arrange()
  45. {
  46. var random = new Random();
  47. _bufferSize = random.Next(5, 15);
  48. _fileSize = _bufferSize + 2; //force uploading 2 chunks
  49. _fileContent = CreateContent(_fileSize);
  50. _fileName = CreateTemporaryFile(_fileContent);
  51. _connectionInfo = new ConnectionInfo("host", 22, "user", new PasswordAuthenticationMethod("user", "pwd"));
  52. _fileInfo = new FileInfo(_fileName);
  53. _path = random.Next().ToString(CultureInfo.InvariantCulture);
  54. _uploadingRegister = new List<ScpUploadEventArgs>();
  55. _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
  56. _sessionMock = new Mock<ISession>(MockBehavior.Strict);
  57. _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
  58. _pipeStreamMock = new Mock<PipeStream>(MockBehavior.Strict);
  59. var sequence = new MockSequence();
  60. _serviceFactoryMock.InSequence(sequence)
  61. .Setup(p => p.CreateSession(_connectionInfo))
  62. .Returns(_sessionMock.Object);
  63. _sessionMock.InSequence(sequence).Setup(p => p.Connect());
  64. _serviceFactoryMock.InSequence(sequence).Setup(p => p.CreatePipeStream()).Returns(_pipeStreamMock.Object);
  65. _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
  66. _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
  67. _channelSessionMock.InSequence(sequence)
  68. .Setup(
  69. p => p.SendExecRequest(string.Format("scp -t \"{0}\"", _path))).Returns(true);
  70. for (var i = 0; i < random.Next(1, 3); i++)
  71. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
  72. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  73. _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>()));
  74. for (var i = 0; i < random.Next(1, 3); i++)
  75. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
  76. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  77. _channelSessionMock.InSequence(sequence)
  78. .Setup(p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(CreateData(
  79. string.Format("C0644 {0} {1}\n",
  80. _fileInfo.Length,
  81. Path.GetFileName(_fileName)
  82. )
  83. )))));
  84. for (var i = 0; i < random.Next(1, 3); i++)
  85. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
  86. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  87. #if TUNING
  88. _channelSessionMock.InSequence(sequence)
  89. .Setup(
  90. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Take(_bufferSize))), 0, _bufferSize));
  91. _channelSessionMock.InSequence(sequence)
  92. .Setup(
  93. p => p.SendData(It.Is<byte[]>(b => b.Take(0, _fileContent.Length - _bufferSize).SequenceEqual(_fileContent.Take(_bufferSize, _fileContent.Length - _bufferSize))), 0, _fileContent.Length - _bufferSize));
  94. #else
  95. _channelSessionMock.InSequence(sequence)
  96. .Setup(
  97. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Take(_bufferSize)))));
  98. _channelSessionMock.InSequence(sequence)
  99. .Setup(
  100. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Skip(_bufferSize)))));
  101. #endif
  102. _channelSessionMock.InSequence(sequence)
  103. .Setup(
  104. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(new byte[] { 0 }))));
  105. for (var i = 0; i < random.Next(1, 3); i++)
  106. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
  107. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  108. _channelSessionMock.InSequence(sequence).Setup(p => p.Close());
  109. _channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
  110. _pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
  111. _scpClient = new ScpClient(_connectionInfo, false, _serviceFactoryMock.Object)
  112. {
  113. BufferSize = (uint) _bufferSize
  114. };
  115. _scpClient.Uploading += (sender, args) => _uploadingRegister.Add(args);
  116. _scpClient.Connect();
  117. }
  118. protected virtual void Act()
  119. {
  120. _scpClient.Upload(_fileInfo, _path);
  121. }
  122. [TestMethod]
  123. public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
  124. {
  125. _channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -t \"{0}\"", _path)), Times.Once);
  126. }
  127. [TestMethod]
  128. public void CloseOnChannelShouldBeInvokedOnce()
  129. {
  130. _channelSessionMock.Verify(p => p.Close(), Times.Once);
  131. }
  132. [TestMethod]
  133. public void DisposeOnChannelShouldBeInvokedOnce()
  134. {
  135. _channelSessionMock.Verify(p => p.Dispose(), Times.Once);
  136. }
  137. [TestMethod]
  138. public void DisposeOnPipeStreamShouldBeInvokedOnce()
  139. {
  140. _pipeStreamMock.As<IDisposable>().Verify(p => p.Dispose(), Times.Once);
  141. }
  142. [TestMethod]
  143. public void UploadingShouldHaveFiredTwice()
  144. {
  145. Assert.AreEqual(2, _uploadingRegister.Count);
  146. var uploading = _uploadingRegister[0];
  147. Assert.IsNotNull(uploading);
  148. Assert.AreSame(_fileInfo.Name, uploading.Filename);
  149. Assert.AreEqual(_fileSize, uploading.Size);
  150. Assert.AreEqual(_bufferSize, uploading.Uploaded);
  151. uploading = _uploadingRegister[1];
  152. Assert.IsNotNull(uploading);
  153. Assert.AreSame(_fileInfo.Name, uploading.Filename);
  154. Assert.AreEqual(_fileSize, uploading.Size);
  155. Assert.AreEqual(_fileSize, uploading.Uploaded);
  156. }
  157. private IEnumerable<byte> CreateData(string command)
  158. {
  159. return Encoding.Default.GetBytes(command);
  160. }
  161. private byte[] CreateContent(int length)
  162. {
  163. var random = new Random();
  164. var content = new byte[length];
  165. for (var i = 0; i < length; i++)
  166. content[i] = (byte) random.Next(byte.MinValue, byte.MaxValue);
  167. return content;
  168. }
  169. private string CreateTemporaryFile(byte[] content)
  170. {
  171. var tempFile = Path.GetTempFileName();
  172. using (var fs = File.OpenWrite(tempFile))
  173. {
  174. fs.Write(content, 0, content.Length);
  175. }
  176. return tempFile;
  177. }
  178. }
  179. }