changeset 951:9361c7eddfc1

Tests: parallel tests support.
author Andrey Zelenkov <zelenkov@nginx.com>
date Tue, 21 Jun 2016 16:37:58 +0300
parents 991ef7781b38
children e9064d691790
files lib/Test/Nginx.pm lib/Test/Nginx/HTTP2.pm lib/Test/Nginx/IMAP.pm lib/Test/Nginx/POP3.pm lib/Test/Nginx/SMTP.pm lib/Test/Nginx/Stream.pm
diffstat 6 files changed, 47 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/lib/Test/Nginx.pm
+++ b/lib/Test/Nginx.pm
@@ -11,7 +11,7 @@ use strict;
 
 use base qw/ Exporter /;
 
-our @EXPORT = qw/ log_in log_out http http_get http_head /;
+our @EXPORT = qw/ log_in log_out http http_get http_head port /;
 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 / ]
@@ -31,6 +31,7 @@ use Test::More qw//;
 
 our $NGINX = defined $ENV{TEST_NGINX_BINARY} ? $ENV{TEST_NGINX_BINARY}
 	: '../nginx/objs/nginx';
+our @ports = ();
 
 sub new {
 	my $self = {};
@@ -304,6 +305,36 @@ sub run(;$) {
 	return $self;
 }
 
+sub port {
+	my ($num, %opts) = @_;
+	my ($s_tcp, $s_udp, $port);
+
+	goto done if defined $ports[$num];
+
+	for (1 .. 10) {
+		$port = 8000 + int(rand(1000));
+
+		$s_udp = IO::Socket::INET->new(
+			Proto => 'udp',
+			LocalAddr => '127.0.0.1:' . $port,
+		) or next;
+
+		$s_tcp = IO::Socket::INET->new(
+			Proto => 'tcp',
+			LocalAddr => '127.0.0.1:' . $port,
+			Reuse => 1,
+		) and last;
+	}
+
+	die "Port limit exceeded" unless defined $s_tcp and defined $s_udp;
+
+	$ports[$num] = {port => $port, socket => $opts{udp} ? $s_tcp : $s_udp};
+
+done:
+	return $ports[$num]{socket} if $opts{socket};
+	return $ports[$num]{port};
+}
+
 sub dump_config() {
 	my ($self) = @_;
 
@@ -427,6 +458,8 @@ sub write_file_expand($$) {
 	$content =~ s/%%TEST_GLOBALS%%/$self->test_globals()/gmse;
 	$content =~ s/%%TEST_GLOBALS_HTTP%%/$self->test_globals_http()/gmse;
 	$content =~ s/%%TESTDIR%%/$self->{_testdir}/gms;
+	$content =~ s/%%PORT_(\d+)%%/port($1)/gmse;
+	$content =~ s/%%PORT_(\d+)_UDP%%/port($1, udp => 1)/gmse;
 
 	return $self->write_file($name, $content);
 }
@@ -608,7 +641,7 @@ sub http_start($;%) {
 
 		$s = $extra{socket} || IO::Socket::INET->new(
 			Proto => 'tcp',
-			PeerAddr => '127.0.0.1:8080'
+			PeerAddr => '127.0.0.1:' . ($ports[0]{port} || 8080)
 		)
 			or die "Can't connect to nginx: $!\n";
 
--- a/lib/Test/Nginx/HTTP2.pm
+++ b/lib/Test/Nginx/HTTP2.pm
@@ -479,7 +479,7 @@ sub new_socket {
 	my $alpn = $extra{'alpn'};
 	my $s;
 
-	$port = 8080 unless defined $port;
+	$port = ($Test::Nginx::ports[0]{port} || 8080) unless defined $port;
 
 	eval {
 		local $SIG{ALRM} = sub { die "timeout\n" };
--- a/lib/Test/Nginx/IMAP.pm
+++ b/lib/Test/Nginx/IMAP.pm
@@ -89,9 +89,11 @@ sub ok {
 ###############################################################################
 
 sub imap_test_daemon {
+	my ($port) = @_;
+
 	my $server = IO::Socket::INET->new(
 		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8144',
+		LocalAddr => '127.0.0.1:' . ($port || 8144),
 		Listen => 5,
 		Reuse => 1
 	)
--- a/lib/Test/Nginx/POP3.pm
+++ b/lib/Test/Nginx/POP3.pm
@@ -89,9 +89,11 @@ sub ok {
 ###############################################################################
 
 sub pop3_test_daemon {
+	my ($port) = @_;
+
 	my $server = IO::Socket::INET->new(
 		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8111',
+		LocalAddr => '127.0.0.1:' . ($port || 8111),
 		Listen => 5,
 		Reuse => 1
 	)
--- a/lib/Test/Nginx/SMTP.pm
+++ b/lib/Test/Nginx/SMTP.pm
@@ -93,9 +93,11 @@ sub authok {
 ###############################################################################
 
 sub smtp_test_daemon {
+	my ($port) = @_;
+
 	my $server = IO::Socket::INET->new(
 		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8026',
+		LocalAddr => '127.0.0.1:' . ($port || 8026),
 		Listen => 5,
 		Reuse => 1
 	)
--- a/lib/Test/Nginx/Stream.pm
+++ b/lib/Test/Nginx/Stream.pm
@@ -28,7 +28,6 @@ sub dgram {
 
 	return Test::Nginx::Stream->new(
 		Proto => "udp",
-		PeerAddr => '127.0.0.1:8080',
 		@_
 	);
 }
@@ -41,7 +40,8 @@ sub new {
 
 	$self->{_socket} = IO::Socket::INET->new(
 		Proto => "tcp",
-		PeerAddr => '127.0.0.1:8080',
+		PeerAddr => '127.0.0.1',
+		PeerPort => ($Test::Nginx::ports[0]{port} || 8080),
 		@_
 	)
 		or die "Can't connect to nginx: $!\n";