changeset 1860:58951cf933e1

Tests: added has_feature() test for SSL libraries. This makes it possible to further simplify various SSL tests. It also avoids direct testing of the $t->{_configure_args} internal field, and implements proper comparison of version numbers.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 18 May 2023 18:07:06 +0300
parents 5f46af4707e7
children 7b7b64569f55
files grpc_pass.t grpc_ssl.t h2_ssl.t lib/Test/Nginx.pm mail_ssl.t mail_ssl_conf_command.t proxy_ssl_conf_command.t ssl_certificate.t ssl_certificate_perl.t ssl_conf_command.t ssl_curve.t stream_proxy_ssl_conf_command.t stream_ssl_alpn.t stream_ssl_certificate.t stream_ssl_conf_command.t
diffstat 15 files changed, 62 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/grpc_pass.t
+++ b/grpc_pass.t
@@ -107,8 +107,7 @@ like(http_get('/basic'), qr/200 OK/, 'no
 like(http_get('/grpc'), qr/200 OK/, 'grpc scheme');
 
 SKIP: {
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-skip 'OpenSSL too old', 1 unless defined $1 and $1 ge '1.0.2';
+skip 'OpenSSL too old', 1 unless $t->has_feature('openssl:1.0.2');
 
 like(http_get('/grpcs'), qr/200 OK/, 'grpcs scheme');
 
--- a/grpc_ssl.t
+++ b/grpc_ssl.t
@@ -24,12 +24,9 @@ select STDERR; $| = 1;
 select STDOUT; $| = 1;
 
 my $t = Test::Nginx->new()->has(qw/http rewrite http_v2 grpc/)
-	->has(qw/upstream_keepalive http_ssl/)->has_daemon('openssl');
-
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
-
-$t->write_file_expand('nginx.conf', <<'EOF')->plan(38);
+	->has(qw/upstream_keepalive http_ssl openssl:1.0.2/)
+	->has_daemon('openssl')
+	->write_file_expand('nginx.conf', <<'EOF')->plan(38);
 
 %%TEST_GLOBALS%%
 
--- a/h2_ssl.t
+++ b/h2_ssl.t
@@ -87,10 +87,12 @@ plan(skip_all => 'no ALPN negotiation') 
 ###############################################################################
 
 SKIP: {
-$t->{_configure_args} =~ /LibreSSL ([\d\.]+)/;
-skip 'LibreSSL too old', 1 if defined $1 and $1 lt '3.4.0';
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-skip 'OpenSSL too old', 1 if defined $1 and $1 lt '1.1.0';
+skip 'LibreSSL too old', 1
+	if $t->has_module('LibreSSL')
+	and not $t->has_feature('libressl:3.4.0');
+skip 'OpenSSL too old', 1
+	if $t->has_module('OpenSSL')
+	and not $t->has_feature('openssl:1.1.0');
 
 TODO: {
 local $TODO = 'not yet' unless $t->has_version('1.21.4');
--- a/lib/Test/Nginx.pm
+++ b/lib/Test/Nginx.pm
@@ -266,6 +266,28 @@ sub has_feature($) {
 		return 0;
 	}
 
+	if ($feature =~ /^(openssl|libressl):([0-9.]+)/) {
+		my $library = $1;
+		my $need = $2;
+
+		$self->{_configure_args} = `$NGINX -V 2>&1`
+			if !defined $self->{_configure_args};
+
+		return 0 unless
+			$self->{_configure_args} =~ /with $library ([0-9.]+)/i;
+
+		my @v = split(/\./, $1);
+		my ($n, $v);
+
+		for $n (split(/\./, $need)) {
+			$v = shift @v || 0;
+			return 0 if $n > $v;
+			return 1 if $v > $n;
+		}
+
+		return 1;
+	}
+
 	return 0;
 }
 
--- a/mail_ssl.t
+++ b/mail_ssl.t
@@ -175,10 +175,12 @@ like(Net::SSLeay::dump_peer_certificate(
 ok(get_ssl_socket(8148, ['imap']), 'alpn');
 
 SKIP: {
-$t->{_configure_args} =~ /LibreSSL ([\d\.]+)/;
-skip 'LibreSSL too old', 1 if defined $1 and $1 lt '3.4.0';
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-skip 'OpenSSL too old', 1 if defined $1 and $1 lt '1.1.0';
+skip 'LibreSSL too old', 1
+	if $t->has_module('LibreSSL')
+	and not $t->has_feature('libressl:3.4.0');
+skip 'OpenSSL too old', 1
+	if $t->has_module('OpenSSL')
+	and not $t->has_feature('openssl:1.1.0');
 
 TODO: {
 local $TODO = 'not yet' unless $t->has_version('1.21.4');
--- a/mail_ssl_conf_command.t
+++ b/mail_ssl_conf_command.t
@@ -32,11 +32,9 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay not installed') if $@;
 
-my $t = Test::Nginx->new()->has(qw/mail mail_ssl imap/)
+my $t = Test::Nginx->new()->has(qw/mail mail_ssl imap openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
 plan(skip_all => 'no ssl_conf_command') if $t->has_module('BoringSSL');
 
 $t->write_file_expand('nginx.conf', <<'EOF');
--- a/proxy_ssl_conf_command.t
+++ b/proxy_ssl_conf_command.t
@@ -22,11 +22,10 @@ use Test::Nginx;
 select STDERR; $| = 1;
 select STDOUT; $| = 1;
 
-my $t = Test::Nginx->new()->has(qw/http http_ssl proxy uwsgi http_v2 grpc/)
+my $t = Test::Nginx->new()
+	->has(qw/http http_ssl proxy uwsgi http_v2 grpc openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
 plan(skip_all => 'no ssl_conf_command') if $t->has_module('BoringSSL');
 
 $t->write_file_expand('nginx.conf', <<'EOF');
--- a/ssl_certificate.t
+++ b/ssl_certificate.t
@@ -39,12 +39,9 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@;
 
-my $t = Test::Nginx->new()->has(qw/http http_ssl geo/)
+my $t = Test::Nginx->new()->has(qw/http http_ssl geo openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
-
 $t->write_file_expand('nginx.conf', <<'EOF');
 
 %%TEST_GLOBALS%%
--- a/ssl_certificate_perl.t
+++ b/ssl_certificate_perl.t
@@ -37,10 +37,9 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@;
 
-my $t = Test::Nginx->new()->has(qw/http http_ssl perl/)->has_daemon('openssl');
-
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
+my $t = Test::Nginx->new()
+	->has(qw/http http_ssl perl openssl:1.0.2/)
+	->has_daemon('openssl');
 
 $t->write_file_expand('nginx.conf', <<'EOF');
 
--- a/ssl_conf_command.t
+++ b/ssl_conf_command.t
@@ -30,11 +30,9 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay not installed') if $@;
 
-my $t = Test::Nginx->new()->has(qw/http http_ssl/)
+my $t = Test::Nginx->new()->has(qw/http http_ssl openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
 plan(skip_all => 'no ssl_conf_command') if $t->has_module('BoringSSL');
 
 $t->write_file_expand('nginx.conf', <<'EOF');
--- a/ssl_curve.t
+++ b/ssl_curve.t
@@ -22,12 +22,10 @@ use Test::Nginx;
 select STDERR; $| = 1;
 select STDOUT; $| = 1;
 
-my $t = Test::Nginx->new()->has(qw/http http_ssl rewrite socket_ssl/)
+my $t = Test::Nginx->new()
+	->has(qw/http http_ssl rewrite socket_ssl openssl:3.0.0/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL (\d+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 >= 3;
-
 $t->write_file_expand('nginx.conf', <<'EOF');
 
 %%TEST_GLOBALS%%
--- a/stream_proxy_ssl_conf_command.t
+++ b/stream_proxy_ssl_conf_command.t
@@ -22,11 +22,10 @@ use Test::Nginx;
 select STDERR; $| = 1;
 select STDOUT; $| = 1;
 
-my $t = Test::Nginx->new()->has(qw/stream stream_ssl http http_ssl/)
+my $t = Test::Nginx->new()
+	->has(qw/stream stream_ssl http http_ssl openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
 plan(skip_all => 'no ssl_conf_command') if $t->has_module('BoringSSL');
 
 $t->write_file_expand('nginx.conf', <<'EOF');
--- a/stream_ssl_alpn.t
+++ b/stream_ssl_alpn.t
@@ -81,10 +81,12 @@ is(get_ssl('wrong', 'second'), 'X second
 is(get_ssl(), 'X  X', 'no alpn');
 
 SKIP: {
-$t->{_configure_args} =~ /LibreSSL ([\d\.]+)/;
-skip 'LibreSSL too old', 2 if defined $1 and $1 lt '3.4.0';
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-skip 'OpenSSL too old', 2 if defined $1 and $1 lt '1.1.0';
+skip 'LibreSSL too old', 2
+	if $t->has_module('LibreSSL')
+	and not $t->has_feature('libressl:3.4.0');
+skip 'OpenSSL too old', 2
+	if $t->has_module('OpenSSL')
+	and not $t->has_feature('openssl:1.1.0');
 
 ok(!get_ssl('wrong'), 'alpn mismatch');
 
--- a/stream_ssl_certificate.t
+++ b/stream_ssl_certificate.t
@@ -37,13 +37,10 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@;
 
-my $t = Test::Nginx->new()->has(qw/stream stream_ssl stream_geo stream_return/)
-	->has_daemon('openssl');
-
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
-
-$t->write_file_expand('nginx.conf', <<'EOF');
+my $t = Test::Nginx->new()
+	->has(qw/stream stream_ssl stream_geo stream_return openssl:1.0.2/)
+	->has_daemon('openssl')
+	->write_file_expand('nginx.conf', <<'EOF');
 
 %%TEST_GLOBALS%%
 
--- a/stream_ssl_conf_command.t
+++ b/stream_ssl_conf_command.t
@@ -30,11 +30,10 @@ eval {
 };
 plan(skip_all => 'Net::SSLeay not installed') if $@;
 
-my $t = Test::Nginx->new()->has(qw/stream stream_ssl stream_return/)
+my $t = Test::Nginx->new()
+	->has(qw/stream stream_ssl stream_return openssl:1.0.2/)
 	->has_daemon('openssl');
 
-$t->{_configure_args} =~ /OpenSSL ([\d\.]+)/;
-plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2';
 plan(skip_all => 'no ssl_conf_command') if $t->has_module('BoringSSL');
 
 $t->write_file_expand('nginx.conf', <<'EOF');