Skip to content

Commit 127e3f6

Browse files
committed
Throw an SshException when SCP request is rejected by the remote host.
1 parent 9df22e3 commit 127e3f6

9 files changed

+612
-11
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.IO;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using Moq;
7+
using Renci.SshNet.Channels;
8+
using Renci.SshNet.Common;
9+
10+
namespace Renci.SshNet.Tests.Classes
11+
{
12+
[TestClass]
13+
public class ScpClientTest_Download_PathAndDirectoryInfo_SendExecRequestReturnsFalse
14+
{
15+
private Mock<IServiceFactory> _serviceFactoryMock;
16+
private Mock<ISession> _sessionMock;
17+
private Mock<IChannelSession> _channelSessionMock;
18+
private Mock<PipeStream> _pipeStreamMock;
19+
private ConnectionInfo _connectionInfo;
20+
private ScpClient _scpClient;
21+
private DirectoryInfo _directoryInfo;
22+
private string _path;
23+
private string _quotedPath;
24+
private IList<ScpUploadEventArgs> _uploadingRegister;
25+
private SshException _actualException;
26+
27+
[TestInitialize]
28+
public void Setup()
29+
{
30+
Arrange();
31+
Act();
32+
}
33+
34+
protected void Arrange()
35+
{
36+
var random = new Random();
37+
_connectionInfo = new ConnectionInfo("host", 22, "user", new PasswordAuthenticationMethod("user", "pwd"));
38+
_directoryInfo = new DirectoryInfo("destination");
39+
_path = "/home/sshnet/" + random.Next().ToString(CultureInfo.InvariantCulture);
40+
_quotedPath = _path.ShellQuote();
41+
_uploadingRegister = new List<ScpUploadEventArgs>();
42+
43+
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
44+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
45+
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
46+
_pipeStreamMock = new Mock<PipeStream>(MockBehavior.Strict);
47+
48+
var sequence = new MockSequence();
49+
_serviceFactoryMock.InSequence(sequence)
50+
.Setup(p => p.CreateSession(_connectionInfo))
51+
.Returns(_sessionMock.Object);
52+
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
53+
_serviceFactoryMock.InSequence(sequence).Setup(p => p.CreatePipeStream()).Returns(_pipeStreamMock.Object);
54+
_sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
55+
_channelSessionMock.InSequence(sequence).Setup(p => p.Open());
56+
_channelSessionMock.InSequence(sequence)
57+
.Setup(p => p.SendExecRequest(string.Format("scp -prf {0}", _quotedPath))).Returns(false);
58+
_channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
59+
_pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
60+
61+
_scpClient = new ScpClient(_connectionInfo, false, _serviceFactoryMock.Object);
62+
_scpClient.Uploading += (sender, args) => _uploadingRegister.Add(args);
63+
_scpClient.Connect();
64+
}
65+
66+
protected virtual void Act()
67+
{
68+
try
69+
{
70+
_scpClient.Download(_path, _directoryInfo);
71+
Assert.Fail();
72+
}
73+
catch (SshException ex)
74+
{
75+
_actualException = ex;
76+
}
77+
}
78+
79+
[TestMethod]
80+
public void UploadShouldHaveThrownSshException()
81+
{
82+
Assert.IsNotNull(_actualException);
83+
Assert.IsNull(_actualException.InnerException);
84+
Assert.AreEqual("Secure copy execution request was rejected by the server. Please consult the server logs.", _actualException.Message);
85+
}
86+
87+
[TestMethod]
88+
public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
89+
{
90+
_channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -prf {0}", _quotedPath)), Times.Once);
91+
}
92+
93+
[TestMethod]
94+
public void DisposeOnChannelShouldBeInvokedOnce()
95+
{
96+
_channelSessionMock.Verify(p => p.Dispose(), Times.Once);
97+
}
98+
99+
[TestMethod]
100+
public void DisposeOnPipeStreamShouldBeInvokedOnce()
101+
{
102+
_pipeStreamMock.As<IDisposable>().Verify(p => p.Dispose(), Times.Once);
103+
}
104+
105+
[TestMethod]
106+
public void UploadingShouldNeverHaveFired()
107+
{
108+
Assert.AreEqual(0, _uploadingRegister.Count);
109+
}
110+
}
111+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.IO;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using Moq;
7+
using Renci.SshNet.Channels;
8+
using Renci.SshNet.Common;
9+
10+
namespace Renci.SshNet.Tests.Classes
11+
{
12+
[TestClass]
13+
public class ScpClientTest_Download_PathAndFileInfo_SendExecRequestReturnsFalse
14+
{
15+
private Mock<IServiceFactory> _serviceFactoryMock;
16+
private Mock<ISession> _sessionMock;
17+
private Mock<IChannelSession> _channelSessionMock;
18+
private Mock<PipeStream> _pipeStreamMock;
19+
private ConnectionInfo _connectionInfo;
20+
private ScpClient _scpClient;
21+
private FileInfo _fileInfo;
22+
private string _path;
23+
private string _quotedPath;
24+
private IList<ScpUploadEventArgs> _uploadingRegister;
25+
private SshException _actualException;
26+
27+
[TestInitialize]
28+
public void Setup()
29+
{
30+
Arrange();
31+
Act();
32+
}
33+
34+
protected void Arrange()
35+
{
36+
var random = new Random();
37+
_connectionInfo = new ConnectionInfo("host", 22, "user", new PasswordAuthenticationMethod("user", "pwd"));
38+
_fileInfo = new FileInfo("destination");
39+
_path = "/home/sshnet/" + random.Next().ToString(CultureInfo.InvariantCulture);
40+
_quotedPath = _path.ShellQuote();
41+
_uploadingRegister = new List<ScpUploadEventArgs>();
42+
43+
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
44+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
45+
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
46+
_pipeStreamMock = new Mock<PipeStream>(MockBehavior.Strict);
47+
48+
var sequence = new MockSequence();
49+
_serviceFactoryMock.InSequence(sequence)
50+
.Setup(p => p.CreateSession(_connectionInfo))
51+
.Returns(_sessionMock.Object);
52+
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
53+
_serviceFactoryMock.InSequence(sequence).Setup(p => p.CreatePipeStream()).Returns(_pipeStreamMock.Object);
54+
_sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
55+
_channelSessionMock.InSequence(sequence).Setup(p => p.Open());
56+
_channelSessionMock.InSequence(sequence)
57+
.Setup(p => p.SendExecRequest(string.Format("scp -pf {0}", _quotedPath))).Returns(false);
58+
_channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
59+
_pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
60+
61+
_scpClient = new ScpClient(_connectionInfo, false, _serviceFactoryMock.Object);
62+
_scpClient.Uploading += (sender, args) => _uploadingRegister.Add(args);
63+
_scpClient.Connect();
64+
}
65+
66+
protected virtual void Act()
67+
{
68+
try
69+
{
70+
_scpClient.Download(_path, _fileInfo);
71+
Assert.Fail();
72+
}
73+
catch (SshException ex)
74+
{
75+
_actualException = ex;
76+
}
77+
}
78+
79+
[TestMethod]
80+
public void UploadShouldHaveThrownSshException()
81+
{
82+
Assert.IsNotNull(_actualException);
83+
Assert.IsNull(_actualException.InnerException);
84+
Assert.AreEqual("Secure copy execution request was rejected by the server. Please consult the server logs.", _actualException.Message);
85+
}
86+
87+
[TestMethod]
88+
public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
89+
{
90+
_channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -pf {0}", _quotedPath)), Times.Once);
91+
}
92+
93+
[TestMethod]
94+
public void DisposeOnChannelShouldBeInvokedOnce()
95+
{
96+
_channelSessionMock.Verify(p => p.Dispose(), Times.Once);
97+
}
98+
99+
[TestMethod]
100+
public void DisposeOnPipeStreamShouldBeInvokedOnce()
101+
{
102+
_pipeStreamMock.As<IDisposable>().Verify(p => p.Dispose(), Times.Once);
103+
}
104+
105+
[TestMethod]
106+
public void UploadingShouldNeverHaveFired()
107+
{
108+
Assert.AreEqual(0, _uploadingRegister.Count);
109+
}
110+
}
111+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.IO;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
using Moq;
7+
using Renci.SshNet.Channels;
8+
using Renci.SshNet.Common;
9+
10+
namespace Renci.SshNet.Tests.Classes
11+
{
12+
[TestClass]
13+
public class ScpClientTest_Download_PathAndStream_SendExecRequestReturnsFalse
14+
{
15+
private Mock<IServiceFactory> _serviceFactoryMock;
16+
private Mock<ISession> _sessionMock;
17+
private Mock<IChannelSession> _channelSessionMock;
18+
private Mock<PipeStream> _pipeStreamMock;
19+
private ConnectionInfo _connectionInfo;
20+
private ScpClient _scpClient;
21+
private Stream _destination;
22+
private string _path;
23+
private string _quotedPath;
24+
private IList<ScpUploadEventArgs> _uploadingRegister;
25+
private SshException _actualException;
26+
27+
[TestInitialize]
28+
public void Setup()
29+
{
30+
Arrange();
31+
Act();
32+
}
33+
34+
[TestCleanup]
35+
public void Cleanup()
36+
{
37+
if (_destination != null)
38+
{
39+
_destination.Dispose();
40+
}
41+
}
42+
43+
protected void Arrange()
44+
{
45+
var random = new Random();
46+
_connectionInfo = new ConnectionInfo("host", 22, "user", new PasswordAuthenticationMethod("user", "pwd"));
47+
_destination = new MemoryStream();
48+
_path = "/home/sshnet/" + random.Next().ToString(CultureInfo.InvariantCulture);
49+
_quotedPath = _path.ShellQuote();
50+
_uploadingRegister = new List<ScpUploadEventArgs>();
51+
52+
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
53+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
54+
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
55+
_pipeStreamMock = new Mock<PipeStream>(MockBehavior.Strict);
56+
57+
var sequence = new MockSequence();
58+
_serviceFactoryMock.InSequence(sequence)
59+
.Setup(p => p.CreateSession(_connectionInfo))
60+
.Returns(_sessionMock.Object);
61+
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
62+
_serviceFactoryMock.InSequence(sequence).Setup(p => p.CreatePipeStream()).Returns(_pipeStreamMock.Object);
63+
_sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
64+
_channelSessionMock.InSequence(sequence).Setup(p => p.Open());
65+
_channelSessionMock.InSequence(sequence)
66+
.Setup(p => p.SendExecRequest(string.Format("scp -f {0}", _quotedPath))).Returns(false);
67+
_channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
68+
_pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
69+
70+
_scpClient = new ScpClient(_connectionInfo, false, _serviceFactoryMock.Object);
71+
_scpClient.Uploading += (sender, args) => _uploadingRegister.Add(args);
72+
_scpClient.Connect();
73+
}
74+
75+
protected virtual void Act()
76+
{
77+
try
78+
{
79+
_scpClient.Download(_path, _destination);
80+
Assert.Fail();
81+
}
82+
catch (SshException ex)
83+
{
84+
_actualException = ex;
85+
}
86+
}
87+
88+
[TestMethod]
89+
public void UploadShouldHaveThrownSshException()
90+
{
91+
Assert.IsNotNull(_actualException);
92+
Assert.IsNull(_actualException.InnerException);
93+
Assert.AreEqual("Secure copy execution request was rejected by the server. Please consult the server logs.", _actualException.Message);
94+
}
95+
96+
[TestMethod]
97+
public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
98+
{
99+
_channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -f {0}", _quotedPath)), Times.Once);
100+
}
101+
102+
[TestMethod]
103+
public void DisposeOnChannelShouldBeInvokedOnce()
104+
{
105+
_channelSessionMock.Verify(p => p.Dispose(), Times.Once);
106+
}
107+
108+
[TestMethod]
109+
public void DisposeOnPipeStreamShouldBeInvokedOnce()
110+
{
111+
_pipeStreamMock.As<IDisposable>().Verify(p => p.Dispose(), Times.Once);
112+
}
113+
114+
[TestMethod]
115+
public void UploadingShouldNeverHaveFired()
116+
{
117+
Assert.AreEqual(0, _uploadingRegister.Count);
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)