SftpSessionTest_Connected_RequestStatVfs.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using Moq;
  6. using Renci.SshNet.Channels;
  7. using Renci.SshNet.Common;
  8. using Renci.SshNet.Sftp;
  9. namespace Renci.SshNet.Tests.Classes.Sftp
  10. {
  11. [TestClass]
  12. public class SftpSessionTest_Connected_RequestStatVfs
  13. {
  14. private Mock<ISession> _sessionMock;
  15. private Mock<IChannelSession> _channelSessionMock;
  16. private SftpSession _sftpSession;
  17. private TimeSpan _operationTimeout;
  18. private SftpFileSytemInformation _actual;
  19. private Encoding _encoding;
  20. private ulong _bAvail;
  21. [TestInitialize]
  22. public void Setup()
  23. {
  24. Arrange();
  25. Act();
  26. }
  27. protected void Arrange()
  28. {
  29. var random = new Random();
  30. _operationTimeout = TimeSpan.FromMilliseconds(random.Next(100, 500));
  31. _encoding = Encoding.UTF8;
  32. _bAvail = (ulong) random.Next(0, int.MaxValue);
  33. _sessionMock = new Mock<ISession>(MockBehavior.Strict);
  34. _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
  35. var sequence = new MockSequence();
  36. _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
  37. _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
  38. _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
  39. _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
  40. _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
  41. () =>
  42. {
  43. // generate response for SftpInitRequest
  44. var versionInfoResponse = SftpVersionResponseBuilder.Create(3)
  45. .AddExtension("statvfs@openssh.com", "")
  46. .Build();
  47. _channelSessionMock.Raise(
  48. c => c.DataReceived += null,
  49. new ChannelDataEventArgs(0, versionInfoResponse));
  50. });
  51. _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
  52. _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
  53. () =>
  54. {
  55. var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
  56. _channelSessionMock.Raise(
  57. c => c.DataReceived += null,
  58. new ChannelDataEventArgs(0, sftpNameResponse));
  59. }
  60. );
  61. _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
  62. _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
  63. () =>
  64. {
  65. var statVfsReplyBuilder = StatVfsReplyBuilder.Create(2);
  66. statVfsReplyBuilder.WithBAvail(_bAvail);
  67. var statVfsReply = statVfsReplyBuilder.Build();
  68. _channelSessionMock.Raise(
  69. c => c.DataReceived += null,
  70. new ChannelDataEventArgs(0, statVfsReply));
  71. }
  72. );
  73. _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
  74. _sftpSession.Connect();
  75. }
  76. protected void Act()
  77. {
  78. _actual = _sftpSession.RequestStatVfs("path");
  79. }
  80. [TestMethod]
  81. public void ReturnedValueShouldNotBeNull()
  82. {
  83. Assert.IsNotNull(_actual);
  84. }
  85. [TestMethod]
  86. public void AvailableBlocksInReturnedValueShouldMatchValueInSftpResponse()
  87. {
  88. Assert.AreEqual(_bAvail, _actual.AvailableBlocks);
  89. }
  90. private static byte[] CreateSftpNameResponse(uint responseId, Encoding encoding, params string[] names)
  91. {
  92. var namesAndAttributes = new List<byte>();
  93. foreach (var name in names)
  94. {
  95. var nameBytes = encoding.GetBytes(name);
  96. var attributesBytes = SftpFileAttributes.Empty.GetBytes();
  97. namesAndAttributes.AddRange((((uint) nameBytes.Length).GetBytes())); // filename length
  98. namesAndAttributes.AddRange(nameBytes); // filename
  99. namesAndAttributes.AddRange(((uint) 0).GetBytes()); // longname length
  100. namesAndAttributes.AddRange(attributesBytes); // attributes
  101. }
  102. var namesAndAttributesBytes = namesAndAttributes.ToArray();
  103. var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + namesAndAttributesBytes.Length);
  104. sshDataStream.Write((uint) sshDataStream.Capacity - 4);
  105. sshDataStream.WriteByte((byte) SftpMessageTypes.Name);
  106. sshDataStream.Write(responseId);
  107. sshDataStream.Write((uint) names.Length);
  108. sshDataStream.Write(namesAndAttributesBytes, 0, namesAndAttributesBytes.Length);
  109. return sshDataStream.ToArray();
  110. }
  111. public class StatVfsReplyBuilder
  112. {
  113. private readonly uint _responseId;
  114. private ulong _bsize;
  115. private ulong _frsize;
  116. private ulong _blocks;
  117. private ulong _bfree;
  118. private ulong _bavail;
  119. private ulong _files;
  120. private ulong _ffree;
  121. private ulong _favail;
  122. private ulong _sid;
  123. private ulong _flag;
  124. private ulong _namemax;
  125. private StatVfsReplyBuilder(uint responseId)
  126. {
  127. _responseId = responseId;
  128. }
  129. public static StatVfsReplyBuilder Create(uint responseId)
  130. {
  131. return new StatVfsReplyBuilder(responseId);
  132. }
  133. public StatVfsReplyBuilder WithBSize(ulong bsize)
  134. {
  135. _bsize = bsize;
  136. return this;
  137. }
  138. public StatVfsReplyBuilder WithFrSize(ulong frsize)
  139. {
  140. _frsize = frsize;
  141. return this;
  142. }
  143. public StatVfsReplyBuilder WithBlocks(ulong blocks)
  144. {
  145. _blocks = blocks;
  146. return this;
  147. }
  148. public StatVfsReplyBuilder WithBFree(ulong bfree)
  149. {
  150. _bfree = bfree;
  151. return this;
  152. }
  153. public StatVfsReplyBuilder WithBAvail(ulong bavail)
  154. {
  155. _bavail = bavail;
  156. return this;
  157. }
  158. public StatVfsReplyBuilder WithFiles(ulong files)
  159. {
  160. _files = files;
  161. return this;
  162. }
  163. public StatVfsReplyBuilder WithFFree(ulong ffree)
  164. {
  165. _ffree = ffree;
  166. return this;
  167. }
  168. public StatVfsReplyBuilder WithFAvail(ulong favail)
  169. {
  170. _favail = favail;
  171. return this;
  172. }
  173. public StatVfsReplyBuilder WithSid(ulong sid)
  174. {
  175. _sid = sid;
  176. return this;
  177. }
  178. public StatVfsReplyBuilder WithIsReadOnly(bool isReadOnly)
  179. {
  180. if (isReadOnly)
  181. _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
  182. else
  183. _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
  184. return this;
  185. }
  186. public StatVfsReplyBuilder WithSupportsSetUid(bool supportsSetUid)
  187. {
  188. if (supportsSetUid)
  189. _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
  190. else
  191. _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
  192. return this;
  193. }
  194. public StatVfsReplyBuilder WithNameMax(ulong nameMax)
  195. {
  196. _namemax = nameMax;
  197. return this;
  198. }
  199. public byte[] Build()
  200. {
  201. var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
  202. sshDataStream.Write((uint) sshDataStream.Capacity - 4);
  203. sshDataStream.WriteByte((byte) SftpMessageTypes.ExtendedReply);
  204. sshDataStream.Write(_responseId);
  205. sshDataStream.Write(_bsize);
  206. sshDataStream.Write(_frsize);
  207. sshDataStream.Write(_blocks);
  208. sshDataStream.Write(_bfree);
  209. sshDataStream.Write(_bavail);
  210. sshDataStream.Write(_files);
  211. sshDataStream.Write(_ffree);
  212. sshDataStream.Write(_favail);
  213. sshDataStream.Write(_sid);
  214. sshDataStream.Write(_flag);
  215. sshDataStream.Write(_namemax);
  216. return sshDataStream.ToArray();
  217. }
  218. }
  219. }
  220. }