fake_ftp 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'net/ftp'
3
+
4
+ describe FakeFtp::Server, 'with ftp client' do
5
+ let(:server) { FakeFtp::Server.new(21212, 21213) }
6
+ let(:client) { Net::FTP.new }
7
+ let(:text_filename) { File.expand_path("../fixtures/text_file.txt", File.dirname(__FILE__)) }
8
+
9
+ before { server.start }
10
+
11
+ after :each do
12
+ client.close
13
+ server.stop
14
+ end
15
+
16
+ it 'should accept connections' do
17
+ expect { client.connect('127.0.0.1', 21212) }.to_not raise_error
18
+ end
19
+
20
+ context "with client" do
21
+ before { client.connect("127.0.0.1", 21212) }
22
+
23
+ it "should allow anonymous authentication" do
24
+ expect { client.login }.to_not raise_error
25
+ end
26
+
27
+ it "should allow named authentication" do
28
+ expect { client.login('someone', 'password') }.to_not raise_error
29
+ end
30
+
31
+ it "should allow client to quit" do
32
+ expect { client.login('someone', 'password') }.to_not raise_error
33
+ expect { client.quit }.to_not raise_error
34
+ end
35
+
36
+ it "should allow mtime" do
37
+ filename = 'someone'
38
+ time = Time.now
39
+ server.add_file(filename, "some data", time)
40
+
41
+ client.passive = false
42
+ mtime = client.mtime(filename)
43
+ expect(mtime.to_s).to eql(time.to_s)
44
+
45
+ client.passive = true
46
+ mtime = client.mtime(filename)
47
+ expect(mtime.to_s).to eql(time.to_s)
48
+ end
49
+
50
+ it "should put files using PASV" do
51
+ expect(File.stat(text_filename).size).to eql(20)
52
+
53
+ client.passive = true
54
+ expect { client.put(text_filename) }.to_not raise_error
55
+
56
+ expect(server.files).to include('text_file.txt')
57
+ expect(server.file('text_file.txt').bytes).to eql(20)
58
+ expect(server.file('text_file.txt')).to be_passive
59
+ expect(server.file('text_file.txt')).to_not be_active
60
+ end
61
+
62
+ it "should put files using active" do
63
+ expect(File.stat(text_filename).size).to eql(20)
64
+
65
+ client.passive = false
66
+ expect { client.put(text_filename) }.to_not raise_error
67
+
68
+ expect(server.files).to include('text_file.txt')
69
+ expect(server.file('text_file.txt').bytes).to eql(20)
70
+ expect(server.file('text_file.txt')).to_not be_passive
71
+ expect(server.file('text_file.txt')).to be_active
72
+ end
73
+
74
+ xit "should disconnect clients on close" do
75
+ # TODO: when this succeeds, we can care less about manually closing clients
76
+ # otherwise we get a CLOSE_WAIT process hanging around that blocks our port
77
+ server.stop
78
+ expect(client.closed?).to be_true
79
+ end
80
+ end
81
+ end
@@ -1,5 +1,4 @@
1
1
  require "spec_helper.rb"
2
- require 'net/ftp'
3
2
 
4
3
  describe FakeFtp::Server, 'setup' do
5
4
  it "starts a server on port n" do
@@ -75,549 +74,3 @@ describe FakeFtp::Server, 'files' do
75
74
  end
76
75
  end
77
76
 
78
- describe FakeFtp::Server, 'commands' do
79
- let(:server) { FakeFtp::Server.new(21212, 21213) }
80
- let(:client) { TCPSocket.open('127.0.0.1', 21212) }
81
-
82
- before { server.start }
83
- after {
84
- client.close
85
- server.stop
86
- }
87
-
88
- context 'general' do
89
-
90
- it "should accept connections" do
91
- expect(client.gets).to eql("220 Can has FTP?\r\n")
92
- end
93
-
94
- it "should get unknown command response when nothing is sent" do
95
- client.gets
96
- client.puts
97
- expect(client.gets).to eql("500 Unknown command\r\n")
98
- end
99
-
100
- it "accepts QUIT" do
101
- client.gets
102
- client.puts "QUIT"
103
- expect(client.gets).to eql("221 OMG bye!\r\n")
104
- end
105
-
106
- it "should accept multiple commands in one session" do
107
- client.gets
108
- client.puts "USER thing"
109
- client.gets
110
- client.puts "PASS thing"
111
- client.gets
112
- client.puts "ACCT thing"
113
- client.gets
114
- client.puts "USER thing"
115
- end
116
- end
117
-
118
- context 'passive' do
119
-
120
- it "accepts PASV" do
121
- expect(server.mode).to eql(:active)
122
- client.gets
123
- client.puts "PASV"
124
- expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,221)\r\n")
125
- expect(server.mode).to eql(:passive)
126
- end
127
-
128
- it "responds with correct PASV port" do
129
- server.stop
130
- server.passive_port = 21111
131
- server.start
132
- client.gets
133
- client.puts "PASV"
134
- expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,119)\r\n")
135
- end
136
-
137
- it "does not accept PASV if no port set" do
138
- server.stop
139
- server.passive_port = nil
140
- server.start
141
- client.gets
142
- client.puts "PASV"
143
- expect(client.gets).to eql("502 Aww hell no, use Active\r\n")
144
- end
145
- end
146
-
147
- context 'active' do
148
- before :each do
149
- client.gets
150
-
151
- @data_server = ::TCPServer.new('127.0.0.1', 21216)
152
- @data_connection = Thread.new do
153
- @server_client = @data_server.accept
154
- expect(@server_client).to_not be_nil
155
- end
156
- end
157
-
158
- after :each do
159
- @data_server.close
160
- @data_server = nil
161
- @data_connection = nil
162
- end
163
-
164
- it "accepts PORT and connects to port" do
165
- client.puts "PORT 127,0,0,1,82,224"
166
- expect(client.gets).to eql("200 Okay\r\n")
167
-
168
- @data_connection.join
169
- end
170
-
171
- it "should switch to :active on port command" do
172
- expect(server.mode).to eql(:active)
173
- client.puts 'PASV'
174
- client.gets
175
- expect(server.mode).to eql(:passive)
176
-
177
- client.puts "PORT 127,0,0,1,82,224"
178
- expect(client.gets).to eql("200 Okay\r\n")
179
-
180
- @data_connection.join
181
-
182
- expect(server.mode).to eql(:active)
183
- end
184
- end
185
-
186
- context 'authentication commands' do
187
- before :each do
188
- client.gets ## connection successful response
189
- end
190
-
191
- it "accepts USER" do
192
- client.puts "USER some_dude"
193
- expect(client.gets).to eql("331 send your password\r\n")
194
- end
195
-
196
- it "accepts anonymous USER" do
197
- client.puts "USER anonymous"
198
- expect(client.gets).to eql("230 logged in\r\n")
199
- end
200
-
201
- it "accepts PASS" do
202
- client.puts "PASS password"
203
- expect(client.gets).to eql("230 logged in\r\n")
204
- end
205
-
206
- it "accepts ACCT" do
207
- client.puts "ACCT"
208
- expect(client.gets).to eql("230 WHATEVER!\r\n")
209
- end
210
- end
211
-
212
- context 'directory commands' do
213
- before :each do
214
- client.gets ## connection successful response
215
- end
216
-
217
- it "returns directory on PWD" do
218
- client.puts "PWD"
219
- expect(client.gets).to eql("257 \"/pub\" is current directory\r\n")
220
- end
221
-
222
- it "says OK to any CWD, CDUP, without doing anything" do
223
- client.puts "CWD somewhere/else"
224
- expect(client.gets).to eql("250 OK!\r\n")
225
- client.puts "CDUP"
226
- expect(client.gets).to eql("250 OK!\r\n")
227
- end
228
- end
229
-
230
- context 'file commands' do
231
- before :each do
232
- client.gets ## connection successful response
233
- end
234
-
235
- it "accepts TYPE ascii" do
236
- client.puts "TYPE A"
237
- expect(client.gets).to eql("200 Type set to A.\r\n")
238
- end
239
-
240
- it "accepts TYPE image" do
241
- client.puts "TYPE I"
242
- expect(client.gets).to eql("200 Type set to I.\r\n")
243
- end
244
-
245
- it "does not accept TYPEs other than ascii or image" do
246
- client.puts "TYPE E"
247
- expect(client.gets).to eql("504 We don't allow those\r\n")
248
- client.puts "TYPE N"
249
- expect(client.gets).to eql("504 We don't allow those\r\n")
250
- client.puts "TYPE T"
251
- expect(client.gets).to eql("504 We don't allow those\r\n")
252
- client.puts "TYPE C"
253
- expect(client.gets).to eql("504 We don't allow those\r\n")
254
- client.puts "TYPE L"
255
- expect(client.gets).to eql("504 We don't allow those\r\n")
256
- end
257
-
258
- context 'passive' do
259
- let(:data_client) { TCPSocket.open('127.0.0.1', 21213) }
260
-
261
- before :each do
262
- client.puts 'PASV'
263
- expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,221)\r\n")
264
- end
265
-
266
- it "accepts STOR with filename" do
267
- client.puts "STOR some_file"
268
- expect(client.gets).to eql("125 Do it!\r\n")
269
- data_client.puts "1234567890"
270
- data_client.close
271
- expect(client.gets).to eql("226 Did it!\r\n")
272
- expect(server.files).to include('some_file')
273
- expect(server.file('some_file').bytes).to eql(10)
274
- expect(server.file('some_file').data).to eql("1234567890")
275
- end
276
-
277
- it "accepts STOR with filename and trailing newline" do
278
- client.puts "STOR some_file"
279
- client.gets
280
- # puts tries to be smart and only write a single \n
281
- data_client.puts "1234567890\n\n"
282
- data_client.close
283
- expect(client.gets).to eql("226 Did it!\r\n")
284
- expect(server.files).to include('some_file')
285
- expect(server.file('some_file').bytes).to eql(11)
286
- expect(server.file('some_file').data).to eql("1234567890\n")
287
- end
288
-
289
- it "accepts STOR with filename and long file" do
290
- client.puts "STOR some_file"
291
- expect(client.gets).to eql("125 Do it!\r\n")
292
- data_client.puts("1234567890" * 10_000)
293
- data_client.close
294
- expect(client.gets).to eql("226 Did it!\r\n")
295
- expect(server.files).to include('some_file')
296
- end
297
-
298
- it "accepts STOR with streams" do
299
- client.puts "STOR some_file"
300
- expect(client.gets).to eql("125 Do it!\r\n")
301
- data_client.write "1234567890"
302
- data_client.flush
303
- data_client.write "1234567890"
304
- data_client.flush
305
- data_client.close
306
- expect(client.gets).to eql("226 Did it!\r\n")
307
- expect(server.file('some_file').data).to eql("12345678901234567890")
308
- end
309
-
310
- it "does not accept RETR without a filename" do
311
- client.puts "RETR"
312
- expect(client.gets).to eql("501 No filename given\r\n")
313
- end
314
-
315
- it "does not serve files that do not exist" do
316
- client.puts "RETR some_file"
317
- expect(client.gets).to eql("550 File not found\r\n")
318
- end
319
-
320
- it "accepts RETR with a filename" do
321
- server.add_file('some_file', '1234567890')
322
- client.puts "RETR some_file"
323
- expect(client.gets).to eql("150 File status ok, about to open data connection\r\n")
324
- data = data_client.read(1024)
325
- data_client.close
326
- expect(data).to eql('1234567890')
327
- expect(client.gets).to eql("226 File transferred\r\n")
328
- end
329
-
330
- it "accepts DELE with a filename" do
331
- server.add_file('some_file', '1234567890')
332
- client.puts "DELE some_file"
333
- expect(client.gets).to eql("250 Delete operation successful.\r\n")
334
- expect(server.files).to_not include('some_file')
335
- end
336
-
337
- it "gives error message when trying to delete a file that does not exist" do
338
- client.puts "DELE non_existing_file"
339
- expect(client.gets).to eql("550 Delete operation failed.\r\n")
340
- end
341
-
342
- it "accepts a LIST command" do
343
- server.add_file('some_file', '1234567890')
344
- server.add_file('another_file', '1234567890')
345
- client.puts "LIST"
346
- expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
347
- data = data_client.read(2048)
348
- data_client.close
349
- expect(data).to eql([
350
- "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file('some_file').created.strftime('%b %d %H:%M')}\tsome_file",
351
- "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file('another_file').created.strftime('%b %d %H:%M')}\tanother_file",
352
- ].join("\n"))
353
- expect(client.gets).to eql("226 List information transferred\r\n")
354
- end
355
-
356
- it "accepts a LIST command with a wildcard argument" do
357
- files = ['test.jpg', 'test-2.jpg', 'test.txt']
358
- files.each do |file|
359
- server.add_file(file, '1234567890')
360
- end
361
-
362
- client.puts "LIST *.jpg"
363
- expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
364
-
365
- data = data_client.read(2048)
366
- data_client.close
367
- expect(data).to eql(files[0,2].map do |file|
368
- "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file(file).created.strftime('%b %d %H:%M')}\t#{file}"
369
- end.join("\n"))
370
- expect(client.gets).to eql("226 List information transferred\r\n")
371
- end
372
-
373
- it "accepts a LIST command with multiple wildcard arguments" do
374
- files = ['test.jpg', 'test.gif', 'test.txt']
375
- files.each do |file|
376
- server.add_file(file, '1234567890')
377
- end
378
-
379
- client.puts "LIST *.jpg *.gif"
380
- expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
381
-
382
- data = data_client.read(2048)
383
- data_client.close
384
- expect(data).to eql(files[0,2].map do |file|
385
- "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file(file).created.strftime('%b %d %H:%M')}\t#{file}"
386
- end.join("\n"))
387
- expect(client.gets).to eql("226 List information transferred\r\n")
388
- end
389
-
390
- it "accepts an NLST command" do
391
- server.add_file('some_file', '1234567890')
392
- server.add_file('another_file', '1234567890')
393
- client.puts "NLST"
394
- expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
395
- data = data_client.read(1024)
396
- data_client.close
397
- expect(data).to eql("some_file\nanother_file")
398
- expect(client.gets).to eql("226 List information transferred\r\n")
399
- end
400
-
401
- it "should allow mdtm" do
402
- filename = "file.txt"
403
- now = Time.now
404
- server.add_file(filename, "some dummy content", now)
405
- client.puts "MDTM #{filename}"
406
- expect(client.gets).to eql("213 #{now.strftime("%Y%m%d%H%M%S")}\r\n")
407
- end
408
- end
409
-
410
- context 'active' do
411
- before :each do
412
- @data_server = ::TCPServer.new('127.0.0.1', 21216)
413
- @data_connection = Thread.new do
414
- @server_client = @data_server.accept
415
- end
416
- end
417
-
418
- after :each do
419
- @data_server.close
420
- @data_connection = nil
421
- @data_server = nil
422
- end
423
-
424
- it 'creates a directory on MKD' do
425
- client.puts "MKD some_dir"
426
- expect(client.gets).to eql("257 OK!\r\n")
427
- end
428
-
429
- it 'should save the directory after you CWD' do
430
- client.puts "CWD /somewhere/else"
431
- expect(client.gets).to eql("250 OK!\r\n")
432
- client.puts "PWD"
433
- expect(client.gets).to eql("257 \"/somewhere/else\" is current directory\r\n")
434
- end
435
-
436
- it 'CWD should add a / to the beginning of the directory' do
437
- client.puts "CWD somewhere/else"
438
- expect(client.gets).to eql("250 OK!\r\n")
439
- client.puts "PWD"
440
- expect(client.gets).to eql("257 \"/somewhere/else\" is current directory\r\n")
441
- end
442
-
443
- it 'should not change the directory on CDUP' do
444
- client.puts "CDUP"
445
- expect(client.gets).to eql("250 OK!\r\n")
446
- client.puts "PWD"
447
- expect(client.gets).to eql("257 \"/pub\" is current directory\r\n")
448
- end
449
-
450
- it "sends error message if no PORT received" do
451
- client.puts "STOR some_file"
452
- expect(client.gets).to eql("425 Ain't no data port!\r\n")
453
- end
454
-
455
- it "accepts STOR with filename" do
456
- client.puts "PORT 127,0,0,1,82,224"
457
- expect(client.gets).to eql("200 Okay\r\n")
458
-
459
- client.puts "STOR some_other_file"
460
- expect(client.gets).to eql("125 Do it!\r\n")
461
-
462
- @data_connection.join
463
- @server_client.print "12345"
464
- @server_client.close
465
-
466
- expect(client.gets).to eql("226 Did it!\r\n")
467
- expect(server.files).to include('some_other_file')
468
- expect(server.file('some_other_file').bytes).to eql(5)
469
- end
470
-
471
- it "accepts RETR with a filename" do
472
- client.puts "PORT 127,0,0,1,82,224"
473
- expect(client.gets).to eql("200 Okay\r\n")
474
-
475
- server.add_file('some_file', '1234567890')
476
- client.puts "RETR some_file"
477
- expect(client.gets).to eql("150 File status ok, about to open data connection\r\n")
478
-
479
- @data_connection.join
480
- data = @server_client.read(1024)
481
- @server_client.close
482
-
483
- expect(data).to eql('1234567890')
484
- expect(client.gets).to eql("226 File transferred\r\n")
485
- end
486
-
487
- it "accepts RNFR without filename" do
488
- client.puts "RNFR"
489
- expect(client.gets).to eql("501 Send path name.\r\n")
490
- end
491
-
492
- it "accepts RNTO without RNFR" do
493
- client.puts "RNTO some_other_file"
494
- expect(client.gets).to eql("503 Send RNFR first.\r\n")
495
- end
496
-
497
- it "accepts RNTO and RNFR without filename" do
498
- client.puts "RNFR from_file"
499
- expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
500
-
501
- client.puts "RNTO"
502
- expect(client.gets).to eql("501 Send path name.\r\n")
503
- end
504
-
505
- it "accepts RNTO and RNFR for not existing file" do
506
- client.puts "RNFR from_file"
507
- expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
508
-
509
- client.puts "RNTO to_file"
510
- expect(client.gets).to eql("550 File not found.\r\n")
511
- end
512
-
513
- it "accepts RNTO and RNFR" do
514
- server.add_file('from_file', '1234567890')
515
-
516
- client.puts "RNFR from_file"
517
- expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
518
-
519
- client.puts "RNTO to_file"
520
- expect(client.gets).to eql("250 Path renamed.\r\n")
521
-
522
- expect(server.files).to include('to_file')
523
- expect(server.files).to_not include('from_file')
524
- end
525
-
526
- it "accepts an NLST command" do
527
- client.puts "PORT 127,0,0,1,82,224"
528
- expect(client.gets).to eql("200 Okay\r\n")
529
-
530
- server.add_file('some_file', '1234567890')
531
- server.add_file('another_file', '1234567890')
532
- client.puts "NLST"
533
- expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
534
-
535
- @data_connection.join
536
- data = @server_client.read(1024)
537
- @server_client.close
538
-
539
- expect(data).to eql("some_file\nanother_file")
540
- expect(client.gets).to eql("226 List information transferred\r\n")
541
- end
542
- end
543
- end
544
- end
545
-
546
- describe FakeFtp::Server, 'with ftp client' do
547
- let(:server) { FakeFtp::Server.new(21212, 21213) }
548
- let(:client) { Net::FTP.new }
549
- let(:text_filename) { File.expand_path("../../fixtures/text_file.txt", File.dirname(__FILE__)) }
550
-
551
- before { server.start }
552
-
553
- after :each do
554
- client.close
555
- server.stop
556
- end
557
-
558
- it 'should accept connections' do
559
- expect { client.connect('127.0.0.1', 21212) }.to_not raise_error
560
- end
561
-
562
- context "" do
563
- before { client.connect("127.0.0.1", 21212) }
564
-
565
- it "should allow anonymous authentication" do
566
- expect { client.login }.to_not raise_error
567
- end
568
-
569
- it "should allow named authentication" do
570
- expect { client.login('someone', 'password') }.to_not raise_error
571
- end
572
-
573
- it "should allow client to quit" do
574
- expect { client.login('someone', 'password') }.to_not raise_error
575
- expect { client.quit }.to_not raise_error
576
- end
577
-
578
- it "should allow mtime" do
579
- filename = 'someone'
580
- time = Time.now
581
- server.add_file(filename, "some data", time)
582
-
583
- client.passive = false
584
- mtime = client.mtime(filename)
585
- expect(mtime.to_s).to eql(time.to_s)
586
-
587
- client.passive = true
588
- mtime = client.mtime(filename)
589
- expect(mtime.to_s).to eql(time.to_s)
590
- end
591
-
592
- it "should put files using PASV" do
593
- expect(File.stat(text_filename).size).to eql(20)
594
-
595
- client.passive = true
596
- expect { client.put(text_filename) }.to_not raise_error
597
-
598
- expect(server.files).to include('text_file.txt')
599
- expect(server.file('text_file.txt').bytes).to eql(20)
600
- expect(server.file('text_file.txt')).to be_passive
601
- expect(server.file('text_file.txt')).to_not be_active
602
- end
603
-
604
- it "should put files using active" do
605
- expect(File.stat(text_filename).size).to eql(20)
606
-
607
- client.passive = false
608
- expect { client.put(text_filename) }.to_not raise_error
609
-
610
- expect(server.files).to include('text_file.txt')
611
- expect(server.file('text_file.txt').bytes).to eql(20)
612
- expect(server.file('text_file.txt')).to_not be_passive
613
- expect(server.file('text_file.txt')).to be_active
614
- end
615
-
616
- xit "should disconnect clients on close" do
617
- # TODO: when this succeeds, we can care less about manually closing clients
618
- # otherwise we get a CLOSE_WAIT process hanging around that blocks our port
619
- server.stop
620
- expect(client.closed?).to be_true
621
- end
622
- end
623
- end
data/spec/spec_helper.rb CHANGED
@@ -10,4 +10,9 @@ require 'fake_ftp' # and any other gems you need
10
10
 
11
11
  RSpec.configure do |config|
12
12
 
13
- end
13
+ # Run specs in random order to surface order dependencies. If you find an
14
+ # order dependency and want to debug it, you can fix the order by providing
15
+ # the seed, which is printed after each run.
16
+ # --seed 1234
17
+ config.order = 'random'
18
+ end