1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
|
package DebbugsTest;
=head1 NAME
DebbugsTest
=head1 SYNOPSIS
use DebbugsTest
=head1 DESCRIPTION
This module contains various testing routines used to test debbugs in
a "pseudo install"
=head1 FUNCTIONS
=cut
use warnings;
use strict;
use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
use base qw(Exporter);
use IO::File;
use File::Temp qw(tempdir);
use Cwd qw(getcwd);
use Debbugs::MIME qw(create_mime_message);
use File::Basename qw(dirname basename);
use IPC::Open3;
use IO::Handle;
use Test::More;
use Params::Validate qw(validate_with :types);
BEGIN{
$VERSION = 1.00;
$DEBUG = 0 unless defined $DEBUG;
@EXPORT = ();
%EXPORT_TAGS = (configuration => [qw(dirsize create_debbugs_configuration send_message)],
mail => [qw(num_messages_sent)],
control => [qw(test_control_commands)],
);
@EXPORT_OK = ();
Exporter::export_ok_tags(qw(configuration mail control));
$EXPORT_TAGS{all} = [@EXPORT_OK];
}
# First, we're going to send mesages to receive.
# To do so, we'll first send a message to submit,
# then send messages to the newly created bugnumber.
sub create_debbugs_configuration {
my %param = validate_with(params => \@_,
spec => {debug => {type => BOOLEAN,
default => exists $ENV{DEBUG}?
$ENV{DEBUG}:0,
},
cleanup => {type => BOOLEAN,
optional => 1,
},
},
);
$param{cleanup} = $param{debug}?0:1 if not exists $param{cleanup};
my $sendmail_dir = tempdir(CLEANUP => $param{cleanup});
my $spool_dir = tempdir(CLEANUP => $param{cleanup});
my $config_dir = tempdir(CLEANUP => $param{cleanup});
$ENV{DEBBUGS_CONFIG_FILE} ="$config_dir/debbugs_config";
$ENV{PERL5LIB} = getcwd();
$ENV{SENDMAIL_TESTDIR} = $sendmail_dir;
eval {
my $sendmail_tester = getcwd().'/t/sendmail_tester';
unless (-x $sendmail_tester) {
die q(t/sendmail_tester doesn't exist or isn't executable. You may be in the wrong directory.);
}
my %files_to_create = ("$config_dir/debbugs_config" => <<END,
\$gSendmail='$sendmail_tester';
\$gSpoolDir='$spool_dir';
\$gLibPath='@{[getcwd()]}/scripts';
\$gTemplateDir='@{[getcwd()]}/templates';
\$gWebDir='@{[getcwd()]}/html';
\$gWebHost='localhost';
1;
END
"$spool_dir/nextnumber" => qq(1\n),
"$config_dir/Maintainers" => qq(foo Blah Bleargh <foo\@baz.com>\nbar Bar Bleargh <bar\@baz.com>\n),
"$config_dir/Maintainers.override" => qq(),
"$config_dir/Source_maintainers" => qq(foo Blah Bleargh <foo\@baz.com>\nbar Bar Bleargh <bar\@baz.com>\n),
"$config_dir/indices/sources" => <<END,
foo main foo
END
"$config_dir/pseudo-packages.description" => '',
"$config_dir/pseudo-packages.maintainers" => '',
);
while (my ($file,$contents) = each %files_to_create) {
system('mkdir','-p',dirname($file));
my $fh = IO::File->new($file,'w') or
die "Unable to create $file: $!";
print {$fh} $contents or die "Unable to write $contents to $file: $!";
close $fh or die "Unable to close $file: $!";
}
system('touch',"$spool_dir/index.db.realtime");
system('ln','-s','index.db.realtime',
"$spool_dir/index.db");
system('touch',"$spool_dir/index.archive.realtime");
system('ln','-s','index.archive.realtime',
"$spool_dir/index.archive");
# create the spool files and sub directories
for my $dir (0..99) {
for my $archive (qw(db-h archive)) {
system('mkdir','-p',"$spool_dir/$archive/".sprintf('%02d',$dir));
}
}
system('mkdir','-p',"$spool_dir/incoming");
system('mkdir','-p',"$spool_dir/lock");
# generate the maintainers index files
system('scripts/maintainer-indices') == 0
or die "Unable to generate maintainer index files";
eval '
END{
if ($ENV{DEBUG}) {
diag("spool_dir: $spool_dir\n");
diag("config_dir: $config_dir\n",);
diag("sendmail_dir: $sendmail_dir\n");
}
}';
};
BAIL_OUT ($@) if ($@);
return (spool_dir => $spool_dir,
sendmail_dir => $sendmail_dir,
config_dir => $config_dir,
);
}
sub dirsize{
my ($dir) = @_;
opendir(DIR,$dir);
my @content = grep {!/^\.\.?$/} readdir(DIR);
closedir(DIR);
return scalar @content;
}
# We're going to use create mime message to create these messages, and
# then just send them to receive.
# First, check that submit@ works
sub send_message{
my %param = validate_with(params => \@_,
spec => {to => {type => SCALAR,
default => 'submit@bugs.something',
},
headers => {type => ARRAYREF,
},
body => {type => SCALAR,
},
attachments => {type => ARRAYREF,
default => [],
},
run_processall =>{type => BOOLEAN,
default => 1,
},
}
);
$ENV{LOCAL_PART} = $param{to};
my ($rfd,$wfd);
my $output='';
my $pipe_handler = $SIG{PIPE};
$SIG{PIPE} = 'IGNORE';
$SIG{CHLD} = 'DEFAULT';
my $pid = open3($wfd,$rfd,$rfd,'scripts/receive')
or die "Unable to start receive: $!";
print {$wfd} create_mime_message($param{headers},
$param{body},
$param{attachments}) or
die "Unable to to print to receive";
close($wfd) or die "Unable to close receive";
$SIG{PIPE} = $pipe_handler;
my $err = $? >> 8;
my $childpid = waitpid($pid,0);
if ($childpid != -1) {
$err = $? >> 8;
print STDERR "receive pid: $pid doesn't match childpid: $childpid\n" if $childpid != $pid;
}
if ($err != 0 ) {
my $rfh = IO::Handle->new_from_fd($rfd,'r') or die "Unable to create filehandle: $!";
$rfh->blocking(0);
my $rv;
while ($rv = $rfh->sysread($output,1000,length($output))) {}
if (not defined $rv) {
print STDERR "Reading from STDOUT/STDERR would have blocked.";
}
print STDERR $output,qq(\n);
die "receive failed with exit status $err";
}
# now we should run processall to see if the message gets processed
if ($param{run_processall}) {
system('scripts/processall') == 0 or die "processall failed";
}
}
=item test_control_commands
test_control_commands(\%config,
forcemerge => {command => 'forcemerge',
value => '1 2',
status_key => 'mergedwith',
status_value => '2',
expect_error => 0,
});
Test a set of control commands to see if they will fail or not. Takes
SCALAR/HASHREF pairs, where the scalar should be unique, and the HASHREF
contains the following keys:
=over
=item command -- control command to issue
=item value -- value to pass to control command
=item status_key -- bug status key to check
=item status_value -- value of status key
=item expect_error -- whether to expect the control command to error or not
=back
=cut
sub test_control_commands {
my ($config,@commands) = @_;
# now we need to check to make sure that the control message actually did anything
# This is an eval because $ENV{DEBBUGS_CONFIG_FILE} isn't set at BEGIN{} time
eval "use Debbugs::Status qw(read_bug writebug);";
while (my ($command,$control_command) = splice(@commands,0,2)) {
# just check to see that control doesn't explode
$control_command->{value} = " $control_command->{value}" if length $control_command->{value}
and $control_command->{value} !~ /^\s/;
send_message(to => 'control@bugs.something',
headers => [To => 'control@bugs.something',
From => 'foo@bugs.something',
Subject => "Munging a bug with $command",
],
body => <<EOF) or fail 'message to control@bugs.something failed';
debug 10
$control_command->{command} $control_command->{value}
thanks
EOF
;
# now we need to check to make sure the control message was processed without errors
if (not ($control_command->{expect_error} // 0)) {
ok(system('sh','-c','find '.$config->{sendmail_dir}.
q( -type f | xargs grep -q "Subject: Processed: Munging a bug with $command")
) == 0,
'control@bugs.something'. "$command message was parsed without errors");
}
# now we need to check to make sure that the control message actually did anything
my $status;
$status = read_bug(exists $control_command->{bug}?(bug => $control_command->{bug}):(bug=>1),
exists $control_command->{location}?(location => $control_command->{location}):(),
);
is_deeply($status->{$control_command->{status_key}},
$control_command->{status_value},
"bug " .
(exists $control_command->{bug}?$control_command->{bug}:1).
" $command"
)
or fail(Data::Dumper->Dump([$status],[qw(status)]));
}
}
$SIG{CHLD} = sub {};
{
package DebbugsTest::HTTPServer;
use base qw(HTTP::Server::Simple::CGI HTTP::Server::Simple::CGI::Environment);
our $child_pid = undef;
our $webserver = undef;
our $server_handler = undef;
END {
if (defined $child_pid) {
# stop the child
my $temp_exit = $?;
kill(15,$child_pid);
waitpid(-1,0);
$? = $temp_exit;
}
}
sub fork_and_create_webserver {
my ($handler,$port) = @_;
$port ||= 8080;
if (defined $child_pid) {
die "We appear to have already forked once";
}
$server_handler = $handler;
my $pid = fork;
return 0 if not defined $pid;
if ($pid) {
$child_pid = $pid;
# Wait here for a second to let the child start up
sleep 1;
return $pid;
}
else {
$webserver = DebbugsTest::HTTPServer->new($port);
$webserver->run;
}
}
sub handle_request {
if (defined $server_handler) {
$server_handler->(@_);
}
else {
warn "No handler defined\n";
print "No handler defined\n";
}
}
}
=head2 num_messages_sent
$SD_SIZE = num_messages_sent($SD_SIZE,2,$sendmail_dir,'2 messages have been sent properly');
Tests to make sure that at least a certain number of messages have
been sent since the last time this command was run. Usefull to test to
make sure that mail has been sent.
=cut
sub num_messages_sent {
my ($prev_size,$num_messages,$sendmail_dir,$test_name) = @_;
my $cur_size = dirsize($sendmail_dir);
## print STDERR "sendmail: $sendmail_dir, want: $num_messages,
## size: $cur_size, prev_size: $prev_size\n";
ok($cur_size-$prev_size >= $num_messages, $test_name);
return $cur_size;
}
1;
__END__
|