ScpClientTest_Upload_FileInfoAndPath_Success.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 string _quotedPath;
  25. private int _bufferSize;
  26. private byte[] _fileContent;
  27. private string _fileName;
  28. private int _fileSize;
  29. private IList<ScpUploadEventArgs> _uploadingRegister;
  30. [TestInitialize]
  31. public void Setup()
  32. {
  33. Arrange();
  34. Act();
  35. }
  36. [TestCleanup]
  37. public void Cleanup()
  38. {
  39. if (_fileName != null)
  40. {
  41. File.Delete(_fileName);
  42. _fileName = null;
  43. }
  44. }
  45. private void SetupData()
  46. {
  47. var random = new Random();
  48. _bufferSize = random.Next(5, 15);
  49. _fileSize = _bufferSize + 2; //force uploading 2 chunks
  50. _fileContent = CreateContent(_fileSize);
  51. _fileName = CreateTemporaryFile(_fileContent);
  52. _connectionInfo = new ConnectionInfo("host", 22, "user", new PasswordAuthenticationMethod("user", "pwd"));
  53. _fileInfo = new FileInfo(_fileName);
  54. _path = "/home/sshnet/" + random.Next().ToString(CultureInfo.InvariantCulture);
  55. _quotedPath = _path.ShellQuote();
  56. _uploadingRegister = new List<ScpUploadEventArgs>();
  57. }
  58. private void CreateMocks()
  59. {
  60. _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
  61. _sessionMock = new Mock<ISession>(MockBehavior.Strict);
  62. _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
  63. _pipeStreamMock = new Mock<PipeStream>(MockBehavior.Strict);
  64. }
  65. private void SetupMocks()
  66. {
  67. var sequence = new MockSequence();
  68. _serviceFactoryMock.InSequence(sequence)
  69. .Setup(p => p.CreateSession(_connectionInfo))
  70. .Returns(_sessionMock.Object);
  71. _sessionMock.InSequence(sequence).Setup(p => p.Connect());
  72. _serviceFactoryMock.InSequence(sequence).Setup(p => p.CreatePipeStream()).Returns(_pipeStreamMock.Object);
  73. _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
  74. _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
  75. _channelSessionMock.InSequence(sequence)
  76. .Setup(p => p.SendExecRequest(string.Format("scp -t {0}", _quotedPath))).Returns(true);
  77. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  78. _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>()));
  79. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  80. _channelSessionMock.InSequence(sequence)
  81. .Setup(p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(CreateData(
  82. string.Format("C0644 {0} {1}\n", _fileInfo.Length, string.Empty))))));
  83. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  84. _channelSessionMock.InSequence(sequence)
  85. .Setup(
  86. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Take(_bufferSize))), 0, _bufferSize));
  87. _channelSessionMock.InSequence(sequence)
  88. .Setup(
  89. p => p.SendData(It.Is<byte[]>(b => b.Take(0, _fileContent.Length - _bufferSize).SequenceEqual(_fileContent.Take(_bufferSize, _fileContent.Length - _bufferSize))), 0, _fileContent.Length - _bufferSize));
  90. _channelSessionMock.InSequence(sequence)
  91. .Setup(
  92. p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(new byte[] {0}))));
  93. _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
  94. _channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
  95. _pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
  96. }
  97. protected void Arrange()
  98. {
  99. SetupData();
  100. CreateMocks();
  101. SetupMocks();
  102. _scpClient = new ScpClient(_connectionInfo, false, _serviceFactoryMock.Object)
  103. {
  104. BufferSize = (uint) _bufferSize
  105. };
  106. _scpClient.Uploading += (sender, args) => _uploadingRegister.Add(args);
  107. _scpClient.Connect();
  108. }
  109. protected virtual void Act()
  110. {
  111. _scpClient.Upload(_fileInfo, _path);
  112. }
  113. [TestMethod]
  114. public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
  115. {
  116. _channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -t {0}", _quotedPath)), Times.Once);
  117. }
  118. [TestMethod]
  119. public void DisposeOnChannelShouldBeInvokedOnce()
  120. {
  121. _channelSessionMock.Verify(p => p.Dispose(), Times.Once);
  122. }
  123. [TestMethod]
  124. public void DisposeOnPipeStreamShouldBeInvokedOnce()
  125. {
  126. _pipeStreamMock.As<IDisposable>().Verify(p => p.Dispose(), Times.Once);
  127. }
  128. [TestMethod]
  129. public void UploadingShouldHaveFiredTwice()
  130. {
  131. Assert.AreEqual(2, _uploadingRegister.Count);
  132. var uploading = _uploadingRegister[0];
  133. Assert.IsNotNull(uploading);
  134. Assert.AreSame(_fileInfo.Name, uploading.Filename);
  135. Assert.AreEqual(_fileSize, uploading.Size);
  136. Assert.AreEqual(_bufferSize, uploading.Uploaded);
  137. uploading = _uploadingRegister[1];
  138. Assert.IsNotNull(uploading);
  139. Assert.AreSame(_fileInfo.Name, uploading.Filename);
  140. Assert.AreEqual(_fileSize, uploading.Size);
  141. Assert.AreEqual(_fileSize, uploading.Uploaded);
  142. }
  143. private static IEnumerable<byte> CreateData(string command)
  144. {
  145. return Encoding.Default.GetBytes(command);
  146. }
  147. private static byte[] CreateContent(int length)
  148. {
  149. var random = new Random();
  150. var content = new byte[length];
  151. for (var i = 0; i < length; i++)
  152. content[i] = (byte) random.Next(byte.MinValue, byte.MaxValue);
  153. return content;
  154. }
  155. private static string CreateTemporaryFile(byte[] content)
  156. {
  157. var tempFile = Path.GetTempFileName();
  158. using (var fs = File.OpenWrite(tempFile))
  159. {
  160. fs.Write(content, 0, content.Length);
  161. }
  162. return tempFile;
  163. }
  164. }
  165. }