2004-07-16 04:22:27 +02:00
|
|
|
package Test::Qpsmtpd;
|
|
|
|
use strict;
|
2014-09-16 08:41:31 +02:00
|
|
|
|
2004-07-16 04:22:27 +02:00
|
|
|
use Carp qw(croak);
|
|
|
|
use Test::More;
|
2014-09-16 08:41:31 +02:00
|
|
|
|
|
|
|
use lib 't';
|
|
|
|
use lib 'lib';
|
|
|
|
use parent 'Qpsmtpd::SMTP';
|
|
|
|
|
2004-07-16 04:22:27 +02:00
|
|
|
use Qpsmtpd::Constants;
|
2004-09-08 18:26:33 +02:00
|
|
|
use Test::Qpsmtpd::Plugin;
|
2004-07-16 04:22:27 +02:00
|
|
|
|
|
|
|
sub new_conn {
|
2013-04-21 06:08:43 +02:00
|
|
|
ok(my $smtpd = __PACKAGE__->new(), "new");
|
|
|
|
ok(
|
|
|
|
my $conn =
|
|
|
|
$smtpd->start_connection(
|
|
|
|
remote_host => 'localhost',
|
|
|
|
remote_ip => '127.0.0.1'
|
|
|
|
),
|
|
|
|
"start_connection"
|
|
|
|
);
|
|
|
|
is(($smtpd->response)[0], "220", "greetings");
|
|
|
|
($smtpd, $conn);
|
2004-07-16 04:22:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub start_connection {
|
|
|
|
my $self = shift;
|
|
|
|
my %args = @_;
|
|
|
|
|
|
|
|
my $remote_host = $args{remote_host} or croak "no remote_host parameter";
|
|
|
|
my $remote_info = "test\@$remote_host";
|
|
|
|
my $remote_ip = $args{remote_ip} or croak "no remote_ip parameter";
|
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
my $conn =
|
|
|
|
$self->SUPER::connection->start(
|
|
|
|
remote_info => $remote_info,
|
|
|
|
remote_ip => $remote_ip,
|
|
|
|
remote_host => $remote_host,
|
|
|
|
@_
|
|
|
|
);
|
2004-07-16 04:22:27 +02:00
|
|
|
|
|
|
|
$self->load_plugins;
|
|
|
|
|
|
|
|
my $rc = $self->start_conversation;
|
|
|
|
return if $rc != DONE;
|
|
|
|
|
|
|
|
$conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub respond {
|
2013-04-21 06:08:43 +02:00
|
|
|
my $self = shift;
|
|
|
|
$self->{_response} = [@_];
|
2004-07-16 04:22:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub response {
|
2013-04-21 06:08:43 +02:00
|
|
|
my $self = shift;
|
|
|
|
$self->{_response} ? (@{delete $self->{_response}}) : ();
|
2004-07-16 04:22:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub command {
|
2013-04-21 06:08:43 +02:00
|
|
|
my ($self, $command) = @_;
|
|
|
|
$self->input($command);
|
|
|
|
$self->response;
|
2004-07-16 04:22:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub input {
|
2014-09-17 08:16:53 +02:00
|
|
|
my ($self, $command) = @_;
|
2004-07-16 04:22:27 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
my $timeout = $self->config('timeout');
|
|
|
|
alarm $timeout;
|
2004-07-16 04:22:27 +02:00
|
|
|
|
2013-04-21 06:08:43 +02:00
|
|
|
$command =~ s/\r?\n$//s; # advanced chomp
|
|
|
|
$self->log(LOGDEBUG, "dispatching $command");
|
2014-09-17 08:16:53 +02:00
|
|
|
if (!defined $self->dispatch(split / +/, $command, 2)) {
|
|
|
|
$self->respond(502, "command unrecognized: '$command'");
|
|
|
|
}
|
2013-04-21 06:08:43 +02:00
|
|
|
alarm $timeout;
|
2004-07-16 04:22:27 +02:00
|
|
|
}
|
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
sub config_dir {
|
2012-06-03 04:56:05 +02:00
|
|
|
return './t/config' if $ENV{QPSMTPD_DEVELOPER};
|
2014-09-16 08:41:31 +02:00
|
|
|
return './config.sample';
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
|
|
|
|
2007-01-12 00:52:51 +01:00
|
|
|
sub plugin_dirs {
|
2014-09-17 20:38:40 +02:00
|
|
|
('./plugins', './plugins/ident');
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub log {
|
2007-05-18 00:02:32 +02:00
|
|
|
my ($self, $trace, $hook, $plugin, @log) = @_;
|
2008-02-14 19:57:27 +01:00
|
|
|
my $level = Qpsmtpd::TRACE_LEVEL() || 5;
|
2014-09-17 08:16:53 +02:00
|
|
|
$level = $self->init_logger if !defined $level;
|
|
|
|
print("# " . join(' ', $$, @log) . "\n") if $trace <= $level;
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
|
|
|
|
2005-05-25 22:07:58 +02:00
|
|
|
sub varlog {
|
|
|
|
shift->log(@_);
|
|
|
|
}
|
|
|
|
|
2004-07-16 04:22:27 +02:00
|
|
|
# sub run
|
|
|
|
# sub disconnect
|
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
sub run_plugin_tests {
|
2014-11-04 21:49:15 +01:00
|
|
|
my ($self, $only_plugin) = @_;
|
2004-09-08 18:26:33 +02:00
|
|
|
$self->{_test_mode} = 1;
|
|
|
|
my @plugins = $self->load_plugins();
|
2013-04-21 06:08:43 +02:00
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
require Test::Builder;
|
|
|
|
my $Test = Test::Builder->new();
|
2004-11-09 16:25:52 +01:00
|
|
|
|
2004-09-08 18:26:33 +02:00
|
|
|
foreach my $plugin (@plugins) {
|
2014-11-04 21:49:15 +01:00
|
|
|
next if ($only_plugin && $plugin !~ /$only_plugin/);
|
2014-09-17 08:16:53 +02:00
|
|
|
$plugin->register_tests();
|
2004-09-08 23:48:27 +02:00
|
|
|
$plugin->run_tests($self);
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
2014-09-17 08:16:53 +02:00
|
|
|
$Test->done_testing();
|
2004-09-08 18:26:33 +02:00
|
|
|
}
|
2004-07-16 04:22:27 +02:00
|
|
|
|
2014-12-18 04:25:12 +01:00
|
|
|
sub fake_hook {
|
2014-12-18 21:01:32 +01:00
|
|
|
# Used to test core code against different potential plugins
|
|
|
|
# it will interact with
|
2014-12-18 04:25:12 +01:00
|
|
|
my ( $self, $hook, $sub ) = @_;
|
|
|
|
unshift @{ $self->hooks->{$hook} ||= [] },
|
|
|
|
{
|
|
|
|
name => '___FakeHook___',
|
|
|
|
code => $sub,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub unfake_hook {
|
|
|
|
my ( $self, $hook ) = @_;
|
|
|
|
$self->hooks->{$hook} = [
|
|
|
|
grep { $_->{name} ne '___FakeHook___' }
|
|
|
|
@{ $self->hooks->{$hook} || [] }
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
sub fake_config {
|
2014-12-18 21:01:32 +01:00
|
|
|
# Used to test code against various possible configurations
|
2014-12-18 04:25:12 +01:00
|
|
|
my $self = shift;
|
|
|
|
my $fake_config = {@_};
|
|
|
|
$self->fake_hook( 'config',
|
|
|
|
sub {
|
|
|
|
my ( $self, $txn, $conf ) = @_;
|
|
|
|
return DECLINED if ! exists $fake_config->{$conf};
|
|
|
|
return OK, $fake_config->{$conf};
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
sub unfake_config {
|
|
|
|
my ( $self ) = @_;
|
|
|
|
$self->unfake_hook('config');
|
|
|
|
}
|
|
|
|
|
2004-07-16 04:22:27 +02:00
|
|
|
1;
|