mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 01:05:42 +00:00
Add UploadFileAsync and DownloadFileAsync methods (#1634)
* add interface methods * add internal file methods * impl interface methods * tweak buffer size usage * swap tests with async upload * swap more upload file references * add async download tests * add upload/download integration async test * check if net48 * silence not await warning * try tweaking test init * remove request close from upload * dispose already closes, remove dup call * remove extra upload overload * inherit doc * configure await * remove excess util functions * add cancel throws * add cancellation tests * missed one configure await * use default buffer size * private ctor * docs --------- Co-authored-by: Rob Hague <rob.hague00@gmail.com>
This commit is contained in:
@@ -556,23 +556,36 @@ namespace Renci.SshNet
|
||||
Task DeleteFileAsync(string path, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Downloads remote file specified by the path into the stream.
|
||||
/// Downloads a remote file into a <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">File to download.</param>
|
||||
/// <param name="output">Stream to write the file into.</param>
|
||||
/// <param name="path">The path to the remote file.</param>
|
||||
/// <param name="output">The <see cref="Stream"/> to write the file into.</param>
|
||||
/// <param name="downloadCallback">The download callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="output" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="output"/> or <paramref name="path"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path"/> is empty or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to perform the operation was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>///
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to perform the operation was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>
|
||||
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="output" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
void DownloadFile(string path, Stream output, Action<ulong>? downloadCallback = null);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously downloads a remote file into a <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the remote file.</param>
|
||||
/// <param name="output">The <see cref="Stream"/> to write the file into.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous download operation.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="output"/> or <paramref name="path"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path"/> is empty or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to perform the operation was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>
|
||||
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
Task DownloadFileAsync(string path, Stream output, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Ends an asynchronous file downloading into the stream.
|
||||
/// </summary>
|
||||
@@ -1070,40 +1083,49 @@ namespace Renci.SshNet
|
||||
IEnumerable<FileInfo> SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern);
|
||||
|
||||
/// <summary>
|
||||
/// Uploads stream into remote file.
|
||||
/// Uploads a <see cref="Stream"/> to a remote file path.
|
||||
/// </summary>
|
||||
/// <param name="input">Data input stream.</param>
|
||||
/// <param name="path">Remote file path.</param>
|
||||
/// <param name="input">The <see cref="Stream"/> to write to the remote path.</param>
|
||||
/// <param name="path">The remote file path to write to.</param>
|
||||
/// <param name="uploadCallback">The upload callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> or <paramref name="path" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is empty or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="input" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
void UploadFile(Stream input, string path, Action<ulong>? uploadCallback = null);
|
||||
|
||||
/// <summary>
|
||||
/// Uploads stream into remote file.
|
||||
/// Uploads a <see cref="Stream"/> to a remote file path.
|
||||
/// </summary>
|
||||
/// <param name="input">Data input stream.</param>
|
||||
/// <param name="path">Remote file path.</param>
|
||||
/// <param name="canOverride">if set to <see langword="true"/> then existing file will be overwritten.</param>
|
||||
/// <param name="input">The <see cref="Stream"/> to write to the remote path.</param>
|
||||
/// <param name="path">The remote file path to write to.</param>
|
||||
/// <param name="canOverride">Whether the remote file can be overwritten if it already exists.</param>
|
||||
/// <param name="uploadCallback">The upload callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> or <paramref name="path" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is empty or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="input" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
void UploadFile(Stream input, string path, bool canOverride, Action<ulong>? uploadCallback = null);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously uploads a <see cref="Stream"/> to a remote file path.
|
||||
/// </summary>
|
||||
/// <param name="input">The <see cref="Stream"/> to write to the remote path.</param>
|
||||
/// <param name="path">The remote file path to write to.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to observe.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous upload operation.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input"/> or <paramref name="path"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is empty or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> An SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">An SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified byte array to the specified file, and closes the file.
|
||||
/// </summary>
|
||||
|
||||
@@ -893,22 +893,7 @@ namespace Renci.SshNet
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads remote file specified by the path into the stream.
|
||||
/// </summary>
|
||||
/// <param name="path">File to download.</param>
|
||||
/// <param name="output">Stream to write the file into.</param>
|
||||
/// <param name="downloadCallback">The download callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="output" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to perform the operation was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>///
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="output" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public void DownloadFile(string path, Stream output, Action<ulong>? downloadCallback = null)
|
||||
{
|
||||
CheckDisposed();
|
||||
@@ -916,6 +901,14 @@ namespace Renci.SshNet
|
||||
InternalDownloadFile(path, output, asyncResult: null, downloadCallback);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task DownloadFileAsync(string path, Stream output, CancellationToken cancellationToken = default)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
return InternalDownloadFileAsync(path, output, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous file downloading into the stream.
|
||||
/// </summary>
|
||||
@@ -1023,42 +1016,13 @@ namespace Renci.SshNet
|
||||
ar.EndInvoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uploads stream into remote file.
|
||||
/// </summary>
|
||||
/// <param name="input">Data input stream.</param>
|
||||
/// <param name="path">Remote file path.</param>
|
||||
/// <param name="uploadCallback">The upload callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="input" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public void UploadFile(Stream input, string path, Action<ulong>? uploadCallback = null)
|
||||
{
|
||||
UploadFile(input, path, canOverride: true, uploadCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uploads stream into remote file.
|
||||
/// </summary>
|
||||
/// <param name="input">Data input stream.</param>
|
||||
/// <param name="path">Remote file path.</param>
|
||||
/// <param name="canOverride">if set to <see langword="true"/> then existing file will be overwritten.</param>
|
||||
/// <param name="uploadCallback">The upload callback.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="input" /> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="path" /> is <see langword="null"/> or contains only whitespace characters.</exception>
|
||||
/// <exception cref="SshConnectionException">Client is not connected.</exception>
|
||||
/// <exception cref="SftpPermissionDeniedException">Permission to upload the file was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
|
||||
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
|
||||
/// <remarks>
|
||||
/// Method calls made by this method to <paramref name="input" />, may under certain conditions result in exceptions thrown by the stream.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public void UploadFile(Stream input, string path, bool canOverride, Action<ulong>? uploadCallback = null)
|
||||
{
|
||||
CheckDisposed();
|
||||
@@ -1077,6 +1041,14 @@ namespace Renci.SshNet
|
||||
InternalUploadFile(input, path, flags, asyncResult: null, uploadCallback);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
return InternalUploadFileAsync(input, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous uploading the stream into remote file.
|
||||
/// </summary>
|
||||
@@ -2433,6 +2405,27 @@ namespace Renci.SshNet
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InternalDownloadFileAsync(string path, Stream output, CancellationToken cancellationToken)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(output);
|
||||
ThrowHelper.ThrowIfNullOrWhiteSpace(path);
|
||||
|
||||
if (_sftpSession is null)
|
||||
{
|
||||
throw new SshConnectionException("Client not connected.");
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
var openStreamTask = SftpFileStream.OpenAsync(_sftpSession, fullPath, FileMode.Open, FileAccess.Read, (int)_bufferSize, cancellationToken);
|
||||
|
||||
using (var input = await openStreamTask.ConfigureAwait(false))
|
||||
{
|
||||
await input.CopyToAsync(output, 81920, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internals the upload file.
|
||||
/// </summary>
|
||||
@@ -2515,6 +2508,27 @@ namespace Renci.SshNet
|
||||
responseReceivedWaitHandle.Dispose();
|
||||
}
|
||||
|
||||
private async Task InternalUploadFileAsync(Stream input, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
ThrowHelper.ThrowIfNull(input);
|
||||
ThrowHelper.ThrowIfNullOrWhiteSpace(path);
|
||||
|
||||
if (_sftpSession is null)
|
||||
{
|
||||
throw new SshConnectionException("Client not connected.");
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var fullPath = await _sftpSession.GetCanonicalPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
var openStreamTask = SftpFileStream.OpenAsync(_sftpSession, fullPath, FileMode.Create, FileAccess.Write, (int)_bufferSize, cancellationToken);
|
||||
|
||||
using (var output = await openStreamTask.ConfigureAwait(false))
|
||||
{
|
||||
await input.CopyToAsync(output, 81920, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when client is connected to the server.
|
||||
/// </summary>
|
||||
|
||||
@@ -31,6 +31,44 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_DownloadAsync_Forbidden()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, AdminUser.UserName, AdminUser.Password))
|
||||
{
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<SftpPermissionDeniedException>(() => sftp.DownloadFileAsync("/root/.profile", Stream.Null));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_DownloadAsync_File_Not_Exists()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<SftpPathNotFoundException>(() => sftp.DownloadFileAsync("/xxx/eee/yyy", Stream.Null));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_DownloadAsync_Cancellation_Requested()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var cancelledToken = new CancellationToken(true);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<OperationCanceledException>(() => sftp.DownloadFileAsync("/xxx/eee/yyy", Stream.Null, cancelledToken));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
[Description("Test passing null to BeginDownloadFile")]
|
||||
|
||||
@@ -51,6 +51,49 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_Upload_And_Download_Async_1MB_File()
|
||||
{
|
||||
RemoveAllFiles();
|
||||
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var uploadedFileName = Path.GetTempFileName();
|
||||
var remoteFileName = Path.GetRandomFileName();
|
||||
|
||||
CreateTestFile(uploadedFileName, 1);
|
||||
|
||||
// Calculate has value
|
||||
var uploadedHash = CalculateMD5(uploadedFileName);
|
||||
|
||||
using (var file = File.OpenRead(uploadedFileName))
|
||||
{
|
||||
await sftp.UploadFileAsync(file, remoteFileName).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var downloadedFileName = Path.GetTempFileName();
|
||||
|
||||
using (var file = File.OpenWrite(downloadedFileName))
|
||||
{
|
||||
await sftp.DownloadFileAsync(remoteFileName, file).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var downloadedHash = CalculateMD5(downloadedFileName);
|
||||
|
||||
await sftp.DeleteFileAsync(remoteFileName, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
File.Delete(uploadedFileName);
|
||||
File.Delete(downloadedFileName);
|
||||
|
||||
sftp.Disconnect();
|
||||
|
||||
Assert.AreEqual(uploadedHash, downloadedHash);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public void Test_Sftp_Upload_Forbidden()
|
||||
@@ -73,6 +116,28 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public async Task Test_Sftp_UploadAsync_Cancellation_Requested()
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
await sftp.ConnectAsync(CancellationToken.None);
|
||||
|
||||
var uploadedFileName = Path.GetTempFileName();
|
||||
var remoteFileName = "/root/1";
|
||||
|
||||
CreateTestFile(uploadedFileName, 1);
|
||||
|
||||
var cancelledToken = new CancellationToken(true);
|
||||
|
||||
using (var file = File.OpenRead(uploadedFileName))
|
||||
{
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(() => sftp.UploadFileAsync(file, remoteFileName, cancelledToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("Sftp")]
|
||||
public void Test_Sftp_Multiple_Async_Upload_And_Download_10Files_5MB_Each()
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
var directory = await sftp.GetAsync("/", default).ConfigureAwait(false);
|
||||
|
||||
Assert.AreEqual("/", directory.FullName);
|
||||
@@ -103,7 +103,7 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<SftpPathNotFoundException>(() => sftp.GetAsync("/xyz", default));
|
||||
}
|
||||
@@ -115,9 +115,9 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
sftp.UploadFile(new MemoryStream(), "abc.txt");
|
||||
await sftp.UploadFileAsync(new MemoryStream(), "abc.txt").ConfigureAwait(false);
|
||||
|
||||
var file = await sftp.GetAsync("abc.txt", default).ConfigureAwait(false);
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => sftp.GetAsync(null, default));
|
||||
}
|
||||
@@ -145,9 +145,9 @@ namespace Renci.SshNet.IntegrationTests.OldIntegrationTests
|
||||
{
|
||||
using (var sftp = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password))
|
||||
{
|
||||
sftp.Connect();
|
||||
await sftp.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
sftp.UploadFile(new MemoryStream(), "test-üöä-");
|
||||
await sftp.UploadFileAsync(new MemoryStream(), "test-üöä-").ConfigureAwait(false);
|
||||
|
||||
var file = await sftp.GetAsync("test-üöä-", default).ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -6,14 +6,26 @@ namespace Renci.SshNet.IntegrationTests
|
||||
/// The SFTP client integration tests
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class SftpClientTests : IntegrationTestBase, IDisposable
|
||||
public class SftpClientTests : IntegrationTestBase
|
||||
{
|
||||
private readonly SftpClient _sftpClient;
|
||||
|
||||
public SftpClientTests()
|
||||
{
|
||||
_sftpClient = new SftpClient(SshServerHostName, SshServerPort, User.UserName, User.Password);
|
||||
_sftpClient.Connect();
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _sftpClient.ConnectAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
_sftpClient.Disconnect();
|
||||
_sftpClient.Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -65,7 +77,7 @@ namespace Renci.SshNet.IntegrationTests
|
||||
|
||||
// Upload file and check if it exists
|
||||
using var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(testContent));
|
||||
_sftpClient.UploadFile(fileStream, testFilePath);
|
||||
await _sftpClient.UploadFileAsync(fileStream, testFilePath).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testFilePath));
|
||||
|
||||
// Check if ListDirectory works
|
||||
@@ -118,12 +130,12 @@ namespace Renci.SshNet.IntegrationTests
|
||||
var testContent = "file content";
|
||||
|
||||
// Create new directory and check if it exists
|
||||
await _sftpClient.CreateDirectoryAsync(testDirectory);
|
||||
await _sftpClient.CreateDirectoryAsync(testDirectory).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testDirectory).ConfigureAwait(false));
|
||||
|
||||
// Upload file and check if it exists
|
||||
using var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(testContent));
|
||||
_sftpClient.UploadFile(fileStream, testFilePath);
|
||||
await _sftpClient.UploadFileAsync(fileStream, testFilePath).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testFilePath).ConfigureAwait(false));
|
||||
|
||||
await _sftpClient.DeleteFileAsync(testFilePath, CancellationToken.None).ConfigureAwait(false);
|
||||
@@ -142,7 +154,7 @@ namespace Renci.SshNet.IntegrationTests
|
||||
var testDirectory = "/home/sshnet/sshnet-test";
|
||||
|
||||
// Create new directory and check if it exists
|
||||
await _sftpClient.CreateDirectoryAsync(testDirectory);
|
||||
await _sftpClient.CreateDirectoryAsync(testDirectory).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testDirectory).ConfigureAwait(false));
|
||||
|
||||
await _sftpClient.DeleteAsync(testDirectory, CancellationToken.None).ConfigureAwait(false);
|
||||
@@ -158,18 +170,12 @@ namespace Renci.SshNet.IntegrationTests
|
||||
|
||||
// Upload file and check if it exists
|
||||
using var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(testContent));
|
||||
_sftpClient.UploadFile(fileStream, testFileName);
|
||||
await _sftpClient.UploadFileAsync(fileStream, testFileName).ConfigureAwait(false);
|
||||
Assert.IsTrue(await _sftpClient.ExistsAsync(testFileName).ConfigureAwait(false));
|
||||
|
||||
await _sftpClient.DeleteAsync(testFileName, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
Assert.IsFalse(await _sftpClient.ExistsAsync(testFileName).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_sftpClient.Disconnect();
|
||||
_sftpClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4115,7 +4115,7 @@ namespace Renci.SshNet.IntegrationTests
|
||||
{
|
||||
uploadStream.Position = 0;
|
||||
|
||||
client.UploadFile(uploadStream, "gert.txt");
|
||||
await client.UploadFileAsync(uploadStream, "gert.txt").ConfigureAwait(false);
|
||||
|
||||
uploadStream.Position = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user