| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- using System;
- using System.Buffers.Binary;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Renci.SshNet.Common;
- using Renci.SshNet.Sftp;
- namespace Renci.SshNet.Tests.Classes.Sftp
- {
- [TestClass]
- public class SftpFileAttributesTest
- {
- [TestMethod]
- [DataRow(0xC000u, true, false, false, false, false, false, false)] // Socket
- [DataRow(0xA000u, false, true, false, false, false, false, false)] // Symbolic link
- [DataRow(0x8000u, false, false, true, false, false, false, false)] // Regular file
- [DataRow(0x6000u, false, false, false, true, false, false, false)] // Block device
- [DataRow(0x4000u, false, false, false, false, true, false, false)] // Directory
- [DataRow(0x2000u, false, false, false, false, false, true, false)] // Character device
- [DataRow(0x1000u, false, false, false, false, false, false, true)] // Named pipe
- public void FileTypePropertiesAreMutuallyExclusive(
- uint permissions,
- bool isSocket,
- bool isSymbolicLink,
- bool isRegularFile,
- bool isBlockDevice,
- bool isDirectory,
- bool isCharacterDevice,
- bool isNamedPipe)
- {
- var attributeBytes = new byte[8];
- attributeBytes[3] = 0x4; // SSH_FILEXFER_ATTR_PERMISSIONS
- BinaryPrimitives.WriteUInt32BigEndian(attributeBytes.AsSpan(4), permissions);
- var attributes = SftpFileAttributes.FromBytes(attributeBytes);
- Assert.AreEqual(isSocket, attributes.IsSocket);
- Assert.AreEqual(isSymbolicLink, attributes.IsSymbolicLink);
- Assert.AreEqual(isRegularFile, attributes.IsRegularFile);
- Assert.AreEqual(isBlockDevice, attributes.IsBlockDevice);
- Assert.AreEqual(isDirectory, attributes.IsDirectory);
- Assert.AreEqual(isCharacterDevice, attributes.IsCharacterDevice);
- Assert.AreEqual(isNamedPipe, attributes.IsNamedPipe);
- }
- [TestMethod]
- public void FromBytesGetBytes()
- {
- // 81a4 in hex = 100644 in octal
- var attributes = SftpFileAttributes.FromBytes([0, 0, 0, 0x4, 0, 0, 0x81, 0xa4]);
- Assert.IsTrue(attributes.IsRegularFile);
- Assert.IsFalse(attributes.IsUIDBitSet);
- Assert.IsFalse(attributes.IsGroupIDBitSet);
- Assert.IsFalse(attributes.IsStickyBitSet);
- Assert.IsTrue(attributes.OwnerCanRead);
- Assert.IsTrue(attributes.OwnerCanWrite);
- Assert.IsFalse(attributes.OwnerCanExecute);
- Assert.IsTrue(attributes.GroupCanRead);
- Assert.IsFalse(attributes.GroupCanWrite);
- Assert.IsFalse(attributes.GroupCanExecute);
- Assert.IsTrue(attributes.OthersCanRead);
- Assert.IsFalse(attributes.OthersCanWrite);
- Assert.IsFalse(attributes.OthersCanExecute);
- Assert.AreEqual(-1, attributes.Size); // Erm, OK?
- Assert.AreEqual(-1, attributes.UserId);
- Assert.AreEqual(-1, attributes.GroupId);
- Assert.AreEqual(default, attributes.LastAccessTimeUtc);
- Assert.AreEqual(DateTimeKind.Utc, attributes.LastAccessTimeUtc.Kind);
- Assert.AreEqual(default, attributes.LastWriteTimeUtc);
- Assert.AreEqual(DateTimeKind.Utc, attributes.LastWriteTimeUtc.Kind);
- Assert.AreEqual("-rw-r--r--", attributes.ToString());
- // No changes
- CollectionAssert.AreEqual(
- new byte[] { 0, 0, 0, 0 },
- attributes.GetBytes());
- // Permissions change
- attributes.IsUIDBitSet = true;
- attributes.OwnerCanExecute = true;
- CollectionAssert.AreEqual(
- new byte[] { 0, 0, 0, 0x4, 0, 0, 0x89, 0xe4 },
- attributes.GetBytes());
- Assert.AreEqual("-rwsr--r--", attributes.ToString());
- // Size change
- attributes.Size = 123;
- CollectionAssert.AreEqual(
- new byte[] {
- 0, 0, 0, 0x1 | 0x4,
- 0, 0, 0, 0, 0, 0, 0, 123,
- 0, 0, 0x89, 0xe4 },
- attributes.GetBytes());
- Assert.IsTrue(attributes.ToString().StartsWith("-rwsr--r-- Size: ", StringComparison.Ordinal));
- // Uid/gid change
- attributes.UserId = 99;
- attributes.GroupId = 66;
- CollectionAssert.AreEqual(
- new byte[] {
- 0, 0, 0, 0x1 | 0x2 | 0x4,
- 0, 0, 0, 0, 0, 0, 0, 123,
- 0, 0, 0, 99, 0, 0, 0, 66,
- 0, 0, 0x89, 0xe4 },
- attributes.GetBytes());
- // Access/mod time change
- attributes.LastAccessTimeUtc = new DateTime(2025, 08, 10, 17, 51, 37, DateTimeKind.Unspecified);
- attributes.LastWriteTime = new DateTimeOffset(2016, 12, 02, 13, 18, 20, TimeSpan.FromHours(3)).LocalDateTime;
- var expectedTimeBytes = new byte[8];
- BinaryPrimitives.WriteUInt32BigEndian(expectedTimeBytes, 1754848297);
- BinaryPrimitives.WriteUInt32BigEndian(expectedTimeBytes.AsSpan(4), 1480673900);
- CollectionAssert.AreEqual(
- new byte[] {
- 0, 0, 0, 0x1 | 0x2 | 0x4 | 0x8,
- 0, 0, 0, 0, 0, 0, 0, 123,
- 0, 0, 0, 99, 0, 0, 0, 66,
- 0, 0, 0x89, 0xe4
- }.Concat(expectedTimeBytes),
- attributes.GetBytes());
- Assert.AreEqual(new DateTime(2016, 12, 02, 10, 18, 20, DateTimeKind.Utc), attributes.LastWriteTimeUtc);
- Assert.AreEqual(DateTimeKind.Utc, attributes.LastWriteTimeUtc.Kind);
- var attributesString = attributes.ToString();
- Assert.IsTrue(attributesString.StartsWith("-rwsr--r-- Size: ", StringComparison.Ordinal));
- Assert.Contains(" LastWriteTime: ", attributesString, StringComparison.CurrentCulture);
- }
- [TestMethod]
- [DataRow((short)8888)]
- [DataRow((short)10000)]
- [DataRow((short)8000)]
- [DataRow((short)0080)]
- [DataRow((short)0008)]
- [DataRow((short)1797)]
- [DataRow((short)-1)]
- [DataRow(short.MaxValue)]
- public void SetPermissions_InvalidMode_ThrowsArgumentOutOfRangeException(short mode)
- {
- var attributes = SftpFileAttributes.FromBytes([0, 0, 0, 0]);
- var ex = Assert.Throws<ArgumentOutOfRangeException>(() => attributes.SetPermissions(mode));
- Assert.AreEqual("mode", ex.ParamName);
- }
- [TestMethod]
- [DataRow((short)0777, false, false, false, true, true, true, true, true, true, true, true, true)]
- [DataRow((short)0755, false, false, false, true, true, true, true, false, true, true, false, true)]
- [DataRow((short)0644, false, false, false, true, true, false, true, false, false, true, false, false)]
- [DataRow((short)0444, false, false, false, true, false, false, true, false, false, true, false, false)]
- [DataRow((short)0000, false, false, false, false, false, false, false, false, false, false, false, false)]
- [DataRow((short)4700, true, false, false, true, true, true, false, false, false, false, false, false)]
- [DataRow((short)3001, false, true, true, false, false, false, false, false, false, false, false, true)]
- [DataRow((short)7777, true, true, true, true, true, true, true, true, true, true, true, true)]
- public void SetPermissions_ValidMode(
- short mode,
- bool setUid, bool setGid, bool sticky,
- bool ownerRead, bool ownerWrite, bool ownerExec,
- bool groupRead, bool groupWrite, bool groupExec,
- bool othersRead, bool othersWrite, bool othersExec)
- {
- var attributes = SftpFileAttributes.FromBytes([0, 0, 0, 0]);
- attributes.SetPermissions(mode);
- Assert.AreEqual(setUid, attributes.IsUIDBitSet);
- Assert.AreEqual(setGid, attributes.IsGroupIDBitSet);
- Assert.AreEqual(sticky, attributes.IsStickyBitSet);
- Assert.AreEqual(ownerRead, attributes.OwnerCanRead);
- Assert.AreEqual(ownerWrite, attributes.OwnerCanWrite);
- Assert.AreEqual(ownerExec, attributes.OwnerCanExecute);
- Assert.AreEqual(groupRead, attributes.GroupCanRead);
- Assert.AreEqual(groupWrite, attributes.GroupCanWrite);
- Assert.AreEqual(groupExec, attributes.GroupCanExecute);
- Assert.AreEqual(othersRead, attributes.OthersCanRead);
- Assert.AreEqual(othersWrite, attributes.OthersCanWrite);
- Assert.AreEqual(othersExec, attributes.OthersCanExecute);
- }
- [TestMethod]
- [DataRow(0xC000u, (short)1770, "srwxrwx--T")] // Socket
- [DataRow(0xA000u, (short)2707, "lrwx--Srwx")] // Symbolic link
- [DataRow(0x8000u, (short)4755, "-rwsr-xr-x")] // Regular file
- [DataRow(0x8000u, (short)4644, "-rwSr--r--")] // Regular file
- [DataRow(0x6000u, (short)2711, "brwx--s--x")] // Block device
- [DataRow(0x4000u, (short)1777, "drwxrwxrwt")] // Directory
- [DataRow(0x4000u, (short)1776, "drwxrwxrwT")] // Directory
- [DataRow(0x2000u, (short)0660, "crw-rw----")] // Character device
- [DataRow(0x1000u, (short)0022, "p----w--w-")] // Named pipe
- public void ToStringWithPermissions(
- uint fileType,
- short permissions,
- string expected)
- {
- var attributeBytes = new byte[8];
- attributeBytes[3] = 0x4; // SSH_FILEXFER_ATTR_PERMISSIONS
- BinaryPrimitives.WriteUInt32BigEndian(attributeBytes.AsSpan(4), fileType);
- var attributes = SftpFileAttributes.FromBytes(attributeBytes);
- attributes.SetPermissions(permissions);
- Assert.AreEqual(expected, attributes.ToString());
- }
- }
- }
|