source: src/router/proftpd/tests/t/lib/ProFTPD/Tests/Config/TimeoutStalled.pm @ 17876

Last change on this file since 17876 was 17876, checked in by BrainSlayer, 20 months ago

update proftp

File size: 23.9 KB
Line 
1package ProFTPD::Tests::Config::TimeoutStalled;
2
3use lib qw(t/lib);
4use base qw(ProFTPD::TestSuite::Child);
5use strict;
6
7use File::Spec;
8use IO::Handle;
9
10use ProFTPD::TestSuite::FTP;
11use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
12
13$| = 1;
14
15my $order = 0;
16
17my $TESTS = {
18  timeoutstalled_ok => {
19    order => ++$order,
20    test_class => [qw(forking)],
21  },
22
23  timeoutstalled_exceeded_list => {
24    order => ++$order,
25    test_class => [qw(forking)],
26  },
27
28  timeoutstalled_exceeded_nlst => {
29    order => ++$order,
30    test_class => [qw(forking)],
31  },
32
33  timeoutstalled_exceeded_mlsd => {
34    order => ++$order,
35    test_class => [qw(forking)],
36  },
37
38  timeoutstalled_exceeded_retr => {
39    order => ++$order,
40    test_class => [qw(forking)],
41  },
42
43  timeoutstalled_exceeded_stor => {
44    order => ++$order,
45    test_class => [qw(forking)],
46  },
47
48  timeoutstalled_exceeded_retr_usesendfile_on => {
49    order => ++$order,
50    test_class => [qw(feat_sendfile forking)],
51  },
52
53};
54
55sub new {
56  return shift()->SUPER::new(@_);
57}
58
59sub list_tests {
60  return testsuite_get_runnable_tests($TESTS);
61}
62
63sub timeoutstalled_ok {
64  my $self = shift;
65  my $tmpdir = $self->{tmpdir};
66
67  my $config_file = "$tmpdir/config.conf";
68  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
69  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
70
71  my $log_file = File::Spec->rel2abs('tests.log');
72
73  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
74  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
75
76  my $user = 'proftpd';
77  my $passwd = 'test';
78  my $group = 'ftpd';
79  my $home_dir = File::Spec->rel2abs($tmpdir);
80  my $uid = 500;
81  my $gid = 500;
82
83  # Make sure that, if we're running as root, that the home directory has
84  # permissions/privs set for the account we create
85  if ($< == 0) {
86    unless (chmod(0755, $home_dir)) {
87      die("Can't set perms on $home_dir to 0755: $!");
88    }
89   
90    unless (chown($uid, $gid, $home_dir)) {
91      die("Can't set owner of $home_dir to $uid/$gid: $!");
92    }
93  }
94
95  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
96    '/bin/bash');
97  auth_group_write($auth_group_file, $group, $gid, $user);
98
99  my $timeout_stalled = 2;
100
101  my $config = {
102    PidFile => $pid_file,
103    ScoreboardFile => $scoreboard_file,
104    SystemLog => $log_file,
105
106    AuthUserFile => $auth_user_file,
107    AuthGroupFile => $auth_group_file,
108
109    TimeoutStalled => $timeout_stalled,
110
111    IfModules => {
112      'mod_delay.c' => {
113        DelayEngine => 'off',
114      },
115    },
116  };
117
118  my ($port, $config_user, $config_group) = config_write($config_file, $config);
119
120  # Open pipes, for use between the parent and child processes.  Specifically,
121  # the child will indicate when it's done with its test by writing a message
122  # to the parent.
123  my ($rfh, $wfh);
124  unless (pipe($rfh, $wfh)) {
125    die("Can't open pipe: $!");
126  }
127
128  my $ex;
129
130  # Fork child
131  $self->handle_sigchld();
132  defined(my $pid = fork()) or die("Can't fork: $!");
133  if ($pid) {
134    eval {
135      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
136
137      $client->login($user, $passwd);
138
139      my $conn = $client->list_raw($home_dir);
140      unless ($conn) {
141        die("LIST failed: " . $client->response_code() . " " .
142          $client->response_msg());
143      }
144
145      # Wait for one second less than the stalled period
146      sleep($timeout_stalled - 1);
147
148      my $buf;
149      $conn->read($buf, 8192, 30);
150      $conn->close();
151
152      my ($resp_code, $resp_msg);
153      ($resp_code, $resp_msg) = $client->noop();
154
155      my $expected;
156
157      $expected = 200;
158      $self->assert($expected == $resp_code,
159        test_msg("Expected $expected, got $resp_code"));
160
161      $expected = "NOOP command successful";
162      $self->assert($expected eq $resp_msg,
163        test_msg("Expected '$expected', got '$resp_msg'"));
164    };
165
166    if ($@) {
167      $ex = $@;
168    }
169
170    $wfh->print("done\n");
171    $wfh->flush();
172
173  } else {
174    eval { server_wait($config_file, $rfh) };
175    if ($@) {
176      warn($@);
177      exit 1;
178    }
179
180    exit 0;
181  }
182
183  # Stop server
184  server_stop($pid_file);
185
186  $self->assert_child_ok($pid);
187
188  if ($ex) {
189    die($ex);
190  }
191
192  unlink($log_file);
193}
194
195sub timeoutstalled_exceeded_list {
196  my $self = shift;
197  my $tmpdir = $self->{tmpdir};
198
199  my $config_file = "$tmpdir/config.conf";
200  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
201  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
202
203  my $log_file = File::Spec->rel2abs('tests.log');
204
205  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
206  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
207
208  my $user = 'proftpd';
209  my $passwd = 'test';
210  my $group = 'ftpd';
211  my $home_dir = File::Spec->rel2abs($tmpdir);
212  my $uid = 500;
213  my $gid = 500;
214
215  # Make sure that, if we're running as root, that the home directory has
216  # permissions/privs set for the account we create
217  if ($< == 0) {
218    unless (chmod(0755, $home_dir)) {
219      die("Can't set perms on $home_dir to 0755: $!");
220    }
221   
222    unless (chown($uid, $gid, $home_dir)) {
223      die("Can't set owner of $home_dir to $uid/$gid: $!");
224    }
225  }
226
227  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
228    '/bin/bash');
229  auth_group_write($auth_group_file, $group, $gid, $user);
230
231  my $timeout_stalled = 1;
232
233  my $config = {
234    PidFile => $pid_file,
235    ScoreboardFile => $scoreboard_file,
236    SystemLog => $log_file,
237
238    AuthUserFile => $auth_user_file,
239    AuthGroupFile => $auth_group_file,
240
241    TimeoutStalled => $timeout_stalled,
242
243    IfModules => {
244      'mod_delay.c' => {
245        DelayEngine => 'off',
246      },
247    },
248  };
249
250  my ($port, $config_user, $config_group) = config_write($config_file, $config);
251
252  # Open pipes, for use between the parent and child processes.  Specifically,
253  # the child will indicate when it's done with its test by writing a message
254  # to the parent.
255  my ($rfh, $wfh);
256  unless (pipe($rfh, $wfh)) {
257    die("Can't open pipe: $!");
258  }
259
260  my $ex;
261
262  # Fork child
263  $self->handle_sigchld();
264  defined(my $pid = fork()) or die("Can't fork: $!");
265  if ($pid) {
266    eval {
267      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
268
269      $client->login($user, $passwd);
270
271      my $conn = $client->list_raw($home_dir);
272      unless ($conn) {
273        die("LIST failed: " . $client->response_code() . " " .
274          $client->response_msg());
275      }
276
277      # Wait for one second more than the stalled period
278      sleep($timeout_stalled + 1);
279
280      my $buf;
281      $conn->read($buf, 8192, 30);
282      $conn->close();
283
284      eval { $client->noop() };
285      unless ($@) {
286        die("NOOP succeeded unexpectedly");
287      }
288
289      my $resp_code = $client->response_code();
290      my $resp_msg = $client->response_msg();
291
292      my $expected;
293
294      # Perl's Net::Cmd module uses a very non-standard 599 code to
295      # indicate that the connection is closed
296      $expected = 599;
297      $self->assert($expected == $resp_code,
298        test_msg("Expected $expected, got $resp_code"));
299
300      $expected = "Connection closed";
301      $self->assert($expected eq $resp_msg,
302        test_msg("Expected '$expected', got '$resp_msg'"));
303    };
304
305    if ($@) {
306      $ex = $@;
307    }
308
309    $wfh->print("done\n");
310    $wfh->flush();
311
312  } else {
313    eval { server_wait($config_file, $rfh) };
314    if ($@) {
315      warn($@);
316      exit 1;
317    }
318
319    exit 0;
320  }
321
322  # Stop server
323  server_stop($pid_file);
324
325  $self->assert_child_ok($pid);
326
327  if ($ex) {
328    die($ex);
329  }
330
331  unlink($log_file);
332}
333
334sub timeoutstalled_exceeded_nlst {
335  my $self = shift;
336  my $tmpdir = $self->{tmpdir};
337
338  my $config_file = "$tmpdir/config.conf";
339  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
340  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
341
342  my $log_file = File::Spec->rel2abs('tests.log');
343
344  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
345  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
346
347  my $user = 'proftpd';
348  my $passwd = 'test';
349  my $group = 'ftpd';
350  my $home_dir = File::Spec->rel2abs($tmpdir);
351  my $uid = 500;
352  my $gid = 500;
353
354  # Make sure that, if we're running as root, that the home directory has
355  # permissions/privs set for the account we create
356  if ($< == 0) {
357    unless (chmod(0755, $home_dir)) {
358      die("Can't set perms on $home_dir to 0755: $!");
359    }
360   
361    unless (chown($uid, $gid, $home_dir)) {
362      die("Can't set owner of $home_dir to $uid/$gid: $!");
363    }
364  }
365
366  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
367    '/bin/bash');
368  auth_group_write($auth_group_file, $group, $gid, $user);
369
370  my $timeout_stalled = 1;
371
372  my $config = {
373    PidFile => $pid_file,
374    ScoreboardFile => $scoreboard_file,
375    SystemLog => $log_file,
376
377    AuthUserFile => $auth_user_file,
378    AuthGroupFile => $auth_group_file,
379
380    TimeoutStalled => $timeout_stalled,
381
382    IfModules => {
383      'mod_delay.c' => {
384        DelayEngine => 'off',
385      },
386    },
387  };
388
389  my ($port, $config_user, $config_group) = config_write($config_file, $config);
390
391  # Open pipes, for use between the parent and child processes.  Specifically,
392  # the child will indicate when it's done with its test by writing a message
393  # to the parent.
394  my ($rfh, $wfh);
395  unless (pipe($rfh, $wfh)) {
396    die("Can't open pipe: $!");
397  }
398
399  my $ex;
400
401  # Fork child
402  $self->handle_sigchld();
403  defined(my $pid = fork()) or die("Can't fork: $!");
404  if ($pid) {
405    eval {
406      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
407
408      $client->login($user, $passwd);
409
410      my $conn = $client->nlst_raw($home_dir);
411      unless ($conn) {
412        die("NLST failed: " . $client->response_code() . " " .
413          $client->response_msg());
414      }
415
416      # Wait for one second more than the stalled period
417      sleep($timeout_stalled + 1);
418
419      my $buf;
420      $conn->read($buf, 8192, 30);
421      $conn->close();
422
423      eval { $client->noop() };
424      unless ($@) {
425        die("NOOP succeeded unexpectedly");
426      }
427
428      my $resp_code = $client->response_code();
429      my $resp_msg = $client->response_msg();
430
431      my $expected;
432
433      # Perl's Net::Cmd module uses a very non-standard 599 code to
434      # indicate that the connection is closed
435      $expected = 599;
436      $self->assert($expected == $resp_code,
437        test_msg("Expected $expected, got $resp_code"));
438
439      $expected = "Connection closed";
440      $self->assert($expected eq $resp_msg,
441        test_msg("Expected '$expected', got '$resp_msg'"));
442    };
443
444    if ($@) {
445      $ex = $@;
446    }
447
448    $wfh->print("done\n");
449    $wfh->flush();
450
451  } else {
452    eval { server_wait($config_file, $rfh) };
453    if ($@) {
454      warn($@);
455      exit 1;
456    }
457
458    exit 0;
459  }
460
461  # Stop server
462  server_stop($pid_file);
463
464  $self->assert_child_ok($pid);
465
466  if ($ex) {
467    die($ex);
468  }
469
470  unlink($log_file);
471}
472
473sub timeoutstalled_exceeded_mlsd {
474  my $self = shift;
475  my $tmpdir = $self->{tmpdir};
476
477  my $config_file = "$tmpdir/config.conf";
478  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
479  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
480
481  my $log_file = File::Spec->rel2abs('tests.log');
482
483  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
484  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
485
486  my $user = 'proftpd';
487  my $passwd = 'test';
488  my $group = 'ftpd';
489  my $home_dir = File::Spec->rel2abs($tmpdir);
490  my $uid = 500;
491  my $gid = 500;
492
493  # Make sure that, if we're running as root, that the home directory has
494  # permissions/privs set for the account we create
495  if ($< == 0) {
496    unless (chmod(0755, $home_dir)) {
497      die("Can't set perms on $home_dir to 0755: $!");
498    }
499   
500    unless (chown($uid, $gid, $home_dir)) {
501      die("Can't set owner of $home_dir to $uid/$gid: $!");
502    }
503  }
504
505  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
506    '/bin/bash');
507  auth_group_write($auth_group_file, $group, $gid, $user);
508
509  my $timeout_stalled = 1;
510
511  my $config = {
512    PidFile => $pid_file,
513    ScoreboardFile => $scoreboard_file,
514    SystemLog => $log_file,
515
516    AuthUserFile => $auth_user_file,
517    AuthGroupFile => $auth_group_file,
518
519    TimeoutStalled => $timeout_stalled,
520
521    IfModules => {
522      'mod_delay.c' => {
523        DelayEngine => 'off',
524      },
525    },
526  };
527
528  my ($port, $config_user, $config_group) = config_write($config_file, $config);
529
530  # Open pipes, for use between the parent and child processes.  Specifically,
531  # the child will indicate when it's done with its test by writing a message
532  # to the parent.
533  my ($rfh, $wfh);
534  unless (pipe($rfh, $wfh)) {
535    die("Can't open pipe: $!");
536  }
537
538  my $ex;
539
540  # Fork child
541  $self->handle_sigchld();
542  defined(my $pid = fork()) or die("Can't fork: $!");
543  if ($pid) {
544    eval {
545      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
546
547      $client->login($user, $passwd);
548
549      my $conn = $client->mlsd_raw($home_dir);
550      unless ($conn) {
551        die("MLSD failed: " . $client->response_code() . " " .
552          $client->response_msg());
553      }
554
555      # Wait for one second more than the stalled period
556      sleep($timeout_stalled + 1);
557
558      my $buf;
559      $conn->read($buf, 8192, 30);
560      $conn->close();
561
562      eval { $client->noop() };
563      unless ($@) {
564        die("NOOP succeeded unexpectedly");
565      }
566
567      my $resp_code = $client->response_code();
568      my $resp_msg = $client->response_msg();
569
570      my $expected;
571
572      # Perl's Net::Cmd module uses a very non-standard 599 code to
573      # indicate that the connection is closed
574      $expected = 599;
575      $self->assert($expected == $resp_code,
576        test_msg("Expected $expected, got $resp_code"));
577
578      $expected = "Connection closed";
579      $self->assert($expected eq $resp_msg,
580        test_msg("Expected '$expected', got '$resp_msg'"));
581    };
582
583    if ($@) {
584      $ex = $@;
585    }
586
587    $wfh->print("done\n");
588    $wfh->flush();
589
590  } else {
591    eval { server_wait($config_file, $rfh) };
592    if ($@) {
593      warn($@);
594      exit 1;
595    }
596
597    exit 0;
598  }
599
600  # Stop server
601  server_stop($pid_file);
602
603  $self->assert_child_ok($pid);
604
605  if ($ex) {
606    die($ex);
607  }
608
609  unlink($log_file);
610}
611
612sub timeoutstalled_exceeded_retr {
613  my $self = shift;
614  my $tmpdir = $self->{tmpdir};
615
616  my $config_file = "$tmpdir/config.conf";
617  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
618  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
619
620  my $log_file = File::Spec->rel2abs('tests.log');
621
622  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
623  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
624
625  my $user = 'proftpd';
626  my $passwd = 'test';
627  my $group = 'ftpd';
628  my $home_dir = File::Spec->rel2abs($tmpdir);
629  my $uid = 500;
630  my $gid = 500;
631
632  # Make sure that, if we're running as root, that the home directory has
633  # permissions/privs set for the account we create
634  if ($< == 0) {
635    unless (chmod(0755, $home_dir)) {
636      die("Can't set perms on $home_dir to 0755: $!");
637    }
638   
639    unless (chown($uid, $gid, $home_dir)) {
640      die("Can't set owner of $home_dir to $uid/$gid: $!");
641    }
642  }
643
644  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
645    '/bin/bash');
646  auth_group_write($auth_group_file, $group, $gid, $user);
647
648  my $timeout_stalled = 1;
649
650  my $config = {
651    PidFile => $pid_file,
652    ScoreboardFile => $scoreboard_file,
653    SystemLog => $log_file,
654
655    AuthUserFile => $auth_user_file,
656    AuthGroupFile => $auth_group_file,
657
658    TimeoutStalled => $timeout_stalled,
659
660    IfModules => {
661      'mod_delay.c' => {
662        DelayEngine => 'off',
663      },
664    },
665  };
666
667  my ($port, $config_user, $config_group) = config_write($config_file, $config);
668
669  # Open pipes, for use between the parent and child processes.  Specifically,
670  # the child will indicate when it's done with its test by writing a message
671  # to the parent.
672  my ($rfh, $wfh);
673  unless (pipe($rfh, $wfh)) {
674    die("Can't open pipe: $!");
675  }
676
677  my $ex;
678
679  # Fork child
680  $self->handle_sigchld();
681  defined(my $pid = fork()) or die("Can't fork: $!");
682  if ($pid) {
683    eval {
684      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
685
686      $client->login($user, $passwd);
687
688      my $conn = $client->retr_raw($config_file);
689      unless ($conn) {
690        die("RETR failed: " . $client->response_code() . " " .
691          $client->response_msg());
692      }
693
694      # Wait for one second more than the stalled period
695      sleep($timeout_stalled + 1);
696
697      my $buf;
698      $conn->read($buf, 8192, 30);
699      $conn->close();
700
701      eval { $client->noop() };
702      unless ($@) {
703        die("NOOP succeeded unexpectedly");
704      }
705
706      my $resp_code = $client->response_code();
707      my $resp_msg = $client->response_msg();
708
709      my $expected;
710
711      # Perl's Net::Cmd module uses a very non-standard 599 code to
712      # indicate that the connection is closed
713      $expected = 599;
714      $self->assert($expected == $resp_code,
715        test_msg("Expected $expected, got $resp_code"));
716
717      $expected = "Connection closed";
718      $self->assert($expected eq $resp_msg,
719        test_msg("Expected '$expected', got '$resp_msg'"));
720    };
721
722    if ($@) {
723      $ex = $@;
724    }
725
726    $wfh->print("done\n");
727    $wfh->flush();
728
729  } else {
730    eval { server_wait($config_file, $rfh) };
731    if ($@) {
732      warn($@);
733      exit 1;
734    }
735
736    exit 0;
737  }
738
739  # Stop server
740  server_stop($pid_file);
741
742  $self->assert_child_ok($pid);
743
744  if ($ex) {
745    die($ex);
746  }
747
748  unlink($log_file);
749}
750
751sub timeoutstalled_exceeded_stor {
752  my $self = shift;
753  my $tmpdir = $self->{tmpdir};
754
755  my $config_file = "$tmpdir/config.conf";
756  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
757  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
758
759  my $log_file = File::Spec->rel2abs('tests.log');
760
761  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
762  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
763
764  my $user = 'proftpd';
765  my $passwd = 'test';
766  my $group = 'ftpd';
767  my $home_dir = File::Spec->rel2abs($tmpdir);
768  my $uid = 500;
769  my $gid = 500;
770
771  # Make sure that, if we're running as root, that the home directory has
772  # permissions/privs set for the account we create
773  if ($< == 0) {
774    unless (chmod(0755, $home_dir)) {
775      die("Can't set perms on $home_dir to 0755: $!");
776    }
777   
778    unless (chown($uid, $gid, $home_dir)) {
779      die("Can't set owner of $home_dir to $uid/$gid: $!");
780    }
781  }
782
783  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
784    '/bin/bash');
785  auth_group_write($auth_group_file, $group, $gid, $user);
786
787  my $timeout_stalled = 1;
788
789  my $config = {
790    PidFile => $pid_file,
791    ScoreboardFile => $scoreboard_file,
792    SystemLog => $log_file,
793
794    AuthUserFile => $auth_user_file,
795    AuthGroupFile => $auth_group_file,
796
797    TimeoutStalled => $timeout_stalled,
798
799    IfModules => {
800      'mod_delay.c' => {
801        DelayEngine => 'off',
802      },
803    },
804  };
805
806  my ($port, $config_user, $config_group) = config_write($config_file, $config);
807
808  # Open pipes, for use between the parent and child processes.  Specifically,
809  # the child will indicate when it's done with its test by writing a message
810  # to the parent.
811  my ($rfh, $wfh);
812  unless (pipe($rfh, $wfh)) {
813    die("Can't open pipe: $!");
814  }
815
816  my $ex;
817
818  # Fork child
819  $self->handle_sigchld();
820  defined(my $pid = fork()) or die("Can't fork: $!");
821  if ($pid) {
822    eval {
823      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
824
825      $client->login($user, $passwd);
826
827      my $conn = $client->stor_raw('foo.bar.baz');
828      unless ($conn) {
829        die("STOR failed: " . $client->response_code() . " " .
830          $client->response_msg());
831      }
832
833      # Wait for one second more than the stalled period
834      sleep($timeout_stalled + 1);
835
836      my $buf;
837      $conn->read($buf, 8192, 30);
838      $conn->close();
839
840      eval { $client->noop() };
841      unless ($@) {
842        die("NOOP succeeded unexpectedly");
843      }
844
845      my $resp_code = $client->response_code();
846      my $resp_msg = $client->response_msg();
847
848      my $expected;
849
850      # Perl's Net::Cmd module uses a very non-standard 599 code to
851      # indicate that the connection is closed
852      $expected = 599;
853      $self->assert($expected == $resp_code,
854        test_msg("Expected $expected, got $resp_code"));
855
856      $expected = "Connection closed";
857      $self->assert($expected eq $resp_msg,
858        test_msg("Expected '$expected', got '$resp_msg'"));
859    };
860
861    if ($@) {
862      $ex = $@;
863    }
864
865    $wfh->print("done\n");
866    $wfh->flush();
867
868  } else {
869    eval { server_wait($config_file, $rfh) };
870    if ($@) {
871      warn($@);
872      exit 1;
873    }
874
875    exit 0;
876  }
877
878  # Stop server
879  server_stop($pid_file);
880
881  $self->assert_child_ok($pid);
882
883  if ($ex) {
884    die($ex);
885  }
886
887  unlink($log_file);
888}
889
890sub timeoutstalled_exceeded_retr_usesendfile_on {
891  my $self = shift;
892  my $tmpdir = $self->{tmpdir};
893
894  my $config_file = "$tmpdir/config.conf";
895  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
896  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
897
898  my $log_file = File::Spec->rel2abs('tests.log');
899
900  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
901  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
902
903  my $user = 'proftpd';
904  my $passwd = 'test';
905  my $group = 'ftpd';
906  my $home_dir = File::Spec->rel2abs($tmpdir);
907  my $uid = 500;
908  my $gid = 500;
909
910  # Make sure that, if we're running as root, that the home directory has
911  # permissions/privs set for the account we create
912  if ($< == 0) {
913    unless (chmod(0755, $home_dir)) {
914      die("Can't set perms on $home_dir to 0755: $!");
915    }
916   
917    unless (chown($uid, $gid, $home_dir)) {
918      die("Can't set owner of $home_dir to $uid/$gid: $!");
919    }
920  }
921
922  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
923    '/bin/bash');
924  auth_group_write($auth_group_file, $group, $gid, $user);
925
926  my $timeout_stalled = 1;
927
928  my $config = {
929    PidFile => $pid_file,
930    ScoreboardFile => $scoreboard_file,
931    SystemLog => $log_file,
932
933    AuthUserFile => $auth_user_file,
934    AuthGroupFile => $auth_group_file,
935
936    TimeoutStalled => $timeout_stalled,
937    UseSendfile => 'on',
938
939    IfModules => {
940      'mod_delay.c' => {
941        DelayEngine => 'off',
942      },
943    },
944  };
945
946  my ($port, $config_user, $config_group) = config_write($config_file, $config);
947
948  # Open pipes, for use between the parent and child processes.  Specifically,
949  # the child will indicate when it's done with its test by writing a message
950  # to the parent.
951  my ($rfh, $wfh);
952  unless (pipe($rfh, $wfh)) {
953    die("Can't open pipe: $!");
954  }
955
956  my $ex;
957
958  # Fork child
959  $self->handle_sigchld();
960  defined(my $pid = fork()) or die("Can't fork: $!");
961  if ($pid) {
962    eval {
963      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
964
965      $client->login($user, $passwd);
966
967      my $conn = $client->retr_raw($config_file);
968      unless ($conn) {
969        die("RETR failed: " . $client->response_code() . " " .
970          $client->response_msg());
971      }
972
973      # Wait for one second more than the stalled period
974      sleep($timeout_stalled + 1);
975
976      my $buf;
977      $conn->read($buf, 8192, 30);
978      $conn->close();
979
980      eval { $client->noop() };
981      unless ($@) {
982        die("NOOP succeeded unexpectedly");
983      }
984
985      my $resp_code = $client->response_code();
986      my $resp_msg = $client->response_msg();
987
988      my $expected;
989
990      # Perl's Net::Cmd module uses a very non-standard 599 code to
991      # indicate that the connection is closed
992      $expected = 599;
993      $self->assert($expected == $resp_code,
994        test_msg("Expected $expected, got $resp_code"));
995
996      $expected = "Connection closed";
997      $self->assert($expected eq $resp_msg,
998        test_msg("Expected '$expected', got '$resp_msg'"));
999    };
1000
1001    if ($@) {
1002      $ex = $@;
1003    }
1004
1005    $wfh->print("done\n");
1006    $wfh->flush();
1007
1008  } else {
1009    eval { server_wait($config_file, $rfh) };
1010    if ($@) {
1011      warn($@);
1012      exit 1;
1013    }
1014
1015    exit 0;
1016  }
1017
1018  # Stop server
1019  server_stop($pid_file);
1020
1021  $self->assert_child_ok($pid);
1022
1023  if ($ex) {
1024    die($ex);
1025  }
1026
1027  unlink($log_file);
1028}
1029
10301;
Note: See TracBrowser for help on using the repository browser.