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

Last change on this file since 14672 was 14672, checked in by BrainSlayer, 3 years ago

proftp update

File size: 7.4 KB
Line 
1package ProFTPD::Tests::Config::TimeoutStalled;
2
3use lib qw(t/lib);
4use base qw(Test::Unit::TestCase ProFTPD::TestSuite::Child);
5use strict;
6
7use File::Path qw(mkpath rmtree);
8use File::Spec;
9use IO::Handle;
10
11use ProFTPD::TestSuite::FTP;
12use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
13
14$| = 1;
15
16my $order = 0;
17
18my $TESTS = {
19  timeoutstalled_ok => {
20    order => ++$order,
21    test_class => [qw(forking)],
22  },
23
24  timeoutstalled_exceeded => {
25    order => ++$order,
26    test_class => [qw(forking)],
27  },
28
29};
30
31sub new {
32  return shift()->SUPER::new(@_);
33}
34
35sub list_tests {
36  return testsuite_get_runnable_tests($TESTS);
37}
38
39sub set_up {
40  my $self = shift;
41  $self->{tmpdir} = testsuite_get_tmp_dir();
42
43  # Create temporary scratch dir
44  eval { mkpath($self->{tmpdir}) };
45  if ($@) {
46    my $abs_path = File::Spec->rel2abs($self->{tmpdir});
47    die("Can't create dir $abs_path: $@");
48  }
49}
50
51sub tear_down {
52  my $self = shift;
53
54  # Remove temporary scratch dir
55  if ($self->{tmpdir}) {
56    eval { rmtree($self->{tmpdir}) };
57  }
58
59  undef $self;
60};
61
62sub timeoutstalled_ok {
63  my $self = shift;
64  my $tmpdir = $self->{tmpdir};
65
66  my $config_file = "$tmpdir/config.conf";
67  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
68  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
69
70  my $log_file = File::Spec->rel2abs('tests.log');
71
72  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
73  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
74
75  my $user = 'proftpd';
76  my $passwd = 'test';
77  my $home_dir = File::Spec->rel2abs($tmpdir);
78  my $uid = 500;
79  my $gid = 500;
80
81  # Make sure that, if we're running as root, that the home directory has
82  # permissions/privs set for the account we create
83  if ($< == 0) {
84    unless (chmod(0755, $home_dir)) {
85      die("Can't set perms on $home_dir to 0755: $!");
86    }
87   
88    unless (chown($uid, $gid, $home_dir)) {
89      die("Can't set owner of $home_dir to $uid/$gid: $!");
90    }
91  }
92
93  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
94    '/bin/bash');
95  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
96
97  my $timeout_stalled = 2;
98
99  my $config = {
100    PidFile => $pid_file,
101    ScoreboardFile => $scoreboard_file,
102    SystemLog => $log_file,
103
104    AuthUserFile => $auth_user_file,
105    AuthGroupFile => $auth_group_file,
106
107    TimeoutStalled => $timeout_stalled,
108
109    IfModules => {
110      'mod_delay.c' => {
111        DelayEngine => 'off',
112      },
113    },
114  };
115
116  my ($port, $config_user, $config_group) = config_write($config_file, $config);
117
118  # Open pipes, for use between the parent and child processes.  Specifically,
119  # the child will indicate when it's done with its test by writing a message
120  # to the parent.
121  my ($rfh, $wfh);
122  unless (pipe($rfh, $wfh)) {
123    die("Can't open pipe: $!");
124  }
125
126  my $ex;
127
128  # Fork child
129  $self->handle_sigchld();
130  defined(my $pid = fork()) or die("Can't fork: $!");
131  if ($pid) {
132    eval {
133      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
134
135      $client->login($user, $passwd);
136
137      my $conn = $client->list_raw($home_dir);
138      unless ($conn) {
139        die("LIST failed: " . $client->response_code() . " " .
140          $client->response_msg());
141      }
142
143      # Wait for one second less than the stalled period
144      sleep($timeout_stalled - 1);
145
146      my $buf;
147      $conn->read($buf, 8192);
148      $conn->close();
149
150      my ($resp_code, $resp_msg);
151      ($resp_code, $resp_msg) = $client->noop();
152
153      my $expected;
154
155      $expected = 200;
156      $self->assert($expected == $resp_code,
157        test_msg("Expected $expected, got $resp_code"));
158
159      $expected = "NOOP command successful";
160      $self->assert($expected eq $resp_msg,
161        test_msg("Expected '$expected', got '$resp_msg'"));
162    };
163
164    if ($@) {
165      $ex = $@;
166    }
167
168    $wfh->print("done\n");
169    $wfh->flush();
170
171  } else {
172    eval { server_wait($config_file, $rfh) };
173    if ($@) {
174      warn($@);
175      exit 1;
176    }
177
178    exit 0;
179  }
180
181  # Stop server
182  server_stop($pid_file);
183
184  $self->assert_child_ok($pid);
185
186  if ($ex) {
187    die($ex);
188  }
189
190  unlink($log_file);
191}
192
193sub timeoutstalled_exceeded {
194  my $self = shift;
195  my $tmpdir = $self->{tmpdir};
196
197  my $config_file = "$tmpdir/config.conf";
198  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
199  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
200
201  my $log_file = File::Spec->rel2abs('tests.log');
202
203  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
204  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
205
206  my $user = 'proftpd';
207  my $passwd = 'test';
208  my $home_dir = File::Spec->rel2abs($tmpdir);
209  my $uid = 500;
210  my $gid = 500;
211
212  # Make sure that, if we're running as root, that the home directory has
213  # permissions/privs set for the account we create
214  if ($< == 0) {
215    unless (chmod(0755, $home_dir)) {
216      die("Can't set perms on $home_dir to 0755: $!");
217    }
218   
219    unless (chown($uid, $gid, $home_dir)) {
220      die("Can't set owner of $home_dir to $uid/$gid: $!");
221    }
222  }
223
224  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
225    '/bin/bash');
226  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
227
228  my $timeout_stalled = 1;
229
230  my $config = {
231    PidFile => $pid_file,
232    ScoreboardFile => $scoreboard_file,
233    SystemLog => $log_file,
234
235    AuthUserFile => $auth_user_file,
236    AuthGroupFile => $auth_group_file,
237
238    TimeoutStalled => $timeout_stalled,
239
240    IfModules => {
241      'mod_delay.c' => {
242        DelayEngine => 'off',
243      },
244    },
245  };
246
247  my ($port, $config_user, $config_group) = config_write($config_file, $config);
248
249  # Open pipes, for use between the parent and child processes.  Specifically,
250  # the child will indicate when it's done with its test by writing a message
251  # to the parent.
252  my ($rfh, $wfh);
253  unless (pipe($rfh, $wfh)) {
254    die("Can't open pipe: $!");
255  }
256
257  my $ex;
258
259  # Fork child
260  $self->handle_sigchld();
261  defined(my $pid = fork()) or die("Can't fork: $!");
262  if ($pid) {
263    eval {
264      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
265
266      $client->login($user, $passwd);
267
268      my $conn = $client->list_raw($home_dir);
269      unless ($conn) {
270        die("LIST failed: " . $client->response_code() . " " .
271          $client->response_msg());
272      }
273
274      # Wait for one second more than the stalled period
275      sleep($timeout_stalled + 1);
276
277      my $buf;
278      $conn->read($buf, 8192);
279      $conn->close();
280
281      my ($resp_code, $resp_msg);
282      eval { $client->noop() };
283      unless ($@) {
284        die("NOOP succeeded unexpectedly");
285
286      } else {
287        $resp_code = $client->response_code();
288        $resp_msg = $client->response_msg();
289      }
290
291      my $expected;
292
293      # Perl's Net::Cmd module uses a very non-standard 599 code to
294      # indicate that the connection is closed
295      $expected = 599;
296      $self->assert($expected == $resp_code,
297        test_msg("Expected $expected, got $resp_code"));
298
299      $expected = "Connection closed";
300      $self->assert($expected eq $resp_msg,
301        test_msg("Expected '$expected', got '$resp_msg'"));
302    };
303
304    if ($@) {
305      $ex = $@;
306    }
307
308    $wfh->print("done\n");
309    $wfh->flush();
310
311  } else {
312    eval { server_wait($config_file, $rfh) };
313    if ($@) {
314      warn($@);
315      exit 1;
316    }
317
318    exit 0;
319  }
320
321  # Stop server
322  server_stop($pid_file);
323
324  $self->assert_child_ok($pid);
325
326  if ($ex) {
327    die($ex);
328  }
329
330  unlink($log_file);
331}
332
3331;
Note: See TracBrowser for help on using the repository browser.