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

Last change on this file since 12685 was 12685, checked in by BrainSlayer, 4 years ago

new version

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  my $log_file = File::Spec->rel2abs('config.log');
70
71  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
72  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
73
74  my $user = 'proftpd';
75  my $passwd = 'test';
76  my $home_dir = File::Spec->rel2abs($tmpdir);
77  my $uid = 500;
78  my $gid = 500;
79
80  # Make sure that, if we're running as root, that the home directory has
81  # permissions/privs set for the account we create
82  if ($< == 0) {
83    unless (chmod(0755, $home_dir)) {
84      die("Can't set perms on $home_dir to 0755: $!");
85    }
86   
87    unless (chown($uid, $gid, $home_dir)) {
88      die("Can't set owner of $home_dir to $uid/$gid: $!");
89    }
90  }
91
92  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
93    '/bin/bash');
94  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
95
96  my $timeout_stalled = 2;
97
98  my $config = {
99    PidFile => $pid_file,
100    ScoreboardFile => $scoreboard_file,
101    SystemLog => $log_file,
102
103    AuthUserFile => $auth_user_file,
104    AuthGroupFile => $auth_group_file,
105
106    TimeoutStalled => $timeout_stalled,
107
108    IfModules => {
109      'mod_delay.c' => {
110        DelayEngine => 'off',
111      },
112    },
113  };
114
115  my ($port, $config_user, $config_group) = config_write($config_file, $config);
116
117  # Open pipes, for use between the parent and child processes.  Specifically,
118  # the child will indicate when it's done with its test by writing a message
119  # to the parent.
120  my ($rfh, $wfh);
121  unless (pipe($rfh, $wfh)) {
122    die("Can't open pipe: $!");
123  }
124
125  my $ex;
126
127  # Fork child
128  $self->handle_sigchld();
129  defined(my $pid = fork()) or die("Can't fork: $!");
130  if ($pid) {
131    eval {
132      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
133
134      $client->login($user, $passwd);
135
136      my $conn = $client->list_raw($home_dir);
137      unless ($conn) {
138        die("LIST failed: " . $client->response_code() . " " .
139          $client->response_msg());
140      }
141
142      # Wait for one second less than the stalled period
143      sleep($timeout_stalled - 1);
144
145      my $buf;
146      $conn->read($buf, 8192);
147      $conn->close();
148
149      my ($resp_code, $resp_msg);
150      ($resp_code, $resp_msg) = $client->noop();
151
152      my $expected;
153
154      $expected = 200;
155      $self->assert($expected == $resp_code,
156        test_msg("Expected $expected, got $resp_code"));
157
158      $expected = "NOOP command successful";
159      $self->assert($expected eq $resp_msg,
160        test_msg("Expected '$expected', got '$resp_msg'"));
161    };
162
163    if ($@) {
164      $ex = $@;
165    }
166
167    $wfh->print("done\n");
168    $wfh->flush();
169
170  } else {
171    eval { server_wait($config_file, $rfh) };
172    if ($@) {
173      warn($@);
174      exit 1;
175    }
176
177    exit 0;
178  }
179
180  # Stop server
181  server_stop($pid_file);
182
183  $self->assert_child_ok($pid);
184
185  if ($ex) {
186    die($ex);
187  }
188
189  unlink($log_file);
190}
191
192sub timeoutstalled_exceeded {
193  my $self = shift;
194  my $tmpdir = $self->{tmpdir};
195
196  my $config_file = "$tmpdir/config.conf";
197  my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid");
198  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard");
199  my $log_file = File::Spec->rel2abs('config.log');
200
201  my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd");
202  my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group");
203
204  my $user = 'proftpd';
205  my $passwd = 'test';
206  my $home_dir = File::Spec->rel2abs($tmpdir);
207  my $uid = 500;
208  my $gid = 500;
209
210  # Make sure that, if we're running as root, that the home directory has
211  # permissions/privs set for the account we create
212  if ($< == 0) {
213    unless (chmod(0755, $home_dir)) {
214      die("Can't set perms on $home_dir to 0755: $!");
215    }
216   
217    unless (chown($uid, $gid, $home_dir)) {
218      die("Can't set owner of $home_dir to $uid/$gid: $!");
219    }
220  }
221
222  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
223    '/bin/bash');
224  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
225
226  my $timeout_stalled = 1;
227
228  my $config = {
229    PidFile => $pid_file,
230    ScoreboardFile => $scoreboard_file,
231    SystemLog => $log_file,
232
233    AuthUserFile => $auth_user_file,
234    AuthGroupFile => $auth_group_file,
235
236    TimeoutStalled => $timeout_stalled,
237
238    IfModules => {
239      'mod_delay.c' => {
240        DelayEngine => 'off',
241      },
242    },
243  };
244
245  my ($port, $config_user, $config_group) = config_write($config_file, $config);
246
247  # Open pipes, for use between the parent and child processes.  Specifically,
248  # the child will indicate when it's done with its test by writing a message
249  # to the parent.
250  my ($rfh, $wfh);
251  unless (pipe($rfh, $wfh)) {
252    die("Can't open pipe: $!");
253  }
254
255  my $ex;
256
257  # Fork child
258  $self->handle_sigchld();
259  defined(my $pid = fork()) or die("Can't fork: $!");
260  if ($pid) {
261    eval {
262      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
263
264      $client->login($user, $passwd);
265
266      my $conn = $client->list_raw($home_dir);
267      unless ($conn) {
268        die("LIST failed: " . $client->response_code() . " " .
269          $client->response_msg());
270      }
271
272      # Wait for one second more than the stalled period
273      sleep($timeout_stalled + 1);
274
275      my $buf;
276      $conn->read($buf, 8192);
277      $conn->close();
278
279      my ($resp_code, $resp_msg);
280      eval { $client->noop() };
281      unless ($@) {
282        die("NOOP succeeded unexpectedly");
283
284      } else {
285        $resp_code = $client->response_code();
286        $resp_msg = $client->response_msg();
287      }
288
289      my $expected;
290
291      # Perl's Net::Cmd module uses a very non-standard 599 code to
292      # indicate that the connection is closed
293      $expected = 599;
294      $self->assert($expected == $resp_code,
295        test_msg("Expected $expected, got $resp_code"));
296
297      $expected = "Connection closed";
298      $self->assert($expected eq $resp_msg,
299        test_msg("Expected '$expected', got '$resp_msg'"));
300    };
301
302    if ($@) {
303      $ex = $@;
304    }
305
306    $wfh->print("done\n");
307    $wfh->flush();
308
309  } else {
310    eval { server_wait($config_file, $rfh) };
311    if ($@) {
312      warn($@);
313      exit 1;
314    }
315
316    exit 0;
317  }
318
319  # Stop server
320  server_stop($pid_file);
321
322  $self->assert_child_ok($pid);
323
324  if ($ex) {
325    die($ex);
326  }
327
328  unlink($log_file);
329}
330
3311;
Note: See TracBrowser for help on using the repository browser.