Skip to content

Commit 8037bdf

Browse files
committed
Fix #395 : SftpClient Enumerates Rather Than Accumulates Directory Items
1 parent 7691cb0 commit 8037bdf

File tree

4 files changed

+327
-19
lines changed

4 files changed

+327
-19
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Renci.SshNet.Common;
3+
using Renci.SshNet.Tests.Common;
4+
using Renci.SshNet.Tests.Properties;
5+
using System;
6+
using System.Diagnostics;
7+
using System.Linq;
8+
9+
namespace Renci.SshNet.Tests.Classes
10+
{
11+
/// <summary>
12+
/// Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
13+
/// </summary>
14+
public partial class SftpClientTest : TestBase
15+
{
16+
[TestMethod]
17+
[TestCategory("Sftp")]
18+
[ExpectedException(typeof(SshConnectionException))]
19+
public void Test_Sftp_EnumerateDirectory_Without_Connecting()
20+
{
21+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
22+
{
23+
var files = sftp.EnumerateDirectory(".");
24+
foreach (var file in files)
25+
{
26+
Debug.WriteLine(file.FullName);
27+
}
28+
}
29+
}
30+
31+
[TestMethod]
32+
[TestCategory("Sftp")]
33+
[TestCategory("integration")]
34+
[ExpectedException(typeof(SftpPermissionDeniedException))]
35+
public void Test_Sftp_EnumerateDirectory_Permission_Denied()
36+
{
37+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
38+
{
39+
sftp.Connect();
40+
41+
var files = sftp.EnumerateDirectory("/root");
42+
foreach (var file in files)
43+
{
44+
Debug.WriteLine(file.FullName);
45+
}
46+
47+
sftp.Disconnect();
48+
}
49+
}
50+
51+
[TestMethod]
52+
[TestCategory("Sftp")]
53+
[TestCategory("integration")]
54+
[ExpectedException(typeof(SftpPathNotFoundException))]
55+
public void Test_Sftp_EnumerateDirectory_Not_Exists()
56+
{
57+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
58+
{
59+
sftp.Connect();
60+
61+
var files = sftp.EnumerateDirectory("/asdfgh");
62+
foreach (var file in files)
63+
{
64+
Debug.WriteLine(file.FullName);
65+
}
66+
67+
sftp.Disconnect();
68+
}
69+
}
70+
71+
[TestMethod]
72+
[TestCategory("Sftp")]
73+
[TestCategory("integration")]
74+
public void Test_Sftp_EnumerateDirectory_Current()
75+
{
76+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
77+
{
78+
sftp.Connect();
79+
80+
var files = sftp.EnumerateDirectory(".");
81+
82+
Assert.IsTrue(files.Count() > 0);
83+
84+
foreach (var file in files)
85+
{
86+
Debug.WriteLine(file.FullName);
87+
}
88+
89+
sftp.Disconnect();
90+
}
91+
}
92+
93+
[TestMethod]
94+
[TestCategory("Sftp")]
95+
[TestCategory("integration")]
96+
public void Test_Sftp_EnumerateDirectory_Empty()
97+
{
98+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
99+
{
100+
sftp.Connect();
101+
102+
var files = sftp.EnumerateDirectory(string.Empty);
103+
104+
Assert.IsTrue(files.Count() > 0);
105+
106+
foreach (var file in files)
107+
{
108+
Debug.WriteLine(file.FullName);
109+
}
110+
111+
sftp.Disconnect();
112+
}
113+
}
114+
115+
[TestMethod]
116+
[TestCategory("Sftp")]
117+
[TestCategory("integration")]
118+
[Description("Test passing null to EnumerateDirectory.")]
119+
[ExpectedException(typeof(ArgumentNullException))]
120+
public void Test_Sftp_EnumerateDirectory_Null()
121+
{
122+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
123+
{
124+
sftp.Connect();
125+
126+
var files = sftp.EnumerateDirectory(null);
127+
128+
Assert.IsTrue(files.Count() > 0);
129+
130+
foreach (var file in files)
131+
{
132+
Debug.WriteLine(file.FullName);
133+
}
134+
135+
sftp.Disconnect();
136+
}
137+
}
138+
139+
[TestMethod]
140+
[TestCategory("Sftp")]
141+
[TestCategory("integration")]
142+
public void Test_Sftp_EnumerateDirectory_HugeDirectory()
143+
{
144+
var stopwatch = Stopwatch.StartNew();
145+
try
146+
{
147+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
148+
{
149+
sftp.Connect();
150+
sftp.ChangeDirectory("/home/" + Resources.USERNAME);
151+
152+
var count = 10000;
153+
// Create 10000 directory items
154+
for (int i = 0; i < count; i++)
155+
{
156+
sftp.CreateDirectory(string.Format("test_{0}", i));
157+
}
158+
Debug.WriteLine("Created {0} directories within {1} seconds", count, stopwatch.Elapsed.TotalSeconds);
159+
160+
stopwatch.Restart();
161+
var files = sftp.EnumerateDirectory(".");
162+
Debug.WriteLine("Listed {0} directories within {1} seconds", count, stopwatch.Elapsed.TotalSeconds);
163+
164+
// Ensure that directory has at least 10000 items
165+
stopwatch.Restart();
166+
var actualCount = files.Count();
167+
Assert.IsTrue(actualCount >= 10000);
168+
Debug.WriteLine("Used {0} items within {1} seconds", actualCount, stopwatch.Elapsed.TotalSeconds);
169+
170+
sftp.Disconnect();
171+
}
172+
}
173+
finally
174+
{
175+
stopwatch.Restart();
176+
RemoveAllFiles();
177+
stopwatch.Stop();
178+
Debug.WriteLine("Removed all files within {0} seconds", stopwatch.Elapsed.TotalSeconds);
179+
}
180+
}
181+
182+
[TestMethod]
183+
[TestCategory("Sftp")]
184+
[TestCategory("integration")]
185+
[ExpectedException(typeof(SshConnectionException))]
186+
public void Test_Sftp_EnumerateDirectory_After_Disconnected()
187+
{
188+
try {
189+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
190+
{
191+
sftp.Connect();
192+
193+
sftp.CreateDirectory("test_at_dsiposed");
194+
195+
var files = sftp.EnumerateDirectory(".").Take(1);
196+
197+
sftp.Disconnect();
198+
199+
// Must fail on disconnected session.
200+
var count = files.Count();
201+
}
202+
}
203+
finally
204+
{
205+
RemoveAllFiles();
206+
}
207+
}
208+
}
209+
}

src/Renci.SshNet.Tests/Classes/SftpClientTest.ListDirectory.cs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,42 @@ public void Test_Sftp_ListDirectory_Null()
141141
[TestCategory("integration")]
142142
public void Test_Sftp_ListDirectory_HugeDirectory()
143143
{
144-
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
144+
var stopwatch = Stopwatch.StartNew();
145+
try
145146
{
146-
sftp.Connect();
147-
148-
// Create 10000 directory items
149-
for (int i = 0; i < 10000; i++)
147+
using (var sftp = new SftpClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
150148
{
151-
sftp.CreateDirectory(string.Format("test_{0}", i));
152-
Debug.WriteLine("Created " + i);
149+
sftp.Connect();
150+
sftp.ChangeDirectory("/home/" + Resources.USERNAME);
151+
152+
var count = 10000;
153+
// Create 10000 directory items
154+
for (int i = 0; i < count; i++)
155+
{
156+
sftp.CreateDirectory(string.Format("test_{0}", i));
157+
}
158+
Debug.WriteLine("Created {0} directories within {1} seconds", count, stopwatch.Elapsed.TotalSeconds);
159+
160+
stopwatch.Restart();
161+
var files = sftp.ListDirectory(".");
162+
Debug.WriteLine("Listed {0} directories within {1} seconds", count, stopwatch.Elapsed.TotalSeconds);
163+
164+
// Ensure that directory has at least 10000 items
165+
stopwatch.Restart();
166+
var actualCount = files.Count();
167+
Assert.IsTrue(actualCount >= 10000);
168+
Debug.WriteLine("Used {0} items within {1} seconds", actualCount, stopwatch.Elapsed.TotalSeconds);
169+
170+
sftp.Disconnect();
153171
}
154-
155-
var files = sftp.ListDirectory(".");
156-
157-
// Ensure that directory has at least 10000 items
158-
Assert.IsTrue(files.Count() > 10000);
159-
160-
sftp.Disconnect();
161172
}
162-
163-
RemoveAllFiles();
173+
finally
174+
{
175+
stopwatch.Restart();
176+
RemoveAllFiles();
177+
stopwatch.Stop();
178+
Debug.WriteLine("Removed all files within {0} seconds", stopwatch.Elapsed.TotalSeconds);
179+
}
164180
}
165181

166182
[TestMethod]

src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@
309309
<Compile Include="Classes\SessionTest_Connected_ServerShutsDownSocket.cs" />
310310
<Compile Include="Classes\SessionTest_NotConnected.cs" />
311311
<Compile Include="Classes\SessionTest_SocketConnected_BadPacketAndDispose.cs" />
312+
<Compile Include="Classes\SftpClientTest.EnumerateDirectory.cs" />
312313
<Compile Include="Classes\SftpClientTest.SynchronizeDirectories.cs" />
313314
<Compile Include="Classes\SftpClientTest.cs" />
314315
<Compile Include="Classes\SftpClientTest.Download.cs" />

0 commit comments

Comments
 (0)