Mercurial > hg > nginx-tests
view lib/Test/Nginx.pm @ 37:6cf314ec8f7b
Tests: while starting nginx monitor pidfile instead of sleeping.
This reduces test execution time significantly.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 24 Oct 2008 14:42:21 +0400 |
parents | 4f57d57543e1 |
children | 1b3c22a87e5d |
line wrap: on
line source
package Test::Nginx; # (C) Maxim Dounin # Generict module for nginx tests. ############################################################################### use warnings; use strict; use base qw/ Exporter /; our @EXPORT = qw/ log_in log_out http http_get /; ############################################################################### use File::Temp qw/ tempdir /; use IO::Socket; use Socket qw/ CRLF /; use Test::More qw//; ############################################################################### our $NGINX = '../nginx/objs/nginx'; sub new { my $self = {}; bless $self; $self->{_testdir} = tempdir( 'nginx-test-XXXXXXXXXX', TMPDIR => 1, CLEANUP => not $ENV{LEAVE} ) or die "Can't create temp directory: $!\n"; return $self; } sub DESTROY { my ($self) = @_; $self->stop(); } sub has { my ($self, $feature) = @_; my %regex = ( mail => '--with-mail', flv => '--with-http_flv_module', rewrite => '(?s)^(?!.*--without-http_rewrite_module)', ); Test::More::plan(skip_all => "$feature not compiled in") unless `$NGINX -V 2>&1` =~ $regex{$feature}; return $self; } sub has_daemon($) { my ($self, $daemon) = @_; Test::More::plan(skip_all => "$daemon not found") unless `which $daemon`; return $self; } sub plan($) { my ($self, $plan) = @_; Test::More::plan(tests => $plan); return $self; } sub run(;$) { my ($self, $conf) = @_; my $testdir = $self->{_testdir}; if (defined $conf) { my $c = `cat $conf`; $self->write_file_expand('nginx.conf', $c); } my $pid = fork(); die "Unable to fork(): $!\n" unless defined $pid; if ($pid == 0) { exec($NGINX, '-c', "$testdir/nginx.conf", '-g', "pid $testdir/nginx.pid; " . "error_log $testdir/error.log debug;") or die "Unable to exec(): $!\n"; } # wait for nginx to start for (1 .. 30) { select undef, undef, undef, 0.05; last if -e "$self->{_testdir}/nginx.pid"; } die "Can't start nginx" unless -e "$self->{_testdir}/nginx.pid"; $self->{_started} = 1; return $self; } sub stop() { my ($self) = @_; while ($self->{_daemons} && scalar @{$self->{_daemons}}) { my $p = shift @{$self->{_daemons}}; kill 'TERM', $p; wait; } return $self unless $self->{_started}; kill 'TERM', `cat $self->{_testdir}/nginx.pid`; wait; $self->{_started} = 0; return $self; } sub write_file($$) { my ($self, $name, $content) = @_; open F, '>' . $self->{_testdir} . '/' . $name or die "Can't create $name: $!"; print F $content; close F; return $self; } sub write_file_expand($$) { my ($self, $name, $content) = @_; $content =~ s/%%TESTDIR%%/$self->{_testdir}/gms; return $self->write_file($name, $content); } sub run_daemon($;@) { my ($self, $code, @args) = @_; my $pid = fork(); die "Can't fork daemon: $!\n" unless defined $pid; if ($pid == 0) { if (ref($code) eq 'CODE') { $code->(@args); exit 0; } else { exec($code, @args); } } $self->{_daemons} = [] unless defined $self->{_daemons}; push @{$self->{_daemons}}, $pid; return $self; } ############################################################################### sub log_out { my ($msg) = @_; $msg =~ s/^/# >> /gm; $msg .= "\n" unless $msg =~ /\n\Z/; print $msg; } sub log_in { my ($msg) = @_; $msg =~ s/^/# << /gm; $msg =~ s/([^\x20-\x7e])/sprintf('\\x%02x', ord($1)) . (($1 eq "\n") ? "\n" : '')/gmxe; $msg .= "\n" unless $msg =~ /\n\Z/; print $msg; } ############################################################################### sub http_get($) { my ($url) = @_; return http(<<EOF); GET $url HTTP/1.0 Host: localhost EOF } sub http($) { my ($request) = @_; my $reply; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm(2); my $s = IO::Socket::INET->new( Proto => 'tcp', PeerHost => 'localhost:8080' ); log_out($request); $s->print($request); local $/; $reply = $s->getline(); log_in($reply); alarm(0); }; alarm(0); if ($@) { log_in('(timeout)'); return undef; } return $reply; } ############################################################################### 1; ###############################################################################