changeset 438:60888e2c3f5a

Tests: new http_start() and http_end() functions. When used together, they allow to break an http request into two separate send/receive phases and are used to run long requests asynchronously. An http() "start" extra flag introduced as a convenience shortcut.
author Sergey Kandaurov <pluknet@nginx.com>
date Fri, 18 Jul 2014 13:19:55 +0400
parents 8b4a6b8691eb
children d5b541a8cf95
files http_resolver.t lib/Test/Nginx.pm limit_conn.t proxy_cache_lock.t upstream_least_conn.t
diffstat 5 files changed, 46 insertions(+), 190 deletions(-) [+]
line wrap: on
line diff
--- a/http_resolver.t
+++ b/http_resolver.t
@@ -15,7 +15,7 @@ use Test::More;
 BEGIN { use FindBin; chdir($FindBin::Bin); }
 
 use lib 'lib';
-use Test::Nginx;
+use Test::Nginx qw/ :DEFAULT http_end /;
 
 ###############################################################################
 
@@ -94,7 +94,7 @@ EOF
 
 # schedule resend test, which takes abound 5 seconds to complete
 
-my $s = http_start('id.example.net', '/resend');
+my $s = http_host_header('id.example.net', '/resend', start => 1);
 
 like(http_host_header('a.example.net', '/'), qr/200 OK/, 'A');
 
@@ -231,8 +231,8 @@ like(http_end($s), qr/200 OK/, 'resend a
 ###############################################################################
 
 sub http_host_header {
-	my ($host, $uri) = @_;
-	return http(<<EOF);
+	my ($host, $uri, %extra) = @_;
+	return http(<<EOF, %extra);
 GET $uri HTTP/1.0
 Host: $host
 
@@ -248,57 +248,6 @@ X-Name: $host
 EOF
 }
 
-sub http_start {
-	my ($host, $uri) = @_;
-
-	my $s;
-	my $request = <<EOF;
-GET $uri HTTP/1.0
-Host: $host
-
-EOF
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(5);
-		$s = IO::Socket::INET->new(
-			Proto => 'tcp',
-			PeerAddr => '127.0.0.1:8080'
-		);
-		log_out($request);
-		$s->print($request);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $s;
-}
-
-sub http_end {
-	my ($s) = @_;
-	my $reply;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		local $/;
-		$reply = $s->getline();
-		log_in($reply);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $reply;
-}
-
 ###############################################################################
 
 sub reply_handler {
--- a/lib/Test/Nginx.pm
+++ b/lib/Test/Nginx.pm
@@ -12,7 +12,7 @@ use strict;
 use base qw/ Exporter /;
 
 our @EXPORT = qw/ log_in log_out http http_get http_head /;
-our @EXPORT_OK = qw/ http_gzip_request http_gzip_like /;
+our @EXPORT_OK = qw/ http_gzip_request http_gzip_like http_start http_end /;
 our %EXPORT_TAGS = (
 	gzip => [ qw/ http_gzip_request http_gzip_like / ]
 );
@@ -455,14 +455,23 @@ EOF
 
 sub http($;%) {
 	my ($request, %extra) = @_;
-	my $reply;
+
+	my $s = http_start($request, %extra);
+
+	return $s if $extra{start} or !defined $s;
+	return http_end($s);
+}
+
+sub http_start($;%) {
+	my ($request, %extra) = @_;
+	my $s;
 
 	eval {
 		local $SIG{ALRM} = sub { die "timeout\n" };
 		local $SIG{PIPE} = sub { die "sigpipe\n" };
 		alarm(5);
 
-		my $s = $extra{socket} || IO::Socket::INET->new(
+		$s = $extra{socket} || IO::Socket::INET->new(
 			Proto => 'tcp',
 			PeerAddr => '127.0.0.1:8080'
 		)
@@ -479,6 +488,26 @@ sub http($;%) {
 			$s->print($extra{body});
 		}
 
+		alarm(0);
+	};
+	alarm(0);
+	if ($@) {
+		log_in("died: $@");
+		return undef;
+	}
+
+	return $s;
+}
+
+sub http_end($;%) {
+	my ($s) = @_;
+	my $reply;
+
+	eval {
+		local $SIG{ALRM} = sub { die "timeout\n" };
+		local $SIG{PIPE} = sub { die "sigpipe\n" };
+		alarm(5);
+
 		local $/;
 		$reply = $s->getline();
 
--- a/limit_conn.t
+++ b/limit_conn.t
@@ -104,7 +104,7 @@ http_get('/w');
 
 # same and other zones in different locations
 
-my $s = http_start('/w');
+my $s = http_get('/w', start => 1);
 like(http_get('/'), qr/^HTTP\/1.. 503 /, 'rejected');
 like(http_get('/1'), qr/^HTTP\/1.. 503 /, 'rejected different location');
 unlike(http_get('/zone'), qr/^HTTP\/1.. 503 /, 'passed different zone');
@@ -114,7 +114,7 @@ unlike(http_get('/1'), qr/^HTTP\/1.. 503
 
 # custom error code and log level
 
-$s = http_start('/custom/w');
+$s = http_get('/custom/w', start => 1);
 like(http_get('/custom'), qr/^HTTP\/1.. 501 /, 'limit_conn_status');
 
 like(`grep -F '[info]' ${\($t->testdir())}/error.log`,
@@ -123,7 +123,7 @@ like(`grep -F '[info]' ${\($t->testdir()
 
 # limit_zone
 
-$s = http_start('/legacy/w');
+$s = http_get('/legacy/w', start => 1);
 like(http_get('/legacy'), qr/^HTTP\/1.. 503 /, 'legacy rejected');
 
 $s->close;
@@ -131,36 +131,8 @@ unlike(http_get('/legacy'), qr/^HTTP\/..
 
 # limited after unlimited
 
-$s = http_start('/w');
+$s = http_get('/w', start => 1);
 like(http_get('/unlim'), qr/404 Not Found/, 'unlimited passed');
 like(http_get('/'), qr/503 Service/, 'limited rejected');
 
 ###############################################################################
-
-sub http_start {
-	my ($uri) = @_;
-
-	my $s;
-	my $request = "GET $uri HTTP/1.0" . CRLF . CRLF;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		$s = IO::Socket::INET->new(
-			Proto => 'tcp',
-			PeerAddr => '127.0.0.1:8080'
-		);
-		log_out($request);
-		$s->print($request);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $s;
-}
-
-###############################################################################
--- a/proxy_cache_lock.t
+++ b/proxy_cache_lock.t
@@ -15,7 +15,7 @@ use Socket qw/ CRLF /;
 BEGIN { use FindBin; chdir($FindBin::Bin); }
 
 use lib 'lib';
-use Test::Nginx;
+use Test::Nginx qw/ :DEFAULT http_end /;
 
 ###############################################################################
 
@@ -87,7 +87,7 @@ for my $i (1 .. 5) {
 my @sockets;
 
 for my $i (1 .. 5) {
-	$sockets[$i] = http_start('/par1');
+	$sockets[$i] = http_get('/par1', start => 1);
 }
 
 for my $i (1 .. 5) {
@@ -99,7 +99,7 @@ like(http_get('/par1'), qr/request 1/, '
 # parallel requests with cache lock timeout
 
 for my $i (1 .. 3) {
-	$sockets[$i] = http_start('/timeout');
+	$sockets[$i] = http_get('/timeout', start => 1);
 }
 
 for my $i (1 .. 3) {
@@ -111,7 +111,7 @@ like(http_get('/timeout'), qr/request 3/
 # no lock
 
 for my $i (1 .. 3) {
-	$sockets[$i] = http_start('/nolock');
+	$sockets[$i] = http_get('/nolock', start => 1);
 }
 
 for my $i (1 .. 3) {
@@ -122,53 +122,6 @@ like(http_get('/nolock'), qr/request 3/,
 
 ###############################################################################
 
-sub http_start {
-	my ($uri) = @_;
-
-	my $s;
-	my $request = "GET $uri HTTP/1.0" . CRLF . CRLF;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		$s = IO::Socket::INET->new(
-			Proto => 'tcp',
-			PeerAddr => '127.0.0.1:8080'
-		);
-		log_out($request);
-		$s->print($request);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $s;
-}
-
-sub http_end {
-	my ($s) = @_;
-	my $reply;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		local $/;
-		$reply = $s->getline();
-		log_in($reply);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $reply;
-}
-
 ###############################################################################
 
 sub http_fake_daemon {
--- a/upstream_least_conn.t
+++ b/upstream_least_conn.t
@@ -16,7 +16,7 @@ use Socket qw/ CRLF /;
 BEGIN { use FindBin; chdir($FindBin::Bin); }
 
 use lib 'lib';
-use Test::Nginx;
+use Test::Nginx qw/ :DEFAULT http_end /;
 
 ###############################################################################
 
@@ -88,7 +88,7 @@ sub parallel {
 	my (@sockets, %ports);
 
 	for (1 .. $count) {
-		push(@sockets, http_start($uri));
+		push(@sockets, http_get($uri, start => 1));
 		select undef, undef, undef, 0.1;
 	}
 
@@ -102,53 +102,6 @@ sub parallel {
 	return join ', ', map { $_ . ": " . $ports{$_} } sort keys %ports;
 }
 
-sub http_start {
-	my ($uri) = @_;
-
-	my $s;
-	my $request = "GET $uri HTTP/1.0" . CRLF . CRLF;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		$s = IO::Socket::INET->new(
-			Proto => 'tcp',
-			PeerAddr => '127.0.0.1:8080'
-		);
-		log_out($request);
-		$s->print($request);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $s;
-}
-
-sub http_end {
-	my ($s) = @_;
-	my $reply;
-
-	eval {
-		local $SIG{ALRM} = sub { die "timeout\n" };
-		local $SIG{PIPE} = sub { die "sigpipe\n" };
-		alarm(3);
-		local $/;
-		$reply = $s->getline();
-		log_in($reply);
-		alarm(0);
-	};
-	alarm(0);
-	if ($@) {
-		log_in("died: $@");
-		return undef;
-	}
-	return $reply;
-}
-
 ###############################################################################
 
 sub http_daemon {