ScpClientTest_Upload_FileInfoAndPath_Success.cs 6.9 KB

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