mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 01:05:42 +00:00
Added GetAttributesAsync to SftpClient (#1648)
* Added GetAttributesAsync to SftpClient * Adding integration tests + unit test * Address warnings in test classes. --------- Co-authored-by: William Decker <william.decker@syndigo.com>
This commit is contained in:
@@ -700,6 +700,21 @@ namespace Renci.SshNet
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
SftpFileAttributes GetAttributes(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="SftpFileAttributes"/> of the file on the path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{SftpFileAttributes}"/> that represents the attribute retrieval operation.
|
||||
/// The task result contains the <see cref="SftpFileAttributes"/> of the file on the path.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
Task<SftpFileAttributes> GetAttributesAsync(string path, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the date and time the specified file or directory was last accessed.
|
||||
/// </summary>
|
||||
|
||||
@@ -2094,6 +2094,33 @@ namespace Renci.SshNet
|
||||
return _sftpSession.RequestLStat(fullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="SftpFileAttributes"/> of the file on the path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{SftpFileAttributes}"/> that represents the attribute retrieval operation.
|
||||
/// The task result contains the <see cref="SftpFileAttributes"/> of the file on the path.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
public async Task<SftpFileAttributes> GetAttributesAsync(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
if (_sftpSession is null)
|
||||
{
|
||||
throw new SshConnectionException("Client not connected.");
|
||||
}
|
||||
|
||||
var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await _sftpSession.RequestLStatAsync(fullPath, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified <see cref="SftpFileAttributes"/> of the file on the specified path.
|
||||
/// </summary>
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
using Renci.SshNet.Common;
|
||||
|
||||
namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
public partial class SftpClientTest
|
||||
{
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public void Test_Sftp_GetAttributes_Not_Exists()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
|
||||
Assert.ThrowsException<SftpPathNotFoundException>(() => sftp.GetAttributes("/asdfgh"));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public void Test_Sftp_GetAttributes_Null()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
|
||||
Assert.ThrowsException<ArgumentNullException>(() => sftp.GetAttributes(null));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public void Test_Sftp_GetAttributes_Current()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
|
||||
var attributes = sftp.GetAttributes(".");
|
||||
|
||||
Assert.IsNotNull(attributes);
|
||||
|
||||
sftp.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
using Renci.SshNet.Common;
|
||||
|
||||
namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
|
||||
/// </summary>
|
||||
public partial class SftpClientTest
|
||||
{
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_GetAttributesAsync_Not_Exists()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromMinutes(1));
|
||||
|
||||
await sftp.ConnectAsync(cts.Token);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<SftpPathNotFoundException>(async () => await sftp.GetAttributesAsync("/asdfgh", cts.Token));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_GetAttributesAsync_Null()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromMinutes(1));
|
||||
|
||||
await sftp.ConnectAsync(cts.Token);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () => await sftp.GetAttributesAsync(null, cts.Token));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_GetAttributesAsync_Current()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromMinutes(1));
|
||||
|
||||
await sftp.ConnectAsync(cts.Token);
|
||||
|
||||
var fileAttributes = await sftp.GetAttributesAsync(".", cts.Token);
|
||||
|
||||
Assert.IsNotNull(fileAttributes);
|
||||
|
||||
sftp.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,5 +177,33 @@ namespace Renci.SshNet.IntegrationTests
|
||||
|
||||
Assert.IsFalse(await _sftpClient.ExistsAsync(testFileName).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Create_file_and_use_GetAttributes()
|
||||
{
|
||||
var testFileName = "test-file.txt";
|
||||
var testContent = "file content";
|
||||
|
||||
using var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(testContent));
|
||||
_sftpClient.UploadFile(fileStream, testFileName);
|
||||
|
||||
var attributes = _sftpClient.GetAttributes(testFileName);
|
||||
Assert.IsNotNull(attributes);
|
||||
Assert.IsTrue(attributes.IsRegularFile);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Create_file_and_use_GetAttributesAsync()
|
||||
{
|
||||
var testFileName = "test-file.txt";
|
||||
var testContent = "file content";
|
||||
|
||||
using var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(testContent));
|
||||
await _sftpClient.UploadFileAsync(fileStream, testFileName).ConfigureAwait(false);
|
||||
|
||||
var attributes = await _sftpClient.GetAttributesAsync(testFileName, CancellationToken.None).ConfigureAwait(false);
|
||||
Assert.IsNotNull(attributes);
|
||||
Assert.IsTrue(attributes.IsRegularFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Tests.Properties;
|
||||
|
||||
namespace Renci.SshNet.Tests.Classes
|
||||
{
|
||||
public partial class SftpClientTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void GetAttributes_Throws_WhenNotConnected()
|
||||
{
|
||||
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
|
||||
{
|
||||
Assert.ThrowsException<SshConnectionException>(() => sftp.GetAttributes("."));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetAttributes_Throws_WhenDisposed()
|
||||
{
|
||||
var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD);
|
||||
sftp.Dispose();
|
||||
|
||||
Assert.ThrowsException<ObjectDisposedException>(() => sftp.GetAttributes("."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Tests.Properties;
|
||||
|
||||
namespace Renci.SshNet.Tests.Classes
|
||||
{
|
||||
public partial class SftpClientTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task GetAttributesAsync_Throws_WhenNotConnected()
|
||||
{
|
||||
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
|
||||
{
|
||||
await Assert.ThrowsExceptionAsync<SshConnectionException>(() => sftp.GetAttributesAsync(".", CancellationToken.None));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetAttributesAsync_Throws_WhenDisposed()
|
||||
{
|
||||
var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD);
|
||||
sftp.Dispose();
|
||||
|
||||
await Assert.ThrowsExceptionAsync<ObjectDisposedException>(() => sftp.GetAttributesAsync(".", CancellationToken.None));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user