package Pushmi::Test; use strict; use warnings; use Pushmi::Config; use base 'Exporter'; our @EXPORT = qw(get_dav_server run_pushmi is_svn_output start_memcached check_apache); use FindBin; BEGIN { $ENV{PATH} = "$FindBin::Bin/../bin:".$ENV{PATH}; $ENV{SVKNOSVNCONFIG} = 1; $SIG{INT} = $SIG{TERM} = sub { exit }; # calls END properly $ENV{PUSHMI_CONFIG} = "$FindBin::Bin/pushmi.conf"; } use SVK::Util qw(can_run abs_path); use IPC::Run3 'run3'; use Test::More; my $apache_port = 5008; my $apxs = $ENV{APXS} || can_run('apxs2') || can_run ('apxs'); my @CLEANUP; sub run_pushmi { system($^X, (map { "-I$_" } @INC), 'bin/pushmi', @_); die $! if $?; return; } sub _mk_cmp_closure { my ($exp, $err) = @_; my $line = 0; sub { my $output = shift; chomp $output; ++$line; unless (@$exp) { push @$err, "$line: got $output"; return; } my $item = shift @$exp; push @$err, "$line: got ($output), expect ($item)\n" unless ref($item) ? ($output =~ m/$item/) : ($output eq $item); } } sub is_svn_output { my ($arg, $exp_stdout, $exp_stderr) = @_; my $stdout_err = []; $exp_stderr ||= []; my $ret = run3 ['svn', @$arg], undef, _mk_cmp_closure($exp_stdout, $stdout_err), # stdout _mk_cmp_closure($exp_stderr, $stdout_err); # stderr if (@$stdout_err) { @_ = (0, join(' ', 'svn', @$arg)); diag("Different in line: ".join(',', @$stdout_err)); goto \&ok; } else { @_ = (1, join(' ', 'svn', @$arg)); goto \&ok; } } sub check_apache { plan (skip_all => "Test does not run under root") if $> == 0; my $apxs = $ENV{APXS} || can_run('apxs2') || can_run ('apxs'); plan skip_all => "Can't find apxs utility. Use APXS env to specify path" unless $apxs; } sub get_dav_server { require RunApp::Apache; my %args = @_; my $apache_root = $args{apache_root}; mkdir($apache_root); mkdir("$apache_root/logs"); my $apache = RunApp::Apache->new( CTL => 'RunApp::Control::ApacheCtl', root => $args{apache_root}, port => ( $apache_port++ ), hostname => 'localhost', webmaster => 'root@localhost', mime_file => '/etc/mime.types', documentroot => '/tmp', report => 1, apxs => $apxs, config_block => ($args{prelude_config} || ''). qq{ KeepAlive On # [% AP2_VERSION %] [% IF AP2_VERSION == '2.2' %] PerlLoadModule Apache::AuthenHook [% END %] DAV svn SVNPath $args{repospath} AuthType Basic AuthName "Auth Realm" } . ( $args{svnpasswd} ? "Require valid-user AuthUserFile $args{svnpasswd}\n" : '' ) . ( $args{svnpolicy} ? "AuthzSVNAccessFile $args{svnpolicy} \n " : '' ). ($args{extra_config} || ''). q{ }); my $ret = `$apache->{httpd} -V`; my ($ap_version) = $ret =~ m{version: Apache/([\d.]+)}; $args{extra_modules} ||= []; if ($ap_version =~ m/^2\.2/) { $ap_version = '2.2'; push @{$args{extra_modules}}, "auth_basic", "authn_file", "authz_user"; } else { $ap_version = '2.0'; push @{$args{extra_modules}}, "auth"; } $apache->build({ AP2_VERSION => $ap_version, required_modules => [ "dav", "dav_svn", "authz_svn", "log_config", @{$args{extra_modules}}]}); push @CLEANUP, sub { $apache->stop }; return ($apache, "http://localhost:$apache->{port}/svn"); } sub start_memcached { my $port = Pushmi::Config->config->{authproxy_port}; my $memcached_pid; my $memcached = can_run('memcached') or die "Can't find memcached"; system($memcached, -p => $port, qw(-l 127.0.0.1 -dP), abs_path("t/memcached.pid")); die $! if $?; sleep 1; open my $fh, '<', 't/memcached.pid' or die $!; $memcached_pid = <$fh>; diag $memcached_pid; chomp $memcached_pid; my $pid = $$; push @CLEANUP, sub { return unless $$ == $pid; diag 'stopping memcached'; kill 'TERM', $memcached_pid if $memcached_pid }; } END { for (@CLEANUP) { $_->(); } } 1;