diff lib/Test/Nginx.pm @ 951:9361c7eddfc1

Tests: parallel tests support.
author Andrey Zelenkov <zelenkov@nginx.com>
date Tue, 21 Jun 2016 16:37:58 +0300
parents b9e42c554ba7
children 3bc5b72e4377
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";