diff --git a/.perltidyrc b/.perltidyrc index 386fbaa93..7cbdc6eb5 100644 --- a/.perltidyrc +++ b/.perltidyrc @@ -1,17 +1,21 @@ --ole=unix --se --bext=~ --l=120 +# Locked defaults -i=4 -ci=2 -nsbl -cti=0 --pt=0 -sbt=1 -bt=1 -bbt=0 -sfs --tso --csc --csci=20 --nbbc + +# Local policy +-conv # Iterate application of perltidy profile to come closer to idempotency +-se # Print errors to stderr instead of a file +-ole=unix # Standardize on LF line endings +-bext=~ # Use ~ as backup extension instead of .bak +-l=120 # Modern line length +-pt=0 # Put whitespace inside parentheses +-tso # Format things like 0+ and +0 without space in between +-csc -csci=20 # Add closing comments to blocks of at least 20 lines +-nbbc # Prevent automatic blank lines before comments +-wtc=m -atc -dtc # Add trailing commas to multi-line lists, and remove them from single-line lists diff --git a/lib/Zonemaster/Engine.pm b/lib/Zonemaster/Engine.pm index 003e557d4..feaa68502 100644 --- a/lib/Zonemaster/Engine.pm +++ b/lib/Zonemaster/Engine.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v9.0.1"); +use version; our $VERSION = version->declare( "v9.0.1" ); BEGIN { # Locale::TextDomain (<= 1.20) doesn't know about File::ShareDir so give a helping hand. @@ -30,6 +30,7 @@ our $logger; our $recursor = Zonemaster::Engine::Recursor->new; my $init_done; + sub init_engine { return if $init_done++; Zonemaster::Engine::Recursor::init_recursor(); @@ -128,7 +129,7 @@ sub add_fake_delegation { or croak 'Each key of argument $href must omit the trailing dot, or it must be a single dot'; ( !defined $href->{$name} or ref $href->{$name} eq 'ARRAY' ) or croak 'Each value of argument $href must be an arrayref or undef'; - $href->{$name} //= []; # normalize undef to empty arrayref + $href->{$name} //= []; # normalize undef to empty arrayref } # Check fake delegation @@ -171,7 +172,7 @@ sub add_fake_delegation { return; } return 1; -} +} ## end sub add_fake_delegation sub add_fake_ds { my ( $class, $domain, $aref ) = @_; diff --git a/lib/Zonemaster/Engine/ASNLookup.pm b/lib/Zonemaster/Engine/ASNLookup.pm index 94dcc2b7f..6235d5ee6 100644 --- a/lib/Zonemaster/Engine/ASNLookup.pm +++ b/lib/Zonemaster/Engine/ASNLookup.pm @@ -24,7 +24,7 @@ sub get_with_prefix { if ( not @db_sources ) { $db_style = Zonemaster::Engine::Profile->effective->get( q{asn_db.style} ); my %db_sources = %{ Zonemaster::Engine::Profile->effective->get( q{asn_db.sources} ) }; - @db_sources = map { name( $_ ) } @{ $db_sources{ $db_style } }; + @db_sources = map { name( $_ ) } @{ $db_sources{$db_style} }; } if ( not ref( $ip ) or not $ip->isa( 'Net::IP::XS' ) ) { @@ -38,10 +38,10 @@ sub get_with_prefix { my ( $asnref, $prefix, $raw, $ret_code ); if ( $db_style eq q{cymru} ) { - ( $asnref, $prefix, $raw, $ret_code ) = _cymru_asn_lookup($ip); + ( $asnref, $prefix, $raw, $ret_code ) = _cymru_asn_lookup( $ip ); } elsif ( $db_style eq q{ripe} ) { - ( $asnref, $prefix, $raw, $ret_code ) = _ripe_asn_lookup($ip); + ( $asnref, $prefix, $raw, $ret_code ) = _ripe_asn_lookup( $ip ); } else { if ( not $db_style ) { @@ -59,15 +59,15 @@ sub get_with_prefix { } ## end sub get_with_prefix sub _cymru_asn_lookup { - my $ip = shift; + my $ip = shift; my @asns = (); my $db_source_nb = 0; foreach my $db_source ( @db_sources ) { Zonemaster::Engine->logger->add( ASN_LOOKUP_SOURCE => { name => $db_source } ); my $reverse = $ip->reverse_ip; - my $domain = $db_source->string; - my $pair = { + my $domain = $db_source->string; + my $pair = { 'in-addr.arpa.' => "origin.$domain", 'ip6.arpa.' => "origin6.$domain", }; @@ -79,7 +79,10 @@ sub _cymru_asn_lookup { if ( $p ) { if ( $p->rcode eq q{NXDOMAIN} ) { - if ( $p->get_records( 'SOA', 'authority' ) and scalar $p->get_records( 'SOA', 'authority' ) == 1 and ($p->get_records( 'SOA', 'authority' ))[0]->owner eq name( $db_source ) ) { + if ( $p->get_records( 'SOA', 'authority' ) + and scalar $p->get_records( 'SOA', 'authority' ) == 1 + and ( $p->get_records( 'SOA', 'authority' ) )[0]->owner eq name( $db_source ) ) + { return \@asns, undef, q{}, q{EMPTY_ASN_SET}; } } @@ -93,75 +96,78 @@ sub _cymru_asn_lookup { my $str; foreach my $rr ( @rr ) { - my $_str = $rr->txtdata; + my $_str = $rr->txtdata; my @_fields = split( /[ ][|][ ]?/x, $_str ); next if scalar @_fields <= 1; - return \@asns, undef, q{}, q{ERROR_ASN_DATABASE} unless Net::IP::XS->new( $_fields[1] )->overlaps( $ip ); + return \@asns, undef, q{}, q{ERROR_ASN_DATABASE} + unless Net::IP::XS->new( $_fields[1] )->overlaps( $ip ); - my @_asns = split( /\s+/x, $_fields[0] ); - my $_prefix_length = ($_fields[1] =~ m!^.*[/](.*)!x)[0]; + my @_asns = split( /\s+/x, $_fields[0] ); + my $_prefix_length = ( $_fields[1] =~ m!^.*[/](.*)!x )[0]; if ( $_prefix_length > $max_length ) { - $str = $_str; - @asns = @_asns; - @fields = @_fields; + $str = $_str; + @asns = @_asns; + @fields = @_fields; $max_length = $_prefix_length; } } if ( @fields ) { if ( Net::IP::XS->new( $fields[1] )->overlaps( $ip ) ) { - return \@asns, Net::IP::XS->new( $fields[1] ), $str, q{AS_FOUND} + return \@asns, Net::IP::XS->new( $fields[1] ), $str, q{AS_FOUND}; } } else { return \@asns, undef, q{}, q{EMPTY_ASN_SET}; } - } + } ## end if ( @rr ) return \@asns, undef, q{}, q{ERROR_ASN_DATABASE}; - } + } ## end if ( $p->answer ) return \@asns, undef, q{}, q{EMPTY_ASN_SET}; - } - } + } ## end elsif ( $p->rcode eq q{NOERROR}) + } ## end if ( $p ) if ( $db_source_nb == scalar @db_sources ) { return \@asns, undef, q{}, q{ERROR_ASN_DATABASE}; } last; - } - } - } ## end foreach my $db_source ( @db_sources ) + } ## end if ( $reverse =~ s/$root/$pair->{$root}/ix) + } ## end foreach my $root ( keys %{$pair...}) + } ## end foreach my $db_source ( @db_sources) return; -} +} ## end sub _cymru_asn_lookup sub _ripe_asn_lookup { - my $ip = shift; + my $ip = shift; my @asns = (); my $db_source_nb = 0; foreach my $db_source ( @db_sources ) { $db_source_nb++; - my $socket = IO::Socket::INET->new( PeerAddr => $db_source->string, - PeerPort => q{43}, - Proto => q{tcp} ); - unless ( $socket ) { + my $socket = IO::Socket::INET->new( + PeerAddr => $db_source->string, + PeerPort => q{43}, + Proto => q{tcp}, + ); + unless ( $socket ) { if ( $db_source_nb == scalar @db_sources ) { return \@asns, undef, q{}, q{ERROR_ASN_DATABASE}; } else { next; } - }; + } printf $socket "-F -M %s\n", $ip->short(); my $data; my $str; my $has_answer = 0; - while ( defined ($data = <$socket>) ) { + while ( defined( $data = <$socket> ) ) { $has_answer = 1; chop $data; if ( $data !~ /^%/x and $data !~ /^\s*$/x ) { @@ -178,17 +184,17 @@ sub _ripe_asn_lookup { next; } } - elsif ( $str ) { + elsif ( $str ) { my @fields = split( /\s+/x, $str ); - my @asns = split( '/', $fields[0] ); + my @asns = split( '/', $fields[0] ); return \@asns, Net::IP::XS->new( $fields[1] ), $str, q{AS_FOUND}; } else { return \@asns, undef, q{}, q{EMPTY_ASN_SET}; } - } ## end foreach my $db_source ( @ + } ## end foreach my $db_source ( @db_sources) return; -} +} ## end sub _ripe_asn_lookup sub get { my ( $class, $ip ) = @_; diff --git a/lib/Zonemaster/Engine/Constants.pm b/lib/Zonemaster/Engine/Constants.pm index 1cdccfeaa..a954389cd 100644 --- a/lib/Zonemaster/Engine/Constants.pm +++ b/lib/Zonemaster/Engine/Constants.pm @@ -3,10 +3,10 @@ package Zonemaster::Engine::Constants; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.2.5"); +use version; our $VERSION = version->declare( "v1.2.5" ); use Carp; -use English qw( -no_match_vars ) ; +use English qw( -no_match_vars ); use parent 'Exporter'; use Net::IP::XS; use Text::CSV; @@ -100,14 +100,15 @@ our %EXPORT_TAGS = ( algo => [ qw($ALGO_STATUS_DEPRECATED $ALGO_STATUS_PRIVATE $ALGO_STATUS_RESERVED $ALGO_STATUS_UNASSIGNED $ALGO_STATUS_OTHER $ALGO_STATUS_NOT_ZONE_SIGN $ALGO_STATUS_NOT_RECOMMENDED) ], - cname => [ qw($CNAME_MAX_CHAIN_LENGTH $CNAME_MAX_RECORDS) ], - name => [qw($FQDN_MAX_LENGTH $LABEL_MAX_LENGTH)], - ip => [qw($IP_VERSION_4 $IP_VERSION_6)], - soa => [ + cname => [qw($CNAME_MAX_CHAIN_LENGTH $CNAME_MAX_RECORDS)], + name => [qw($FQDN_MAX_LENGTH $LABEL_MAX_LENGTH)], + ip => [qw($IP_VERSION_4 $IP_VERSION_6)], + soa => [ qw($DURATION_5_MINUTES_IN_SECONDS $DURATION_1_HOUR_IN_SECONDS $DURATION_4_HOURS_IN_SECONDS $DURATION_12_HOURS_IN_SECONDS $DURATION_1_DAY_IN_SECONDS $DURATION_1_WEEK_IN_SECONDS $DURATION_180_DAYS_IN_SECONDS $SERIAL_BITS $SERIAL_MAX_VARIATION) ], - misc => [qw($UDP_PAYLOAD_LIMIT $EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT $EDNS_UDP_PAYLOAD_DEFAULT $EDNS_UDP_PAYLOAD_COMMON_LIMIT $MINIMUM_NUMBER_OF_NAMESERVERS $BLACKLISTING_ENABLED)] - , # everything in %EXPORT_OK that isn't included in any of the other tags + misc => [ + qw($UDP_PAYLOAD_LIMIT $EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT $EDNS_UDP_PAYLOAD_DEFAULT $EDNS_UDP_PAYLOAD_COMMON_LIMIT $MINIMUM_NUMBER_OF_NAMESERVERS $BLACKLISTING_ENABLED) + ], # everything in %EXPORT_OK that isn't included in any of the other tags addresses => [qw(@IPV4_SPECIAL_ADDRESSES @IPV6_SPECIAL_ADDRESSES)], ); @@ -199,18 +200,18 @@ Readonly our $ALGO_STATUS_OTHER => 5; Readonly our $ALGO_STATUS_NOT_ZONE_SIGN => 8; Readonly our $ALGO_STATUS_NOT_RECOMMENDED => 9; -Readonly our $BLACKLISTING_ENABLED => 1; +Readonly our $BLACKLISTING_ENABLED => 1; -Readonly our $CNAME_MAX_CHAIN_LENGTH => 10; -Readonly our $CNAME_MAX_RECORDS => 9; +Readonly our $CNAME_MAX_CHAIN_LENGTH => 10; +Readonly our $CNAME_MAX_RECORDS => 9; -Readonly our $DURATION_5_MINUTES_IN_SECONDS => 5 * 60; -Readonly our $DURATION_1_HOUR_IN_SECONDS => 60 * 60; -Readonly our $DURATION_4_HOURS_IN_SECONDS => 4 * 60 * 60; -Readonly our $DURATION_12_HOURS_IN_SECONDS => 12 * 60 * 60; -Readonly our $DURATION_1_DAY_IN_SECONDS => 24 * 60 * 60; -Readonly our $DURATION_1_WEEK_IN_SECONDS => 7 * 24 * 60 * 60; -Readonly our $DURATION_180_DAYS_IN_SECONDS => 180 * 24 * 60 * 60; +Readonly our $DURATION_5_MINUTES_IN_SECONDS => 5 * 60; +Readonly our $DURATION_1_HOUR_IN_SECONDS => 60 * 60; +Readonly our $DURATION_4_HOURS_IN_SECONDS => 4 * 60 * 60; +Readonly our $DURATION_12_HOURS_IN_SECONDS => 12 * 60 * 60; +Readonly our $DURATION_1_DAY_IN_SECONDS => 24 * 60 * 60; +Readonly our $DURATION_1_WEEK_IN_SECONDS => 7 * 24 * 60 * 60; +Readonly our $DURATION_180_DAYS_IN_SECONDS => 180 * 24 * 60 * 60; # Maximum length of ASCII version of a domain name, with trailing dot. Readonly our $FQDN_MAX_LENGTH => 254; @@ -221,7 +222,7 @@ Readonly our $IP_VERSION_6 => 6; Readonly our $MINIMUM_NUMBER_OF_NAMESERVERS => 2; -Readonly our $SERIAL_BITS => 32; +Readonly our $SERIAL_BITS => 32; Readonly our $SERIAL_MAX_VARIATION => 0; Readonly our $UDP_PAYLOAD_LIMIT => 512; @@ -229,8 +230,8 @@ Readonly our $EDNS_UDP_PAYLOAD_DEFAULT => 512; Readonly our $EDNS_UDP_PAYLOAD_COMMON_LIMIT => 4096; Readonly our $EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT => 1232; -Readonly::Array our @IPV4_SPECIAL_ADDRESSES => _extract_iana_ip_blocks($IP_VERSION_4); -Readonly::Array our @IPV6_SPECIAL_ADDRESSES => _extract_iana_ip_blocks($IP_VERSION_6); +Readonly::Array our @IPV4_SPECIAL_ADDRESSES => _extract_iana_ip_blocks( $IP_VERSION_4 ); +Readonly::Array our @IPV6_SPECIAL_ADDRESSES => _extract_iana_ip_blocks( $IP_VERSION_6 ); =head1 METHODS @@ -253,13 +254,15 @@ and C (string). sub _extract_iana_ip_blocks { my $ip_version = shift; - my @list = (); + my @list = (); - my $csv = Text::CSV->new ({ - binary => 1, - auto_diag => 1, - sep_char => q{,} - }); + my $csv = Text::CSV->new( + { + binary => 1, + auto_diag => 1, + sep_char => q{,}, + } + ); my @files_details = ( { name => q{iana-ipv4-special-registry.csv}, ip_version => $IP_VERSION_4 }, { name => q{iana-ipv6-special-registry.csv}, ip_version => $IP_VERSION_6 }, @@ -268,10 +271,10 @@ sub _extract_iana_ip_blocks { foreach my $file_details ( @files_details ) { my $first_line = 1; next if ${$file_details}{ip_version} != $ip_version; - my $makefile_name = 'Zonemaster-Engine'; # This must be the same name as "name" in Makefile.PL - my $data_location = dist_file($makefile_name, ${$file_details}{name}); - open(my $data, '<:encoding(utf8)', $data_location) or croak "Cannot open '${data_location}' : ${OS_ERROR}"; - while (my $fields = $csv->getline( $data )) { + my $makefile_name = 'Zonemaster-Engine'; # This must be the same name as "name" in Makefile.PL + my $data_location = dist_file( $makefile_name, ${$file_details}{name} ); + open( my $data, '<:encoding(utf8)', $data_location ) or croak "Cannot open '${data_location}' : ${OS_ERROR}"; + while ( my $fields = $csv->getline( $data ) ) { if ( $first_line ) { $first_line = 0; next; @@ -280,11 +283,17 @@ sub _extract_iana_ip_blocks { $address_data =~ s/[ ]+//smx; foreach my $address_item ( split /,/smx, $address_data ) { $address_item =~ s/(\A.+\/\d+).*\z/$1/smx; - push @list, { ip => Net::IP::XS->new( $address_item ), name => $fields->[1], reference => $fields->[2], globally_reachable => $fields->[8] }; + push @list, + { + ip => Net::IP::XS->new( $address_item ), + name => $fields->[1], + reference => $fields->[2], + globally_reachable => $fields->[8], + }; } } close $data or croak "Cannot close '${data_location}' : ${OS_ERROR}"; - } + } ## end foreach my $file_details ( ...) return @list; } ## end sub _extract_iana_ip_blocks diff --git a/lib/Zonemaster/Engine/DNSName.pm b/lib/Zonemaster/Engine/DNSName.pm index 4aa7d4cb1..731b53378 100644 --- a/lib/Zonemaster/Engine/DNSName.pm +++ b/lib/Zonemaster/Engine/DNSName.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::DNSName; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.3"); +use version; our $VERSION = version->declare( "v1.0.3" ); use Carp; use Scalar::Util qw( blessed ); @@ -69,7 +69,7 @@ sub new { } return Class::Accessor::new( $class, $attrs ); -} +} ## end sub new sub string { my $self = shift; @@ -94,7 +94,7 @@ sub str_cmp { # For performance reasons, we do not unpack @_. # As a reminder, the calling convention is my ( $self, $other, $swap ) = @_. - my $me = uc ( $_[0]->{_string} // $_[0]->string ); + my $me = uc( $_[0]->{_string} // $_[0]->string ); # Treat undefined value as root my $other = $_[1] // q{}; @@ -110,14 +110,14 @@ sub str_cmp { }; return $_[2] ? -$comparison : $comparison; -} +} ## end sub str_cmp sub next_higher { my $self = shift; my @l = @{ $self->labels }; if ( @l ) { shift @l; - return Zonemaster::Engine::DNSName->new({ labels => \@l }); + return Zonemaster::Engine::DNSName->new( { labels => \@l } ); } else { return; diff --git a/lib/Zonemaster/Engine/Exception.pm b/lib/Zonemaster/Engine/Exception.pm index 17f8fdab2..23bb897ec 100644 --- a/lib/Zonemaster/Engine/Exception.pm +++ b/lib/Zonemaster/Engine/Exception.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::Exception; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.3"); +use version; our $VERSION = version->declare( "v1.0.3" ); use Class::Accessor "antlers"; diff --git a/lib/Zonemaster/Engine/Logger.pm b/lib/Zonemaster/Engine/Logger.pm index 70b68ed13..c47435279 100644 --- a/lib/Zonemaster/Engine/Logger.pm +++ b/lib/Zonemaster/Engine/Logger.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::Logger; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.8"); +use version; our $VERSION = version->declare( "v1.0.8" ); use Class::Accessor "antlers"; @@ -11,12 +11,12 @@ use Carp qw( confess ); use Data::Dumper; use JSON::PP; use List::MoreUtils qw[none any]; -use Scalar::Util qw[blessed]; +use Scalar::Util qw[blessed]; use Zonemaster::Engine::Profile; use Zonemaster::Engine::Logger::Entry; our $TEST_CASE_NAME = 'Unspecified'; -our $MODULE_NAME = 'System'; +our $MODULE_NAME = 'System'; has 'entries' => ( is => 'ro', @@ -41,11 +41,12 @@ sub new { sub add { my ( $self, $tag, $argref, $module, $testcase ) = @_; - $module //= $MODULE_NAME; + $module //= $MODULE_NAME; $testcase //= $TEST_CASE_NAME; my $new = - Zonemaster::Engine::Logger::Entry->new( { tag => uc( $tag ), args => $argref, testcase => $testcase, module => $module } ); + Zonemaster::Engine::Logger::Entry->new( + { tag => uc( $tag ), args => $argref, testcase => $testcase, module => $module } ); $self->_check_filter( $new ); push @{ $self->entries }, $new; @@ -69,20 +70,21 @@ sub add { sub _check_filter { my ( $self, $entry ) = @_; - if ( ! defined $logfilter ) { - $logfilter = Zonemaster::Engine::Profile->effective->get(q{logfilter}); + if ( !defined $logfilter ) { + $logfilter = Zonemaster::Engine::Profile->effective->get( q{logfilter} ); } if ( $logfilter ) { if ( $logfilter->{ uc $entry->module } ) { my $match = 0; - foreach my $rule ( @{$logfilter->{ uc $entry->module }{ $entry->tag }} ) { + foreach my $rule ( @{ $logfilter->{ uc $entry->module }{ $entry->tag } } ) { foreach my $key ( keys %{ $rule->{when} } ) { my $cond = $rule->{when}{$key}; if ( ref( $cond ) and ref( $cond ) eq 'ARRAY' ) { if ( any { $_ eq $entry->args->{$key} } @$cond ) { $match = 1; - } else { + } + else { $match = 0; last; } @@ -90,19 +92,20 @@ sub _check_filter { else { if ( $cond eq $entry->args->{$key} ) { $match = 1; - } else { + } + else { $match = 0; last; } } - } + } ## end foreach my $key ( keys %{ $rule...}) if ( $match ) { $entry->_set_level( $rule->{set} ); last; } - } - } - } + } ## end foreach my $rule ( @{ $logfilter...}) + } ## end if ( $logfilter->{ uc ...}) + } ## end if ( $logfilter ) return; } ## end sub _check_filter diff --git a/lib/Zonemaster/Engine/Logger/Entry.pm b/lib/Zonemaster/Engine/Logger/Entry.pm index cb2935301..ec9bc6e68 100644 --- a/lib/Zonemaster/Engine/Logger/Entry.pm +++ b/lib/Zonemaster/Engine/Logger/Entry.pm @@ -3,9 +3,9 @@ package Zonemaster::Engine::Logger::Entry; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.1.8"); +use version; our $VERSION = version->declare( "v1.1.8" ); -use Carp qw( confess ); +use Carp qw( confess ); use Time::HiRes qw[time]; use JSON::PP; use Class::Accessor; @@ -32,8 +32,7 @@ our $start_time = time(); my $json = JSON::PP->new->allow_blessed->convert_blessed->canonical; my $test_levels_config; -__PACKAGE__->mk_ro_accessors(qw(tag args timestamp testcase module)); - +__PACKAGE__->mk_ro_accessors( qw(tag args timestamp testcase module) ); sub new { my ( $proto, $attrs ) = @_; @@ -61,7 +60,7 @@ sub new { my $class = ref $proto || $proto; return Class::Accessor::new( $class, $attrs ); -} +} ## end sub new sub level { my $self = shift; @@ -71,7 +70,7 @@ sub level { $self->{_level} = $self->_build_level(); } - return $self->{_level} + return $self->{_level}; } sub _build_level { @@ -95,15 +94,14 @@ sub _build_level { else { die "Unknown level string: $string"; } -} +} ## end sub _build_level sub _set_level { my ( $self, $level ) = @_; - $self->{_level} = $level + $self->{_level} = $level; } - sub numeric_level { my ( $self ) = @_; @@ -117,7 +115,8 @@ sub levels { sub string { my ( $self ) = @_; - return sprintf( '%s%s:%s %s', $self->module, $self->testcase ? q{:} . $self->testcase : q{}, $self->tag, $self->argstr ); + return + sprintf( '%s%s:%s %s', $self->module, $self->testcase ? q{:} . $self->testcase : q{}, $self->tag, $self->argstr ); } sub argstr { @@ -131,7 +130,7 @@ sub argstr { my $p_args = $self->printable_args; $argstr = join( q{; }, map { $_ . q{=} . ( ref( $p_args->{$_} ) ? $json->encode( $p_args->{$_} ) : $p_args->{$_} ) } - sort keys %{$p_args} ); + sort keys %{$p_args}, ); } return $argstr; diff --git a/lib/Zonemaster/Engine/NSArray.pm b/lib/Zonemaster/Engine/NSArray.pm index d2f9e4611..c6933530a 100644 --- a/lib/Zonemaster/Engine/NSArray.pm +++ b/lib/Zonemaster/Engine/NSArray.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::NSArray; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.3"); +use version; our $VERSION = version->declare( "v1.0.3" ); use Carp qw( confess croak ); use Zonemaster::Engine::Recursor; @@ -12,7 +12,7 @@ use Zonemaster::Engine::Nameserver; use Class::Accessor 'antlers'; has 'names' => ( is => 'ro', isa => 'ArrayRef', required => 1 ); -has 'ary' => ( is => 'ro', isa => 'ArrayRef', default => sub { [] } ); +has 'ary' => ( is => 'ro', isa => 'ArrayRef', default => sub { [] } ); sub TIEARRAY { my ( $class, @names ) = @_; @@ -20,7 +20,7 @@ sub TIEARRAY { return $class->new( { ary => [], - names => [ sort { $a cmp $b } @names ] + names => [ sort { $a cmp $b } @names ], } ); } diff --git a/lib/Zonemaster/Engine/Nameserver/Cache.pm b/lib/Zonemaster/Engine/Nameserver/Cache.pm index 5b4ef5a9c..28dce1929 100644 --- a/lib/Zonemaster/Engine/Nameserver/Cache.pm +++ b/lib/Zonemaster/Engine/Nameserver/Cache.pm @@ -3,13 +3,13 @@ package Zonemaster::Engine::Nameserver::Cache; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.4"); +use version; our $VERSION = version->declare( "v1.0.4" ); use Class::Accessor "antlers"; our %object_cache; -has 'data' => ( is => 'ro' ); +has 'data' => ( is => 'ro' ); has 'address' => ( is => 'ro' ); sub get_cache_type { @@ -30,7 +30,7 @@ sub get_cache_class { my $cache_class = "Zonemaster::Engine::Nameserver::Cache::$cache_type"; - require ( "$cache_class.pm" =~ s{::}{/}gr ); + require( "$cache_class.pm" =~ s{::}{/}gr ); $cache_class->import(); return $cache_class; diff --git a/lib/Zonemaster/Engine/Nameserver/Cache/LocalCache.pm b/lib/Zonemaster/Engine/Nameserver/Cache/LocalCache.pm index aa0e23497..b484aaa32 100644 --- a/lib/Zonemaster/Engine/Nameserver/Cache/LocalCache.pm +++ b/lib/Zonemaster/Engine/Nameserver/Cache/LocalCache.pm @@ -3,9 +3,9 @@ package Zonemaster::Engine::Nameserver::Cache::LocalCache; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.4"); +use version; our $VERSION = version->declare( "v1.0.4" ); -use Carp qw( confess ); +use Carp qw( confess ); use Scalar::Util qw( blessed ); use Zonemaster::Engine; @@ -21,38 +21,38 @@ sub new { my $attrs = shift; confess "Attribute \(address\) is required" - if !exists $attrs->{address}; + if !exists $attrs->{address}; # Type coercions $attrs->{address} = Net::IP::XS->new( $attrs->{address} ) - if !blessed $attrs->{address} || !$attrs->{address}->isa( 'Net::IP::XS' ); + if !blessed $attrs->{address} || !$attrs->{address}->isa( 'Net::IP::XS' ); # Type constraint confess "Argument must be coercible into a Net::IP::XS: address" - if !$attrs->{address}->isa( 'Net::IP::XS' ); + if !$attrs->{address}->isa( 'Net::IP::XS' ); confess "Argument must be a HASHREF: data" - if exists $attrs->{data} && ref $attrs->{data} ne 'HASH'; + if exists $attrs->{data} && ref $attrs->{data} ne 'HASH'; # Default value $attrs->{data} //= {}; my $ip = $attrs->{address}->ip; - if ( exists $object_cache->{ $ip } ) { + if ( exists $object_cache->{$ip} ) { Zonemaster::Engine->logger->add( CACHE_FETCHED => { ip => $ip } ); - return $object_cache->{ $ip }; + return $object_cache->{$ip}; } my $obj = Class::Accessor::new( $class, $attrs ); Zonemaster::Engine->logger->add( CACHE_CREATED => { ip => $ip } ); - $object_cache->{ $ip } = $obj; + $object_cache->{$ip} = $obj; return $obj; -} +} ## end sub new sub set_key { - my ( $self, $idx, $packet ) = @_; - $self->data->{$idx} = $packet; + my ( $self, $idx, $packet ) = @_; + $self->data->{$idx} = $packet; } sub get_key { diff --git a/lib/Zonemaster/Engine/Nameserver/Cache/RedisCache.pm b/lib/Zonemaster/Engine/Nameserver/Cache/RedisCache.pm index 9111f8f02..14d39c05a 100644 --- a/lib/Zonemaster/Engine/Nameserver/Cache/RedisCache.pm +++ b/lib/Zonemaster/Engine/Nameserver/Cache/RedisCache.pm @@ -3,11 +3,11 @@ package Zonemaster::Engine::Nameserver::Cache::RedisCache; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.0"); +use version; our $VERSION = version->declare( "v1.0.0" ); use Class::Accessor "antlers"; use Time::HiRes qw[gettimeofday tv_interval]; -use List::Util qw( min ); +use List::Util qw( min ); use Zonemaster::LDNS::Packet; use Zonemaster::Engine::Packet; @@ -28,39 +28,40 @@ my $redis; my $config; our $object_cache = \%Zonemaster::Engine::Nameserver::Cache::object_cache; -my $REDIS_EXPIRE_DEFAULT = 300; # seconds +my $REDIS_EXPIRE_DEFAULT = 300; # seconds -has 'redis' => ( is => 'ro' ); +has 'redis' => ( is => 'ro' ); has 'config' => ( is => 'ro' ); my $mp = Data::MessagePack->new(); sub new { - my $proto = shift; + my $proto = shift; my $params = shift; $params->{address} = $params->{address}->ip; if ( exists $object_cache->{ $params->{address} } ) { Zonemaster::Engine->logger->add( CACHE_FETCHED => { ip => $params->{address} } ); return $object_cache->{ $params->{address} }; - } else { - if (! defined $redis) { + } + else { + if ( !defined $redis ) { my $redis_config = Zonemaster::Engine::Profile->effective->get( q{cache} )->{'redis'}; - $redis = Redis->new(server => $redis_config->{server}); + $redis = Redis->new( server => $redis_config->{server} ); $config = $redis_config; } - $params->{redis} //= $redis; - $params->{data} //= {}; + $params->{redis} //= $redis; + $params->{data} //= {}; $params->{config} //= $config; $config->{expire} //= $REDIS_EXPIRE_DEFAULT; my $class = ref $proto || $proto; - my $obj = Class::Accessor::new( $class, $params ); + my $obj = Class::Accessor::new( $class, $params ); Zonemaster::Engine->logger->add( CACHE_CREATED => { ip => $params->{address} } ); $object_cache->{ $params->{address} } = $obj; return $obj; } -} +} ## end sub new sub set_key { my ( $self, $hash, $packet ) = @_; @@ -77,19 +78,21 @@ sub set_key { $self->data->{$hash} = $packet; if ( defined $packet ) { - my $msg = $mp->pack({ - data => $packet->data, - answerfrom => $packet->answerfrom, - timestamp => $packet->timestamp, - querytime => $packet->querytime, - }); + my $msg = $mp->pack( + { + data => $packet->data, + answerfrom => $packet->answerfrom, + timestamp => $packet->timestamp, + querytime => $packet->querytime, + } + ); if ( $packet->answer ) { my @rr = $packet->answer; $ttl = min( map { $_->ttl } @rr ); } elsif ( $packet->authority ) { my @rr = $packet->authority; - foreach my $r (@rr) { + foreach my $r ( @rr ) { if ( $r->type eq 'SOA' ) { $ttl = $r->ttl; last; @@ -99,17 +102,19 @@ sub set_key { if ( defined( $ttl ) ) { $ttl = $ttl < $redis_expire ? $ttl : $redis_expire; - } else { + } + else { $ttl = $ttl_no_response; } # Redis requires cache time to be greater than 0 to be stored. return if $ttl == 0; $self->redis->set( $key, $msg, 'EX', $ttl ); - } else { + } ## end if ( defined $packet ) + else { $self->redis->set( $key, '', 'EX', $ttl_no_response ); } -} +} ## end sub set_key sub get_key { my ( $self, $hash ) = @_; @@ -118,15 +123,18 @@ sub get_key { if ( exists $self->data->{$hash} ) { Zonemaster::Engine->logger->add( MEMORY_CACHE_HIT => { hash => $hash } ); return ( 1, $self->data->{$hash} ); - } elsif ( $self->redis->exists($key) ) { - my $fetch_start_time = [ gettimeofday ]; - my $data = $self->redis->get( $key ); + } + elsif ( $self->redis->exists( $key ) ) { + my $fetch_start_time = [gettimeofday]; + my $data = $self->redis->get( $key ); Zonemaster::Engine->logger->add( REDIS_CACHE_HIT => { key => $key } ); - if ( not length($data) ) { + if ( not length( $data ) ) { $self->data->{$hash} = undef; - } else { - my $msg = $mp->unpack( $data ); - my $packet = Zonemaster::Engine::Packet->new({ packet => Zonemaster::LDNS::Packet->new_from_wireformat($msg->{data}) }); + } + else { + my $msg = $mp->unpack( $data ); + my $packet = Zonemaster::Engine::Packet->new( + { packet => Zonemaster::LDNS::Packet->new_from_wireformat( $msg->{data} ) } ); $packet->answerfrom( $msg->{answerfrom} ); $packet->timestamp( $msg->{timestamp} ); $packet->querytime( $msg->{querytime} ); @@ -136,8 +144,8 @@ sub get_key { return ( 1, $self->data->{$hash} ); } Zonemaster::Engine->logger->add( CACHE_MISS => { key => $key } ); - return ( 0, undef ) -} + return ( 0, undef ); +} ## end sub get_key 1; diff --git a/lib/Zonemaster/Engine/NameserverSet.pm b/lib/Zonemaster/Engine/NameserverSet.pm index 57637a025..c852c5285 100644 --- a/lib/Zonemaster/Engine/NameserverSet.pm +++ b/lib/Zonemaster/Engine/NameserverSet.pm @@ -16,9 +16,7 @@ sub new { my ( $proto, @initial_items ) = @_; my $class = ref $proto || $proto; - my $self = { - _names => {}, - }; + my $self = { _names => {} }; bless $self, $class; $self->push( @initial_items ); @@ -37,15 +35,15 @@ sub push { next if not defined $item; next if $item eq ''; - if ( $item->isa('Zonemaster::Engine::DNSName') ) { - if ( not exists $self->{_names}{lc $item} ) { - $self->{_names}{lc $item} = $item; + if ( $item->isa( 'Zonemaster::Engine::DNSName' ) ) { + if ( not exists $self->{_names}{ lc $item } ) { + $self->{_names}{ lc $item } = $item; } } - elsif ( $item->isa('Zonemaster::Engine::Nameserver') ) { + elsif ( $item->isa( 'Zonemaster::Engine::Nameserver' ) ) { my ( $name, $addr ) = ( $item->name, $item->address->short ); - my $r = \$self->{_names}{lc $name}; + my $r = \$self->{_names}{ lc $name }; if ( not defined $$r or ref $$r ne 'HASH' ) { $$r = {}; } @@ -53,14 +51,14 @@ sub push { } else { my $name = Zonemaster::Engine::DNSName->new( "$item" ); - if ( not exists $self->{_names}{lc $name} ) { - $self->{_names}{lc $item} = $name; + if ( not exists $self->{_names}{ lc $name } ) { + $self->{_names}{ lc $item } = $name; } } - } + } ## end for my $item ( @items ) return $self; -} +} ## end sub push #### #### Access to items @@ -165,10 +163,10 @@ sub is_empty { sub difference { my ( $self, $other ) = @_; - my $only_in_left = __PACKAGE__->new(); + my $only_in_left = __PACKAGE__->new(); my $only_in_right = __PACKAGE__->new(); - my @left_items = $self->sorted_items(); + my @left_items = $self->sorted_items(); my @right_items = $other->sorted_items(); while ( @left_items and @right_items ) { @@ -188,12 +186,12 @@ sub difference { $only_in_right->push( @right_items ); return ( $only_in_left, $only_in_right ); -} +} ## end sub difference sub equals { my ( $self, $other ) = @_; - my @left_items = $self->sorted_items(); + my @left_items = $self->sorted_items(); my @right_items = $other->sorted_items(); while ( @left_items and @right_items ) { diff --git a/lib/Zonemaster/Engine/Normalization.pm b/lib/Zonemaster/Engine/Normalization.pm index 9e056b20f..f6620711d 100644 --- a/lib/Zonemaster/Engine/Normalization.pm +++ b/lib/Zonemaster/Engine/Normalization.pm @@ -14,7 +14,6 @@ use Zonemaster::LDNS; use Zonemaster::Engine::Normalization::Error; - =head1 NAME Zonemaster::Engine::Normalization - utility functions for names normalization @@ -31,24 +30,25 @@ Zonemaster::Engine::Normalization - utility functions for names normalization =over =cut +our @EXPORT = qw[ normalize_name ]; +our @EXPORT_OK = qw[ normalize_name normalize_label trim_space ]; -our @EXPORT = qw[ normalize_name ]; -our @EXPORT_OK = qw[ normalize_name normalize_label trim_space ]; - -Readonly my $ASCII => qr/^[[:ascii:]]+$/; +Readonly my $ASCII => qr/^[[:ascii:]]+$/; Readonly my $VALID_ASCII => qr(^[A-Za-z0-9/_-]+$); -Readonly my $ASCII_FULL_STOP => "\x{002E}"; +Readonly my $ASCII_FULL_STOP => "\x{002E}"; Readonly my $ASCII_FULL_STOP_RE => qr/\x{002E}/; Readonly my %FULL_STOPS => ( FULLWIDTH_FULL_STOP => q/\x{FF0E}/, IDEOGRAPHIC_FULL_STOP => q/\x{3002}/, - HALFWIDTH_IDEOGRAPHIC_FULL_STOP => q/\x{FF61}/ + HALFWIDTH_IDEOGRAPHIC_FULL_STOP => q/\x{FF61}/, ); -Readonly my $FULL_STOPS_RE => (sub { - my $re = '[' . (join '', values %FULL_STOPS) . ']'; - return qr/$re/; -})->(); +Readonly my $FULL_STOPS_RE => ( + sub { + my $re = '[' . ( join '', values %FULL_STOPS ) . ']'; + return qr/$re/; + } +)->(); Readonly my %WHITE_SPACES => ( SPACE => q/\x{0020}/, CHARACTER_TABULATION => q/\x{0009}/, @@ -68,15 +68,13 @@ Readonly my %WHITE_SPACES => ( IDEOGRAPHIC_SPACE => q/\x{3000}/, OGHAM_SPACE_MARK => q/\x{1680}/, ); -Readonly my $WHITE_SPACES_RE => (sub { - my $re = '[' . (join '', values %WHITE_SPACES) . ']'; - return qr/$re/; -})->(); -Readonly my %AMBIGUOUS_CHARACTERS => ( - "LATIN CAPITAL LETTER I WITH DOT ABOVE" => q/\x{0130}/, -); - - +Readonly my $WHITE_SPACES_RE => ( + sub { + my $re = '[' . ( join '', values %WHITE_SPACES ) . ']'; + return qr/$re/; + } +)->(); +Readonly my %AMBIGUOUS_CHARACTERS => ( "LATIN CAPITAL LETTER I WITH DOT ABOVE" => q/\x{0130}/ ); =item normalize_label($label) @@ -104,29 +102,34 @@ sub normalize_label { if ( $label =~ $VALID_ASCII ) { $alabel = lc $label; - } elsif ( $label =~ $ASCII ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(INVALID_ASCII => {label => $label}); + } + elsif ( $label =~ $ASCII ) { + push @messages, Zonemaster::Engine::Normalization::Error->new( INVALID_ASCII => { label => $label } ); return \@messages, undef; - } elsif ( Zonemaster::LDNS::has_idn ) { + } + elsif ( Zonemaster::LDNS::has_idn ) { try { - $alabel = Zonemaster::LDNS::to_idn($label); - } catch { - push @messages, Zonemaster::Engine::Normalization::Error->new(INVALID_U_LABEL => {label => $label}); + $alabel = Zonemaster::LDNS::to_idn( $label ); + } + catch { + push @messages, Zonemaster::Engine::Normalization::Error->new( INVALID_U_LABEL => { label => $label } ); return \@messages, undef; } - } else { - croak 'The domain name contains at least one non-ASCII character and this installation of Zonemaster has no support for IDNA.'; + } + else { + croak +'The domain name contains at least one non-ASCII character and this installation of Zonemaster has no support for IDNA.'; } - if ( length($alabel) > 63 ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(LABEL_TOO_LONG => {label => $label}); + if ( length( $alabel ) > 63 ) { + push @messages, Zonemaster::Engine::Normalization::Error->new( LABEL_TOO_LONG => { label => $label } ); return \@messages, undef; } return \@messages, $alabel; -} +} ## end sub normalize_label =item trim_space($str) @@ -162,15 +165,16 @@ sub normalize_name { my ( $uname ) = @_; my @messages; - if ( length($uname) == 0 ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(EMPTY_DOMAIN_NAME => {}); + if ( length( $uname ) == 0 ) { + push @messages, Zonemaster::Engine::Normalization::Error->new( EMPTY_DOMAIN_NAME => {} ); return \@messages, undef; } foreach my $char_name ( keys %AMBIGUOUS_CHARACTERS ) { my $char = $AMBIGUOUS_CHARACTERS{$char_name}; - if ( $uname =~ m/${char}/) { - push @messages, Zonemaster::Engine::Normalization::Error->new(AMBIGUOUS_DOWNCASING => { unicode_name => $char_name }); + if ( $uname =~ m/${char}/ ) { + push @messages, + Zonemaster::Engine::Normalization::Error->new( AMBIGUOUS_DOWNCASING => { unicode_name => $char_name } ); } } @@ -185,20 +189,20 @@ sub normalize_name { } if ( $uname =~ m/^${ASCII_FULL_STOP_RE}/ ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(INITIAL_DOT => {}); + push @messages, Zonemaster::Engine::Normalization::Error->new( INITIAL_DOT => {} ); return \@messages, undef; } if ( $uname =~ m/${ASCII_FULL_STOP_RE}{2,}/ ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(REPEATED_DOTS => {}); + push @messages, Zonemaster::Engine::Normalization::Error->new( REPEATED_DOTS => {} ); return \@messages, undef; } $uname =~ s/${ASCII_FULL_STOP_RE}$//g; - my @labels = split $ASCII_FULL_STOP_RE, $uname; - my @label_results = map { [ normalize_label($_) ] } @labels; - my @label_errors = map { @{$_->[0]} } @label_results; + my @labels = split $ASCII_FULL_STOP_RE, $uname; + my @label_results = map { [ normalize_label( $_ ) ] } @labels; + my @label_errors = map { @{ $_->[0] } } @label_results; push @messages, @label_errors; @@ -210,14 +214,13 @@ sub normalize_name { my $final_name = join '.', @label_ok; - if ( length($final_name) > 253 ) { - push @messages, Zonemaster::Engine::Normalization::Error->new(DOMAIN_NAME_TOO_LONG => {}); + if ( length( $final_name ) > 253 ) { + push @messages, Zonemaster::Engine::Normalization::Error->new( DOMAIN_NAME_TOO_LONG => {} ); return \@messages, undef; } return \@messages, $final_name; -} - +} ## end sub normalize_name =back =cut diff --git a/lib/Zonemaster/Engine/Normalization/Error.pm b/lib/Zonemaster/Engine/Normalization/Error.pm index 2f8abbae2..b2aa26d06 100644 --- a/lib/Zonemaster/Engine/Normalization/Error.pm +++ b/lib/Zonemaster/Engine/Normalization/Error.pm @@ -9,7 +9,6 @@ use Locale::TextDomain qw[Zonemaster-Engine]; use overload '""' => \&string; - =head1 NAME Zonemaster::Engine::Normalization::Error - normalization error class @@ -23,11 +22,11 @@ Zonemaster::Engine::Normalization::Error - normalization error class =cut - Readonly my %ERRORS => ( AMBIGUOUS_DOWNCASING => { - message => N__ 'Ambiguous downcasing of character "{unicode_name}" in the domain name. Use all lower case instead.', - arguments => [ 'unicode_name' ] + message => N__ + 'Ambiguous downcasing of character "{unicode_name}" in the domain name. Use all lower case instead.', + arguments => ['unicode_name'], }, DOMAIN_NAME_TOO_LONG => { message => N__ 'Domain name is too long (more than 253 characters with no final dot).', @@ -39,19 +38,19 @@ Readonly my %ERRORS => ( message => N__ 'Domain name starts with dot.' }, INVALID_ASCII => { - message => N__ 'Domain name has an ASCII label ("{label}") with a character not permitted.', - arguments => [ 'label' ] + message => N__ 'Domain name has an ASCII label ("{label}") with a character not permitted.', + arguments => ['label'], }, INVALID_U_LABEL => { - message => N__ 'Domain name has a non-ASCII label ("{label}") which is not a valid U-label.', - arguments => [ 'label' ] + message => N__ 'Domain name has a non-ASCII label ("{label}") which is not a valid U-label.', + arguments => ['label'], }, REPEATED_DOTS => { message => N__ 'Domain name has repeated dots.' }, LABEL_TOO_LONG => { - message => N__ 'Domain name has a label that is too long (more than 63 characters), "{label}".', - arguments => [ 'label' ] + message => N__ 'Domain name has a label that is too long (more than 63 characters), "{label}".', + arguments => ['label'], }, ); @@ -91,7 +90,7 @@ sub new { my $obj = { tag => $tag, params => {} }; if ( exists $ERRORS{$tag}->{arguments} ) { - foreach my $arg ( @{$ERRORS{$tag}->{arguments}} ) { + foreach my $arg ( @{ $ERRORS{$tag}->{arguments} } ) { if ( !exists $params->{$arg} ) { croak "Missing arguments $arg."; } @@ -100,8 +99,7 @@ sub new { } return bless $obj, $class; -} - +} ## end sub new =item message @@ -111,10 +109,9 @@ Returns the translated error message using the parameters given when creating th sub message { my ( $self ) = @_; - return __x $ERRORS{$self->{tag}}->{message}, %{$self->{params}}; + return __x $ERRORS{ $self->{tag} }->{message}, %{ $self->{params} }; } - =item tag Returns the message tag associated to the error. @@ -139,7 +136,6 @@ sub string { return $self->message; } - =back =cut diff --git a/lib/Zonemaster/Engine/Packet.pm b/lib/Zonemaster/Engine/Packet.pm index 8ee033ea9..20a653bed 100644 --- a/lib/Zonemaster/Engine/Packet.pm +++ b/lib/Zonemaster/Engine/Packet.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::Packet; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.5"); +use version; our $VERSION = version->declare( "v1.0.5" ); use Class::Accessor 'antlers'; use Carp qw( confess ); @@ -61,7 +61,8 @@ sub no_such_record { if ( $self->type eq 'nodata' ) { my ( $q ) = $self->question; - Zonemaster::Engine::Util::info( NO_SUCH_RECORD => { name => Zonemaster::Engine::Util::name( $q->name ), type => $q->type } ); + Zonemaster::Engine::Util::info( + NO_SUCH_RECORD => { name => Zonemaster::Engine::Util::name( $q->name ), type => $q->type } ); return 1; } @@ -94,7 +95,7 @@ sub is_redirect { IS_REDIRECT => { name => Zonemaster::Engine::DNSName->from_string( $q->name ), type => $q->type, - to => Zonemaster::Engine::DNSName->from_string( $a->name ) + to => Zonemaster::Engine::DNSName->from_string( $a->name ), } ); diff --git a/lib/Zonemaster/Engine/Test.pm b/lib/Zonemaster/Engine/Test.pm index de3fc9ac7..1f78cb4fb 100644 --- a/lib/Zonemaster/Engine/Test.pm +++ b/lib/Zonemaster/Engine/Test.pm @@ -19,9 +19,9 @@ use Zonemaster::Engine::Util; use IO::Socket::INET6; # Lazy-loads, so make sure it's here for the version logging use File::ShareDir qw[dist_file]; -use File::Slurp qw[read_file]; -use Scalar::Util qw[blessed]; -use POSIX qw[strftime]; +use File::Slurp qw[read_file]; +use Scalar::Util qw[blessed]; +use POSIX qw[strftime]; =head1 NAME @@ -113,18 +113,18 @@ Adds logging messages regarding the current version of some modules, specificall sub _log_versions { info( GLOBAL_VERSION => { version => Zonemaster::Engine->VERSION } ); - info( DEPENDENCY_VERSION => { name => 'Zonemaster::LDNS', version => $Zonemaster::LDNS::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'IO::Socket::INET6', version => $IO::Socket::INET6::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'Module::Find', version => $Module::Find::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'File::ShareDir', version => $File::ShareDir::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'File::Slurp', version => $File::Slurp::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'Net::IP::XS', version => $Net::IP::XS::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'List::MoreUtils', version => $List::MoreUtils::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'Clone', version => $Clone::VERSION } ); - info( DEPENDENCY_VERSION => { name => 'Readonly', version => $Readonly::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'Zonemaster::LDNS', version => $Zonemaster::LDNS::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'IO::Socket::INET6', version => $IO::Socket::INET6::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'Module::Find', version => $Module::Find::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'File::ShareDir', version => $File::ShareDir::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'File::Slurp', version => $File::Slurp::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'Net::IP::XS', version => $Net::IP::XS::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'List::MoreUtils', version => $List::MoreUtils::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'Clone', version => $Clone::VERSION } ); + info( DEPENDENCY_VERSION => { name => 'Readonly', version => $Readonly::VERSION } ); return; -} ## end sub _log_versions +} =head1 METHODS @@ -182,7 +182,11 @@ sub run_all_for { push @results, info( TEST_TARGET => { zone => $zone->name->string, module => 'all' } ); _log_versions(); - if ( not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) ) { + if ( + not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) + or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) + ) + { return info( NO_NETWORK => {} ); } @@ -210,8 +214,8 @@ sub run_all_for { push @results, info( CANNOT_CONTINUE => { domain => $zone->name->string } ); last; } - } - } + } ## end foreach my $mod ( __PACKAGE__...) + } ## end if ( Zonemaster::Engine...) return @results; } ## end sub run_all_for @@ -247,7 +251,11 @@ sub run_module { push @res, info( TEST_TARGET => { zone => $zone->name->string, module => $requested } ); _log_versions(); - if ( not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) ) { + if ( + not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) + or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) + ) + { return info( NO_NETWORK => {} ); } @@ -269,9 +277,10 @@ sub run_module { return @res; } else { - info( UNKNOWN_MODULE => { module => $requested, testcase => 'all', module_list => join( ':', sort $class->modules ) } ); + info( UNKNOWN_MODULE => + { module => $requested, testcase => 'all', module_list => join( ':', sort $class->modules ) } ); } - } + } ## end if ( Zonemaster::Engine...) else { info( CANNOT_CONTINUE => { domain => $zone->name->string } ); } @@ -309,8 +318,12 @@ sub run_one { push @res, info( START_TIME => { time_t => time(), string => strftime( "%F %T %z", ( localtime() ) ) } ); push @res, info( TEST_TARGET => { zone => $zone->name->string, module => $requested, testcase => $test } ); _log_versions(); - - if ( not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) ) { + + if ( + not( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) + or Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) + ) + { return info( NO_NETWORK => {} ); } @@ -335,11 +348,12 @@ sub run_one { else { info( UNKNOWN_METHOD => { module => $m, testcase => $test } ); } - } + } ## end if ( $module ) else { - info( UNKNOWN_MODULE => { module => $requested, testcase => $test, module_list => join( ':', sort $class->modules ) } ); + info( UNKNOWN_MODULE => + { module => $requested, testcase => $test, module_list => join( ':', sort $class->modules ) } ); } - } + } ## end if ( Zonemaster::Engine...) else { info( CANNOT_CONTINUE => { domain => $zone->name->string } ); } diff --git a/lib/Zonemaster/Engine/Test/Address.pm b/lib/Zonemaster/Engine/Test/Address.pm index b66a1a871..35c1cc1ed 100644 --- a/lib/Zonemaster/Engine/Test/Address.pm +++ b/lib/Zonemaster/Engine/Test/Address.pm @@ -3,10 +3,10 @@ package Zonemaster::Engine::Test::Address; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.8"); +use version; our $VERSION = version->declare( "v1.0.8" ); use Carp; -use List::MoreUtils qw[none any uniq]; +use List::MoreUtils qw[none any uniq]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; @@ -63,7 +63,7 @@ sub all { } return @results; -} +} ## end sub all =over @@ -90,7 +90,7 @@ sub metadata { A01_LOCAL_USE_ADDR A01_NO_GLOBALLY_REACHABLE_ADDR A01_NO_NAME_SERVERS_FOUND - ) + ) ], address02 => [ qw( @@ -99,7 +99,7 @@ sub metadata { NO_RESPONSE_PTR_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], address03 => [ qw( @@ -109,7 +109,7 @@ sub metadata { NO_RESPONSE_PTR_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -296,10 +296,10 @@ sub address01 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Address01'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my @nss = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @nss = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); unless ( @nss ) { push @results, _emit_log( A01_NO_NAME_SERVERS_FOUND => {} ); @@ -309,7 +309,7 @@ sub address01 { my ( @documentation_addr, @local_use_addr, @not_globally_reachable, @globally_reachable ); my %ip_already_processed; - NSS: + NSS: foreach my $ns ( @nss ) { my $ns_ip = $ns->address->short; @@ -328,7 +328,8 @@ sub address01 { next; } - my @categories = ( 'Private-Use', 'Loopback', 'Link Local', 'Link-Local', 'Unique-Local', 'Shared Address Space' ); + my @categories = + ( 'Private-Use', 'Loopback', 'Link Local', 'Link-Local', 'Unique-Local', 'Shared Address Space' ); foreach my $category ( @categories ) { if ( index( $ip_category, $category ) != -1 ) { push @local_use_addr, @matching_nss; @@ -340,51 +341,48 @@ sub address01 { push @not_globally_reachable, @matching_nss; next; } - } + } ## end if ( $ip_details_ref ) push @globally_reachable, @matching_nss; - } + } ## end NSS: foreach my $ns ( @nss ) if ( @globally_reachable ) { push @results, - _emit_log( - A01_GLOBALLY_REACHABLE_ADDR => { - ns_list => join( q{;}, uniq sort @globally_reachable ) - } - ); + _emit_log( + A01_GLOBALLY_REACHABLE_ADDR => { + ns_list => join( q{;}, uniq sort @globally_reachable ) + } + ); } else { - push @results, - _emit_log( - A01_NO_GLOBALLY_REACHABLE_ADDR => {} - ); + push @results, _emit_log( A01_NO_GLOBALLY_REACHABLE_ADDR => {} ); } if ( @documentation_addr ) { push @results, - _emit_log( - A01_DOCUMENTATION_ADDR => { - ns_list => join( q{;}, uniq sort @documentation_addr ) - } - ); + _emit_log( + A01_DOCUMENTATION_ADDR => { + ns_list => join( q{;}, uniq sort @documentation_addr ) + } + ); } if ( @local_use_addr ) { push @results, - _emit_log( - A01_LOCAL_USE_ADDR => { - ns_list => join( q{;}, uniq sort @local_use_addr ) - } - ); + _emit_log( + A01_LOCAL_USE_ADDR => { + ns_list => join( q{;}, uniq sort @local_use_addr ) + } + ); } if ( @not_globally_reachable ) { push @results, - _emit_log( - A01_ADDR_NOT_GLOBALLY_REACHABLE => { - ns_list => join( q{;}, uniq sort @not_globally_reachable ) - } - ); + _emit_log( + A01_ADDR_NOT_GLOBALLY_REACHABLE => { + ns_list => join( q{;}, uniq sort @not_globally_reachable ) + } + ); } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); @@ -415,8 +413,10 @@ sub address02 { my %ips; my $ptr_query; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $ips{ $local_ns->address->short }; @@ -431,7 +431,7 @@ sub address02 { if ( $p and $p->rcode eq q{NOERROR} and $p->get_records( q{CNAME}, q{answer} ) ) { my ( $cname ) = $p->get_records( q{CNAME}, q{answer} ); $ptr_query = $cname->cname; - $p = Zonemaster::Engine::Recursor->recurse( $ptr_query, q{PTR} ); + $p = Zonemaster::Engine::Recursor->recurse( $ptr_query, q{PTR} ); } if ( $p ) { diff --git a/lib/Zonemaster/Engine/Test/Basic.pm b/lib/Zonemaster/Engine/Test/Basic.pm index 389f9578a..4ab090eea 100644 --- a/lib/Zonemaster/Engine/Test/Basic.pm +++ b/lib/Zonemaster/Engine/Test/Basic.pm @@ -3,10 +3,10 @@ package Zonemaster::Engine::Test::Basic; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.19"); +use version; our $VERSION = version->declare( "v1.0.19" ); use Carp; -use List::MoreUtils qw[any none uniq]; +use List::MoreUtils qw[any none uniq]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; @@ -141,7 +141,7 @@ sub metadata { B01_SERVER_ZONE_ERROR TEST_CASE_END TEST_CASE_START - ) + ) ], basic02 => [ qw( @@ -159,7 +159,7 @@ sub metadata { IPV6_ENABLED TEST_CASE_END TEST_CASE_START - ) + ) ], basic03 => [ qw( @@ -172,7 +172,7 @@ sub metadata { NO_A_RECORDS TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -196,7 +196,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, B01_CHILD_IS_ALIAS => sub { __x # BASIC:B01_CHILD_IS_ALIAS - '"{domain_child}" is not a zone. It is an alias for "{domain_target}". Run a test for "{domain_target}" instead. ' +'"{domain_child}" is not a zone. It is an alias for "{domain_target}". Run a test for "{domain_target}" instead. ' . 'Returned from name servers "{ns_list}".', @_; }, B01_CHILD_FOUND => sub { @@ -216,7 +216,7 @@ Readonly my %TAG_DESCRIPTIONS => ( __x # BASIC:B01_NO_CHILD '"{domain_child}" does not exist as a DNS zone. Try to test "{domain_super}" instead.', @_; }, - B01_PARENT_DISREGARDED => sub { + B01_PARENT_DISREGARDED => sub { __x # BASIC:B01_PARENT_DISREGARDED 'This is a test of an undelegated domain so finding the parent zone is disregarded.'; }, @@ -397,27 +397,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -441,26 +427,12 @@ Takes a reference to an array of L objects, a sub _ip_enabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_ENABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_ENABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; } - if ( Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_ENABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_ENABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; } } @@ -491,15 +463,12 @@ sub basic01 { if ( $zone->name eq '.' ) { push @results, _emit_log( - B01_CHILD_FOUND => { + B01_CHILD_FOUND => { domain => $zone->name->string - } + } ); - push @results, - _emit_log( - B01_ROOT_HAS_NO_PARENT => {} - ); + push @results, _emit_log( B01_ROOT_HAS_NO_PARENT => {} ); return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } @@ -507,15 +476,12 @@ sub basic01 { if ( Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ) ) { push @results, _emit_log( - B01_CHILD_FOUND => { + B01_CHILD_FOUND => { domain => $zone->name->string - } + } ); - push @results, - _emit_log( - B01_PARENT_DISREGARDED => {} - ); + push @results, _emit_log( B01_PARENT_DISREGARDED => {} ); return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } @@ -531,18 +497,18 @@ sub basic01 { my %aa_nodata; my %rrs_ns; - my $type_soa = q{SOA}; - my $type_ns = q{NS}; + my $type_soa = q{SOA}; + my $type_ns = q{NS}; my $type_dname = q{DNAME}; - my %all_servers = ( '.' => [ Zonemaster::Engine::Recursor->root_servers ] ); - my @all_labels = ( '.' ); + my %all_servers = ( '.' => [ Zonemaster::Engine::Recursor->root_servers ] ); + my @all_labels = ( '.' ); my @remaining_labels = ( '.' ); while ( my $zone_name = shift @remaining_labels ) { my @remaining_servers = @{ $all_servers{$zone_name} }; - CUR_SERVERS: + CUR_SERVERS: while ( my $ns = shift @remaining_servers ) { next CUR_SERVERS if grep { $_ eq $ns->address->short } @{ $handled_servers{$zone_name} }; push @{ $handled_servers{$zone_name} }, $ns->address->short; @@ -554,14 +520,18 @@ sub basic01 { my $p_soa = $ns->query( $zone_name, $type_soa ); - unless ( $p_soa and $p_soa->rcode eq 'NOERROR' and $p_soa->aa and scalar $p_soa->get_records_for_name( $type_soa, $zone_name, 'answer' ) == 1 ) { + unless ($p_soa + and $p_soa->rcode eq 'NOERROR' + and $p_soa->aa + and scalar $p_soa->get_records_for_name( $type_soa, $zone_name, 'answer' ) == 1 ) + { push @results, _emit_log( - B01_SERVER_ZONE_ERROR => { - query_name => $zone_name, - rrtype => $type_soa, - ns => $ns->string - } + B01_SERVER_ZONE_ERROR => { + query_name => $zone_name, + rrtype => $type_soa, + ns => $ns->string, + } ); next CUR_SERVERS; @@ -569,26 +539,31 @@ sub basic01 { my $p_ns = $ns->query( $zone_name, $type_ns ); - unless ( $p_ns and $p_ns->rcode eq 'NOERROR' and $p_ns->aa and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 - and scalar $p_ns->get_records( $type_ns, 'answer' ) == scalar $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ) - ) { + unless ($p_ns + and $p_ns->rcode eq 'NOERROR' + and $p_ns->aa + and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 + and scalar $p_ns->get_records( $type_ns, 'answer' ) == + scalar $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ) ) + { push @results, _emit_log( - B01_SERVER_ZONE_ERROR => { - query_name => $zone_name, - rrtype => $type_ns, - ns => $ns->string - } + B01_SERVER_ZONE_ERROR => { + query_name => $zone_name, + rrtype => $type_ns, + ns => $ns->string, + } ); next CUR_SERVERS; } - $rrs_ns{name( $_->nsdname )->string} = [] for $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ); + $rrs_ns{ name( $_->nsdname )->string } = [] + for $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ); foreach my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns{name( $rr->owner )->string} ) { - push @{ $rrs_ns{name( $rr->owner )->string} }, $rr->address; + if ( exists $rrs_ns{ name( $rr->owner )->string } ) { + push @{ $rrs_ns{ name( $rr->owner )->string } }, $rr->address; } } @@ -613,78 +588,94 @@ sub basic01 { unless ( grep { $_ eq $zone_name } @all_labels ) { push @remaining_labels, $zone_name; - push @all_labels, $zone_name; + push @all_labels, $zone_name; } } } - } + } ## end foreach my $ns_name ( keys ...) my $intermediate_query_name = name( $zone_name ); - my $loop_zone_name = $zone_name; - my $loop_counter = 0; + my $loop_zone_name = $zone_name; + my $loop_counter = 0; - LOOP: - while() { + LOOP: + while () { $loop_counter += 1; if ( $loop_counter >= 1000 ) { - Zonemaster::Engine->logger->add( LOOP_PROTECTION => { - caller => 'Zonemaster::Engine::Test::Basic->basic01', - child_zone_name => $zone->name, - name => $loop_zone_name, - intermediate_query_name => $intermediate_query_name - } + Zonemaster::Engine->logger->add( + LOOP_PROTECTION => { + caller => 'Zonemaster::Engine::Test::Basic->basic01', + child_zone_name => $zone->name, + name => $loop_zone_name, + intermediate_query_name => $intermediate_query_name, + } ); - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); + return ( @results, + _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ), + ); } last if scalar @{ $intermediate_query_name->labels } >= scalar @{ $zone->name->labels }; - $intermediate_query_name = name( @{ $zone->name->labels }[ ( scalar @{ $zone->name->labels } - scalar @{ $intermediate_query_name->labels } ) - 1 ] . '.' . $intermediate_query_name->string ); + $intermediate_query_name = + name( @{ $zone->name->labels } + [ ( scalar @{ $zone->name->labels } - scalar @{ $intermediate_query_name->labels } ) - 1 ] . '.' + . $intermediate_query_name->string ); $p_soa = $ns->query( $intermediate_query_name, $type_soa ); unless ( $p_soa ) { push @results, _emit_log( - B01_SERVER_ZONE_ERROR => { - query_name => $intermediate_query_name, - rrtype => $type_soa, - ns => $ns->string - } + B01_SERVER_ZONE_ERROR => { + query_name => $intermediate_query_name, + rrtype => $type_soa, + ns => $ns->string, + } ); next CUR_SERVERS; } - if ( $p_soa->rcode eq 'NOERROR' and $p_soa->aa and scalar $p_soa->get_records_for_name( $type_soa, $intermediate_query_name, 'answer' ) == 1 ) { + if ( $p_soa->rcode eq 'NOERROR' + and $p_soa->aa + and scalar $p_soa->get_records_for_name( $type_soa, $intermediate_query_name, 'answer' ) == 1 ) + { if ( $intermediate_query_name->string eq $zone->name->string ) { push @{ $parent_found{$loop_zone_name} }, $ns->string; - push @{ $aa_soa{$loop_zone_name} }, $ns->string; + push @{ $aa_soa{$loop_zone_name} }, $ns->string; } else { $p_ns = $ns->query( $intermediate_query_name, $type_ns ); - unless ( $p_ns and $p_ns->rcode eq 'NOERROR' and $p_ns->aa and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 - and scalar $p_ns->get_records( $type_ns, 'answer' ) == scalar $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ) - ) { + unless ($p_ns + and $p_ns->rcode eq 'NOERROR' + and $p_ns->aa + and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 + and scalar $p_ns->get_records( $type_ns, 'answer' ) == + scalar $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ) ) + { push @results, _emit_log( - B01_SERVER_ZONE_ERROR => { - query_name => $intermediate_query_name, - rrtype => $type_ns, - ns => $ns->string - } + B01_SERVER_ZONE_ERROR => { + query_name => $intermediate_query_name, + rrtype => $type_ns, + ns => $ns->string, + } ); next CUR_SERVERS; } my %rrs_ns_bis; - $rrs_ns_bis{name( $_->nsdname )->string} = [] for $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ); - - foreach my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns_bis{name( $rr->owner )->string} ) { - push @{ $rrs_ns_bis{name( $rr->owner )->string} }, $rr->address; + $rrs_ns_bis{ name( $_->nsdname )->string } = [] + for $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ); + + foreach + my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) + { + if ( exists $rrs_ns_bis{ name( $rr->owner )->string } ) { + push @{ $rrs_ns_bis{ name( $rr->owner )->string } }, $rr->address; } } @@ -693,13 +684,15 @@ sub basic01 { my $p_a = Zonemaster::Engine::Recursor->recurse( $ns_name, q{A} ); if ( $p_a and $p_a->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p_a->get_records_for_name( 'A', $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p_a->get_records_for_name( 'A', $ns_name ); } my $p_aaaa = Zonemaster::Engine::Recursor->recurse( $ns_name, q{AAAA} ); if ( $p_aaaa and $p_aaaa->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p_aaaa->get_records_for_name( 'AAAA', $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p_aaaa->get_records_for_name( 'AAAA', $ns_name ); } } @@ -709,32 +702,37 @@ sub basic01 { unless ( grep { $_ eq $intermediate_query_name } @all_labels ) { push @remaining_labels, $intermediate_query_name; - push @all_labels, $intermediate_query_name; + push @all_labels, $intermediate_query_name; } } } - } + } ## end foreach my $ns_name ( keys ...) $loop_zone_name = $intermediate_query_name->string; next LOOP; - } - } + } ## end else [ if ( $intermediate_query_name...)] + } ## end if ( $p_soa->rcode eq ...) elsif ( $p_soa->rcode eq 'NXDOMAIN' and $p_soa->aa ) { push @{ $parent_found{$loop_zone_name} }, $ns->string; - push @{ $aa_nxdomain{$loop_zone_name} }, $ns->string; + push @{ $aa_nxdomain{$loop_zone_name} }, $ns->string; } - elsif ( $p_soa->is_redirect and scalar $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ) ) { + elsif ( $p_soa->is_redirect + and scalar $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ) ) + { if ( $intermediate_query_name->string eq $zone->name->string ) { - push @{ $parent_found{$loop_zone_name} }, $ns->string; + push @{ $parent_found{$loop_zone_name} }, $ns->string; push @{ $delegation_found{$loop_zone_name} }, $ns->string; } else { my %rrs_ns_bis; - $rrs_ns_bis{name( $_->nsdname )->string} = [] for $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ); - - foreach my $rr ( $p_soa->get_records( 'A', 'additional' ), $p_soa->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns_bis{name( $rr->owner )->string} ) { - push @{ $rrs_ns_bis{name( $rr->owner )->string} }, $rr->address; + $rrs_ns_bis{ name( $_->nsdname )->string } = [] + for $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ); + + foreach my $rr ( $p_soa->get_records( 'A', 'additional' ), + $p_soa->get_records( 'AAAA', 'additional' ), ) + { + if ( exists $rrs_ns_bis{ name( $rr->owner )->string } ) { + push @{ $rrs_ns_bis{ name( $rr->owner )->string } }, $rr->address; } } @@ -743,13 +741,15 @@ sub basic01 { my $p_a = Zonemaster::Engine::Recursor->recurse( $ns_name, q{A} ); if ( $p_a and $p_a->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p_a->get_records_for_name( 'A', $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p_a->get_records_for_name( 'A', $ns_name ); } my $p_aaaa = Zonemaster::Engine::Recursor->recurse( $ns_name, q{AAAA} ); if ( $p_aaaa and $p_aaaa->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p_aaaa->get_records_for_name( 'AAAA', $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p_aaaa->get_records_for_name( 'AAAA', $ns_name ); } } @@ -759,85 +759,92 @@ sub basic01 { unless ( grep { $_ eq $intermediate_query_name } @all_labels ) { push @remaining_labels, $intermediate_query_name; - push @all_labels, $intermediate_query_name; + push @all_labels, $intermediate_query_name; } } } - } - } - } + } ## end foreach my $ns_name ( keys ...) + } ## end else [ if ( $intermediate_query_name...)] + } ## end elsif ( $p_soa->is_redirect...) elsif ( $p_soa->rcode eq 'NOERROR' and $p_soa->aa ) { next LOOP if $intermediate_query_name->string ne $zone->name->string; if ( scalar $p_soa->get_records_for_name( 'CNAME', $zone->name, 'answer' ) ) { push @{ $parent_found{$loop_zone_name} }, $ns->string; - push @{ $aa_cname{$loop_zone_name} }, $ns->string; + push @{ $aa_cname{$loop_zone_name} }, $ns->string; } else { - my $p_dname = $ns->query( $zone->name->string , $type_dname ); + my $p_dname = $ns->query( $zone->name->string, $type_dname ); - if ( $p_dname and $p_dname->aa and $p_dname->rcode eq 'NOERROR' and scalar $p_dname->get_records_for_name( $type_dname, $zone->name, 'answer' ) == 1 ) { + if ( $p_dname + and $p_dname->aa + and $p_dname->rcode eq 'NOERROR' + and scalar $p_dname->get_records_for_name( $type_dname, $zone->name, 'answer' ) == 1 ) + { push @{ $parent_found{$loop_zone_name} }, $ns->string; - push @{ $aa_dname{($p_dname->get_records_for_name( $type_dname, $zone->name, 'answer' ))[0]->dname}{$loop_zone_name} }, $ns->string; + push @{ + $aa_dname{ + ( $p_dname->get_records_for_name( $type_dname, $zone->name, 'answer' ) )[0]->dname + }{$loop_zone_name} + }, + $ns->string; } else { push @{ $parent_found{$loop_zone_name} }, $ns->string; - push @{ $aa_nodata{$loop_zone_name} }, $ns->string; + push @{ $aa_nodata{$loop_zone_name} }, $ns->string; } - } - } - elsif ( $p_soa->is_redirect and scalar $p_soa->get_records_for_name( 'CNAME', $zone->name, 'answer' ) ) { - push @{ $parent_found{$loop_zone_name} }, $ns->string; + } ## end else [ if ( scalar $p_soa->get_records_for_name...)] + } ## end elsif ( $p_soa->rcode eq ...) + elsif ( $p_soa->is_redirect and scalar $p_soa->get_records_for_name( 'CNAME', $zone->name, 'answer' ) ) + { + push @{ $parent_found{$loop_zone_name} }, $ns->string; push @{ $cname_with_referral{$loop_zone_name} }, $ns->string; } else { push @results, _emit_log( - B01_SERVER_ZONE_ERROR => { - query_name => $intermediate_query_name, - rrtype => $type_soa, - ns => $ns->string - } + B01_SERVER_ZONE_ERROR => { + query_name => $intermediate_query_name, + rrtype => $type_soa, + ns => $ns->string, + } ); } next CUR_SERVERS; - } - } - } + } ## end LOOP: while () + } ## end CUR_SERVERS: while ( my $ns = shift @remaining_servers) + } ## end while ( my $zone_name = shift...) if ( scalar keys %parent_found ) { push @results, map { - _emit_log( - B01_PARENT_FOUND => { - domain => $_, - ns_list => join( q{;}, uniq sort @{ $parent_found{$_} } ) - } - ) + _emit_log( + B01_PARENT_FOUND => { + domain => $_, + ns_list => join( q{;}, uniq sort @{ $parent_found{$_} } ), + } + ) } keys %parent_found; if ( scalar keys %parent_found > 1 ) { - push @results, - _emit_log( + push @results, + _emit_log( B01_PARENT_UNDETERMINED => { - ns_list => join( q{;}, uniq sort map { @{ $parent_found{$_} } } keys %parent_found ) + ns_list => join( q{;}, uniq sort map { @{ $parent_found{$_} } } keys %parent_found ) } - ); + ); } } else { - push @results, - _emit_log( - B01_PARENT_NOT_FOUND => {} - ); + push @results, _emit_log( B01_PARENT_NOT_FOUND => {} ); } if ( scalar keys %delegation_found or scalar keys %aa_soa ) { push @results, _emit_log( - B01_CHILD_FOUND => { + B01_CHILD_FOUND => { domain => $zone->name->string - } + } ); unless ( Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ) ) { @@ -845,56 +852,57 @@ sub basic01 { foreach my $parent_domain ( uniq map { keys %$_ } @hash_refs ) { push @results, _emit_log( - B01_INCONSISTENT_DELEGATION => { + B01_INCONSISTENT_DELEGATION => { domain_parent => $parent_domain, - domain_child => $zone->name->string, - ns_list => join( q{;}, uniq sort map { @{ $_->{$parent_domain} // [] } } @hash_refs ) - } + domain_child => $zone->name->string, + ns_list => join( q{;}, uniq sort map { @{ $_->{$parent_domain} // [] } } @hash_refs ), + } ); } } - } + } ## end if ( scalar keys %delegation_found...) if ( not scalar keys %delegation_found and not scalar keys %aa_soa ) { if ( Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ) ) { push @results, _emit_log( - B01_CHILD_NOT_EXIST => { + B01_CHILD_NOT_EXIST => { domain => $zone->name->string - } + } ); } else { push @results, _emit_log( - B01_NO_CHILD => { + B01_NO_CHILD => { domain_child => $zone->name->string, - domain_super => $zone->name->next_higher - } + domain_super => $zone->name->next_higher, + } ); } } if ( scalar keys %aa_dname ) { - push @results, map { my $target = $_; - _emit_log( - B01_CHILD_IS_ALIAS => { - domain_child => $zone->name->string, - domain_target => $target, - ns_list => join( q{;}, uniq sort map { @{ $aa_dname{$target}{$_} } } keys %{ $aa_dname{$target} } ) - } - ) + push @results, map { + my $target = $_; + _emit_log( + B01_CHILD_IS_ALIAS => { + domain_child => $zone->name->string, + domain_target => $target, + ns_list => join( q{;}, uniq sort map { @{ $aa_dname{$target}{$_} } } keys %{ $aa_dname{$target} } ), + } + ) } keys %aa_dname; if ( scalar keys %aa_dname > 1 ) { push @results, _emit_log( - B01_INCONSISTENT_ALIAS => { + B01_INCONSISTENT_ALIAS => { domain => $zone->name->string - } + } ); } - } + } ## end if ( scalar keys %aa_dname) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub basic01 @@ -931,15 +939,15 @@ sub basic02 { my %unexpected_rcode; my @ns_names = @{ Zonemaster::Engine::TestMethods->method2( $zone ) }; - my @ns = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; + my @ns = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; if ( not scalar @ns_names ) { push @results, - _emit_log( - B02_NO_DELEGATION => { - domain => $zone->name - } - ); + _emit_log( + B02_NO_DELEGATION => { + domain => $zone->name + } + ); return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } @@ -949,12 +957,12 @@ sub basic02 { my @ns_ips = @{ $zone->glue_addresses }; foreach my $ns_name ( @ns_names ) { - $found_ip{$ns_name->string} = 0; + $found_ip{ $ns_name->string } = 0; foreach my $rr ( @ns_ips ) { if ( $rr->owner eq $ns_name ) { - $found_ip{$ns_name->string} = 1; - push @ns, Zonemaster::Engine::Nameserver->new({ name => $ns_name, address => $rr->address }); + $found_ip{ $ns_name->string } = 1; + push @ns, Zonemaster::Engine::Nameserver->new( { name => $ns_name, address => $rr->address } ); } } } @@ -964,7 +972,7 @@ sub basic02 { $ns_cant_resolve{$ns_name} = 1; } } - } + } ## end if ( not scalar @ns ) foreach my $ns ( @ns ) { if ( _ip_disabled_message( \@results, $ns, $query_type ) ) { @@ -976,93 +984,63 @@ sub basic02 { if ( $p ) { if ( $p->rcode ne 'NOERROR' ) { - $unexpected_rcode{$ns->string} = $p->rcode; + $unexpected_rcode{ $ns->string } = $p->rcode; } elsif ( not $p->aa ) { - $ns_not_auth{$ns->string} = 1; + $ns_not_auth{ $ns->string } = 1; } else { if ( $p->get_records_for_name( $query_type, $zone->name, q{answer} ) ) { - $auth_response_soa{$ns->string} = 1; + $auth_response_soa{ $ns->string } = 1; } else { - $ns_broken{$ns->string} = 1; + $ns_broken{ $ns->string } = 1; } } } else { - $ns_no_response{$ns->string} = 1; + $ns_no_response{ $ns->string } = 1; } - } + } ## end foreach my $ns ( @ns ) if ( scalar keys %auth_response_soa ) { push @results, - _emit_log( - B02_AUTH_RESPONSE_SOA => { - domain => $zone->name, - ns_list => join( q{;}, sort keys %auth_response_soa ) - } - ); + _emit_log( + B02_AUTH_RESPONSE_SOA => { + domain => $zone->name, + ns_list => join( q{;}, sort keys %auth_response_soa ), + } + ); } else { push @results, - _emit_log( - B02_NO_WORKING_NS => { - domain => $zone->name - } - ); + _emit_log( + B02_NO_WORKING_NS => { + domain => $zone->name + } + ); if ( scalar keys %ns_broken ) { - push @results, map { - _emit_log( - B02_NS_BROKEN => { - ns => $_ - } - ) - } keys %ns_broken; + push @results, map { _emit_log( B02_NS_BROKEN => { ns => $_ } ) } keys %ns_broken; } if ( scalar keys %ns_not_auth ) { - push @results, map { - _emit_log( - B02_NS_NOT_AUTH => { - ns => $_ - } - ) - } keys %ns_not_auth; + push @results, map { _emit_log( B02_NS_NOT_AUTH => { ns => $_ } ) } keys %ns_not_auth; } if ( scalar keys %ns_cant_resolve ) { - push @results, map { - _emit_log( - B02_NS_NO_IP_ADDR => { - nsname => $_ - } - ) - } keys %ns_cant_resolve; + push @results, map { _emit_log( B02_NS_NO_IP_ADDR => { nsname => $_ } ) } keys %ns_cant_resolve; } if ( scalar keys %ns_no_response ) { - push @results, map { - _emit_log( - B02_NS_NO_RESPONSE => { - ns => $_ - } - ) - } keys %ns_no_response; + push @results, map { _emit_log( B02_NS_NO_RESPONSE => { ns => $_ } ) } keys %ns_no_response; } if ( scalar keys %unexpected_rcode ) { - push @results, map { - _emit_log( - B02_UNEXPECTED_RCODE => { - rcode => $unexpected_rcode{$_}, - ns => $_ - } - ) - } keys %unexpected_rcode; + push @results, map { _emit_log( B02_UNEXPECTED_RCODE => { rcode => $unexpected_rcode{$_}, ns => $_ } ) } + keys %unexpected_rcode; } - } + } ## end else [ if ( scalar keys %auth_response_soa)] return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub basic02 diff --git a/lib/Zonemaster/Engine/Test/Connectivity.pm b/lib/Zonemaster/Engine/Test/Connectivity.pm index ef7ade5d7..6c8ae903d 100644 --- a/lib/Zonemaster/Engine/Test/Connectivity.pm +++ b/lib/Zonemaster/Engine/Test/Connectivity.pm @@ -3,10 +3,10 @@ package Zonemaster::Engine::Test::Connectivity; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.1.0"); +use version; our $VERSION = version->declare( "v1.1.0" ); use Carp; -use List::MoreUtils qw[uniq]; +use List::MoreUtils qw[uniq]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; @@ -135,7 +135,7 @@ sub metadata { IPV6_SAME_ASN TEST_CASE_END TEST_CASE_START - ) + ) ], connectivity04 => [ qw( @@ -151,7 +151,7 @@ sub metadata { CN04_IPV6_SINGLE_PREFIX TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -219,11 +219,13 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CN01_WRONG_NS_RECORD_UDP => sub { __x # CONNECTIVITY:CN01_WRONG_NS_RECORD_UDP - 'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over UDP.', @_; +'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over UDP.', + @_; }, CN01_WRONG_SOA_RECORD_UDP => sub { __x # CONNECTIVITY:CN01_WRONG_SOA_RECORD_UDP - 'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over UDP.', @_; +'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over UDP.', + @_; }, CN02_MISSING_NS_RECORD_TCP => sub { __x # CONNECTIVITY:CN02_MISSING_NS_RECORD_TCP @@ -263,11 +265,13 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CN02_WRONG_NS_RECORD_TCP => sub { __x # CONNECTIVITY:CN02_WRONG_NS_RECORD_TCP - 'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over TCP.', @_; +'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over TCP.', + @_; }, CN02_WRONG_SOA_RECORD_TCP => sub { __x # CONNECTIVITY:CN02_WRONG_SOA_RECORD_TCP - 'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over TCP.', @_; +'Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over TCP.', + @_; }, CN04_ASN_INFOS_ANNOUNCE_IN => sub { __x # CONNECTIVITY:ASN_INFOS_ANNOUNCE_IN @@ -455,27 +459,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -503,7 +493,8 @@ sub _connectivity_loop { my ( $testcase_prefix, $use_tcp, $protocol ); if ( $testcase eq 'connectivity01' ) { ( $testcase_prefix, $use_tcp, $protocol ) = ( "CN01", 0, "UDP" ); - } elsif ( $testcase eq 'connectivity02' ) { + } + elsif ( $testcase eq 'connectivity02' ) { ( $testcase_prefix, $use_tcp, $protocol ) = ( "CN02", 1, "TCP" ); } @@ -514,7 +505,7 @@ sub _connectivity_loop { my %packets = ( 'SOA' => $ns->query( $name, q{SOA}, { usevc => $use_tcp } ), - 'NS' => $ns->query( $name, q{NS}, { usevc => $use_tcp } ) + 'NS' => $ns->query( $name, q{NS}, { usevc => $use_tcp } ), ); if ( not $packets{SOA} and not $packets{NS} ) { @@ -526,35 +517,42 @@ sub _connectivity_loop { my $pkt = $packets{$qtype}; if ( not $pkt ) { - push @$results, _emit_log( "${testcase_prefix}_NO_RESPONSE_${qtype}_QUERY_${protocol}" => { ns => $ns->string } ); + push @$results, + _emit_log( "${testcase_prefix}_NO_RESPONSE_${qtype}_QUERY_${protocol}" => { ns => $ns->string } ); } elsif ( $pkt->rcode ne q{NOERROR} ) { - push @$results, _emit_log( "${testcase_prefix}_UNEXPECTED_RCODE_${qtype}_QUERY_${protocol}" => { + push @$results, + _emit_log( + "${testcase_prefix}_UNEXPECTED_RCODE_${qtype}_QUERY_${protocol}" => { ns => $ns->string, - rcode => $pkt->rcode + rcode => $pkt->rcode, } - ); + ); } else { my ( $rr ) = $pkt->get_records( $qtype, q{answer} ); if ( not $rr ) { - push @$results, _emit_log( "${testcase_prefix}_MISSING_${qtype}_RECORD_${protocol}" => { ns => $ns->string } ); + push @$results, + _emit_log( "${testcase_prefix}_MISSING_${qtype}_RECORD_${protocol}" => { ns => $ns->string } ); } - elsif ( lc($rr->owner) ne lc($name->fqdn) ) { - push @$results, _emit_log( "${testcase_prefix}_WRONG_${qtype}_RECORD_${protocol}" => { + elsif ( lc( $rr->owner ) ne lc( $name->fqdn ) ) { + push @$results, + _emit_log( + "${testcase_prefix}_WRONG_${qtype}_RECORD_${protocol}" => { ns => $ns->string, - domain_found => lc($rr->owner), - domain_expected => lc($name->fqdn) + domain_found => lc( $rr->owner ), + domain_expected => lc( $name->fqdn ), } - ); + ); } elsif ( not $pkt->aa ) { - push @$results, _emit_log( "${testcase_prefix}_${qtype}_RECORD_NOT_AA_${protocol}" => { ns => $ns->string } ); + push @$results, + _emit_log( "${testcase_prefix}_${qtype}_RECORD_NOT_AA_${protocol}" => { ns => $ns->string } ); } - } - } - } -} + } ## end else [ if ( not $pkt ) ] + } ## end foreach my $qtype ( qw{SOA NS}) + } ## end foreach my $ns ( @$ns_list ) +} ## end sub _connectivity_loop =head1 TESTS @@ -579,16 +577,19 @@ sub connectivity01 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Connectivity01'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my $name = name( $zone ); + my $name = name( $zone ); my @ns_list = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; my @ns_ipv4 = (); my @ns_ipv6 = (); foreach my $ns ( @ns_list ) { - if ( $ns->address->version == $IP_VERSION_4 and not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) ) { + if ( $ns->address->version == $IP_VERSION_4 and not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) ) + { push @ns_ipv4, $ns; } - elsif ( $ns->address->version == $IP_VERSION_6 and not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) ) { + elsif ( $ns->address->version == $IP_VERSION_6 + and not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) + { push @ns_ipv6, $ns; } } @@ -599,7 +600,7 @@ sub connectivity01 { push @results, _emit_log( "CN01_IPV6_DISABLED" => { ns_list => join( ';', @ns_ipv6 ) } ); } - _connectivity_loop("connectivity01", $name, \@ns_list, \@results); + _connectivity_loop( "connectivity01", $name, \@ns_list, \@results ); return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub connectivity01 @@ -625,13 +626,13 @@ sub connectivity02 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Connectivity02'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my $name = name( $zone ); + my $name = name( $zone ); my @ns_list = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; - _connectivity_loop("connectivity02", $name, \@ns_list, \@results); + _connectivity_loop( "connectivity02", $name, \@ns_list, \@results ); return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); -} ## end sub connectivity02 +} =over @@ -693,7 +694,7 @@ sub connectivity03 { asn => join( q{,}, sort @{$asnref} ), } ); - push @v4asns, @{$asnref}; + push @v4asns, @{$asnref}; push @v4asnsets, join( q{,}, sort { $a <=> $b } @{$asnref} ); } if ( $prefix ) { @@ -706,7 +707,7 @@ sub connectivity03 { } ); } - } + } ## end else [ if ( defined $ret_code...)] } ## end foreach my $v4ip ( @v4ips ) foreach my $v6ip ( @v6ips ) { my ( $asnref, $prefix, $raw, $ret_code ) = Zonemaster::Engine::ASNLookup->get_with_prefix( $v6ip ); @@ -731,7 +732,7 @@ sub connectivity03 { asn => join( q{,}, sort @{$asnref} ), } ); - push @v6asns, @{$asnref}; + push @v6asns, @{$asnref}; push @v6asnsets, join( q{,}, sort { $a <=> $b } @{$asnref} ); } if ( $prefix ) { @@ -744,12 +745,12 @@ sub connectivity03 { } ); } - } + } ## end else [ if ( defined $ret_code...)] } ## end foreach my $v6ip ( @v6ips ) - @v4asns = uniq sort { $a <=> $b } @v4asns; + @v4asns = uniq sort { $a <=> $b } @v4asns; @v4asnsets = uniq sort @v4asnsets; - @v6asns = uniq sort { $a <=> $b } @v6asns; + @v6asns = uniq sort { $a <=> $b } @v6asns; @v6asnsets = uniq sort @v6asnsets; if ( scalar @v4asns ) { @@ -804,16 +805,16 @@ sub connectivity04 { my %prefixes; my %ip_already_processed; - my @nss = grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @nss = grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); foreach my $ns ( @nss ) { my $ip = $ns->address; - next if exists $ip_already_processed{$ip->version}{$ip->short}; - $ip_already_processed{$ip->version}{$ip->short} = 1; + next if exists $ip_already_processed{ $ip->version }{ $ip->short }; + $ip_already_processed{ $ip->version }{ $ip->short } = 1; my ( $asnref, $prefix, $raw, $ret_code ) = Zonemaster::Engine::ASNLookup->get_with_prefix( $ip ); @@ -855,14 +856,15 @@ sub connectivity04 { _emit_log( CN04_ASN_INFOS_ANNOUNCE_IN => { ns_ip => $ip->short, - prefix => sprintf "%s", $prefix_str, + prefix => sprintf "%s", + $prefix_str, } ); - push @{ $prefixes{$prefix->version}{$prefix_str} }, $ns; - } - } - } + push @{ $prefixes{ $prefix->version }{$prefix_str} }, $ns; + } ## end if ( $prefix ) + } ## end else [ if ( defined $ret_code...)] + } ## end foreach my $ns ( @nss ) foreach my $ip_version ( sort keys %prefixes ) { my @combined_ns; @@ -876,7 +878,7 @@ sub connectivity04 { _emit_log( "CN04_IPV${ip_version}_SAME_PREFIX" => { ip_prefix => $prefix, - ns_list => join( q{;}, sort @{ $prefixes{$ip_version}{$prefix} } ) + ns_list => join( q{;}, sort @{ $prefixes{$ip_version}{$prefix} } ), } ); } @@ -891,9 +893,11 @@ sub connectivity04 { ); } - push @results, _emit_log( "CN04_IPV${ip_version}_SINGLE_PREFIX" => {} ) if scalar keys %{ $prefixes{$ip_version} } == 1 - and scalar @{ (values %{ $prefixes{$ip_version} })[0] } == scalar keys %{ $ip_already_processed{$ip_version} }; - } + push @results, _emit_log( "CN04_IPV${ip_version}_SINGLE_PREFIX" => {} ) + if scalar keys %{ $prefixes{$ip_version} } == 1 + and scalar @{ ( values %{ $prefixes{$ip_version} } )[0] } == scalar + keys %{ $ip_already_processed{$ip_version} }; + } ## end foreach my $ip_version ( sort...) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub connectivity04 diff --git a/lib/Zonemaster/Engine/Test/Consistency.pm b/lib/Zonemaster/Engine/Test/Consistency.pm index 7c889b43d..133020e56 100644 --- a/lib/Zonemaster/Engine/Test/Consistency.pm +++ b/lib/Zonemaster/Engine/Test/Consistency.pm @@ -3,9 +3,9 @@ package Zonemaster::Engine::Test::Consistency; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.1.16"); +use version; our $VERSION = version->declare( "v1.1.16" ); -use List::MoreUtils qw[uniq]; +use List::MoreUtils qw[uniq]; use Locale::TextDomain qw[Zonemaster-Engine]; use Net::IP::XS; use Readonly; @@ -67,7 +67,7 @@ sub all { } return @results; -} +} ## end sub all =over @@ -98,7 +98,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], consistency02 => [ qw( @@ -111,7 +111,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], consistency03 => [ qw( @@ -124,7 +124,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], consistency04 => [ qw( @@ -137,7 +137,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], consistency05 => [ qw( @@ -155,7 +155,7 @@ sub metadata { CS05_OOD_ADDR_MISMATCH TEST_CASE_END TEST_CASE_START - ) + ) ], consistency06 => [ qw( @@ -165,7 +165,7 @@ sub metadata { MULTIPLE_SOA_MNAMES TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -201,11 +201,13 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CS05_DELEGATION => sub { __x # CONSISTENCY:CS05_DELEGATION - 'Delegation of the child zone as provided by the parent name servers listed: "{ns_deleg_list}". Parent name servers: "{ns_list}".', @_; +'Delegation of the child zone as provided by the parent name servers listed: "{ns_deleg_list}". Parent name servers: "{ns_list}".', + @_; }, CS05_EXTRA_ADDR_CHILD => sub { __x # CONSISTENCY:CS05_EXTRA_ADDR_CHILD - 'There is one or more extra address records found in the child zone that are not present as glue in the delegation: "{ns_list}".', @_; +'There is one or more extra address records found in the child zone that are not present as glue in the delegation: "{ns_list}".', + @_; }, CS05_NO_MISMATCH_GLUE_ZONE => sub { __ # CONSISTENCY:CS05_NO_MISMATCH_GLUE_ZONE @@ -213,7 +215,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CS05_ID_ADDR_MISMATCH => sub { __x # CONSISTENCY:CS05_ID_ADDR_MISMATCH - 'For name server {nsname} the glue record in the delegation "{ns_ip_list_glue}" is different from the address record in the child zone "{ns_ip_list_zone}".', @_; +'For name server {nsname} the glue record in the delegation "{ns_ip_list_glue}" is different from the address record in the child zone "{ns_ip_list_zone}".', + @_; }, CS05_ID_ADDR_MISSING => sub { __x # CONSISTENCY:CS05_ID_ADDR_MISSING @@ -225,7 +228,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CS05_MISSING_GLUE_FOR_NS => sub { __x # CONSISTENCY:CS05_MISSING_GLUE_FOR_NS - 'Expected glue record for {nsname} is missing in the delegation. Found in the parent name servers "{ns_list}".', @_; +'Expected glue record for {nsname} is missing in the delegation. Found in the parent name servers "{ns_list}".', + @_; }, CS05_MISSING_GLUE_FOR_NS_UNDEL => sub { __x # CONSISTENCY:CS05_MISSING_GLUE_FOR_NS_UNDEL @@ -233,7 +237,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CS05_MISSING_GLUE_FOR_ROOT_NS => sub { __x # CONSISTENCY:CS05_MISSING_GLUE_FOR_ROOT_NS - 'IP address (glue record) is expected but missing for {nsname} in the undelegated data or hint data for root.', @_; +'IP address (glue record) is expected but missing for {nsname} in the undelegated data or hint data for root.', + @_; }, CS05_NO_NS_ADDR_CHILD => sub { __ # CONSISTENCY:CS05_NO_NS_ADDR_CHILD @@ -241,7 +246,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CS05_OOD_ADDR_MISMATCH => sub { __x # CONSISTENCY:CS05_OOD_ADDR_MISMATCH - 'For name server {nsname} the glue record in the delegation "{ns_ip_list_glue}" is different from the address record in the child zone "{ns_ip_list_zone}".', @_; +'For name server {nsname} the glue record in the delegation "{ns_ip_list_glue}" is different from the address record in the child zone "{ns_ip_list_zone}".', + @_; }, IPV4_DISABLED => sub { __x # CONSISTENCY:IPV4_DISABLED @@ -411,33 +417,18 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; } - =head1 TESTS =over @@ -465,8 +456,10 @@ sub consistency01 { my %serials; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }; @@ -531,7 +524,7 @@ sub consistency01 { } ); } - } ## end elsif ( scalar @serial_numbers) + } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub consistency01 @@ -561,8 +554,10 @@ sub consistency02 { my %rnames; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }; @@ -644,8 +639,10 @@ sub consistency03 { my %time_parameter_sets; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }; @@ -738,8 +735,10 @@ sub consistency04 { my %ns_sets; my $query_type = q{NS}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }; @@ -768,7 +767,7 @@ sub consistency04 { } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) if ( scalar( keys %ns_sets ) == 1 ) { - push @results, _emit_log( ONE_NS_SET => { nsname_list => ( keys %ns_sets )[0] }); + push @results, _emit_log( ONE_NS_SET => { nsname_list => ( keys %ns_sets )[0] } ); } elsif ( scalar( keys %ns_sets ) ) { push @results, @@ -814,16 +813,16 @@ sub consistency05 { push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); # Steps 1–3 - my @parent_ns = @{ Zonemaster::Engine::TestMethodsV2->get_parent_ns_names_and_ips( $zone ) // [] }; - my @parent_ns_ips = @{ Zonemaster::Engine::TestMethodsV2->get_parent_ns_ips( $zone ) // [] }; + my @parent_ns = @{ Zonemaster::Engine::TestMethodsV2->get_parent_ns_names_and_ips( $zone ) // [] }; + my @parent_ns_ips = @{ Zonemaster::Engine::TestMethodsV2->get_parent_ns_ips( $zone ) // [] }; my @child_ns_ips = uniq - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_ips( $zone ) // [] }; + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_ips( $zone ) // [] }; my %delegation; my %child_zone_ns; - my $delegation_id_ns = Zonemaster::Engine::NameserverSet->new(); + my $delegation_id_ns = Zonemaster::Engine::NameserverSet->new(); my $delegation_ood_ns = Zonemaster::Engine::NameserverSet->new(); my %missing_glue; my $auth_addr_records_in_child = Zonemaster::Engine::NameserverSet->new(); @@ -839,41 +838,37 @@ sub consistency05 { next unless ( defined $p and $p->is_redirect ); my %authority = - map { lc name( $_->nsdname() ) => 1 } - $p->get_records_for_name( 'NS', $zone, 'authority' ); + map { lc name( $_->nsdname() ) => 1 } $p->get_records_for_name( 'NS', $zone, 'authority' ); - my @additional = - map { - my $name = name( $_->owner() ); + map { + my $name = name( $_->owner() ); - # Filters out A and AAAA records with invalid IP addresses - my $addr = Net::IP::XS->new( $_->address ); - if ( defined $addr ) { - Zonemaster::Engine::Nameserver->new( { name => $name, address => $addr } ) - } - else { - () - } + # Filters out A and AAAA records with invalid IP addresses + my $addr = Net::IP::XS->new( $_->address ); + if ( defined $addr ) { + Zonemaster::Engine::Nameserver->new( { name => $name, address => $addr } ); } - grep { - my $name = lc name( $_->owner() ); - exists $authority{$name} and ( $_->type eq 'A' or $_->type eq 'AAAA' ) + else { + () } - $p->additional; + } + grep { + my $name = lc name( $_->owner() ); + exists $authority{$name} and ( $_->type eq 'A' or $_->type eq 'AAAA' ) + } $p->additional; my $set = Zonemaster::Engine::NameserverSet->new( keys %authority, @additional ); $delegation{$parent_ns} = [ $set->sorted_items() ]; - } - + } ## end foreach my $parent_ns ( @parent_ns_ips) # Step 5 foreach my $parent_ns_ip ( sort keys %delegation ) { foreach my $delegation_ns ( @{ $delegation{$parent_ns_ip} } ) { my $delegation_ns_name = do { - if ( $delegation_ns->isa('Zonemaster::Engine::Nameserver') ) { - $delegation_ns->name() + if ( $delegation_ns->isa( 'Zonemaster::Engine::Nameserver' ) ) { + $delegation_ns->name(); } else { $delegation_ns; @@ -881,31 +876,34 @@ sub consistency05 { }; if ( $zone->name()->is_in_bailiwick( $delegation_ns_name ) ) { - if ( $delegation_ns->isa('Zonemaster::Engine::DNSName') ) { - push @{$missing_glue{ lc $delegation_ns }}, $parent_ns_ip; + if ( $delegation_ns->isa( 'Zonemaster::Engine::DNSName' ) ) { + push @{ $missing_glue{ lc $delegation_ns } }, $parent_ns_ip; } - $delegation_id_ns->push($delegation_ns); + $delegation_id_ns->push( $delegation_ns ); } else { - $delegation_ood_ns->push($delegation_ns); + $delegation_ood_ns->push( $delegation_ns ); } - } - } + } ## end foreach my $delegation_ns (...) + } ## end foreach my $parent_ns_ip ( ...) # Step 6 { my %delegation_sets; for my $d ( keys %delegation ) { - my $s = join(";", @{$delegation{$d}}); - push @{$delegation_sets{$s}}, $d; + my $s = join( ";", @{ $delegation{$d} } ); + push @{ $delegation_sets{$s} }, $d; } if ( scalar %delegation_sets > 1 ) { push @results, _emit_log( CS05_INCONSISTENT_DELEGATION => {} ); - while ( my ($ns_deleg_list, $ns_list) = each %delegation_sets ) { - push @results, _emit_log( CS05_DELEGATION => { - ns_deleg_list => $ns_deleg_list, - ns_list => join( ';', sort @$ns_list ) - } ); + while ( my ( $ns_deleg_list, $ns_list ) = each %delegation_sets ) { + push @results, + _emit_log( + CS05_DELEGATION => { + ns_deleg_list => $ns_deleg_list, + ns_list => join( ';', sort @$ns_list ), + } + ); } } } @@ -914,9 +912,8 @@ sub consistency05 { if ( $zone->name() ne '.' ) { foreach my $fake_name ( Zonemaster::Engine::Recursor->get_fake_names( $zone->name() ) ) { $fake_name = name( $fake_name ); - my @fake_ns = map { - Zonemaster::Engine::Nameserver->new( { name => $fake_name, address => $_ } ) - } Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name(), $fake_name ); + my @fake_ns = map { Zonemaster::Engine::Nameserver->new( { name => $fake_name, address => $_ } ) } + Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name(), $fake_name ); if ( $zone->name()->is_in_bailiwick( $fake_name ) ) { if ( scalar @fake_ns == 0 ) { @@ -934,15 +931,15 @@ sub consistency05 { $delegation_ood_ns->push( @fake_ns ); } } - } - } + } ## end foreach my $fake_name ( Zonemaster::Engine::Recursor...) + } ## end if ( $zone->name() ne ...) # Step 8 if ( $zone->name() eq '.' ) { my @hint_ns = @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) }; foreach my $item ( @hint_ns ) { - if ( $item->isa( 'Zonemaster::Engine::DNSName') ) { + if ( $item->isa( 'Zonemaster::Engine::DNSName' ) ) { push @results, _emit_log( CS05_MISSING_GLUE_FOR_ROOT_NS => { nsname => $item } ); } else { @@ -952,11 +949,14 @@ sub consistency05 { } # Step 9 - while ( my ($ns, $ns_list) = each %missing_glue ) { - push @results, _emit_log( CS05_MISSING_GLUE_FOR_NS => { - nsname => $ns, - ns_list => join(';', @$ns_list) - } ); + while ( my ( $ns, $ns_list ) = each %missing_glue ) { + push @results, + _emit_log( + CS05_MISSING_GLUE_FOR_NS => { + nsname => $ns, + ns_list => join( ';', @$ns_list ), + } + ); } # Step 10 @@ -973,76 +973,74 @@ sub consistency05 { my @ns_nsnames = uniq map { name( lc $_->nsdname() ) } $p->get_records_for_name( 'NS', $zone ); $child_zone_ns{ $ns->address()->short() } = \@ns_nsnames if scalar @ns_nsnames > 0; - my @id_ns = uniq ( - grep( { $zone->name()->is_in_bailiwick(name($_)) } @ns_nsnames ), - $delegation_id_ns->names() - ); + my @id_ns = + uniq( grep( { $zone->name()->is_in_bailiwick( name( $_ ) ) } @ns_nsnames ), $delegation_id_ns->names() ); foreach my $s ( @id_ns ) { foreach my $qtype ( qw(A AAAA) ) { - my $p = Zonemaster::Engine::Recursor->recurse( $s, $qtype, 'IN', [ $ns ] ); + my $p = Zonemaster::Engine::Recursor->recurse( $s, $qtype, 'IN', [$ns] ); next unless defined $p and $p->rcode eq 'NOERROR' and $p->aa; $auth_addr_records_in_child->push( - map { - Zonemaster::Engine::Nameserver->new( { name => $s, address => $_->address() } ) - } $p->get_records_for_name( $qtype, $s, 'answer' ) - ); + map { Zonemaster::Engine::Nameserver->new( { name => $s, address => $_->address() } ) } + $p->get_records_for_name( $qtype, $s, 'answer' ) ); } } - } + } ## end foreach my $ns ( @child_ns_ips) # Step 12 if ( scalar %child_zone_ns == 0 ) { - push @results, _emit_log( CS05_CHILD_ZONE_LAME => { ns_list => join(';', @child_ns_ips) } ); + push @results, _emit_log( CS05_CHILD_ZONE_LAME => { ns_list => join( ';', @child_ns_ips ) } ); goto out; } # Step 13 foreach my $n ( $delegation_id_ns->names() ) { - my $parent_glue = Zonemaster::Engine::NameserverSet->new( - grep { $_->isa('Zonemaster::Engine::Nameserver') } $delegation_id_ns->get($n) - ); + my $parent_glue = Zonemaster::Engine::NameserverSet->new( grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } + $delegation_id_ns->get( $n ) ); next if $parent_glue->is_empty(); my $child_auth = Zonemaster::Engine::NameserverSet->new(); - $child_auth->push( $auth_addr_records_in_child->get($n) ); + $child_auth->push( $auth_addr_records_in_child->get( $n ) ); my ( $only_in_parent, $only_in_child ) = $parent_glue->difference( $child_auth ); if ( $child_auth->is_empty() ) { push @results, _emit_log( CS05_ID_ADDR_MISSING => { nsname => $n } ); } elsif ( not $only_in_parent->is_empty() ) { - push @results, _emit_log( CS05_ID_ADDR_MISMATCH => { - nsname => $n, - ns_ip_list_glue => join( ';', map { $_->address()->short() } $only_in_parent->sorted_items() ), - ns_ip_list_zone => join( ';', map { $_->address()->short() } $child_auth->sorted_items() ) - } ); + push @results, + _emit_log( + CS05_ID_ADDR_MISMATCH => { + nsname => $n, + ns_ip_list_glue => join( ';', map { $_->address()->short() } $only_in_parent->sorted_items() ), + ns_ip_list_zone => join( ';', map { $_->address()->short() } $child_auth->sorted_items() ), + } + ); } elsif ( not $only_in_child->is_empty() ) { $extra_address_child{ $_->address()->short() } = 1 foreach $only_in_child->items(); } - } + } ## end foreach my $n ( $delegation_id_ns...) # Step 14 if ( scalar %extra_address_child ) { - push @results, _emit_log( CS05_EXTRA_ADDR_CHILD => { - ns_list => join(';', sort keys %extra_address_child ) - } ); + push @results, + _emit_log( + CS05_EXTRA_ADDR_CHILD => { + ns_list => join( ';', sort keys %extra_address_child ) + } + ); } # Step 15 foreach my $n ( $delegation_ood_ns->names() ) { - my $set = Zonemaster::Engine::NameserverSet->new( - grep { $_->isa('Zonemaster::Engine::Nameserver') } $delegation_ood_ns->get($n) - ); + my $set = Zonemaster::Engine::NameserverSet->new( grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } + $delegation_ood_ns->get( $n ) ); next if $set->is_empty(); my $lookup = Zonemaster::Engine::NameserverSet->new( - map { - Zonemaster::Engine::Nameserver->new( { name => $_->owner(), address => $_->address() } ) - } - map { + map { Zonemaster::Engine::Nameserver->new( { name => $_->owner(), address => $_->address() } ) } + map { my $p = Zonemaster::Engine::Recursor->recurse( $n, $_ ); if ( defined $p and $p->rcode eq 'NOERROR' ) { $p->get_records_for_name( $_, $n, 'answer' ); @@ -1050,19 +1048,22 @@ sub consistency05 { else { (); } - } ( qw(A AAAA) ) + } ( qw(A AAAA) ) ); if ( not $lookup->is_empty() ) { if ( not $set->equals( $lookup ) ) { - push @results, _emit_log( CS05_OOD_ADDR_MISMATCH => { - nsname => $n, - ns_ip_list_ref => join( ";", map { $_->address() } $set->sorted_items() ), - ns_ip_list_lookup => join( ";", map { $_->address() } $lookup->sorted_items() ) - } ); + push @results, + _emit_log( + CS05_OOD_ADDR_MISMATCH => { + nsname => $n, + ns_ip_list_ref => join( ";", map { $_->address() } $set->sorted_items() ), + ns_ip_list_lookup => join( ";", map { $_->address() } $lookup->sorted_items() ), + } + ); } } - } + } ## end foreach my $n ( $delegation_ood_ns...) # Step 16 if ( not grep /^CS05_/, map { $_->tag() } @results ) { @@ -1071,7 +1072,7 @@ sub consistency05 { out: return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); -} ## end sub consistency05 +} ## end sub consistency05 =over @@ -1098,8 +1099,10 @@ sub consistency06 { my %mnames; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }; diff --git a/lib/Zonemaster/Engine/Test/DNSSEC.pm b/lib/Zonemaster/Engine/Test/DNSSEC.pm index bdcf9363c..a31fb2f9b 100644 --- a/lib/Zonemaster/Engine/Test/DNSSEC.pm +++ b/lib/Zonemaster/Engine/Test/DNSSEC.pm @@ -7,15 +7,15 @@ use version; our $VERSION = version->declare( "v1.1.58" ); use Carp; use List::Compare; -use List::MoreUtils qw[any uniq]; -use List::Util qw[min]; +use List::MoreUtils qw[any uniq]; +use List::Util qw[min]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; use Zonemaster::LDNS::RR; use Zonemaster::Engine::Profile; use Zonemaster::Engine::Constants qw[:algo :soa :ip]; -use Zonemaster::Engine::Util qw[name should_run_test]; +use Zonemaster::Engine::Util qw[name should_run_test]; use Zonemaster::Engine::TestMethods; use Zonemaster::Engine::TestMethodsV2; @@ -137,7 +137,8 @@ Readonly::Hash our %algo_properties => ( sig => 1, }, ( - map { $_ => { status => $ALGO_STATUS_UNASSIGNED, description => q{Unassigned}, mnemonic => q{UNASSIGNED} } } ( 18 .. 22 ) + map { $_ => { status => $ALGO_STATUS_UNASSIGNED, description => q{Unassigned}, mnemonic => q{UNASSIGNED} } } + ( 18 .. 22 ) ), 23 => { status => $ALGO_STATUS_OTHER, @@ -146,10 +147,12 @@ Readonly::Hash our %algo_properties => ( sig => 1, }, ( - map { $_ => { status => $ALGO_STATUS_UNASSIGNED, description => q{Unassigned}, mnemonic => q{UNASSIGNED} } } ( 24 .. 122 ) + map { $_ => { status => $ALGO_STATUS_UNASSIGNED, description => q{Unassigned}, mnemonic => q{UNASSIGNED} } } + ( 24 .. 122 ) ), ( - map { $_ => { status => $ALGO_STATUS_RESERVED, description => q{Reserved}, mnemonic => q{RESERVED} } } ( 123 .. 251 ) + map { $_ => { status => $ALGO_STATUS_RESERVED, description => q{Reserved}, mnemonic => q{RESERVED} } } + ( 123 .. 251 ) ), 252 => { status => $ALGO_STATUS_NOT_ZONE_SIGN, @@ -211,13 +214,11 @@ Readonly::Hash our %digest_algorithms => ( 4 => q{SHA-384}, 5 => q{GOST R 34.11-2012}, 6 => q{SM3}, - ( - map { $_ => q{Unassigned} } ( 7 .. 127 ) - ), + ( map { $_ => q{Unassigned} } ( 7 .. 127 ) ), ( map { $_ => q{Reserved} } ( 128 .. 252 ) ), - ( + ( map { $_ => q{Reserved for Private Use} } ( 253 .. 254 ) ), 255 => q{Unassigned}, @@ -238,29 +239,27 @@ Readonly::Hash our %dnssec01_tags_mapping => ( 4 => q{DS01_DS_ALGO_OK}, 5 => q{DS01_DS_ALGO_OK}, 6 => q{DS01_DS_ALGO_OK}, - ( - map { $_ => q{DS01_DS_ALGO_UNASSIGNED} } ( 7 .. 127 ) - ), + ( map { $_ => q{DS01_DS_ALGO_UNASSIGNED} } ( 7 .. 127 ) ), ( map { $_ => q{DS01_DS_ALGO_RESERVED} } ( 128 .. 252 ) ), - ( + ( map { $_ => q{DS01_DS_ALGO_PRIVATE} } ( 253 .. 254 ) ), 255 => q{DS01_DS_ALGO_UNASSIGNED}, ); Readonly::Hash our %dnssec05_tags_mapping => ( - 0 => q{DS05_ALGO_NOT_ZONE_SIGN}, - 1 => q{DS05_ALGO_DEPRECATED}, - 2 => q{DS05_ALGO_NOT_ZONE_SIGN}, - 3 => q{DS05_ALGO_DEPRECATED}, - 4 => q{DS05_ALGO_RESERVED}, - 5 => q{DS05_ALGO_DEPRECATED}, - 6 => q{DS05_ALGO_DEPRECATED}, - 7 => q{DS05_ALGO_DEPRECATED}, - 8 => q{DS05_ALGO_OK}, - 9 => q{DS05_ALGO_RESERVED}, + 0 => q{DS05_ALGO_NOT_ZONE_SIGN}, + 1 => q{DS05_ALGO_DEPRECATED}, + 2 => q{DS05_ALGO_NOT_ZONE_SIGN}, + 3 => q{DS05_ALGO_DEPRECATED}, + 4 => q{DS05_ALGO_RESERVED}, + 5 => q{DS05_ALGO_DEPRECATED}, + 6 => q{DS05_ALGO_DEPRECATED}, + 7 => q{DS05_ALGO_DEPRECATED}, + 8 => q{DS05_ALGO_OK}, + 9 => q{DS05_ALGO_RESERVED}, 10 => q{DS05_ALGO_NOT_RECOMMENDED}, 11 => q{DS05_ALGO_RESERVED}, 12 => q{DS05_ALGO_DEPRECATED}, @@ -269,9 +268,7 @@ Readonly::Hash our %dnssec05_tags_mapping => ( 15 => q{DS05_ALGO_OK}, 16 => q{DS05_ALGO_OK}, 17 => q{DS05_ALGO_OK}, - ( - map { $_ => q{DS05_ALGO_UNASSIGNED} } ( 18 .. 22 ) - ), + ( map { $_ => q{DS05_ALGO_UNASSIGNED} } ( 18 .. 22 ) ), 23 => q{DS05_ALGO_OK}, ( map { $_ => q{DS05_ALGO_UNASSIGNED} } ( 24 .. 122 ) @@ -414,7 +411,7 @@ sub metadata { DS01_PARENT_ZONE_NO_DS DS01_ROOT_N_NO_UNDEL_DS DS01_UNDEL_N_NO_UNDEL_DS - ) + ) ], dnssec02 => [ qw( @@ -427,7 +424,7 @@ sub metadata { DS02_NO_MATCH_DS_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS DS02_RRSIG_NOT_VALID_BY_DNSKEY - ) + ) ], dnssec03 => [ qw( @@ -450,7 +447,7 @@ sub metadata { DS03_SERVER_NO_DNSSEC_SUPPORT DS03_SERVER_NO_NSEC3 DS03_UNASSIGNED_FLAG_USED - ) + ) ], dnssec04 => [ qw( @@ -462,7 +459,7 @@ sub metadata { DURATION_OK TEST_CASE_END TEST_CASE_START - ) + ) ], dnssec05 => [ qw( @@ -476,7 +473,7 @@ sub metadata { DS05_NO_RESPONSE DS05_SERVER_NO_DNSSEC DS05_ZONE_NO_DNSSEC - ) + ) ], dnssec06 => [ qw( @@ -484,7 +481,7 @@ sub metadata { EXTRA_PROCESSING_BROKEN TEST_CASE_END TEST_CASE_START - ) + ) ], dnssec07 => [ qw( @@ -501,7 +498,7 @@ sub metadata { DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_UNEXP_RCODE_RESP_DNSKEY - ) + ) ], dnssec08 => [ qw( @@ -511,7 +508,7 @@ sub metadata { DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY - ) + ) ], dnssec09 => [ qw( @@ -521,7 +518,7 @@ sub metadata { DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID - ) + ) ], dnssec10 => [ qw( @@ -563,7 +560,7 @@ sub metadata { DS10_NONSTANDARD_NSEC_RESPONSE DS10_SERVER_NO_DNSSEC DS10_ZONE_NO_DNSSEC - ) + ) ], dnssec11 => [ qw( @@ -576,14 +573,14 @@ sub metadata { DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_DS_BUT_UNSIGNED_ZONE - ), + ), ], dnssec13 => [ qw( DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_NS DS13_ALGO_NOT_SIGNED_SOA - ), + ), ], dnssec14 => [ qw( @@ -597,7 +594,7 @@ sub metadata { KEY_SIZE_OK TEST_CASE_END TEST_CASE_START - ), + ), ], dnssec15 => [ qw( @@ -608,7 +605,7 @@ sub metadata { DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY - ), + ), ], dnssec16 => [ qw( @@ -623,7 +620,7 @@ sub metadata { DS16_DELETE_CDS DS16_DNSKEY_NOT_SIGNED_BY_CDS DS16_MIXED_DELETE_CDS - ), + ), ], dnssec17 => [ qw( @@ -638,13 +635,13 @@ sub metadata { DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY - ), + ), ], dnssec18 => [ qw( DS18_NO_MATCH_CDS_RRSIG_DS DS18_NO_MATCH_CDNSKEY_RRSIG_DS - ), + ), ], }; } ## end sub metadata @@ -745,67 +742,65 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS01_DS_ALGO_2_MISSING => sub { __x # DNSSEC:DS01_DS_ALGO_2_MISSING - 'There is a DS record with keytag {keytag}. A DS record using digest algorithm 2 (SHA-256) ' - . 'is missing. Fetched from parent name servers "{ns_list}".', - @_; + 'There is a DS record with keytag {keytag}. A DS record using digest algorithm 2 (SHA-256) ' + . 'is missing. Fetched from parent name servers "{ns_list}".', + @_; }, DS01_DS_ALGO_DEPRECATED => sub { __x # DNSSEC:DS01_DS_ALGO_DEPRECATED - 'The DS record with keytag {keytag} uses a deprecated digest algorithm {ds_algo_num} ' - . '({ds_algo_descr}). Fetched from parent name servers "{ns_list}".', + 'The DS record with keytag {keytag} uses a deprecated digest algorithm {ds_algo_num} ' + . '({ds_algo_descr}). Fetched from parent name servers "{ns_list}".', @_; }, DS01_DS_ALGO_NOT_DS => sub { __x # DNSSEC:DS01_DS_ALGO_NOT_DS - 'The DS record with keytag {keytag} uses a digest algorithm {ds_algo_num} ({ds_algo_descr}) ' - . 'not meant for DS records. Fetched from parent name servers "{ns_list}".', + 'The DS record with keytag {keytag} uses a digest algorithm {ds_algo_num} ({ds_algo_descr}) ' + . 'not meant for DS records. Fetched from parent name servers "{ns_list}".', @_; }, DS01_DS_ALGO_PRIVATE => sub { __x # DNSSEC:DS01_DS_ALGO_PRIVATE - 'The DS record with keytag {keytag} uses a digest algorithm {ds_algo_num} for private use. ' - . 'Fetched from parent name servers "{ns_list}".', + 'The DS record with keytag {keytag} uses a digest algorithm {ds_algo_num} for private use. ' + . 'Fetched from parent name servers "{ns_list}".', @_; }, DS01_DS_ALGO_RESERVED => sub { __x # DNSSEC:DS01_DS_ALGO_RESERVED - 'The DS record with keytag {keytag} uses a reserved digest algorithm {ds_algo_num} on name ' - . 'servers "{ns_list}".', + 'The DS record with keytag {keytag} uses a reserved digest algorithm {ds_algo_num} on name ' + . 'servers "{ns_list}".', @_; }, DS01_DS_ALGO_UNASSIGNED => sub { __x # DNSSEC:DS01_DS_ALGO_UNASSIGNED - 'The DS record with keytag {keytag} uses an unassigned digest algorithm {ds_algo_num} on parent ' - . 'name servers "{ns_list}".', + 'The DS record with keytag {keytag} uses an unassigned digest algorithm {ds_algo_num} on parent ' + . 'name servers "{ns_list}".', @_; }, DS01_NO_RESPONSE => sub { __x # DNSSEC:DS01_NO_RESPONSE - 'No response or error in response from all parent name servers on the DS query. Name servers ' - . 'are "{ns_list}".', + 'No response or error in response from all parent name servers on the DS query. Name servers ' + . 'are "{ns_list}".', @_; }, DS01_PARENT_SERVER_NO_DS => sub { __x # DNSSEC:DS01_PARENT_SERVER_NO_DS - 'The following name servers do not provide DS record or have not been properly configured. ' - . 'Fetched from parent name servers "{ns_list}".', + 'The following name servers do not provide DS record or have not been properly configured. ' + . 'Fetched from parent name servers "{ns_list}".', @_; }, DS01_PARENT_ZONE_NO_DS => sub { __x # DNSSEC:DS01_PARENT_ZONE_NO_DS - 'The parent zone provides no DS records for the child zone. Fetched from parent name ' - . 'servers "{ns_list}".', + 'The parent zone provides no DS records for the child zone. Fetched from parent name ' + . 'servers "{ns_list}".', @_; }, DS01_ROOT_N_NO_UNDEL_DS => sub { __x # DNSSEC:DS01_ROOT_N_NO_UNDEL_DS - 'Tested zone is the root zone, but no undelegated DS has been provided. DS is not tested.', - @_; + 'Tested zone is the root zone, but no undelegated DS has been provided. DS is not tested.', @_; }, DS01_UNDEL_N_NO_UNDEL_DS => sub { __x # DNSSEC:DS01_UNDEL_N_NO_UNDEL_DS - 'Tested zone is undelegated, but no undelegated DS has been provided. DS is not tested.', - @_; + 'Tested zone is undelegated, but no undelegated DS has been provided. DS is not tested.', @_; }, DS02_ALGO_NOT_SUPPORTED_BY_ZM => sub { __x # DNSSEC:DS02_ALGO_NOT_SUPPORTED_BY_ZM @@ -913,8 +908,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS03_LEGAL_EMPTY_SALT => sub { __x # DNSSEC:DS03_LEGAL_EMPTY_SALT - 'The following servers respond with a legal empty salt in NSEC3. ' - . 'Fetched from name servers "{ns_list}".', + 'The following servers respond with a legal empty salt in NSEC3. ' . 'Fetched from name servers "{ns_list}".', @_; }, DS03_LEGAL_HASH_ALGO => sub { @@ -943,7 +937,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS03_NO_RESPONSE_NSEC_QUERY => sub { __x # DNSSEC:DS03_NO_RESPONSE_NSEC_QUERY - 'The following servers do not respond to NSEC query. Fetched from name servers "{ns_list}".', @_; + 'The following servers do not respond to NSEC query. Fetched from name servers "{ns_list}".', @_; }, DS03_NSEC3_OPT_OUT_DISABLED => sub { __x # DNSSEC:DS03_NSEC3_OPT_OUT_DISABLED @@ -960,9 +954,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS03_NSEC3_OPT_OUT_ENABLED_TLD => sub { __x # DNSSEC:DS03_NSEC3_OPT_OUT_ENABLED_TLD - 'The following servers respond with NSEC3 opt-out enabled. ' - . 'Fetched from name servers "{ns_list}".', - @_; + 'The following servers respond with NSEC3 opt-out enabled. ' . 'Fetched from name servers "{ns_list}".', @_; }, DS03_SERVER_NO_DNSSEC_SUPPORT => sub { __x # DNSSEC:DS03_SERVER_NO_DNSSEC_SUPPORT @@ -1028,7 +1020,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS05_NO_RESPONSE => sub { __x # DNSSEC:DS05_NO_RESPONSE - 'No response or error in response from all name servers on the DNSKEY query. Failing name servers: "{ns_list}".', +'No response or error in response from all name servers on the DNSKEY query. Failing name servers: "{ns_list}".', @_; }, DS05_SERVER_NO_DNSSEC => sub { @@ -1073,8 +1065,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS07_NOT_SIGNED_ON_SERVER => sub { __x # DNSSEC:DS07_NOT_SIGNED_ON_SERVER - 'The following name servers respond with no DNSKEY (unsigned child zone). ' - . 'Name servers: "{ns_list}".', + 'The following name servers respond with no DNSKEY (unsigned child zone). ' . 'Name servers: "{ns_list}".', @_; }, DS07_NO_DS_ON_PARENT_SERVER => sub { @@ -1089,8 +1080,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS07_NO_RESPONSE_DNSKEY => sub { __x # DNSSEC:DS07_NO_RESPONSE_DNSKEY - 'The following name servers do not respond on DNSKEY query with DO bit set. ' - . 'Name servers: "{ns_list}".', + 'The following name servers do not respond on DNSKEY query with DO bit set. ' . 'Name servers: "{ns_list}".', @_; }, DS07_SIGNED => sub { @@ -1099,9 +1089,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS07_SIGNED_ON_SERVER => sub { __x # DNSSEC:DS07_SIGNED_ON_SERVER - 'The following name servers respond with DNSKEY (signed child zone). ' - . 'Name servers: "{ns_list}".', - @_; + 'The following name servers respond with DNSKEY (signed child zone). ' . 'Name servers: "{ns_list}".', @_; }, DS07_UNEXP_RCODE_RESP_DNSKEY => sub { __x # DNSSEC:DS07_UNEXP_RCODE_RESP_DNSKEY @@ -1196,13 +1184,11 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_ERR_MULT_NSEC => sub { __x # DNSSEC:DS10_ERR_MULT_NSEC - 'Multiple NSEC records when one is expected. Fetched from name servers "{ns_list}".', - @_; + 'Multiple NSEC records when one is expected. Fetched from name servers "{ns_list}".', @_; }, DS10_ERR_MULT_NSEC3 => sub { __x # DNSSEC:DS10_ERR_MULT_NSEC3 - 'Multiple NSEC3 records when one is expected. Fetched from name servers "{ns_list}".', - @_; + 'Multiple NSEC3 records when one is expected. Fetched from name servers "{ns_list}".', @_; }, DS10_EXPECTED_NSEC_NSEC3_MISSING => sub { __x # DNSSEC:DS10_EXPECTED_NSEC_NSEC3_MISSING @@ -1212,23 +1198,19 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_HAS_NSEC => sub { __x # DNSSEC:DS10_HAS_NSEC - 'The zone has NSEC records. Fetched from name servers "{ns_list}".', - @_; + 'The zone has NSEC records. Fetched from name servers "{ns_list}".', @_; }, DS10_HAS_NSEC3 => sub { __x # DNSSEC:DS10_HAS_NSEC3 - 'The zone has NSEC3 records. Fetched from name servers "{ns_list}".', - @_; + 'The zone has NSEC3 records. Fetched from name servers "{ns_list}".', @_; }, DS10_INCONSISTENT_NSEC => sub { __x # DNSSEC:DS10_INCONSISTENT_NSEC - 'Inconsistent responses from zone with NSEC. Fetched from name servers "{ns_list}".', - @_; + 'Inconsistent responses from zone with NSEC. Fetched from name servers "{ns_list}".', @_; }, DS10_INCONSISTENT_NSEC3 => sub { __x # DNSSEC:DS10_INCONSISTENT_NSEC3 - 'Inconsistent responses from zone with NSEC3. Fetched from name servers "{ns_list}".', - @_; + 'Inconsistent responses from zone with NSEC3. Fetched from name servers "{ns_list}".', @_; }, DS10_INCONSISTENT_NSEC_NSEC3 => sub { __x # DNSSEC:DS10_INCONSISTENT_NSEC_NSEC3 @@ -1256,15 +1238,11 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_NSEC3PARAM_QUERY_RESPONSE_ERR => sub { __x # DNSSEC:DS10_NSEC3PARAM_QUERY_RESPONSE_ERR - 'No response or error in response on query for NSEC3PARAM. Fetched from ' - . 'name servers "{ns_list}".', - @_; + 'No response or error in response on query for NSEC3PARAM. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC3_ERR_TYPE_LIST => sub { __x # DNSSEC:DS10_NSEC3_ERR_TYPE_LIST - 'NSEC3 record for the zone apex with incorrect type list. Fetched from ' - . 'name servers "{ns_list}".', - @_; + 'NSEC3 record for the zone apex with incorrect type list. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC3_MISMATCHES_APEX => sub { __x # DNSSEC:DS10_NSEC3_MISMATCHES_APEX @@ -1274,15 +1252,11 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_NSEC3_MISSING_SIGNATURE => sub { __x # DNSSEC:DS10_NSEC3_MISSING_SIGNATURE - 'Missing RRSIG (signature) for the NSEC3 record or records. Fetched ' - . 'from name servers "{ns_list}".', - @_; + 'Missing RRSIG (signature) for the NSEC3 record or records. Fetched ' . 'from name servers "{ns_list}".', @_; }, DS10_NSEC3_NODATA_MISSING_SOA => sub { __x # DNSSEC:DS10_NSEC3_NODATA_MISSING_SOA - 'Missing SOA record in NODATA response with NSEC3. Fetched from ' - . 'name servers "{ns_list}".', - @_; + 'Missing SOA record in NODATA response with NSEC3. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC3_NODATA_WRONG_SOA => sub { __x # DNSSEC:DS10_NSEC3_NODATA_WRONG_SOA @@ -1292,8 +1266,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_NSEC3_NO_VERIFIED_SIGNATURE => sub { __x # DNSSEC:DS10_NSEC3_NO_VERIFIED_SIGNATURE - 'The RRSIG (signature) for the NSEC3 record cannot be verified. ' - . 'Fetched from name servers "{ns_list}".', + 'The RRSIG (signature) for the NSEC3 record cannot be verified. ' . 'Fetched from name servers "{ns_list}".', @_; }, DS10_NSEC3_RRSIG_EXPIRED => sub { @@ -1322,33 +1295,25 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_NSEC_ERR_TYPE_LIST => sub { __x # DNSSEC:DS10_NSEC_ERR_TYPE_LIST - 'NSEC record for the zone apex with incorrect type list. Fetched from name ' - . 'servers "{ns_list}".', - @_; + 'NSEC record for the zone apex with incorrect type list. Fetched from name ' . 'servers "{ns_list}".', @_; }, DS10_NSEC_GIVES_ERR_ANSWER => sub { __x # DNSSEC:DS10_NSEC_GIVES_ERR_ANSWER - 'Unexpected DNS record in the answer section on an NSEC query. Fetched from ' - . 'name servers "{ns_list}".', + 'Unexpected DNS record in the answer section on an NSEC query. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC_MISMATCHES_APEX => sub { __x # DNSSEC:DS10_NSEC_MISMATCHES_APEX - 'The returned NSEC record has an unexpected non-apex owner name. Fetched from ' - . 'name servers "{ns_list}".', + 'The returned NSEC record has an unexpected non-apex owner name. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC_MISSING_SIGNATURE => sub { __x # DNSSEC:DS10_NSEC_MISSING_SIGNATURE - 'Missing RRSIG (signature) for the NSEC record or records. Fetched from ' - . 'name servers "{ns_list}".', - @_; + 'Missing RRSIG (signature) for the NSEC record or records. Fetched from ' . 'name servers "{ns_list}".', @_; }, DS10_NSEC_NODATA_MISSING_SOA => sub { __x # DNSSEC:DS10_NSEC_NODATA_MISSING_SOA - 'Missing SOA record in NODATA response with NSEC. Fetched from name ' - . 'servers "{ns_list}".', - @_; + 'Missing SOA record in NODATA response with NSEC. Fetched from name ' . 'servers "{ns_list}".', @_; }, DS10_NSEC_NODATA_WRONG_SOA => sub { __x # DNSSEC:DS10_NSEC_NODATA_WRONG_SOA @@ -1364,9 +1329,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS10_NSEC_QUERY_RESPONSE_ERR => sub { __x # DNSSEC:DS10_NSEC_QUERY_RESPONSE_ERR - 'No response or error in response on query for NSEC. Fetched from name ' - . 'servers "{ns_list}".', - @_; + 'No response or error in response on query for NSEC. Fetched from name ' . 'servers "{ns_list}".', @_; }, DS10_NSEC_RRSIG_EXPIRED => sub { __x # DNSSEC:DS10_NSEC_RRSIG_EXPIRED @@ -1415,54 +1378,39 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS11_INCONSISTENT_DS => sub { __x # DNSSEC:DS11_INCONSISTENT_DS - 'Parent name servers are inconsistent on the existence of DS.', - @_; + 'Parent name servers are inconsistent on the existence of DS.', @_; }, DS11_INCONSISTENT_SIGNED_ZONE => sub { __x # DNSSEC:DS11_INCONSISTENT_SIGNED_ZONE - 'Name servers for the child zone are inconsistent on whether the ' - . 'zone is signed or not.', - @_; + 'Name servers for the child zone are inconsistent on whether the ' . 'zone is signed or not.', @_; }, DS11_UNDETERMINED_DS => sub { __x # DNSSEC:DS11_UNDETERMINED_DS - 'It cannot be determined if the parent zone has DS for the child ' - . 'zone or not.', - @_; + 'It cannot be determined if the parent zone has DS for the child ' . 'zone or not.', @_; }, DS11_UNDETERMINED_SIGNED_ZONE => sub { __x # DNSSEC:DS11_UNDETERMINED_SIGNED_ZONE - 'It cannot be determined if the child zone is signed or not.', - @_; + 'It cannot be determined if the child zone is signed or not.', @_; }, DS11_PARENT_WITHOUT_DS => sub { __x # DNSSEC:DS11_PARENT_WITHOUT_DS - 'No DS record for the child zone found on parent nameservers with IP ' - . 'addresses "{ns_ip_list}".', - @_; + 'No DS record for the child zone found on parent nameservers with IP ' . 'addresses "{ns_ip_list}".', @_; }, DS11_PARENT_WITH_DS => sub { __x # DNSSEC:DS11_PARENT_WITH_DS - 'DS record for the child zone found on parent nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'DS record for the child zone found on parent nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS11_NS_WITH_SIGNED_ZONE => sub { __x # DNSSEC:DS11_NS_WITH_SIGNED_ZONE - 'Signed child zone found on nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'Signed child zone found on nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS11_NS_WITH_UNSIGNED_ZONE => sub { __x # DNSSEC:DS11_NS_WITH_UNSIGNED_ZONE - 'Unsigned child zone found on nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'Unsigned child zone found on nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS11_DS_BUT_UNSIGNED_ZONE => sub { __x # DNSSEC:DS11_DS_BUT_UNSIGNED_ZONE - 'The child zone is unsigned, but the parent zone has DS record.', - @_; + 'The child zone is unsigned, but the parent zone has DS record.', @_; }, DS13_ALGO_NOT_SIGNED_DNSKEY => sub { __x # DNSSEC:DS13_ALGO_NOT_SIGNED_DNSKEY @@ -1487,20 +1435,16 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS15_HAS_CDNSKEY_NO_CDS => sub { __x # DNSSEC:DS15_HAS_CDNSKEY_NO_CDS - 'CDNSKEY RRset is found on nameservers that resolve to IP addresses ' - . '({ns_ip_list}), but no CDS RRset.', + 'CDNSKEY RRset is found on nameservers that resolve to IP addresses ' . '({ns_ip_list}), but no CDS RRset.', @_; }, DS15_HAS_CDS_AND_CDNSKEY => sub { __x # DNSSEC:DS15_HAS_CDS_AND_CDNSKEY - 'CDNSKEY and CDS RRsets are found on nameservers that resolve to IP addresses ' - . '({ns_ip_list}).', - @_; + 'CDNSKEY and CDS RRsets are found on nameservers that resolve to IP addresses ' . '({ns_ip_list}).', @_; }, DS15_HAS_CDS_NO_CDNSKEY => sub { __x # DNSSEC:DS15_HAS_CDS_NO_CDNSKEY - 'CDS RRset is found on nameservers that resolve to IP addresses ' - . '({ns_ip_list}), but no CDNSKEY RRset.', + 'CDS RRset is found on nameservers that resolve to IP addresses ' . '({ns_ip_list}), but no CDNSKEY RRset.', @_; }, DS15_INCONSISTENT_CDNSKEY => sub { @@ -1561,9 +1505,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS16_CDS_UNSIGNED => sub { __x # DNSSEC:DS16_CDS_UNSIGNED - 'The CDS RRset is not signed. Fetched from the nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'The CDS RRset is not signed. Fetched from the nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS16_CDS_WITHOUT_DNSKEY => sub { __x # DNSSEC:DS16_CDS_WITHOUT_DNSKEY @@ -1573,9 +1515,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS16_DELETE_CDS => sub { __x # DNSSEC:DS16_DELETE_CDS - 'A single "delete" CDS record is found on the nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'A single "delete" CDS record is found on the nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS16_DNSKEY_NOT_SIGNED_BY_CDS => sub { __x # DNSSEC:DS16_DNSKEY_NOT_SIGNED_BY_CDS @@ -1630,9 +1570,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS17_CDNSKEY_UNSIGNED => sub { __x # DNSSEC:DS17_CDNSKEY_UNSIGNED - 'The CDNSKEY RRset is not signed. Fetched from the nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'The CDNSKEY RRset is not signed. Fetched from the nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS17_CDNSKEY_WITHOUT_DNSKEY => sub { __x # DNSSEC:DS17_CDNSKEY_WITHOUT_DNSKEY @@ -1642,9 +1580,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, DS17_DELETE_CDNSKEY => sub { __x # DNSSEC:DS17_DELETE_CDNSKEY - 'A single "delete" CDNSKEY record is found on the nameservers with IP addresses ' - . '"{ns_ip_list}".', - @_; + 'A single "delete" CDNSKEY record is found on the nameservers with IP addresses ' . '"{ns_ip_list}".', @_; }, DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY => sub { __x # DNSSEC:DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY @@ -1740,7 +1676,7 @@ Readonly my %TAG_DESCRIPTIONS => ( TEST_CASE_START => sub { __x # DNSSEC:TEST_CASE_START 'TEST_CASE_START {testcase}.', @_; - } + }, ); =over @@ -1817,27 +1753,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -1869,14 +1791,14 @@ sub dnssec01 { my @ignored_parent_ns_ip; my ( @responds_without_valid_ds, @responds_with_ds ); - my ( %algo_2_ds, %non_algo_2_ds ); + my ( %algo_2_ds, %non_algo_2_ds ); my %sets = ( 'DS01_DS_ALGO_DEPRECATED' => {}, - 'DS01_DS_ALGO_RESERVED' => {}, + 'DS01_DS_ALGO_RESERVED' => {}, 'DS01_DS_ALGO_UNASSIGNED' => {}, - 'DS01_DS_ALGO_PRIVATE' => {}, - 'DS01_DS_ALGO_NOT_DS' => {}, - 'DS01_DS_ALGO_OK' => {} + 'DS01_DS_ALGO_PRIVATE' => {}, + 'DS01_DS_ALGO_NOT_DS' => {}, + 'DS01_DS_ALGO_OK' => {}, ); my $parent_nss = Zonemaster::Engine::TestMethodsV2->get_parent_ns_names_and_ips( $zone ); @@ -1884,17 +1806,17 @@ sub dnssec01 { my @undelegated_ds; if ( my $parent = $zone->parent ) { foreach my $ns ( @{ $parent->ns } ) { - if ( $ns->fake_ds->{$zone->name} ) { - @undelegated_ds = @{ $ns->fake_ds->{$zone->name} }; + if ( $ns->fake_ds->{ $zone->name } ) { + @undelegated_ds = @{ $ns->fake_ds->{ $zone->name } }; if ( @undelegated_ds ) { - my $ns_ip = "-"; + my $ns_ip = "-"; foreach my $ds_data ( @undelegated_ds ) { my $digest = $ds_data->digtype; my $keytag = $ds_data->keytag; - push @{ $sets{$dnssec01_tags_mapping{$digest}}->{$digest}{$keytag} }, $ns_ip; + push @{ $sets{ $dnssec01_tags_mapping{$digest} }->{$digest}{$keytag} }, $ns_ip; if ( $digest == 2 ) { push @{ $algo_2_ds{$keytag} }, $ns_ip; @@ -1906,10 +1828,10 @@ sub dnssec01 { push @responds_with_ds, $ns_ip; $parent_nss = undef; - } - } - } - } + } ## end if ( @undelegated_ds ) + } ## end if ( $ns->fake_ds->{ $zone...}) + } ## end foreach my $ns ( @{ $parent...}) + } ## end if ( my $parent = $zone...) my @nss = @{ $parent_nss // [] }; @@ -1937,13 +1859,13 @@ sub dnssec01 { my $valid_ds_rr = 0; foreach my $ds_rr ( @rrs ) { - if ( $ds_rr->owner eq $zone->name->fqdn ){ + if ( $ds_rr->owner eq $zone->name->fqdn ) { $valid_ds_rr = 1; last; } } - if ( not $valid_ds_rr ){ + if ( not $valid_ds_rr ) { push @responds_without_valid_ds, @matching_nss; next; } @@ -1954,7 +1876,7 @@ sub dnssec01 { my $digest = $ds_rr->digtype; my $keytag = $ds_rr->keytag; - push @{ $sets{$dnssec01_tags_mapping{$digest}}->{$digest}{$keytag} }, @matching_nss; + push @{ $sets{ $dnssec01_tags_mapping{$digest} }->{$digest}{$keytag} }, @matching_nss; if ( $digest == 2 ) { push @{ $algo_2_ds{$keytag} }, @matching_nss; @@ -1963,83 +1885,80 @@ sub dnssec01 { push @{ $non_algo_2_ds{$keytag} }, @matching_nss; } } - } + } ## end foreach my $ns ( @nss ) - while ( my ($tag_name, $set_ref) = each %sets ) { - my %values = %{ $set_ref }; + while ( my ( $tag_name, $set_ref ) = each %sets ) { + my %values = %{$set_ref}; if ( %values ) { foreach my $digest ( keys %values ) { foreach my $keytag ( keys %{ $values{$digest} } ) { push @results, - _emit_log( - $tag_name => { - ns_list => join( q{;}, uniq sort @{ $values{$digest}{$keytag} } ), - keytag => $keytag, - ds_algo_num => $digest, - ds_algo_descr => $digest_algorithms{$digest} - } - ); + _emit_log( + $tag_name => { + ns_list => join( q{;}, uniq sort @{ $values{$digest}{$keytag} } ), + keytag => $keytag, + ds_algo_num => $digest, + ds_algo_descr => $digest_algorithms{$digest}, + } + ); } } } } if ( %non_algo_2_ds ) { - while ( my ($keytag, $ns_ips) = each %non_algo_2_ds ) { - my $lc = List::Compare->new( $ns_ips, $algo_2_ds{$keytag} ); + while ( my ( $keytag, $ns_ips ) = each %non_algo_2_ds ) { + my $lc = List::Compare->new( $ns_ips, $algo_2_ds{$keytag} ); my @unique_nss = $lc->get_unique; if ( @unique_nss ) { push @results, - _emit_log( - DS01_DS_ALGO_2_MISSING => { - ns_list => join( q{;}, uniq sort @unique_nss ), - keytag => $keytag - } - ); + _emit_log( + DS01_DS_ALGO_2_MISSING => { + ns_list => join( q{;}, uniq sort @unique_nss ), + keytag => $keytag, + } + ); } } } if ( not @responds_without_valid_ds and not @responds_with_ds and @ignored_parent_ns_ip ) { push @results, - _emit_log( - DS01_NO_RESPONSE => { - ns_list => join( q{;}, uniq sort @ignored_parent_ns_ip ) - } - ) + _emit_log( + DS01_NO_RESPONSE => { + ns_list => join( q{;}, uniq sort @ignored_parent_ns_ip ) + } + ); } if ( $zone->name eq '.' and not @undelegated_ds ) { - push @results, - _emit_log( - DS01_ROOT_N_NO_UNDEL_DS => {} - ) + push @results, _emit_log( DS01_ROOT_N_NO_UNDEL_DS => {} ); } - if ( $zone->name ne '.' and Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ) and not @undelegated_ds ) { - push @results, - _emit_log( - DS01_UNDEL_N_NO_UNDEL_DS => {} - ) + if ( $zone->name ne '.' + and Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ) + and not @undelegated_ds ) + { + push @results, _emit_log( DS01_UNDEL_N_NO_UNDEL_DS => {} ); } if ( @responds_without_valid_ds ) { if ( not @responds_with_ds ) { push @results, - _emit_log( - DS01_PARENT_ZONE_NO_DS => { - ns_list => join( q{;}, uniq sort @responds_without_valid_ds ) - } - ) + _emit_log( + DS01_PARENT_ZONE_NO_DS => { + ns_list => join( q{;}, uniq sort @responds_without_valid_ds ) + } + ); } else { push @results, - _emit_log( - DS01_PARENT_SERVER_NO_DS => { - ns_list => join( q{;}, uniq sort @responds_without_valid_ds ) - } - ) + _emit_log( + DS01_PARENT_SERVER_NO_DS => { + ns_list => join( q{;}, uniq sort @responds_without_valid_ds ) + } + ); } } @@ -2092,15 +2011,15 @@ sub dnssec02 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DS} ) ) { next; } my $ds_p = $ns->query( $zone->name, q{DS}, { dnssec => 1 } ); - if ( not $ds_p or $ds_p->rcode ne q{NOERROR} or not $ds_p->has_edns or not $ds_p->do or not $ds_p->aa) { + if ( not $ds_p or $ds_p->rcode ne q{NOERROR} or not $ds_p->has_edns or not $ds_p->do or not $ds_p->aa ) { next; } my @tmp_ds_records = $ds_p->get_records_for_name( q{DS}, $zone->name->string, q{answer} ); @@ -2120,7 +2039,7 @@ sub dnssec02 { push @ds_record, $tmp_ds_record; } } - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( not scalar @ds_record ) { @@ -2137,15 +2056,20 @@ sub dnssec02 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DNSKEY} ) ) { next; } my $dnskey_p = $ns->query( $zone->name, q{DNSKEY}, { dnssec => 1, usevc => 0 } ); - if ( not $dnskey_p or $dnskey_p->rcode ne q{NOERROR} or not $dnskey_p->has_edns or not $dnskey_p->do or not $dnskey_p->aa ) { + if ( not $dnskey_p + or $dnskey_p->rcode ne q{NOERROR} + or not $dnskey_p->has_edns + or not $dnskey_p->do + or not $dnskey_p->aa ) + { next; } my @dnskey_rrs = $dnskey_p->get_records_for_name( q{DNSKEY}, $zone->name->string, q{answer} ); @@ -2153,22 +2077,27 @@ sub dnssec02 { next; } - $responding_child_ns{$ns->address->short} = 1; + $responding_child_ns{ $ns->address->short } = 1; my @dnskey_rrsig = $dnskey_p->get_records_for_name( q{RRSIG}, $zone->name->string, q{answer} ); %dnskey_matching_ds = (); foreach my $ds ( @ds_record ) { - my $matching_dnskey = undef; + my $matching_dnskey = undef; my @matching_keytag_dnskeys = grep { $ds->keytag == $_->keytag } @dnskey_rrs; - my $match_ds_dnskey = 0; + my $match_ds_dnskey = 0; foreach my $matching_keytag_dnskey ( @matching_keytag_dnskeys ) { - if ( exists $LDNS_digest_algorithms_supported{$ds->digtype()} ) { - my $tmp_ds = $matching_keytag_dnskey->ds($LDNS_digest_algorithms_supported{$ds->digtype()}); - - if ( not $tmp_ds or ( $tmp_ds->hexdigest() eq $ds->hexdigest() and $matching_keytag_dnskey->algorithm() == $ds->algorithm() ) ) { + if ( exists $LDNS_digest_algorithms_supported{ $ds->digtype() } ) { + my $tmp_ds = $matching_keytag_dnskey->ds( $LDNS_digest_algorithms_supported{ $ds->digtype() } ); + + if ( + not $tmp_ds + or ( $tmp_ds->hexdigest() eq $ds->hexdigest() + and $matching_keytag_dnskey->algorithm() == $ds->algorithm() ) + ) + { $matching_dnskey = $matching_keytag_dnskey; $match_ds_dnskey = 1; last; @@ -2179,34 +2108,34 @@ sub dnssec02 { $match_ds_dnskey = 1; last; } - } + } ## end foreach my $matching_keytag_dnskey... - if ( scalar @matching_keytag_dnskeys >= 1 and not $match_ds_dnskey) { + if ( scalar @matching_keytag_dnskeys >= 1 and not $match_ds_dnskey ) { $matching_dnskey = shift @matching_keytag_dnskeys; } if ( not $matching_dnskey ) { - push @{ $no_dnskey_for_ds{$ds->keytag} }, $ns->address->short; + push @{ $no_dnskey_for_ds{ $ds->keytag } }, $ns->address->short; } else { if ( not $match_ds_dnskey ) { - push @{ $no_match_ds_dnskey{$ds->keytag} }, $ns->address->short; + push @{ $no_match_ds_dnskey{ $ds->keytag } }, $ns->address->short; } - if ( not $matching_dnskey->flags & 256 ) { # Bit 7 (ZONE) - push @{ $dnskey_not_for_zone_signing{$ds->keytag} }, $ns->address->short; + if ( not $matching_dnskey->flags & 256 ) { # Bit 7 (ZONE) + push @{ $dnskey_not_for_zone_signing{ $ds->keytag } }, $ns->address->short; next; } - if ( not $matching_dnskey->flags & 1 ) { # Bit 15 (SEP) - push @{ $dnskey_not_sep{$ds->keytag} }, $ns->address->short; + if ( not $matching_dnskey->flags & 1 ) { # Bit 15 (SEP) + push @{ $dnskey_not_sep{ $ds->keytag } }, $ns->address->short; } $dnskey_matching_ds{$matching_dnskey} = $matching_dnskey->keytag; - $has_dnskey_match_ds{$ns->address->short} = 1; + $has_dnskey_match_ds{ $ns->address->short } = 1; foreach my $dnskey ( keys %dnskey_matching_ds ) { my @matching_keytag_rrsigs = grep { $dnskey_matching_ds{$dnskey} == $_->keytag } @dnskey_rrsig; - my $time = $dnskey_p->timestamp; - my $found_match = 0; + my $time = $dnskey_p->timestamp; + my $found_match = 0; foreach my $rrsig_record ( @matching_keytag_rrsigs ) { my $msg = q{}; @@ -2215,10 +2144,11 @@ sub dnssec02 { #my $validate = $rrsig_record->verify_time( \@key_list, \@key_list, $time, $msg ); my $validate = $rrsig_record->verify_time( \@dnskey_rrs, \@dnskey_rrs, $time, $msg ); if ( not $validate and $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$rrsig_record->keytag}{$rrsig_record->algorithm} }, $ns->address->short; + push @{ $algo_not_supported_by_zm{ $rrsig_record->keytag }{ $rrsig_record->algorithm } + }, $ns->address->short; } elsif ( not $validate ) { - push @{ $rrsig_not_valid_by_dnskey{$rrsig_record->keytag} }, $ns->address->short; + push @{ $rrsig_not_valid_by_dnskey{ $rrsig_record->keytag } }, $ns->address->short; } else { $found_match++; @@ -2226,104 +2156,104 @@ sub dnssec02 { } if ( not scalar @matching_keytag_rrsigs or not $found_match ) { - push @{ $no_matching_dnskey_rrsig{$dnskey_matching_ds{$dnskey}} }, $ns->address->short; + push @{ $no_matching_dnskey_rrsig{ $dnskey_matching_ds{$dnskey} } }, $ns->address->short; } else { - $has_rrsig_match_ds{$ns->address->short} = 1; + $has_rrsig_match_ds{ $ns->address->short } = 1; } - } - } - } - } - } + } ## end foreach my $dnskey ( keys %dnskey_matching_ds) + } ## end else [ if ( not $matching_dnskey)] + } ## end foreach my $ds ( @ds_record) + } ## end for my $nss_key ( sort ...) + } ## end if ( $continue_with_child_tests) if ( scalar keys %no_dnskey_for_ds ) { push @results, map { - _emit_log( - DS02_NO_DNSKEY_FOR_DS => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_dnskey_for_ds{$_} } ) - } - ) + _emit_log( + DS02_NO_DNSKEY_FOR_DS => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_dnskey_for_ds{$_} } ), + } + ) } keys %no_dnskey_for_ds; } if ( scalar keys %no_match_ds_dnskey ) { push @results, map { - _emit_log( - DS02_NO_MATCH_DS_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_match_ds_dnskey{$_} } ) - } - ) + _emit_log( + DS02_NO_MATCH_DS_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_match_ds_dnskey{$_} } ), + } + ) } keys %no_match_ds_dnskey; } if ( scalar keys %dnskey_not_for_zone_signing ) { push @results, map { - _emit_log( - DS02_DNSKEY_NOT_FOR_ZONE_SIGNING => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_for_zone_signing{$_} } ) - } - ) + _emit_log( + DS02_DNSKEY_NOT_FOR_ZONE_SIGNING => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_for_zone_signing{$_} } ), + } + ) } keys %dnskey_not_for_zone_signing; } if ( scalar keys %dnskey_not_sep ) { push @results, map { - _emit_log( - DS02_DNSKEY_NOT_SEP => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_sep{$_} } ) - } - ) + _emit_log( + DS02_DNSKEY_NOT_SEP => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_sep{$_} } ), + } + ) } keys %dnskey_not_sep; } if ( scalar keys %no_matching_dnskey_rrsig ) { push @results, map { - _emit_log( - DS02_NO_MATCHING_DNSKEY_RRSIG => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey_rrsig{$_} } ) - } - ) + _emit_log( + DS02_NO_MATCHING_DNSKEY_RRSIG => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey_rrsig{$_} } ), + } + ) } keys %no_matching_dnskey_rrsig; } if ( scalar keys %algo_not_supported_by_zm ) { foreach my $keytag ( keys %algo_not_supported_by_zm ) { push @results, map { - _emit_log( - DS02_ALGO_NOT_SUPPORTED_BY_ZM => { - keytag => $keytag, - algo_num => $_, - algo_mnemo => $algo_properties{$_}{mnemonic}, - ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ) - } - ) + _emit_log( + DS02_ALGO_NOT_SUPPORTED_BY_ZM => { + keytag => $keytag, + algo_num => $_, + algo_mnemo => $algo_properties{$_}{mnemonic}, + ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ), + } + ) } keys %{ $algo_not_supported_by_zm{$keytag} }; } } if ( scalar keys %rrsig_not_valid_by_dnskey ) { push @results, map { - _emit_log( - DS02_RRSIG_NOT_VALID_BY_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ) - } - ) + _emit_log( + DS02_RRSIG_NOT_VALID_BY_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ), + } + ) } keys %rrsig_not_valid_by_dnskey; } foreach my $ns_ip ( keys %responding_child_ns ) { push @ns_dnskey, $ns_ip if not exists $has_dnskey_match_ds{$ns_ip}; - push @ns_rrsig, $ns_ip if not exists $has_rrsig_match_ds{$ns_ip}; + push @ns_rrsig, $ns_ip if not exists $has_rrsig_match_ds{$ns_ip}; } if ( scalar @ns_dnskey ) { push @results, - _emit_log( - DS02_NO_VALID_DNSKEY_FOR_ANY_DS => { + _emit_log( + DS02_NO_VALID_DNSKEY_FOR_ANY_DS => { ns_ip_list => join( q{;}, sort @ns_dnskey ) - } - ) + } + ); } else { if ( scalar @ns_rrsig ) { @@ -2332,7 +2262,7 @@ sub dnssec02 { DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS => { ns_ip_list => join( q{;}, sort @ns_rrsig ) } - ) + ); } } @@ -2375,9 +2305,9 @@ sub dnssec03 { my %ip_already_processed; - foreach my $ns ( @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) } ){ - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + foreach my $ns ( @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) } ) { + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, qw{DNSKEY NSEC} ) ) { next; @@ -2423,219 +2353,207 @@ sub dnssec03 { my $rr = ( @nsec3_rrs )[0]; - push @{ $hash_algorithm{$rr->algorithm} }, $ns if defined $rr->algorithm; - push @{ $nsec3_flags{$rr->flags} }, $ns if defined $rr->flags; - push @{ $nsec3_iterations{$rr->iterations} }, $ns if defined $rr->iterations; + push @{ $hash_algorithm{ $rr->algorithm } }, $ns if defined $rr->algorithm; + push @{ $nsec3_flags{ $rr->flags } }, $ns if defined $rr->flags; + push @{ $nsec3_iterations{ $rr->iterations } }, $ns if defined $rr->iterations; if ( defined $rr->salt ) { - push @{ $nsec3_salt_length{length unpack('H*', $rr->salt)} }, $ns; + push @{ $nsec3_salt_length{ length unpack( 'H*', $rr->salt ) } }, $ns; } else { push @{ $nsec3_salt_length{0} }, $ns; } - } - } + } ## end else [ if ( not scalar @nsec3_rrs)] + } ## end foreach my $ns ( @{ Zonemaster::Engine::TestMethods...}) if ( not scalar @responds_with_dnskey and scalar @responds_without_dnskey ) { push @results, - _emit_log( - DS03_NO_DNSSEC_SUPPORT => { + _emit_log( + DS03_NO_DNSSEC_SUPPORT => { ns_list => join( q{;}, sort @responds_without_dnskey ) - } - ); + } + ); } if ( scalar @responds_with_dnskey and scalar @responds_without_dnskey ) { push @results, - _emit_log( - DS03_SERVER_NO_DNSSEC_SUPPORT => { + _emit_log( + DS03_SERVER_NO_DNSSEC_SUPPORT => { ns_list => join( q{;}, sort @responds_without_dnskey ) - } - ); + } + ); } if ( not scalar @responds_with_nsec3 and scalar @responds_without_nsec3 ) { push @results, - _emit_log( - DS03_NO_NSEC3 => { + _emit_log( + DS03_NO_NSEC3 => { ns_list => join( q{;}, sort @responds_without_nsec3 ) - } - ); + } + ); } if ( scalar @responds_with_nsec3 and scalar @responds_without_nsec3 ) { push @results, - _emit_log( - DS03_SERVER_NO_NSEC3 => { + _emit_log( + DS03_SERVER_NO_NSEC3 => { ns_list => join( q{;}, sort @responds_without_nsec3 ) - } - ); + } + ); } if ( scalar @multiple_nsec3 ) { push @results, - _emit_log( - DS03_ERR_MULT_NSEC3 => { + _emit_log( + DS03_ERR_MULT_NSEC3 => { ns_list => join( q{;}, sort @multiple_nsec3 ) - } - ); + } + ); } if ( scalar keys %hash_algorithm ) { if ( scalar keys %hash_algorithm > 1 ) { - push @results, - _emit_log( - DS03_INCONSISTENT_HASH_ALGO => {} - ); + push @results, _emit_log( DS03_INCONSISTENT_HASH_ALGO => {} ); } foreach my $algo ( keys %hash_algorithm ) { if ( $algo eq '1' ) { push @results, - _emit_log( - DS03_LEGAL_HASH_ALGO => { + _emit_log( + DS03_LEGAL_HASH_ALGO => { ns_list => join( q{;}, sort @{ $hash_algorithm{$algo} } ) - } - ); + } + ); } else { push @results, - _emit_log( - DS03_ILLEGAL_HASH_ALGO => { - ns_list => join( q{;}, sort @{ $hash_algorithm{$algo} } ), - algo_num => $algo - } - ); + _emit_log( + DS03_ILLEGAL_HASH_ALGO => { + ns_list => join( q{;}, sort @{ $hash_algorithm{$algo} } ), + algo_num => $algo, + } + ); } } - } + } ## end if ( scalar keys %hash_algorithm) if ( scalar keys %nsec3_flags ) { if ( scalar keys %nsec3_flags > 1 ) { - push @results, - _emit_log( - DS03_INCONSISTENT_NSEC3_FLAGS => {} - ); + push @results, _emit_log( DS03_INCONSISTENT_NSEC3_FLAGS => {} ); } foreach my $flag ( keys %nsec3_flags ) { # Makes a list of bit positions corresponding to flags that are set, where the most-significant bit is 0. - my @bit_positions = grep { $flag & (1 << ( 7 - $_ ) ) } (0..7); + my @bit_positions = grep { $flag & ( 1 << ( 7 - $_ ) ) } ( 0 .. 7 ); foreach my $bit ( grep { $_ >= 0 and $_ <= 6 } @bit_positions ) { push @results, - _emit_log( - DS03_UNASSIGNED_FLAG_USED => { + _emit_log( + DS03_UNASSIGNED_FLAG_USED => { ns_list => join( q{;}, sort @{ $nsec3_flags{$flag} } ), - int => $bit - } - ); + int => $bit, + } + ); } if ( grep { $_ == 7 } @bit_positions ) { # Note below that the Public Suffix List check is not yet implemented. if ( $zone->name eq '.' or $zone->name->next_higher eq '.' ) { push @results, - _emit_log( - DS03_NSEC3_OPT_OUT_ENABLED_TLD => { + _emit_log( + DS03_NSEC3_OPT_OUT_ENABLED_TLD => { ns_list => join( q{;}, sort @{ $nsec3_flags{$flag} } ) - } - ); + } + ); } else { push @results, - _emit_log( - DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD => { + _emit_log( + DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD => { ns_list => join( q{;}, sort @{ $nsec3_flags{$flag} } ) - } - ); + } + ); } } else { push @results, - _emit_log( - DS03_NSEC3_OPT_OUT_DISABLED => { + _emit_log( + DS03_NSEC3_OPT_OUT_DISABLED => { ns_list => join( q{;}, sort @{ $nsec3_flags{$flag} } ) - } - ); + } + ); } - } - } + } ## end foreach my $flag ( keys %nsec3_flags) + } ## end if ( scalar keys %nsec3_flags) if ( scalar keys %nsec3_iterations ) { if ( scalar keys %nsec3_iterations > 1 ) { - push @results, - _emit_log( - DS03_INCONSISTENT_ITERATION => {} - ); + push @results, _emit_log( DS03_INCONSISTENT_ITERATION => {} ); } foreach my $iter ( keys %nsec3_iterations ) { if ( $iter eq '0' ) { push @results, - _emit_log( - DS03_LEGAL_ITERATION_VALUE => { + _emit_log( + DS03_LEGAL_ITERATION_VALUE => { ns_list => join( q{;}, sort @{ $nsec3_iterations{$iter} } ) - } - ); + } + ); } else { push @results, - _emit_log( - DS03_ILLEGAL_ITERATION_VALUE => { + _emit_log( + DS03_ILLEGAL_ITERATION_VALUE => { ns_list => join( q{;}, sort @{ $nsec3_iterations{$iter} } ), - int => $iter - } - ); + int => $iter, + } + ); } } - } + } ## end if ( scalar keys %nsec3_iterations) if ( scalar keys %nsec3_salt_length ) { if ( scalar keys %nsec3_salt_length > 1 ) { - push @results, - _emit_log( - DS03_INCONSISTENT_SALT_LENGTH => {} - ); + push @results, _emit_log( DS03_INCONSISTENT_SALT_LENGTH => {} ); } foreach my $salt ( keys %nsec3_salt_length ) { if ( $salt eq '0' ) { push @results, - _emit_log( - DS03_LEGAL_EMPTY_SALT => { + _emit_log( + DS03_LEGAL_EMPTY_SALT => { ns_list => join( q{;}, sort @{ $nsec3_salt_length{$salt} } ) - } - ); - } + } + ); + } else { push @results, - _emit_log( - DS03_ILLEGAL_SALT_LENGTH => { + _emit_log( + DS03_ILLEGAL_SALT_LENGTH => { ns_list => join( q{;}, sort @{ $nsec3_salt_length{$salt} } ), - int => $salt - } - ); + int => $salt, + } + ); } } - } + } ## end if ( scalar keys %nsec3_salt_length) if ( scalar @no_response_nsec_query ) { push @results, - _emit_log( - DS03_NO_RESPONSE_NSEC_QUERY => { + _emit_log( + DS03_NO_RESPONSE_NSEC_QUERY => { ns_list => join( q{;}, sort @no_response_nsec_query ) - } - ); + } + ); } if ( scalar @error_response_nsec_query ) { push @results, - _emit_log( - DS03_ERROR_RESPONSE_NSEC_QUERY => { + _emit_log( + DS03_ERROR_RESPONSE_NSEC_QUERY => { ns_list => join( q{;}, sort @error_response_nsec_query ) - } - ); + } + ); } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); @@ -2681,7 +2599,7 @@ sub dnssec04 { push @results, _emit_log( RRSIG_EXPIRATION => { - date => scalar( gmtime($sig->expiration) ), + date => scalar( gmtime( $sig->expiration ) ), keytag => $sig->keytag, types => $sig->typecovered, } @@ -2689,9 +2607,12 @@ sub dnssec04 { my $remaining = $sig->expiration - int( $dnskey_p->timestamp ); my $result_remaining; - my $remaining_short_limit = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.REMAINING_SHORT} ); - my $remaining_long_limit = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.REMAINING_LONG} ); - my $duration_long_limit = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.DURATION_LONG} ); + my $remaining_short_limit = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.REMAINING_SHORT} ); + my $remaining_long_limit = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.REMAINING_LONG} ); + my $duration_long_limit = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.dnssec04.DURATION_LONG} ); if ( $remaining < 0 ) { # already expired $result_remaining = _emit_log( @@ -2778,19 +2699,19 @@ sub dnssec05 { my @responds_without_dnskey; my @responds_with_dnskey; my %sets = ( - 'DS05_ALGO_DEPRECATED' => {}, - 'DS05_ALGO_RESERVED' => {}, - 'DS05_ALGO_UNASSIGNED' => {}, + 'DS05_ALGO_DEPRECATED' => {}, + 'DS05_ALGO_RESERVED' => {}, + 'DS05_ALGO_UNASSIGNED' => {}, 'DS05_ALGO_NOT_RECOMMENDED' => {}, - 'DS05_ALGO_PRIVATE' => {}, - 'DS05_ALGO_NOT_ZONE_SIGN' => {}, - 'DS05_ALGO_OK' => {} + 'DS05_ALGO_PRIVATE' => {}, + 'DS05_ALGO_NOT_ZONE_SIGN' => {}, + 'DS05_ALGO_OK' => {}, ); - my @nss = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @nss = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); my %ip_already_processed; for my $ns ( @nss ) { @@ -2822,28 +2743,28 @@ sub dnssec05 { push @responds_with_dnskey, @matching_nss; foreach my $rr ( @dnskey_rrs ) { - my $algo = $rr->algorithm; + my $algo = $rr->algorithm; my $keytag = $rr->keytag; - push @{ $sets{$dnssec05_tags_mapping{$algo}}->{$algo}{$keytag} }, @matching_nss; + push @{ $sets{ $dnssec05_tags_mapping{$algo} }->{$algo}{$keytag} }, @matching_nss; } - } + } ## end for my $ns ( @nss ) - while ( my ($tag_name, $set_ref) = each %sets ) { - my %values = %{ $set_ref }; + while ( my ( $tag_name, $set_ref ) = each %sets ) { + my %values = %{$set_ref}; if ( %values ) { foreach my $algo ( keys %values ) { foreach my $keytag ( keys %{ $values{$algo} } ) { push @results, - _emit_log( - $tag_name => { - ns_list => join( q{;}, uniq sort @{ $values{$algo}{$keytag} } ), - keytag => $keytag, - algo_num => $algo, - algo_descr => $algo_properties{$algo}{description}, - algo_mnemo => $algo_properties{$algo}{mnemonic} - } - ); + _emit_log( + $tag_name => { + ns_list => join( q{;}, uniq sort @{ $values{$algo}{$keytag} } ), + keytag => $keytag, + algo_num => $algo, + algo_descr => $algo_properties{$algo}{description}, + algo_mnemo => $algo_properties{$algo}{mnemonic}, + } + ); } } } @@ -2855,7 +2776,7 @@ sub dnssec05 { DS05_NO_RESPONSE => { ns_list => join( q{;}, uniq sort @ignored_ns_ip ) } - ); + ); } if ( @responds_without_dnskey ) { @@ -2865,7 +2786,7 @@ sub dnssec05 { DS05_ZONE_NO_DNSSEC => { ns_list => join( q{;}, uniq sort @responds_without_dnskey ) } - ); + ); } else { push @results, @@ -2873,7 +2794,7 @@ sub dnssec05 { DS05_SERVER_NO_DNSSEC => { ns_list => join( q{;}, uniq sort @responds_without_dnskey ) } - ); + ); } } @@ -2924,7 +2845,7 @@ sub dnssec06 { EXTRA_PROCESSING_BROKEN => { server => $dnskey_p->answerfrom, keys => scalar( @keys ), - sigs => scalar( @sigs ) + sigs => scalar( @sigs ), } ); } @@ -2955,20 +2876,20 @@ sub dnssec07 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'DNSSEC07'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my $type_soa = q{SOA}; + my $type_soa = q{SOA}; my $type_dnskey = q{DNSKEY}; - my $type_ds = q{DS}; + my $type_ds = q{DS}; my @query_types = ( $type_soa, $type_dnskey, $type_ds ); - my ( @ignored_child_ns, @ignored_parent_ns_ip ); + my ( @ignored_child_ns, @ignored_parent_ns_ip ); my ( @no_response_dnskey, @signed_response ); - my ( @no_auth_dnskey, %error_rcode_dnskey ); - my ( @no_dnskey, @no_ds, @ds_in_response ); + my ( @no_auth_dnskey, %error_rcode_dnskey ); + my ( @no_dnskey, @no_ds, @ds_in_response ); - my @child_nss = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @child_nss = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); my %ip_already_processed; for my $ns ( @child_nss ) { @@ -2985,7 +2906,11 @@ sub dnssec07 { my $soa_p = $ns->query( $zone->name, $type_soa ); - if ( not $soa_p or $soa_p->rcode ne 'NOERROR' or not $soa_p->aa or not $soa_p->get_records( $type_soa, 'answer' ) ) { + if ( not $soa_p + or $soa_p->rcode ne 'NOERROR' + or not $soa_p->aa + or not $soa_p->get_records( $type_soa, 'answer' ) ) + { push @ignored_child_ns, @matching_nss; next; } @@ -3003,12 +2928,12 @@ sub dnssec07 { } if ( $dnskey_p->rcode ne 'NOERROR' ) { - push @{ $error_rcode_dnskey{$dnskey_p->rcode} }, @matching_nss; + push @{ $error_rcode_dnskey{ $dnskey_p->rcode } }, @matching_nss; next; } my @dnskey_rrs = $dnskey_p->get_records( $type_dnskey, 'answer' ); - my @rrsig_rrs = $dnskey_p->get_records( 'RRSIG', 'answer' ); + my @rrsig_rrs = $dnskey_p->get_records( 'RRSIG', 'answer' ); my $covered_dnskey = 0; foreach my $rr ( @rrsig_rrs ) { @@ -3024,15 +2949,15 @@ sub dnssec07 { else { push @no_dnskey, @matching_nss; } - } + } ## end for my $ns ( @child_nss) my $parent_ref = Zonemaster::Engine::TestMethodsV2->get_parent_ns_names_and_ips( $zone ); my @undelegated_ds; if ( my $parent = $zone->parent ) { foreach my $ns ( @{ $parent->ns } ) { - if ( $ns->fake_ds->{$zone->name} ) { - @undelegated_ds = @{ $ns->fake_ds->{$zone->name} }; + if ( $ns->fake_ds->{ $zone->name } ) { + @undelegated_ds = @{ $ns->fake_ds->{ $zone->name } }; if ( @undelegated_ds ) { push @ds_in_response, '-'; @@ -3043,7 +2968,7 @@ sub dnssec07 { } if ( not @signed_response ) { - $parent_ref = undef; + $parent_ref = undef; @ds_in_response = (); } @@ -3069,7 +2994,7 @@ sub dnssec07 { next; } - my @ds_rrs = $ds_p->get_records_for_name( $type_ds, $zone->name, q{answer} ); + my @ds_rrs = $ds_p->get_records_for_name( $type_ds, $zone->name, q{answer} ); my @rrsig_rrs = $ds_p->get_records_for_name( q{RRSIG}, $zone->name, q{answer} ); my $covered_ds = 0; @@ -3086,122 +3011,104 @@ sub dnssec07 { else { push @no_ds, @matching_nss; } - } + } ## end foreach my $ns ( @parent_nss) - my @combined = uniq ( @ignored_child_ns, @no_response_dnskey, @no_auth_dnskey, map { @{ $error_rcode_dnskey{$_} } } keys %error_rcode_dnskey ); - my $lc = List::Compare->new(\@combined, \@child_nss); + my @combined = + uniq( @ignored_child_ns, @no_response_dnskey, @no_auth_dnskey, + map { @{ $error_rcode_dnskey{$_} } } keys %error_rcode_dnskey, + ); + my $lc = List::Compare->new( \@combined, \@child_nss ); if ( not $lc->get_symmetric_difference ) { - push @results, - _emit_log( - DS07_NOT_SIGNED => {} - ); + push @results, _emit_log( DS07_NOT_SIGNED => {} ); } if ( @no_response_dnskey ) { push @results, - _emit_log( - DS07_NO_RESPONSE_DNSKEY => { - ns_list => join( q{;}, uniq sort @no_response_dnskey ) - } - ); + _emit_log( + DS07_NO_RESPONSE_DNSKEY => { + ns_list => join( q{;}, uniq sort @no_response_dnskey ) + } + ); } if ( @no_auth_dnskey ) { push @results, - _emit_log( - DS07_NON_AUTH_RESPONSE_DNSKEY => { - ns_list => join( q{;}, uniq sort @no_auth_dnskey ) - } - ); + _emit_log( + DS07_NON_AUTH_RESPONSE_DNSKEY => { + ns_list => join( q{;}, uniq sort @no_auth_dnskey ) + } + ); } if ( keys %error_rcode_dnskey ) { push @results, - _emit_log( - DS07_UNEXP_RCODE_RESP_DNSKEY => { - ns_list => join( q{;}, uniq sort @{ $error_rcode_dnskey{$_} } ), - rcode => $_ - } - ) for keys %error_rcode_dnskey; + _emit_log( + DS07_UNEXP_RCODE_RESP_DNSKEY => { + ns_list => join( q{;}, uniq sort @{ $error_rcode_dnskey{$_} } ), + rcode => $_, + } + ) for keys %error_rcode_dnskey; } if ( @signed_response ) { push @results, - _emit_log( - DS07_SIGNED_ON_SERVER => { - ns_list => join( q{;}, uniq sort @signed_response ) - } - ); + _emit_log( + DS07_SIGNED_ON_SERVER => { + ns_list => join( q{;}, uniq sort @signed_response ) + } + ); } if ( @no_dnskey ) { push @results, - _emit_log( - DS07_NOT_SIGNED_ON_SERVER => { - ns_list => join( q{;}, uniq sort @no_dnskey ) - } - ); + _emit_log( + DS07_NOT_SIGNED_ON_SERVER => { + ns_list => join( q{;}, uniq sort @no_dnskey ) + } + ); } if ( @signed_response and @no_dnskey ) { - push @results, - _emit_log( - DS07_INCONSISTENT_SIGNED => {} - ); + push @results, _emit_log( DS07_INCONSISTENT_SIGNED => {} ); } if ( @signed_response and not @no_dnskey ) { - push @results, - _emit_log( - DS07_SIGNED => {} - ); + push @results, _emit_log( DS07_SIGNED => {} ); } if ( not @signed_response and @no_dnskey ) { - push @results, - _emit_log( - DS07_NOT_SIGNED => {} - ); + push @results, _emit_log( DS07_NOT_SIGNED => {} ); } if ( @no_ds ) { push @results, - _emit_log( - DS07_NO_DS_ON_PARENT_SERVER => { - ns_list => join( q{;}, uniq sort @no_ds ) - } - ); + _emit_log( + DS07_NO_DS_ON_PARENT_SERVER => { + ns_list => join( q{;}, uniq sort @no_ds ) + } + ); } if ( @ds_in_response ) { push @results, - _emit_log( - DS07_DS_ON_PARENT_SERVER => { - ns_list => join( q{;}, uniq sort @ds_in_response ) - } - ); + _emit_log( + DS07_DS_ON_PARENT_SERVER => { + ns_list => join( q{;}, uniq sort @ds_in_response ) + } + ); } if ( @no_ds and @ds_in_response ) { - push @results, - _emit_log( - DS07_INCONSISTENT_DS => {} - ); + push @results, _emit_log( DS07_INCONSISTENT_DS => {} ); } if ( not @no_dnskey and @signed_response ) { if ( @no_ds and not @ds_in_response ) { - push @results, - _emit_log( - DS07_NO_DS_FOR_SIGNED_ZONE => {} - ); + push @results, _emit_log( DS07_NO_DS_FOR_SIGNED_ZONE => {} ); } if ( not @no_ds and @ds_in_response ) { - push @results, - _emit_log( - DS07_DS_FOR_SIGNED_ZONE => {} - ); + push @results, _emit_log( DS07_DS_FOR_SIGNED_ZONE => {} ); } } @@ -3244,8 +3151,8 @@ sub dnssec08 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DNSKEY} ) ) { next; @@ -3266,8 +3173,8 @@ sub dnssec08 { if ( not scalar @dnskey_records ) { next; } - @dnskey_records = $dnskey_p->get_records( q{DNSKEY}, q{answer} ); - my @rrsig_records = $dnskey_p->get_records( q{RRSIG}, q{answer} ); + @dnskey_records = $dnskey_p->get_records( q{DNSKEY}, q{answer} ); + my @rrsig_records = $dnskey_p->get_records( q{RRSIG}, q{answer} ); if ( not scalar @rrsig_records ) { push @dnskey_without_rrsig, $ns->address->short; @@ -3277,26 +3184,27 @@ sub dnssec08 { my $time = $dnskey_p->timestamp; foreach my $rrsig_record ( @rrsig_records ) { if ( $rrsig_record->inception > $time ) { - push @{ $dnskey_rrsig_not_yet_valid{$rrsig_record->keytag} }, $ns->address->short; + push @{ $dnskey_rrsig_not_yet_valid{ $rrsig_record->keytag } }, $ns->address->short; } elsif ( $rrsig_record->expiration < $time ) { - push @{ $dnskey_rrsig_expired{$rrsig_record->keytag} }, $ns->address->short; + push @{ $dnskey_rrsig_expired{ $rrsig_record->keytag } }, $ns->address->short; } else { - my $msg = q{}; + my $msg = q{}; my $validate = $rrsig_record->verify_time( \@dnskey_records, \@dnskey_records, $time, $msg ); if ( not $validate and $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$rrsig_record->keytag}{$rrsig_record->algorithm} }, $ns->address->short; + push @{ $algo_not_supported_by_zm{ $rrsig_record->keytag }{ $rrsig_record->algorithm } }, + $ns->address->short; } elsif ( not scalar grep { $_->keytag == $rrsig_record->keytag } @dnskey_records ) { - push @{ $no_matching_dnskey{$rrsig_record->keytag} }, $ns->address->short; + push @{ $no_matching_dnskey{ $rrsig_record->keytag } }, $ns->address->short; } elsif ( not $validate ) { - push @{ $rrsig_not_valid_by_dnskey{$rrsig_record->keytag} }, $ns->address->short; + push @{ $rrsig_not_valid_by_dnskey{ $rrsig_record->keytag } }, $ns->address->short; } } - } - } + } ## end foreach my $rrsig_record ( ...) + } ## end for my $nss_key ( sort ...) if ( scalar @dnskey_without_rrsig ) { push @results, _emit_log( @@ -3307,55 +3215,55 @@ sub dnssec08 { } if ( scalar keys %dnskey_rrsig_not_yet_valid ) { push @results, map { - _emit_log( - DS08_DNSKEY_RRSIG_NOT_YET_VALID => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_rrsig_not_yet_valid{$_} } ) - } - ) + _emit_log( + DS08_DNSKEY_RRSIG_NOT_YET_VALID => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_rrsig_not_yet_valid{$_} } ), + } + ) } keys %dnskey_rrsig_not_yet_valid; } if ( scalar keys %dnskey_rrsig_expired ) { push @results, map { - _emit_log( - DS08_DNSKEY_RRSIG_EXPIRED => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_rrsig_expired{$_} } ) - } - ) + _emit_log( + DS08_DNSKEY_RRSIG_EXPIRED => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_rrsig_expired{$_} } ), + } + ) } keys %dnskey_rrsig_expired; } if ( scalar keys %no_matching_dnskey ) { push @results, map { - _emit_log( - DS08_NO_MATCHING_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey{$_} } ) - } - ) + _emit_log( + DS08_NO_MATCHING_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey{$_} } ), + } + ) } keys %no_matching_dnskey; } if ( scalar keys %rrsig_not_valid_by_dnskey ) { push @results, map { - _emit_log( - DS08_RRSIG_NOT_VALID_BY_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ) - } - ) + _emit_log( + DS08_RRSIG_NOT_VALID_BY_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ), + } + ) } keys %rrsig_not_valid_by_dnskey; } if ( scalar keys %algo_not_supported_by_zm ) { foreach my $keytag ( keys %algo_not_supported_by_zm ) { push @results, map { - _emit_log( - DS08_ALGO_NOT_SUPPORTED_BY_ZM => { - keytag => $keytag, - algo_num => $_, - algo_mnemo => $algo_properties{$_}{mnemonic}, - ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ) - } - ) + _emit_log( + DS08_ALGO_NOT_SUPPORTED_BY_ZM => { + keytag => $keytag, + algo_num => $_, + algo_mnemo => $algo_properties{$_}{mnemonic}, + ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ), + } + ) } keys %{ $algo_not_supported_by_zm{$keytag} }; } } @@ -3399,8 +3307,8 @@ sub dnssec09 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DNSKEY} ) ) { next; @@ -3447,26 +3355,27 @@ sub dnssec09 { my $time = $dnskey_p->timestamp; foreach my $rrsig_record ( @rrsig_records ) { if ( $rrsig_record->inception > $time ) { - push @{ $soa_rrsig_not_yet_valid{$rrsig_record->keytag} }, $ns->address->short; + push @{ $soa_rrsig_not_yet_valid{ $rrsig_record->keytag } }, $ns->address->short; } elsif ( $rrsig_record->expiration < $time ) { - push @{ $soa_rrsig_expired{$rrsig_record->keytag} }, $ns->address->short; + push @{ $soa_rrsig_expired{ $rrsig_record->keytag } }, $ns->address->short; } else { - my $msg = q{}; + my $msg = q{}; my $validate = $rrsig_record->verify_time( \@soa_records, \@dnskey_records, $time, $msg ); if ( not $validate and $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$rrsig_record->keytag}{$rrsig_record->algorithm} }, $ns->address->short; + push @{ $algo_not_supported_by_zm{ $rrsig_record->keytag }{ $rrsig_record->algorithm } }, + $ns->address->short; } elsif ( not scalar grep { $_->keytag == $rrsig_record->keytag } @dnskey_records ) { - push @{ $no_matching_dnskey{$rrsig_record->keytag} }, $ns->address->short; + push @{ $no_matching_dnskey{ $rrsig_record->keytag } }, $ns->address->short; } elsif ( not $validate ) { - push @{ $rrsig_not_valid_by_dnskey{$rrsig_record->keytag} }, $ns->address->short; + push @{ $rrsig_not_valid_by_dnskey{ $rrsig_record->keytag } }, $ns->address->short; } } - } - } + } ## end foreach my $rrsig_record ( ...) + } ## end for my $nss_key ( sort ...) if ( scalar @soa_without_rrsig ) { push @results, _emit_log( @@ -3477,56 +3386,56 @@ sub dnssec09 { } if ( scalar keys %soa_rrsig_not_yet_valid ) { push @results, map { - _emit_log( - DS09_SOA_RRSIG_NOT_YET_VALID => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $soa_rrsig_not_yet_valid{$_} } ) - } - ) + _emit_log( + DS09_SOA_RRSIG_NOT_YET_VALID => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $soa_rrsig_not_yet_valid{$_} } ), + } + ) } keys %soa_rrsig_not_yet_valid; } if ( scalar keys %soa_rrsig_expired ) { push @results, map { - _emit_log( - DS09_SOA_RRSIG_EXPIRED => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $soa_rrsig_expired{$_} } ) - } - ) + _emit_log( + DS09_SOA_RRSIG_EXPIRED => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $soa_rrsig_expired{$_} } ), + } + ) } keys %soa_rrsig_expired; } if ( scalar keys %no_matching_dnskey ) { push @results, map { - _emit_log( - DS09_NO_MATCHING_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey{$_} } ) - } - ) + _emit_log( + DS09_NO_MATCHING_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_matching_dnskey{$_} } ), + } + ) } keys %no_matching_dnskey; } if ( scalar keys %rrsig_not_valid_by_dnskey ) { push @results, map { - _emit_log( - DS09_RRSIG_NOT_VALID_BY_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ) - } - ) + _emit_log( + DS09_RRSIG_NOT_VALID_BY_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $rrsig_not_valid_by_dnskey{$_} } ), + } + ) } keys %rrsig_not_valid_by_dnskey; } if ( scalar keys %algo_not_supported_by_zm ) { foreach my $keytag ( keys %algo_not_supported_by_zm ) { push @results, map { - _emit_log( - DS09_ALGO_NOT_SUPPORTED_BY_ZM => { - keytag => $keytag, - algo_num => $_, - algo_mnemo => $algo_properties{$_}{mnemonic}, - ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ) - } - ) - } keys %{ $algo_not_supported_by_zm{$keytag} } + _emit_log( + DS09_ALGO_NOT_SUPPORTED_BY_ZM => { + keytag => $keytag, + algo_num => $_, + algo_mnemo => $algo_properties{$_}{mnemonic}, + ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ), + } + ) + } keys %{ $algo_not_supported_by_zm{$keytag} }; } } @@ -3555,44 +3464,44 @@ sub dnssec10 { push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my $type_soa = q{SOA}; - my $type_dnskey = q{DNSKEY}; - my $type_nsec = q{NSEC}; - my $type_nsec3 = q{NSEC3}; + my $type_soa = q{SOA}; + my $type_dnskey = q{DNSKEY}; + my $type_nsec = q{NSEC}; + my $type_nsec3 = q{NSEC3}; my $type_nsec3param = q{NSEC3PARAM}; - my @query_types = ( $type_dnskey, $type_nsec, $type_nsec3param ); + my @query_types = ( $type_dnskey, $type_nsec, $type_nsec3param ); my %algo_not_supported_by_zm; - my ( @erroneous_multiple_nsec, @erroneous_multiple_nsec3 ); - my ( @nsec_in_response, @nsec_nonstandard_nodata, @nsec3param_in_answer ); + my ( @erroneous_multiple_nsec, @erroneous_multiple_nsec3 ); + my ( @nsec_in_response, @nsec_nonstandard_nodata, @nsec3param_in_answer ); my ( @nsec_incorrect_type_list, @nsec3_incorrect_type_list ); - my ( @nsec_mismatches_apex, @nsec3_mismatches_apex, @nsec3param_mismatches_apex ); - my ( @nsec_missing_signature, @nsec3_missing_signature ); - my ( %nsec_nodata_wrong_soa, %nsec3_nodata_wrong_soa ); - my ( @nsec_nodata_missing_soa, @nsec3_nodata_missing_soa ); - my ( @nsec_erroneous_answer, @nsec3param_erroneous_answer ); - my ( @nsec_nsec3_nodata, @nsec3param_nsec_nodata ); - my ( %nsec_rrsig_verify_error, %nsec3_rrsig_verify_error ); - my ( %nsec_rrsig_expired, %nsec3_rrsig_expired ); + my ( @nsec_mismatches_apex, @nsec3_mismatches_apex, @nsec3param_mismatches_apex ); + my ( @nsec_missing_signature, @nsec3_missing_signature ); + my ( %nsec_nodata_wrong_soa, %nsec3_nodata_wrong_soa ); + my ( @nsec_nodata_missing_soa, @nsec3_nodata_missing_soa ); + my ( @nsec_erroneous_answer, @nsec3param_erroneous_answer ); + my ( @nsec_nsec3_nodata, @nsec3param_nsec_nodata ); + my ( %nsec_rrsig_verify_error, %nsec3_rrsig_verify_error ); + my ( %nsec_rrsig_expired, %nsec3_rrsig_expired ); my ( %nsec_rrsig_not_yet_valid, %nsec3_rrsig_not_yet_valid ); - my ( %nsec_rrsig_no_dnskey, %nsec3_rrsig_no_dnskey ); - my ( @nsec_rrsig_verified, @nsec3_rrsig_verified ); - my ( @nsec_response_error, @nsec3param_response_error ); - my ( @with_dnskey, @without_dnskey ); - - my @all_ns = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my ( %nsec_rrsig_no_dnskey, %nsec3_rrsig_no_dnskey ); + my ( @nsec_rrsig_verified, @nsec3_rrsig_verified ); + my ( @nsec_response_error, @nsec3param_response_error ); + my ( @with_dnskey, @without_dnskey ); + + my @all_ns = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); my @ignored_nss; my %nss; - push @{ $nss{$_->address->short} }, $_ for @all_ns; + push @{ $nss{ $_->address->short } }, $_ for @all_ns; my $testing_time = time; for my $ns_ip ( keys %nss ) { - my $ns = $nss{$ns_ip}[0]; + my $ns = $nss{$ns_ip}[0]; my @all_ns_for_ip = @{ $nss{$ns_ip} }; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { @@ -3628,7 +3537,7 @@ sub dnssec10 { if ( scalar $nsec_p->get_records( $type_nsec, q{answer} ) > 1 ) { push @erroneous_multiple_nsec, @all_ns_for_ip; } - elsif ( ($nsec_p->get_records( $type_nsec, q{answer} ))[0]->owner ne $zone->name ) { + elsif ( ( $nsec_p->get_records( $type_nsec, q{answer} ) )[0]->owner ne $zone->name ) { push @nsec_mismatches_apex, @all_ns_for_ip; } } @@ -3637,14 +3546,14 @@ sub dnssec10 { } } elsif ( not $nsec_p->answer and scalar $nsec_p->get_records( $type_nsec, q{authority} ) ) { - push @nsec_in_response, @all_ns_for_ip; + push @nsec_in_response, @all_ns_for_ip; push @nsec_nonstandard_nodata, @all_ns_for_ip; unless ( scalar $nsec_p->get_records( $type_soa, q{authority} ) ) { push @nsec_nodata_missing_soa, @all_ns_for_ip; } - elsif ( ($nsec_p->get_records( $type_soa, q{authority} ))[0]->owner ne $zone->name ) { - push @{ $nsec_nodata_wrong_soa{$zone->name} }, @all_ns_for_ip; + elsif ( ( $nsec_p->get_records( $type_soa, q{authority} ) )[0]->owner ne $zone->name ) { + push @{ $nsec_nodata_wrong_soa{ $zone->name } }, @all_ns_for_ip; } my @nsec_rrs = $nsec_p->get_records( $type_nsec, q{authority} ); @@ -3659,7 +3568,7 @@ sub dnssec10 { else { my @mandatory_typelist = qw( SOA NS DNSKEY NSEC RRSIG ); my @forbidden_typelist = qw( NSEC3PARAM NSEC3 ); - my %typelist = %{ $nsec_rrs[0]->typehref }; + my %typelist = %{ $nsec_rrs[0]->typehref }; foreach my $type ( @mandatory_typelist ) { if ( not exists $typelist{$type} ) { @@ -3676,7 +3585,8 @@ sub dnssec10 { } } - my @nsec_rrsig_rrs = grep { $_->typecovered eq q{NSEC} } $nsec_p->get_records_for_name( q{RRSIG}, $nsec_rrs[0]->name ); + my @nsec_rrsig_rrs = + grep { $_->typecovered eq q{NSEC} } $nsec_p->get_records_for_name( q{RRSIG}, $nsec_rrs[0]->name ); unless ( scalar @nsec_rrsig_rrs ) { push @nsec_missing_signature, @all_ns_for_ip; @@ -3686,19 +3596,21 @@ sub dnssec10 { my @matching_dnskeys = grep { $rr->keytag == $_->keytag } @dnskey_records; unless ( scalar @matching_dnskeys ) { - push @{ $nsec_rrsig_no_dnskey{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_no_dnskey{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->expiration < $testing_time ) { - push @{ $nsec_rrsig_expired{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_expired{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->inception > $testing_time ) { - push @{ $nsec_rrsig_not_yet_valid{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_not_yet_valid{ $rr->keytag } }, @all_ns_for_ip; } else { my $i = 1; foreach my $dnskey ( @matching_dnskeys ) { my $msg = q{}; - my $validated = $rr->verify_time( [grep { name( $_->name ) eq name( $rr->name ) } @nsec_rrs], [ $dnskey ], $testing_time, $msg ); + my $validated = + $rr->verify_time( [ grep { name( $_->name ) eq name( $rr->name ) } @nsec_rrs ], + [$dnskey], $testing_time, $msg, ); if ( $validated ) { push @nsec_rrsig_verified, @all_ns_for_ip; @@ -3707,28 +3619,29 @@ sub dnssec10 { if ( $i >= scalar @matching_dnskeys ) { if ( $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$dnskey->keytag}{$dnskey->algorithm} }, @all_ns_for_ip; + push @{ $algo_not_supported_by_zm{ $dnskey->keytag }{ $dnskey->algorithm } }, + @all_ns_for_ip; } else { - push @{ $nsec_rrsig_verify_error{$dnskey->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_verify_error{ $dnskey->keytag } }, @all_ns_for_ip; } } $i++; - } - } - } - } - } - } + } ## end foreach my $dnskey ( @matching_dnskeys) + } ## end else [ if ( $rr->expiration <...)] + } ## end foreach my $rr ( @nsec_rrsig_rrs) + } ## end else + } ## end else [ if ( scalar @nsec_rrs ...)] + } ## end elsif ( not $nsec_p->answer...) elsif ( not $nsec_p->answer and scalar $nsec_p->get_records( $type_nsec3, q{authority} ) ) { push @nsec_nsec3_nodata, @all_ns_for_ip; unless ( scalar $nsec_p->get_records( $type_soa, q{authority} ) ) { push @nsec3_nodata_missing_soa, @all_ns_for_ip; } - elsif ( ($nsec_p->get_records( $type_soa, q{authority} ))[0]->owner ne $zone->name ) { - push @{ $nsec3_nodata_wrong_soa{$zone->name} }, @all_ns_for_ip; + elsif ( ( $nsec_p->get_records( $type_soa, q{authority} ) )[0]->owner ne $zone->name ) { + push @{ $nsec3_nodata_wrong_soa{ $zone->name } }, @all_ns_for_ip; } my @nsec3_rrs = $nsec_p->get_records( $type_nsec3, q{authority} ); @@ -3737,13 +3650,14 @@ sub dnssec10 { push @erroneous_multiple_nsec3, @all_ns_for_ip; } else { - unless ( $nsec3_rrs[0]->hash_name( $zone->name ) eq lc( @{ name($nsec3_rrs[0]->owner)->labels }[0] ) ) { + unless ( $nsec3_rrs[0]->hash_name( $zone->name ) eq lc( @{ name( $nsec3_rrs[0]->owner )->labels }[0] ) ) + { push @nsec3_mismatches_apex, @all_ns_for_ip; } else { my @mandatory_typelist = qw( SOA NS DNSKEY NSEC3PARAM RRSIG ); my @forbidden_typelist = qw( NSEC NSEC3 ); - my %typelist = %{ $nsec3_rrs[0]->typehref }; + my %typelist = %{ $nsec3_rrs[0]->typehref }; foreach my $type ( @mandatory_typelist ) { if ( not exists $typelist{$type} ) { @@ -3760,7 +3674,8 @@ sub dnssec10 { } } - my @nsec3_rrsig_rrs = grep { $_->typecovered eq q{NSEC3} } $nsec_p->get_records_for_name( q{RRSIG}, $nsec3_rrs[0]->name ); + my @nsec3_rrsig_rrs = + grep { $_->typecovered eq q{NSEC3} } $nsec_p->get_records_for_name( q{RRSIG}, $nsec3_rrs[0]->name ); unless ( scalar @nsec3_rrsig_rrs ) { push @nsec3_missing_signature, @all_ns_for_ip; @@ -3770,19 +3685,21 @@ sub dnssec10 { my @matching_dnskeys = grep { $rr->keytag == $_->keytag } @dnskey_records; unless ( scalar @matching_dnskeys ) { - push @{ $nsec3_rrsig_no_dnskey{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec3_rrsig_no_dnskey{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->expiration < $testing_time ) { - push @{ $nsec3_rrsig_expired{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec3_rrsig_expired{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->inception > $testing_time ) { - push @{ $nsec3_rrsig_not_yet_valid{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec3_rrsig_not_yet_valid{ $rr->keytag } }, @all_ns_for_ip; } else { my $i = 1; foreach my $dnskey ( @matching_dnskeys ) { my $msg = q{}; - my $validated = $rr->verify_time( [grep { name( $_->name ) eq name( $rr->name ) } @nsec3_rrs], [ $dnskey ], $testing_time, $msg ); + my $validated = + $rr->verify_time( [ grep { name( $_->name ) eq name( $rr->name ) } @nsec3_rrs ], + [$dnskey], $testing_time, $msg, ); if ( $validated ) { push @nsec3_rrsig_verified, @all_ns_for_ip; @@ -3791,20 +3708,21 @@ sub dnssec10 { if ( $i >= scalar @matching_dnskeys ) { if ( $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$dnskey->keytag}{$dnskey->algorithm} }, @all_ns_for_ip; + push @{ $algo_not_supported_by_zm{ $dnskey->keytag }{ $dnskey->algorithm } }, + @all_ns_for_ip; } else { - push @{ $nsec3_rrsig_verify_error{$dnskey->keytag} }, @all_ns_for_ip; + push @{ $nsec3_rrsig_verify_error{ $dnskey->keytag } }, @all_ns_for_ip; } } $i++; - } - } - } - } - } - } + } ## end foreach my $dnskey ( @matching_dnskeys) + } ## end else [ if ( $rr->expiration <...)] + } ## end foreach my $rr ( @nsec3_rrsig_rrs) + } ## end else + } ## end else [ if ( scalar @nsec3_rrs...)] + } ## end elsif ( not $nsec_p->answer...) my $nsec3param_p = $ns->query( $zone->name, $type_nsec3param, { dnssec => 1 } ); @@ -3815,7 +3733,7 @@ sub dnssec10 { if ( scalar $nsec3param_p->get_records( $type_nsec3param, q{answer} ) ) { push @nsec3param_in_answer, @all_ns_for_ip; - if ( ($nsec3param_p->get_records( $type_nsec3param, q{answer} ))[0]->owner ne $zone->name ) { + if ( ( $nsec3param_p->get_records( $type_nsec3param, q{answer} ) )[0]->owner ne $zone->name ) { push @nsec3param_mismatches_apex, @all_ns_for_ip; } } @@ -3831,8 +3749,8 @@ sub dnssec10 { unless ( scalar $nsec3param_p->get_records( $type_soa, q{authority} ) ) { push @nsec_nodata_missing_soa, @all_ns_for_ip; } - elsif ( ($nsec3param_p->get_records( $type_soa, q{authority} ))[0]->owner ne $zone->name ) { - push @{ $nsec_nodata_wrong_soa{$zone->name} }, @all_ns_for_ip; + elsif ( ( $nsec3param_p->get_records( $type_soa, q{authority} ) )[0]->owner ne $zone->name ) { + push @{ $nsec_nodata_wrong_soa{ $zone->name } }, @all_ns_for_ip; } if ( scalar @nsec_rrs > 1 ) { @@ -3845,7 +3763,7 @@ sub dnssec10 { else { my @mandatory_typelist = qw( SOA NS DNSKEY NSEC RRSIG ); my @forbidden_typelist = qw( NSEC3PARAM NSEC3 ); - my %typelist = %{ $nsec_rrs[0]->typehref }; + my %typelist = %{ $nsec_rrs[0]->typehref }; foreach my $type ( @mandatory_typelist ) { if ( not exists $typelist{$type} ) { @@ -3862,7 +3780,8 @@ sub dnssec10 { } } - my @nsec_rrsig_rrs = grep { $_->typecovered eq q{NSEC} } $nsec3param_p->get_records_for_name( q{RRSIG}, $nsec_rrs[0]->name ); + my @nsec_rrsig_rrs = grep { $_->typecovered eq q{NSEC} } + $nsec3param_p->get_records_for_name( q{RRSIG}, $nsec_rrs[0]->name ); unless ( scalar @nsec_rrsig_rrs ) { push @nsec_missing_signature, @all_ns_for_ip; @@ -3872,19 +3791,21 @@ sub dnssec10 { my @matching_dnskeys = grep { $rr->keytag == $_->keytag } @dnskey_records; unless ( scalar @matching_dnskeys ) { - push @{ $nsec_rrsig_no_dnskey{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_no_dnskey{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->expiration < $testing_time ) { - push @{ $nsec_rrsig_expired{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_expired{ $rr->keytag } }, @all_ns_for_ip; } elsif ( $rr->inception > $testing_time ) { - push @{ $nsec_rrsig_not_yet_valid{$rr->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_not_yet_valid{ $rr->keytag } }, @all_ns_for_ip; } else { my $i = 1; foreach my $dnskey ( @matching_dnskeys ) { my $msg = q{}; - my $validated = $rr->verify_time( [grep { name( $_->name ) eq name( $rr->name ) } @nsec_rrs], [ $dnskey ], $testing_time, $msg ); + my $validated = + $rr->verify_time( [ grep { name( $_->name ) eq name( $rr->name ) } @nsec_rrs ], + [$dnskey], $testing_time, $msg, ); if ( $validated ) { push @nsec_rrsig_verified, @all_ns_for_ip; @@ -3893,21 +3814,22 @@ sub dnssec10 { if ( $i >= scalar @matching_dnskeys ) { if ( $msg =~ /Unknown cryptographic algorithm/ ) { - push @{ $algo_not_supported_by_zm{$dnskey->keytag}{$dnskey->algorithm} }, @all_ns_for_ip; + push @{ $algo_not_supported_by_zm{ $dnskey->keytag }{ $dnskey->algorithm } }, + @all_ns_for_ip; } else { - push @{ $nsec_rrsig_verify_error{$dnskey->keytag} }, @all_ns_for_ip; + push @{ $nsec_rrsig_verify_error{ $dnskey->keytag } }, @all_ns_for_ip; } } $i++; - } - } - } - } - } - } - } + } ## end foreach my $dnskey ( @matching_dnskeys) + } ## end else [ if ( $rr->expiration <...)] + } ## end foreach my $rr ( @nsec_rrsig_rrs) + } ## end else + } ## end else [ if ( scalar @nsec_rrs ...)] + } ## end elsif ( not $nsec3param_p...) + } ## end for my $ns_ip ( keys %nss) if ( scalar @erroneous_multiple_nsec ) { push @results, @@ -3936,10 +3858,10 @@ sub dnssec10 { ); } - my $lc = List::Compare->new( \@nsec_in_response, \@nsec3param_nsec_nodata ); - my @diff = $lc->get_symmetric_difference; - my @union = uniq map { $_->string } ( @nsec3param_in_answer, @nsec_nsec3_nodata ); - my $lc2 = List::Compare->new( \@diff, \@union ); + my $lc = List::Compare->new( \@nsec_in_response, \@nsec3param_nsec_nodata ); + my @diff = $lc->get_symmetric_difference; + my @union = uniq map { $_->string } ( @nsec3param_in_answer, @nsec_nsec3_nodata ); + my $lc2 = List::Compare->new( \@diff, \@union ); my @final_diff = $lc2->get_symmetric_difference; if ( scalar @diff and scalar @final_diff ) { @@ -3951,10 +3873,10 @@ sub dnssec10 { ); } - $lc = List::Compare->new( \@nsec3param_in_answer, \@nsec_nsec3_nodata ); - @diff = $lc->get_symmetric_difference; - @union = uniq map { $_->string } ( @nsec_in_response, @nsec3param_nsec_nodata ); - $lc2 = List::Compare->new( \@diff, \@union ); + $lc = List::Compare->new( \@nsec3param_in_answer, \@nsec_nsec3_nodata ); + @diff = $lc->get_symmetric_difference; + @union = uniq map { $_->string } ( @nsec_in_response, @nsec3param_nsec_nodata ); + $lc2 = List::Compare->new( \@diff, \@union ); @final_diff = $lc2->get_symmetric_difference; if ( scalar @diff and scalar @final_diff ) { @@ -3966,7 +3888,10 @@ sub dnssec10 { ); } - $lc = List::Compare->new( [ @nsec3param_in_answer, @nsec_nsec3_nodata ], [ @nsec_in_response, @nsec3param_nsec_nodata ] ); + $lc = List::Compare->new( + [ @nsec3param_in_answer, @nsec_nsec3_nodata ], + [ @nsec_in_response, @nsec3param_nsec_nodata ], + ); my @intersection = $lc->get_intersection; if ( @intersection ) { @@ -3978,7 +3903,10 @@ sub dnssec10 { ); } - if ( ( scalar @nsec_in_response or @nsec3param_nsec_nodata ) and not scalar @nsec3param_in_answer and not scalar @nsec_nsec3_nodata ) { + if ( ( scalar @nsec_in_response or @nsec3param_nsec_nodata ) + and not scalar @nsec3param_in_answer + and not scalar @nsec_nsec3_nodata ) + { push @results, _emit_log( DS10_HAS_NSEC => { @@ -3987,7 +3915,10 @@ sub dnssec10 { ); } - if ( ( scalar @nsec3param_in_answer or @nsec_nsec3_nodata ) and not scalar @nsec_in_response and not scalar @nsec3param_nsec_nodata ) { + if ( ( scalar @nsec3param_in_answer or @nsec_nsec3_nodata ) + and not scalar @nsec_in_response + and not scalar @nsec3param_nsec_nodata ) + { push @results, _emit_log( DS10_HAS_NSEC3 => { @@ -3999,7 +3930,7 @@ sub dnssec10 { @union = ( @nsec3param_in_answer, @nsec_nsec3_nodata ); my @second_union = ( @nsec_in_response, @nsec3param_nsec_nodata ); $lc = List::Compare->new( \@union, \@second_union ); - my @first = $lc->get_unique; + my @first = $lc->get_unique; my @second = $lc->get_complement; if ( scalar @first and scalar @second ) { @@ -4031,13 +3962,13 @@ sub dnssec10 { if ( scalar keys %nsec_nodata_wrong_soa ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC_NODATA_WRONG_SOA => { - domain => $_, - ns_list => join( q{;}, uniq sort @{ $nsec_nodata_wrong_soa{$_} } ) + domain => $_, + ns_list => join( q{;}, uniq sort @{ $nsec_nodata_wrong_soa{$_} } ), } - ) - } keys %nsec_nodata_wrong_soa; + ) + } keys %nsec_nodata_wrong_soa; } if ( scalar @nsec_nodata_missing_soa ) { @@ -4087,13 +4018,13 @@ sub dnssec10 { if ( scalar keys %nsec3_nodata_wrong_soa ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC3_NODATA_WRONG_SOA => { - domain => $_, - ns_list => join( q{;}, uniq sort @{ $nsec3_nodata_wrong_soa{$_} } ) + domain => $_, + ns_list => join( q{;}, uniq sort @{ $nsec3_nodata_wrong_soa{$_} } ), } - ) - } keys %nsec3_nodata_wrong_soa; + ) + } keys %nsec3_nodata_wrong_soa; } if ( scalar @nsec3_nodata_missing_soa ) { @@ -4152,52 +4083,61 @@ sub dnssec10 { if ( scalar keys %nsec_rrsig_no_dnskey ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC_RRSIG_NO_DNSKEY => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_no_dnskey{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_no_dnskey{$_} } ), } - ) - } keys %nsec_rrsig_no_dnskey; + ) + } keys %nsec_rrsig_no_dnskey; } if ( scalar keys %nsec_rrsig_expired ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC_RRSIG_EXPIRED => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_expired{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_expired{$_} } ), } - ) - } keys %nsec_rrsig_expired; + ) + } keys %nsec_rrsig_expired; } if ( scalar keys %nsec_rrsig_not_yet_valid ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC_RRSIG_NOT_YET_VALID => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_not_yet_valid{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_not_yet_valid{$_} } ), } - ) - } keys %nsec_rrsig_not_yet_valid; + ) + } keys %nsec_rrsig_not_yet_valid; } if ( scalar keys %nsec_rrsig_verify_error ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC_RRSIG_VERIFY_ERROR => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_verify_error{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec_rrsig_verify_error{$_} } ), } - ) - } keys %nsec_rrsig_verify_error; - } - - if ( values %nsec_rrsig_no_dnskey or values %nsec_rrsig_expired or values %nsec_rrsig_not_yet_valid or values %nsec_rrsig_verify_error ) { - my @combined_ns = uniq ( values %nsec_rrsig_no_dnskey, values %nsec_rrsig_expired, values %nsec_rrsig_not_yet_valid, values %nsec_rrsig_verify_error ); + ) + } keys %nsec_rrsig_verify_error; + } + + if ( values %nsec_rrsig_no_dnskey + or values %nsec_rrsig_expired + or values %nsec_rrsig_not_yet_valid + or values %nsec_rrsig_verify_error ) + { + my @combined_ns = uniq( + values %nsec_rrsig_no_dnskey, + values %nsec_rrsig_expired, + values %nsec_rrsig_not_yet_valid, + values %nsec_rrsig_verify_error, + ); my @ns_list; - + foreach my $ns_aref ( @combined_ns ) { foreach my $ns ( @$ns_aref ) { push @ns_list, $ns unless grep { $_ eq $ns } @nsec_rrsig_verified; @@ -4210,56 +4150,65 @@ sub dnssec10 { ns_list => join( q{;}, uniq sort @ns_list ) } ) if scalar @ns_list; - } + } ## end if ( values %nsec_rrsig_no_dnskey...) if ( scalar keys %nsec3_rrsig_no_dnskey ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC3_RRSIG_NO_DNSKEY => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_no_dnskey{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_no_dnskey{$_} } ), } - ) - } keys %nsec3_rrsig_no_dnskey; + ) + } keys %nsec3_rrsig_no_dnskey; } if ( scalar keys %nsec3_rrsig_expired ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC3_RRSIG_EXPIRED => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_expired{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_expired{$_} } ), } - ) - } keys %nsec3_rrsig_expired; + ) + } keys %nsec3_rrsig_expired; } if ( scalar keys %nsec3_rrsig_not_yet_valid ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC3_RRSIG_NOT_YET_VALID => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_not_yet_valid{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_not_yet_valid{$_} } ), } - ) - } keys %nsec3_rrsig_not_yet_valid; + ) + } keys %nsec3_rrsig_not_yet_valid; } if ( scalar keys %nsec3_rrsig_verify_error ) { push @results, map { - _emit_log( + _emit_log( DS10_NSEC3_RRSIG_VERIFY_ERROR => { - keytag => $_, - ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_verify_error{$_} } ) + keytag => $_, + ns_list => join( q{;}, uniq sort @{ $nsec3_rrsig_verify_error{$_} } ), } - ) - } keys %nsec3_rrsig_verify_error; - } - - if ( values %nsec3_rrsig_no_dnskey or values %nsec3_rrsig_expired or values %nsec3_rrsig_not_yet_valid or values %nsec3_rrsig_verify_error ) { - my @combined_ns = uniq ( values %nsec3_rrsig_no_dnskey, values %nsec3_rrsig_expired, values %nsec3_rrsig_not_yet_valid, values %nsec3_rrsig_verify_error ); + ) + } keys %nsec3_rrsig_verify_error; + } + + if ( values %nsec3_rrsig_no_dnskey + or values %nsec3_rrsig_expired + or values %nsec3_rrsig_not_yet_valid + or values %nsec3_rrsig_verify_error ) + { + my @combined_ns = uniq( + values %nsec3_rrsig_no_dnskey, + values %nsec3_rrsig_expired, + values %nsec3_rrsig_not_yet_valid, + values %nsec3_rrsig_verify_error, + ); my @ns_list; - + foreach my $ns_aref ( @combined_ns ) { foreach my $ns ( @$ns_aref ) { push @ns_list, $ns unless grep { $_ eq $ns } @nsec3_rrsig_verified; @@ -4272,19 +4221,19 @@ sub dnssec10 { ns_list => join( q{;}, uniq sort @ns_list ) } ) if scalar @ns_list; - } + } ## end if ( values %nsec3_rrsig_no_dnskey...) if ( scalar keys %algo_not_supported_by_zm ) { foreach my $keytag ( keys %algo_not_supported_by_zm ) { push @results, map { - _emit_log( - DS10_ALGO_NOT_SUPPORTED_BY_ZM => { - keytag => $keytag, - algo_num => $_, - algo_mnemo => $algo_properties{$_}{mnemonic}, - ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ) - } - ) + _emit_log( + DS10_ALGO_NOT_SUPPORTED_BY_ZM => { + keytag => $keytag, + algo_num => $_, + algo_mnemo => $algo_properties{$_}{mnemonic}, + ns_ip_list => join( q{;}, uniq sort @{ $algo_not_supported_by_zm{$keytag}{$_} } ), + } + ) } keys %{ $algo_not_supported_by_zm{$keytag} }; } } @@ -4307,7 +4256,13 @@ sub dnssec10 { ); } - $lc = List::Compare->new( [ @all_ns ], [ @ignored_nss, @without_dnskey, @nsec_in_response, @nsec3param_nsec_nodata, @nsec3param_in_answer, @nsec_nsec3_nodata ] ); + $lc = List::Compare->new( + [@all_ns], + [ + @ignored_nss, @without_dnskey, @nsec_in_response, + @nsec3param_nsec_nodata, @nsec3param_in_answer, @nsec_nsec3_nodata, + ], + ); @first = $lc->get_unique; if ( @first ) { @@ -4358,15 +4313,17 @@ sub dnssec11 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - if ( $is_undelegated ){ - if ( not $ns->fake_ds->{$zone->name->string} ){ - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); + if ( $is_undelegated ) { + if ( not $ns->fake_ds->{ $zone->name->string } ) { + return ( @results, + _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ), + ); } last; } - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DS} ) ) { next; @@ -4388,7 +4345,7 @@ sub dnssec11 { else { push @has_ds_record, $ns->address->short; } - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( scalar @undetermined_ds and not scalar @no_ds_record and not scalar @has_ds_record ) { @@ -4408,7 +4365,7 @@ sub dnssec11 { ); push @results, _emit_log( - DS11_PARENT_WITH_DS => { + DS11_PARENT_WITH_DS => { ns_ip_list => join( q{;}, sort @has_ds_record ) } ); @@ -4428,8 +4385,8 @@ sub dnssec11 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -4466,7 +4423,7 @@ sub dnssec11 { else { push @has_dnskey_record, $ns->address->short; } - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( scalar @undetermined_dnskey and not scalar @no_dnskey_record and not scalar @has_dnskey_record ) { @@ -4485,12 +4442,12 @@ sub dnssec11 { ); push @results, _emit_log( - DS11_NS_WITH_SIGNED_ZONE => { + DS11_NS_WITH_SIGNED_ZONE => { ns_ip_list => join( q{;}, sort @has_dnskey_record ) } ); } - } + } ## end if ( $continue_with_child_tests) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub dnssec11 @@ -4526,8 +4483,8 @@ sub dnssec13 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -4550,7 +4507,7 @@ sub dnssec13 { if ( not scalar @type_records ) { next; } - my @rrsig_records = $p->get_records( q{RRSIG} , q{answer} ); + my @rrsig_records = $p->get_records( q{RRSIG}, q{answer} ); if ( not scalar @rrsig_records ) { next; } @@ -4560,21 +4517,21 @@ sub dnssec13 { } foreach my $algorithm ( keys %dnskey_algorithm ) { if ( not scalar grep { $_->algorithm == $algorithm } @rrsig_records ) { - push @{ $algo_not_signed{ lc($query_type) }{$algorithm} }, $ns->address->short; + push @{ $algo_not_signed{ lc( $query_type ) }{$algorithm} }, $ns->address->short; } } - } - } + } ## end foreach my $query_type ( @query_types) + } ## end for my $nss_key ( sort ...) foreach my $query_type ( @query_types ) { - if ( exists $algo_not_signed{ lc($query_type) } ) { - foreach my $algorithm ( keys %{ $algo_not_signed{ lc($query_type) } } ) { + if ( exists $algo_not_signed{ lc( $query_type ) } ) { + foreach my $algorithm ( keys %{ $algo_not_signed{ lc( $query_type ) } } ) { push @results, _emit_log( "DS13_ALGO_NOT_SIGNED_${query_type}" => { - ns_ip_list => join( q{;}, uniq sort @{ $algo_not_signed{ lc($query_type) }{$algorithm} }), + ns_ip_list => join( q{;}, uniq sort @{ $algo_not_signed{ lc( $query_type ) }{$algorithm} } ), algo_num => $algorithm, - algo_mnemo => $algo_properties{$algorithm}{mnemonic} + algo_mnemo => $algo_properties{$algorithm}{mnemonic}, } ); } @@ -4628,10 +4585,11 @@ sub dnssec14 { if ( not @keys ) { push @results, _emit_log( NO_RESPONSE_DNSKEY => { ns => $ns->string } ); next; - } else { + } + else { push @dnskey_rrs, @keys; } - } + } ## end for my $nss_key ( sort ...) my %investigated_keys; foreach my $key ( @dnskey_rrs ) { @@ -4667,9 +4625,9 @@ sub dnssec14 { $investigated_keys{$key_ref} = 1; - } ## end foreach my $key ( @keys ) + } ## end foreach my $key ( @dnskey_rrs) - if ( scalar @dnskey_rrs and scalar @results == scalar grep { $_->tag eq 'NO_RESPONSE' } @results) { + if ( scalar @dnskey_rrs and scalar @results == scalar grep { $_->tag eq 'NO_RESPONSE' } @results ) { push @results, _emit_log( KEY_SIZE_OK => {} ); } @@ -4714,8 +4672,8 @@ sub dnssec15 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -4746,17 +4704,17 @@ sub dnssec15 { } my @cdnskey_records = $cdnskey_p->get_records( q{CDNSKEY}, q{answer} ); push @{ $cdnskey_rrsets{ $ns->address->short } }, @cdnskey_records; - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; my $no_cds_cdnskey = 1; for my $ns_ip ( keys %cds_rrsets ) { - if ( scalar @{ $cds_rrsets{ $ns_ip } } ) { + if ( scalar @{ $cds_rrsets{$ns_ip} } ) { $no_cds_cdnskey = 0; } } for my $ns_ip ( keys %cdnskey_rrsets ) { - if ( scalar @{ $cdnskey_rrsets{ $ns_ip } } ) { + if ( scalar @{ $cdnskey_rrsets{$ns_ip} } ) { $no_cds_cdnskey = 0; } } @@ -4767,65 +4725,60 @@ sub dnssec15 { else { for my $ns_ip ( keys %cds_rrsets ) { - if ( not exists $cdnskey_rrsets{ $ns_ip } ) { + if ( not exists $cdnskey_rrsets{$ns_ip} ) { next; } - if ( - scalar @{ $cds_rrsets{ $ns_ip } } - and not scalar @{ $cdnskey_rrsets{ $ns_ip } } - ) + if ( scalar @{ $cds_rrsets{$ns_ip} } + and not scalar @{ $cdnskey_rrsets{$ns_ip} } ) { - $has_cds_no_cdnskey{ $ns_ip } = 1; + $has_cds_no_cdnskey{$ns_ip} = 1; } - elsif ( - scalar @{ $cdnskey_rrsets{ $ns_ip } } - and not scalar @{ $cds_rrsets{ $ns_ip } } - ) + elsif ( scalar @{ $cdnskey_rrsets{$ns_ip} } + and not scalar @{ $cds_rrsets{$ns_ip} } ) { - $has_cdnskey_no_cds{ $ns_ip } = 1; + $has_cdnskey_no_cds{$ns_ip} = 1; } - elsif ( - scalar @{ $cds_rrsets{ $ns_ip } } - and scalar @{ $cdnskey_rrsets{ $ns_ip } } - ) + elsif ( scalar @{ $cds_rrsets{$ns_ip} } + and scalar @{ $cdnskey_rrsets{$ns_ip} } ) { - $has_cds_and_cdnskey{ $ns_ip } = 1; + $has_cds_and_cdnskey{$ns_ip} = 1; } - } + } ## end for my $ns_ip ( keys %cds_rrsets) for my $ns_ip ( keys %cds_rrsets ) { - if ( - scalar @{ $cds_rrsets{ $ns_ip } } - and exists $cdnskey_rrsets{ $ns_ip } - and scalar @{ $cdnskey_rrsets{ $ns_ip } } - ) + if ( scalar @{ $cds_rrsets{$ns_ip} } + and exists $cdnskey_rrsets{$ns_ip} + and scalar @{ $cdnskey_rrsets{$ns_ip} } ) { - # - # Quick hack. Proper fix should be available in LDNS 1.8.5: https://github.com/NLnetLabs/ldns/commit/b39813870a5fb0f4e8ff1570b3b09416aaee716c - # +# +# Quick hack. Proper fix should be available in LDNS 1.8.5: https://github.com/NLnetLabs/ldns/commit/b39813870a5fb0f4e8ff1570b3b09416aaee716c +# my @dnskey; - foreach my $cdnskey ( @{ $cdnskey_rrsets{ $ns_ip } } ) { + foreach my $cdnskey ( @{ $cdnskey_rrsets{$ns_ip} } ) { my $rr_string = $cdnskey->string; $rr_string =~ s/\s+CDNSKEY\s+/ DNSKEY /; push @dnskey, Zonemaster::LDNS::RR->new( $rr_string ); } - foreach my $cds ( @{ $cds_rrsets{ $ns_ip } } ) { - my @matching_keys = grep { $cds->keytag == $_->keytag or ($cds->algorithm == 0 and $_->algorithm == 0)} @dnskey; + foreach my $cds ( @{ $cds_rrsets{$ns_ip} } ) { + my @matching_keys = + grep { $cds->keytag == $_->keytag or ( $cds->algorithm == 0 and $_->algorithm == 0 ) } @dnskey; if ( not scalar @matching_keys ) { - $mismatch_cds_cdnskey{ $ns_ip } = 1; + $mismatch_cds_cdnskey{$ns_ip} = 1; } } foreach my $dnskey ( @dnskey ) { - my @matching_keys = grep { $dnskey->keytag == $_->keytag or ($dnskey->algorithm == 0 and $_->algorithm == 0)} @{ $cds_rrsets{ $ns_ip } }; + my @matching_keys = + grep { $dnskey->keytag == $_->keytag or ( $dnskey->algorithm == 0 and $_->algorithm == 0 ) } + @{ $cds_rrsets{$ns_ip} }; if ( not scalar @matching_keys ) { - $mismatch_cds_cdnskey{ $ns_ip } = 1; + $mismatch_cds_cdnskey{$ns_ip} = 1; } } - } - } + } ## end if ( scalar @{ $cds_rrsets...}) + } ## end for my $ns_ip ( keys %cds_rrsets) if ( scalar keys %has_cds_no_cdnskey ) { push @results, @@ -4859,12 +4812,12 @@ sub dnssec15 { my $inconsistent_rrset = 0; for my $ns_ip ( keys %cds_rrsets ) { if ( $first ) { - $first_rrlist = Zonemaster::LDNS::RRList->new( $cds_rrsets{ $ns_ip } ); - $first = 0; + $first_rrlist = Zonemaster::LDNS::RRList->new( $cds_rrsets{$ns_ip} ); + $first = 0; next; } - my $rrlist = Zonemaster::LDNS::RRList->new( $cds_rrsets{ $ns_ip } ); + my $rrlist = Zonemaster::LDNS::RRList->new( $cds_rrsets{$ns_ip} ); if ( $rrlist ne $first_rrlist ) { $inconsistent_rrset = 1; @@ -4874,16 +4827,16 @@ sub dnssec15 { push @results, _emit_log( DS15_INCONSISTENT_CDS => {} ) if $inconsistent_rrset; - $first = 1; + $first = 1; $inconsistent_rrset = 0; for my $ns_ip ( keys %cdnskey_rrsets ) { if ( $first ) { - $first_rrlist = Zonemaster::LDNS::RRList->new( $cdnskey_rrsets{ $ns_ip } ); - $first = 0; + $first_rrlist = Zonemaster::LDNS::RRList->new( $cdnskey_rrsets{$ns_ip} ); + $first = 0; next; } - my $rrlist = Zonemaster::LDNS::RRList->new( $cdnskey_rrsets{ $ns_ip } ); + my $rrlist = Zonemaster::LDNS::RRList->new( $cdnskey_rrsets{$ns_ip} ); if ( $rrlist ne $first_rrlist ) { $inconsistent_rrset = 1; @@ -4901,7 +4854,7 @@ sub dnssec15 { } ); } - } + } ## end else [ if ( $no_cds_cdnskey )] return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub dnssec15 @@ -4950,8 +4903,8 @@ sub dnssec16 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -4971,8 +4924,8 @@ sub dnssec16 { if ( not scalar @cds_records ) { next; } - my @cds_rrsig_records = $cds_p->get_records( q{RRSIG} , q{answer} ); - push @{ $cds_rrsets{ $ns->address->short }{cds} }, @cds_records; + my @cds_rrsig_records = $cds_p->get_records( q{RRSIG}, q{answer} ); + push @{ $cds_rrsets{ $ns->address->short }{cds} }, @cds_records; push @{ $cds_rrsets{ $ns->address->short }{rrsig} }, @cds_rrsig_records; foreach my $cds ( @{ $cds_rrsets{ $ns->address->short }{cds} } ) { my $rr_string = $cds->string; @@ -4994,68 +4947,74 @@ sub dnssec16 { if ( not scalar @dnskey_records ) { next; } - my @dnskey_rrsig_records = $dnskey_p->get_records( q{RRSIG} , q{answer} ); + my @dnskey_rrsig_records = $dnskey_p->get_records( q{RRSIG}, q{answer} ); push @{ $dnskey_rrsets{ $ns->address->short }{dnskey} }, @dnskey_records; - push @{ $dnskey_rrsets{ $ns->address->short }{rrsig} }, @dnskey_rrsig_records; + push @{ $dnskey_rrsets{ $ns->address->short }{rrsig} }, @dnskey_rrsig_records; $testing_time = $dnskey_p->timestamp; - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( scalar keys %cds_rrsets ) { for my $ns_ip ( keys %cds_rrsets ) { - if ( not scalar @{ $cds_rrsets{ $ns_ip }{cds} } ) { + if ( not scalar @{ $cds_rrsets{$ns_ip}{cds} } ) { next; } - if ( scalar grep { $_->algorithm == 0 } @{ $cds_rrsets{ $ns_ip }{ds} } ) { - if ( scalar grep { $_->algorithm != 0 } @{ $cds_rrsets{ $ns_ip }{ds} } ) { - $mixed_delete_cds{ $ns_ip } = 1; + if ( scalar grep { $_->algorithm == 0 } @{ $cds_rrsets{$ns_ip}{ds} } ) { + if ( scalar grep { $_->algorithm != 0 } @{ $cds_rrsets{$ns_ip}{ds} } ) { + $mixed_delete_cds{$ns_ip} = 1; } else { - $delete_cds{ $ns_ip } = 1; + $delete_cds{$ns_ip} = 1; } next; } - if ( not defined $dnskey_rrsets{ $ns_ip }{dnskey} or not scalar @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { - $no_dnskey_rrset{ $ns_ip } = 1; + if ( not defined $dnskey_rrsets{$ns_ip}{dnskey} or not scalar @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) { + $no_dnskey_rrset{$ns_ip} = 1; next; } - foreach my $ds ( @{ $cds_rrsets{ $ns_ip }{ds} } ) { + foreach my $ds ( @{ $cds_rrsets{$ns_ip}{ds} } ) { next if $ds->algorithm == 0; - if ( not scalar grep { $ds->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { + if ( not scalar grep { $ds->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) { push @{ $no_match_cds_with_dnskey{ $ds->keytag } }, $ns_ip; } - elsif ( scalar grep { $ds->keytag == $_->keytag and not $_->flags & 256 } @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { + elsif ( scalar grep { $ds->keytag == $_->keytag and not $_->flags & 256 } + @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) + { push @{ $cds_points_to_non_zone_dnskey{ $ds->keytag } }, $ns_ip; } else { - if ( not scalar grep { $ds->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{rrsig} } ) { + if ( not scalar grep { $ds->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{rrsig} } ) { push @{ $dnskey_not_signed_by_cds{ $ds->keytag } }, $ns_ip; } - if ( not scalar grep { $ds->keytag == $_->keytag } @{ $cds_rrsets{ $ns_ip }{rrsig} } ) { + if ( not scalar grep { $ds->keytag == $_->keytag } @{ $cds_rrsets{$ns_ip}{rrsig} } ) { push @{ $cds_not_signed_by_cds{ $ds->keytag } }, $ns_ip; } - if ( scalar grep { $ds->keytag == $_->keytag and not $_->flags & 1 } @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { + if ( scalar grep { $ds->keytag == $_->keytag and not $_->flags & 1 } + @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) + { push @{ $cds_points_to_non_sep_dnskey{ $ds->keytag } }, $ns_ip; } } - } - if ( not scalar @{ $cds_rrsets{ $ns_ip }{rrsig} } ) { - $cds_not_signed{ $ns_ip } = 1; + } ## end foreach my $ds ( @{ $cds_rrsets...}) + if ( not scalar @{ $cds_rrsets{$ns_ip}{rrsig} } ) { + $cds_not_signed{$ns_ip} = 1; } else { - foreach my $rrsig ( @{ $cds_rrsets{ $ns_ip }{rrsig} } ) { - my $msg = q{}; - my @matching_dnskeys = grep { $rrsig->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{dnskey} }; + foreach my $rrsig ( @{ $cds_rrsets{$ns_ip}{rrsig} } ) { + my $msg = q{}; + my @matching_dnskeys = grep { $rrsig->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{dnskey} }; if ( not scalar @matching_dnskeys ) { push @{ $cds_signed_by_unknown_dnskey{ $rrsig->keytag } }, $ns_ip; } - elsif ( not $rrsig->verify_time( $cds_rrsets{ $ns_ip }{cds} , \@matching_dnskeys, $testing_time, $msg) ) { + elsif ( + not $rrsig->verify_time( $cds_rrsets{$ns_ip}{cds}, \@matching_dnskeys, $testing_time, $msg ) ) + { push @{ $cds_invalid_rrsig{ $rrsig->keytag } }, $ns_ip; } } } - } + } ## end for my $ns_ip ( keys %cds_rrsets) if ( scalar keys %no_dnskey_rrset ) { push @results, @@ -5086,67 +5045,67 @@ sub dnssec16 { if ( scalar keys %no_match_cds_with_dnskey ) { push @results, map { - _emit_log( - DS16_CDS_MATCHES_NO_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_match_cds_with_dnskey{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_MATCHES_NO_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_match_cds_with_dnskey{$_} } ), + } + ) } keys %no_match_cds_with_dnskey; } if ( scalar keys %cds_points_to_non_zone_dnskey ) { push @results, map { - _emit_log( - DS16_CDS_MATCHES_NON_ZONE_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cds_points_to_non_zone_dnskey{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_MATCHES_NON_ZONE_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cds_points_to_non_zone_dnskey{$_} } ), + } + ) } keys %cds_points_to_non_zone_dnskey; } if ( scalar keys %cds_points_to_non_sep_dnskey ) { push @results, map { - _emit_log( - DS16_CDS_MATCHES_NON_SEP_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cds_points_to_non_sep_dnskey{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_MATCHES_NON_SEP_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cds_points_to_non_sep_dnskey{$_} } ), + } + ) } keys %cds_points_to_non_sep_dnskey; } if ( scalar keys %dnskey_not_signed_by_cds ) { push @results, map { - _emit_log( - DS16_DNSKEY_NOT_SIGNED_BY_CDS => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_signed_by_cds{ $_ } } ) - } - ) + _emit_log( + DS16_DNSKEY_NOT_SIGNED_BY_CDS => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_signed_by_cds{$_} } ), + } + ) } keys %dnskey_not_signed_by_cds; } if ( scalar keys %cds_not_signed_by_cds ) { push @results, map { - _emit_log( - DS16_CDS_NOT_SIGNED_BY_CDS => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cds_not_signed_by_cds{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_NOT_SIGNED_BY_CDS => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cds_not_signed_by_cds{$_} } ), + } + ) } keys %cds_not_signed_by_cds; } if ( scalar keys %cds_invalid_rrsig ) { push @results, map { - _emit_log( - DS16_CDS_INVALID_RRSIG => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cds_invalid_rrsig{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_INVALID_RRSIG => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cds_invalid_rrsig{$_} } ), + } + ) } keys %cds_invalid_rrsig; } @@ -5161,15 +5120,15 @@ sub dnssec16 { if ( scalar keys %cds_signed_by_unknown_dnskey ) { push @results, map { - _emit_log( - DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cds_signed_by_unknown_dnskey{ $_ } } ) - } - ) + _emit_log( + DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cds_signed_by_unknown_dnskey{$_} } ), + } + ) } keys %cds_signed_by_unknown_dnskey; } - } + } ## end if ( scalar keys %cds_rrsets) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub dnssec16 @@ -5218,8 +5177,8 @@ sub dnssec17 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -5239,9 +5198,9 @@ sub dnssec17 { if ( not scalar @cdnskey_records ) { next; } - my @cdnskey_rrsig_records = $cdnskey_p->get_records( q{RRSIG} , q{answer} ); + my @cdnskey_rrsig_records = $cdnskey_p->get_records( q{RRSIG}, q{answer} ); push @{ $cdnskey_rrsets{ $ns->address->short }{cdnskey} }, @cdnskey_records; - push @{ $cdnskey_rrsets{ $ns->address->short }{rrsig} }, @cdnskey_rrsig_records; + push @{ $cdnskey_rrsets{ $ns->address->short }{rrsig} }, @cdnskey_rrsig_records; foreach my $cdnskey ( @{ $cdnskey_rrsets{ $ns->address->short }{cdnskey} } ) { my $rr_string = $cdnskey->string; $rr_string =~ s/\s+CDNSKEY\s+/ DNSKEY /; @@ -5262,33 +5221,33 @@ sub dnssec17 { if ( not scalar @dnskey_records ) { next; } - my @dnskey_rrsig_records = $dnskey_p->get_records( q{RRSIG} , q{answer} ); + my @dnskey_rrsig_records = $dnskey_p->get_records( q{RRSIG}, q{answer} ); push @{ $dnskey_rrsets{ $ns->address->short }{dnskey} }, @dnskey_records; - push @{ $dnskey_rrsets{ $ns->address->short }{rrsig} }, @dnskey_rrsig_records; + push @{ $dnskey_rrsets{ $ns->address->short }{rrsig} }, @dnskey_rrsig_records; $testing_time = $dnskey_p->timestamp; - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( scalar keys %cdnskey_rrsets ) { for my $ns_ip ( keys %cdnskey_rrsets ) { - if ( not scalar @{ $cdnskey_rrsets{ $ns_ip }{cdnskey} } ) { + if ( not scalar @{ $cdnskey_rrsets{$ns_ip}{cdnskey} } ) { next; } - if ( scalar grep { $_->algorithm == 0 } @{ $cdnskey_rrsets{ $ns_ip }{dnskey} } ) { - if ( scalar grep { $_->algorithm != 0 } @{ $cdnskey_rrsets{ $ns_ip }{dnskey} } ) { - $mixed_delete_cdnskey{ $ns_ip } = 1; + if ( scalar grep { $_->algorithm == 0 } @{ $cdnskey_rrsets{$ns_ip}{dnskey} } ) { + if ( scalar grep { $_->algorithm != 0 } @{ $cdnskey_rrsets{$ns_ip}{dnskey} } ) { + $mixed_delete_cdnskey{$ns_ip} = 1; } else { - $delete_cdnskey{ $ns_ip } = 1; + $delete_cdnskey{$ns_ip} = 1; } next; } - if ( not defined $dnskey_rrsets{ $ns_ip }{dnskey} or not scalar @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { - $no_dnskey_rrset{ $ns_ip } = 1; + if ( not defined $dnskey_rrsets{$ns_ip}{dnskey} or not scalar @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) { + $no_dnskey_rrset{$ns_ip} = 1; next; } - foreach my $dnskey ( @{ $cdnskey_rrsets{ $ns_ip }{dnskey} } ) { + foreach my $dnskey ( @{ $cdnskey_rrsets{$ns_ip}{dnskey} } ) { next if $dnskey->algorithm == 0; if ( not $dnskey->flags & 256 ) { push @{ $cdnskey_is_non_zone_key{ $dnskey->keytag } }, $ns_ip; @@ -5297,35 +5256,40 @@ sub dnssec17 { if ( not $dnskey->flags & 1 ) { push @{ $cdnskey_is_non_sep_key{ $dnskey->keytag } }, $ns_ip; } - if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{dnskey} } ) { + if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{dnskey} } ) { push @{ $no_match_cdnskey_with_dnskey{ $dnskey->keytag } }, $ns_ip; } else { - if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{rrsig} } ) { + if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{rrsig} } ) { push @{ $dnskey_not_signed_by_cdnskey{ $dnskey->keytag } }, $ns_ip; } - if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $cdnskey_rrsets{ $ns_ip }{rrsig} } ) { + if ( not scalar grep { $dnskey->keytag == $_->keytag } @{ $cdnskey_rrsets{$ns_ip}{rrsig} } ) { push @{ $cdnskey_not_signed_by_cdnskey{ $dnskey->keytag } }, $ns_ip; } } } - } - if ( not scalar @{ $cdnskey_rrsets{ $ns_ip }{rrsig} } ) { - $cdnskey_not_signed{ $ns_ip } = 1; + } ## end foreach my $dnskey ( @{ $cdnskey_rrsets...}) + if ( not scalar @{ $cdnskey_rrsets{$ns_ip}{rrsig} } ) { + $cdnskey_not_signed{$ns_ip} = 1; } else { - foreach my $rrsig ( @{ $cdnskey_rrsets{ $ns_ip }{rrsig} } ) { - my $msg = q{}; - my @matching_dnskeys = grep { $rrsig->keytag == $_->keytag } @{ $dnskey_rrsets{ $ns_ip }{dnskey} }; + foreach my $rrsig ( @{ $cdnskey_rrsets{$ns_ip}{rrsig} } ) { + my $msg = q{}; + my @matching_dnskeys = grep { $rrsig->keytag == $_->keytag } @{ $dnskey_rrsets{$ns_ip}{dnskey} }; if ( not scalar @matching_dnskeys ) { push @{ $cdnskey_signed_by_unknown_dnskey{ $rrsig->keytag } }, $ns_ip; } - elsif ( not $rrsig->verify_time( $cdnskey_rrsets{ $ns_ip }{cdnskey} , \@matching_dnskeys, $testing_time, $msg) ) { + elsif ( + not $rrsig->verify_time( + $cdnskey_rrsets{$ns_ip}{cdnskey}, \@matching_dnskeys, $testing_time, $msg + ) + ) + { push @{ $cdnskey_invalid_rrsig{ $rrsig->keytag } }, $ns_ip; } } } - } + } ## end for my $ns_ip ( keys %cdnskey_rrsets) if ( scalar keys %no_dnskey_rrset ) { push @results, @@ -5356,68 +5320,67 @@ sub dnssec17 { if ( scalar keys %no_match_cdnskey_with_dnskey ) { push @results, map { - _emit_log( - DS17_CDNSKEY_MATCHES_NO_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $no_match_cdnskey_with_dnskey{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_MATCHES_NO_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $no_match_cdnskey_with_dnskey{$_} } ), + } + ) } keys %no_match_cdnskey_with_dnskey; } if ( scalar keys %cdnskey_is_non_zone_key ) { push @results, map { - _emit_log( - DS17_CDNSKEY_IS_NON_ZONE => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_is_non_zone_key{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_IS_NON_ZONE => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_is_non_zone_key{$_} } ), + } + ) } keys %cdnskey_is_non_zone_key; } - if ( scalar keys %cdnskey_is_non_sep_key ) { push @results, map { - _emit_log( - DS17_CDNSKEY_IS_NON_SEP => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_is_non_sep_key{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_IS_NON_SEP => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_is_non_sep_key{$_} } ), + } + ) } keys %cdnskey_is_non_sep_key; } if ( scalar keys %dnskey_not_signed_by_cdnskey ) { push @results, map { - _emit_log( - DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_signed_by_cdnskey{ $_ } } ) - } - ) + _emit_log( + DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $dnskey_not_signed_by_cdnskey{$_} } ), + } + ) } keys %dnskey_not_signed_by_cdnskey; } if ( scalar keys %cdnskey_not_signed_by_cdnskey ) { push @results, map { - _emit_log( - DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_not_signed_by_cdnskey{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_not_signed_by_cdnskey{$_} } ), + } + ) } keys %cdnskey_not_signed_by_cdnskey; } if ( scalar keys %cdnskey_invalid_rrsig ) { push @results, map { - _emit_log( - DS17_CDNSKEY_INVALID_RRSIG => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_invalid_rrsig{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_INVALID_RRSIG => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_invalid_rrsig{$_} } ), + } + ) } keys %cdnskey_invalid_rrsig; } @@ -5432,15 +5395,15 @@ sub dnssec17 { if ( scalar keys %cdnskey_signed_by_unknown_dnskey ) { push @results, map { - _emit_log( - DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY => { - keytag => $_, - ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_signed_by_unknown_dnskey{ $_ } } ) - } - ) + _emit_log( + DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY => { + keytag => $_, + ns_ip_list => join( q{;}, uniq sort @{ $cdnskey_signed_by_unknown_dnskey{$_} } ), + } + ) } keys %cdnskey_signed_by_unknown_dnskey; } - } + } ## end if ( scalar keys %cdnskey_rrsets) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub dnssec17 @@ -5482,8 +5445,8 @@ sub dnssec18 { for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, q{DS} ) ) { next; @@ -5510,7 +5473,7 @@ sub dnssec18 { push @ds_records, $tmp_ds_record; } } - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( not scalar @ds_records ) { @@ -5520,16 +5483,16 @@ sub dnssec18 { if ( $continue_with_child_tests ) { my @query_types = qw{CDNSKEY CDS DNSKEY}; - my @nss_del = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; - my @nss_child = @{ Zonemaster::Engine::TestMethods->method5( $zone ) }; - my %nss = map { $_->name->string . '/' . $_->address->short => $_ } @nss_del, @nss_child; + my @nss_del = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; + my @nss_child = @{ Zonemaster::Engine::TestMethods->method5( $zone ) }; + my %nss = map { $_->name->string . '/' . $_->address->short => $_ } @nss_del, @nss_child; my %ip_already_processed; for my $nss_key ( sort keys %nss ) { my $ns = $nss{$nss_key}; - next if exists $ip_already_processed{$ns->address->short}; - $ip_already_processed{$ns->address->short} = 1; + next if exists $ip_already_processed{ $ns->address->short }; + $ip_already_processed{ $ns->address->short } = 1; if ( _ip_disabled_message( \@results, $ns, @query_types ) ) { next; @@ -5541,8 +5504,8 @@ sub dnssec18 { } my @cds_records = $cds_p->get_records( q{CDS}, q{answer} ); if ( scalar @cds_records ) { - my @cds_rrsig_records = $cds_p->get_records( q{RRSIG} , q{answer} ); - push @{ $cds_rrsets{ $ns->address->short }{cds} }, @cds_records; + my @cds_rrsig_records = $cds_p->get_records( q{RRSIG}, q{answer} ); + push @{ $cds_rrsets{ $ns->address->short }{cds} }, @cds_records; push @{ $cds_rrsets{ $ns->address->short }{rrsig} }, @cds_rrsig_records; foreach my $cds ( @{ $cds_rrsets{ $ns->address->short }{cds} } ) { my $rr_string = $cds->string; @@ -5557,9 +5520,9 @@ sub dnssec18 { } my @cdnskey_records = $cdnskey_p->get_records( q{CDNSKEY}, q{answer} ); if ( scalar @cdnskey_records ) { - my @cdnskey_rrsig_records = $cdnskey_p->get_records( q{RRSIG} , q{answer} ); + my @cdnskey_rrsig_records = $cdnskey_p->get_records( q{RRSIG}, q{answer} ); push @{ $cdnskey_rrsets{ $ns->address->short }{cdnskey} }, @cdnskey_records; - push @{ $cdnskey_rrsets{ $ns->address->short }{rrsig} }, @cdnskey_rrsig_records; + push @{ $cdnskey_rrsets{ $ns->address->short }{rrsig} }, @cdnskey_rrsig_records; foreach my $cdnskey ( @{ $cdnskey_rrsets{ $ns->address->short }{cdnskey} } ) { my $rr_string = $cdnskey->string; $rr_string =~ s/\s+CDNSKEY\s+/ DNSKEY /; @@ -5575,16 +5538,16 @@ sub dnssec18 { if ( scalar @dnskey_records ) { push @{ $dnskey_rrsets{ $ns->address->short }{dnskey} }, @dnskey_records; } - } + } ## end for my $nss_key ( sort ...) undef %ip_already_processed; if ( not( not scalar keys %cds_rrsets and not scalar keys %cdnskey_rrsets ) and not( not scalar keys %dnskey_rrsets ) ) { for my $ns_ip ( keys %cds_rrsets ) { - my (@rrsig, @dnskey); - push @rrsig, @{ $cds_rrsets{ $ns_ip }{rrsig} }; - push @dnskey, @{ $dnskey_rrsets{ $ns_ip }{dnskey} }; + my ( @rrsig, @dnskey ); + push @rrsig, @{ $cds_rrsets{$ns_ip}{rrsig} }; + push @dnskey, @{ $dnskey_rrsets{$ns_ip}{dnskey} }; my $match = 0; foreach my $ds ( @ds_records ) { if ( not scalar grep { $ds->keytag == $_->keytag } @dnskey ) { @@ -5596,13 +5559,13 @@ sub dnssec18 { } } if ( not $match ) { - $ds_no_match_cds_rrsig{ $ns_ip } = 1; + $ds_no_match_cds_rrsig{$ns_ip} = 1; } } for my $ns_ip ( keys %cdnskey_rrsets ) { - my (@rrsig, @dnskey); - push @rrsig, @{ $cdnskey_rrsets{ $ns_ip }{rrsig} }; - push @dnskey, @{ $dnskey_rrsets{ $ns_ip }{dnskey} }; + my ( @rrsig, @dnskey ); + push @rrsig, @{ $cdnskey_rrsets{$ns_ip}{rrsig} }; + push @dnskey, @{ $dnskey_rrsets{$ns_ip}{dnskey} }; my $match = 0; foreach my $ds ( @ds_records ) { if ( not scalar grep { $ds->keytag == $_->keytag } @dnskey ) { @@ -5614,13 +5577,13 @@ sub dnssec18 { } } if ( not $match ) { - $ds_no_match_cdnskey_rrsig{ $ns_ip } = 1; + $ds_no_match_cdnskey_rrsig{$ns_ip} = 1; } } if ( scalar keys %ds_no_match_cds_rrsig ) { push @results, _emit_log( - DS18_NO_MATCH_CDS_RRSIG_DS => { + DS18_NO_MATCH_CDS_RRSIG_DS => { ns_ip_list => join( q{;}, sort keys %ds_no_match_cds_rrsig ) } ); @@ -5628,13 +5591,13 @@ sub dnssec18 { if ( scalar keys %ds_no_match_cdnskey_rrsig ) { push @results, _emit_log( - DS18_NO_MATCH_CDNSKEY_RRSIG_DS => { + DS18_NO_MATCH_CDNSKEY_RRSIG_DS => { ns_ip_list => join( q{;}, sort keys %ds_no_match_cdnskey_rrsig ) } ); } - } - } + } ## end if ( not( not scalar keys...)) + } ## end if ( $continue_with_child_tests) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub dnssec18 diff --git a/lib/Zonemaster/Engine/Test/Delegation.pm b/lib/Zonemaster/Engine/Test/Delegation.pm index 1c8f73032..8224e24ba 100644 --- a/lib/Zonemaster/Engine/Test/Delegation.pm +++ b/lib/Zonemaster/Engine/Test/Delegation.pm @@ -3,9 +3,9 @@ package Zonemaster::Engine::Test::Delegation; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.20"); +use version; our $VERSION = version->declare( "v1.0.20" ); -use List::MoreUtils qw[uniq]; +use List::MoreUtils qw[uniq]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; @@ -97,7 +97,7 @@ sub metadata { NO_IPV6_NS_DEL TEST_CASE_END TEST_CASE_START - ) + ) ], delegation02 => [ qw( @@ -109,7 +109,7 @@ sub metadata { DISTINCT_IP_ADDRESS TEST_CASE_END TEST_CASE_START - ) + ) ], delegation03 => [ qw( @@ -117,7 +117,7 @@ sub metadata { REFERRAL_SIZE_OK TEST_CASE_END TEST_CASE_START - ) + ) ], delegation04 => [ qw( @@ -127,7 +127,7 @@ sub metadata { ARE_AUTHORITATIVE TEST_CASE_END TEST_CASE_START - ) + ) ], delegation05 => [ qw( @@ -137,7 +137,7 @@ sub metadata { UNEXPECTED_RCODE TEST_CASE_END TEST_CASE_START - ) + ) ], delegation06 => [ qw( @@ -147,7 +147,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], delegation07 => [ qw( @@ -157,7 +157,7 @@ sub metadata { NAMES_MATCH TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -245,7 +245,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, ENOUGH_NS_DEL => sub { __x # DELEGATION:ENOUGH_NS_DEL - "Delegation lists enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", @_; + "Delegation lists enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", + @_; }, EXTRA_NAME_CHILD => sub { __x # DELEGATION:EXTRA_NAME_CHILD @@ -301,11 +302,13 @@ Readonly my %TAG_DESCRIPTIONS => ( }, NOT_ENOUGH_NS_CHILD => sub { __x # DELEGATION:NOT_ENOUGH_NS_CHILD - "Child does not list enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", @_; + "Child does not list enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", + @_; }, NOT_ENOUGH_NS_DEL => sub { __x # DELEGATION:NOT_ENOUGH_NS_DEL - "Delegation does not list enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", @_; +"Delegation does not list enough ({count}) nameservers. Lower limit set to {minimum}. Name servers: {nsname_list}", + @_; }, NO_IPV4_NS_CHILD => sub { __x # DELEGATION:NO_IPV4_NS_CHILD @@ -452,27 +455,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -503,7 +492,7 @@ sub _max_length_name_for { while ( length( $name ) < $FQDN_MAX_LENGTH - 1 ) { my $len = $FQDN_MAX_LENGTH - length( $name ) - 1; - $len = $LABEL_MAX_LENGTH if $len > $LABEL_MAX_LENGTH; + $len = $LABEL_MAX_LENGTH if $len > $LABEL_MAX_LENGTH; $name = join( q{}, map { $chars[ rand @chars ] } 1 .. $len ) . q{.} . $name; } @@ -563,7 +552,7 @@ sub _find_dup_ns { } return @results; -} +} ## end sub _find_dup_ns =head1 TESTS @@ -590,7 +579,7 @@ sub delegation01 { push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); # Determine delegation NS names - my @del_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) }; + my @del_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) }; my $del_nsnames_args = { count => scalar( @del_nsnames ), minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, @@ -606,7 +595,7 @@ sub delegation01 { } # Determine child NS names - my @child_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method3( $zone ) }; + my @child_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method3( $zone ) }; my $child_nsnames_args = { count => scalar( @child_nsnames ), minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, @@ -622,18 +611,18 @@ sub delegation01 { } # Determine child NS names with addresses - my @child_ns = @{ Zonemaster::Engine::TestMethods->method5( $zone ) }; + my @child_ns = @{ Zonemaster::Engine::TestMethods->method5( $zone ) }; my @child_ns_ipv4 = map { $_ } grep { $_->address->version == 4 } @child_ns; my @child_ns_ipv6 = map { $_ } grep { $_->address->version == 6 } @child_ns; my $child_ns_ipv4_args = { - count => scalar( uniq map { $_->name->string } @child_ns_ipv4 ), - minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, + count => scalar( uniq map { $_->name->string } @child_ns_ipv4 ), + minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, ns_list => join( q{;}, sort map { $_->string } @child_ns_ipv4 ), }; my $child_ns_ipv6_args = { - count => scalar( uniq map { $_->name->string } @child_ns_ipv6 ), - minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, + count => scalar( uniq map { $_->name->string } @child_ns_ipv6 ), + minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, ns_list => join( q{;}, sort map { $_->string } @child_ns_ipv6 ), }; @@ -658,18 +647,18 @@ sub delegation01 { } # Determine delegation NS names with addresses - my @del_ns = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; + my @del_ns = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; my @del_ns_ipv4 = map { $_ } grep { $_->address->version == 4 } @del_ns; my @del_ns_ipv6 = map { $_ } grep { $_->address->version == 6 } @del_ns; my $del_ns_ipv4_args = { - count => scalar( uniq map { $_->name->string } @del_ns_ipv4 ), - minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, + count => scalar( uniq map { $_->name->string } @del_ns_ipv4 ), + minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, ns_list => join( q{;}, sort map { $_->string } @del_ns_ipv4 ), }; my $del_ns_ipv6_args = { - count => scalar( uniq map { $_->name->string } @del_ns_ipv6 ), - minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, + count => scalar( uniq map { $_->name->string } @del_ns_ipv6 ), + minimum => $MINIMUM_NUMBER_OF_NAMESERVERS, ns_list => join( q{;}, sort map { $_->string } @del_ns_ipv6 ), }; @@ -840,8 +829,10 @@ sub delegation04 { my @authoritatives; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { if ( _ip_disabled_message( \@results, $local_ns, $query_type ) ) { @@ -915,7 +906,7 @@ sub delegation05 { my @nsnames = @{ Zonemaster::Engine::TestMethods->method2and3( $zone ) }; - foreach my $local_nsname ( @nsnames ) { + foreach my $local_nsname ( @nsnames ) { if ( $zone->name->is_in_bailiwick( $local_nsname ) ) { my @nss_del = @{ Zonemaster::Engine::TestMethods->method4( $zone ) }; @@ -923,7 +914,7 @@ sub delegation05 { my %nss = map { $_->name->string . '/' . $_->address->short => $_ } @nss_del, @nss_child; for my $key ( sort keys %nss ) { - my $ns = $nss{$key}; + my $ns = $nss{$key}; my $ns_args = { ns => $ns->string, query_name => $local_nsname, @@ -939,7 +930,7 @@ sub delegation05 { push @results, _emit_log( NO_RESPONSE => $ns_args ); next; } - elsif ($p->rcode ne q{NOERROR} ) { + elsif ( $p->rcode ne q{NOERROR} ) { $ns_args->{rcode} = $p->rcode; push @results, _emit_log( UNEXPECTED_RCODE => $ns_args ); next; @@ -948,21 +939,21 @@ sub delegation05 { push @results, _emit_log( NS_IS_CNAME => { nsname => $local_nsname } ); next; } - elsif ($p->is_redirect) { + elsif ( $p->is_redirect ) { my $p = $ns->query( $local_nsname, q{A}, { recurse => 1 } ); if ( defined $p and scalar $p->get_records( q{CNAME}, q{answer} ) > 0 ) { push @results, _emit_log( NS_IS_CNAME => { nsname => $local_nsname } ); } } - } - } + } ## end for my $key ( sort keys...) + } ## end if ( $zone->name->is_in_bailiwick...) else { my $p = Zonemaster::Engine::Recursor->recurse( $local_nsname, q{A} ); if ( defined $p and scalar $p->get_records( q{CNAME}, q{answer} ) > 0 ) { push @results, _emit_log( NS_IS_CNAME => { nsname => $local_nsname } ); } } - } + } ## end foreach my $local_nsname ( ...) if ( not grep { $_->tag eq q{NS_IS_CNAME} } @results ) { push @results, _emit_log( NO_NS_CNAME => {} ); @@ -995,8 +986,10 @@ sub delegation06 { my %nsnames; my $query_type = q{SOA}; - foreach - my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) + foreach my $local_ns ( + @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, + @{ Zonemaster::Engine::TestMethods->method5( $zone ) }, + ) { if ( _ip_disabled_message( \@results, $local_ns, $query_type ) ) { diff --git a/lib/Zonemaster/Engine/Test/Nameserver.pm b/lib/Zonemaster/Engine/Test/Nameserver.pm index 4677a3953..a3fe80890 100644 --- a/lib/Zonemaster/Engine/Test/Nameserver.pm +++ b/lib/Zonemaster/Engine/Test/Nameserver.pm @@ -6,7 +6,7 @@ use warnings; use version; our $VERSION = version->declare( "v1.1.0" ); use JSON::PP; -use List::MoreUtils qw[uniq none]; +use List::MoreUtils qw[uniq none]; use Locale::TextDomain qw[Zonemaster-Engine]; use Net::IP::XS; use Readonly; @@ -125,7 +125,7 @@ sub metadata { NO_RESPONSE TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver02 => [ qw( @@ -138,7 +138,7 @@ sub metadata { NS_ERROR TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver03 => [ qw( @@ -146,7 +146,7 @@ sub metadata { AXFR_AVAILABLE TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver04 => [ qw( @@ -154,7 +154,7 @@ sub metadata { SAME_SOURCE_IP TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver05 => [ qw( @@ -168,7 +168,7 @@ sub metadata { IPV6_DISABLED TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver06 => [ qw( @@ -177,7 +177,7 @@ sub metadata { NO_RESOLUTION TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver07 => [ qw( @@ -186,7 +186,7 @@ sub metadata { NO_UPWARD_REFERRAL TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver08 => [ qw( @@ -194,7 +194,7 @@ sub metadata { QNAME_CASE_SENSITIVE TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver09 => [ qw( @@ -207,7 +207,7 @@ sub metadata { CASE_QUERIES_RESULTS_DIFFER TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver10 => [ qw( @@ -216,7 +216,7 @@ sub metadata { N10_EDNS_RESPONSE_ERROR TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver11 => [ qw( @@ -228,7 +228,7 @@ sub metadata { N11_UNSET_AA TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver12 => [ qw( @@ -238,7 +238,7 @@ sub metadata { NS_ERROR TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver13 => [ qw( @@ -248,7 +248,7 @@ sub metadata { MISSING_OPT_IN_TRUNCATED TEST_CASE_END TEST_CASE_START - ) + ) ], nameserver15 => [ qw( @@ -256,7 +256,7 @@ sub metadata { N15_NO_VERSION_REVEALED N15_SOFTWARE_VERSION N15_WRONG_CLASS - ) + ) ], }; } ## end sub metadata @@ -264,63 +264,63 @@ sub metadata { Readonly my %TAG_DESCRIPTIONS => ( NAMESERVER01 => sub { __x # NAMESERVER:NAMESERVER01 - 'A name server should not be a recursor'; + 'A name server should not be a recursor'; }, NAMESERVER02 => sub { __x # NAMESERVER:NAMESERVER02 - 'Test of EDNS0 support'; + 'Test of EDNS0 support'; }, NAMESERVER03 => sub { __x # NAMESERVER:NAMESERVER03 - 'Test availability of zone transfer (AXFR)'; + 'Test availability of zone transfer (AXFR)'; }, NAMESERVER04 => sub { __x # NAMESERVER:NAMESERVER04 - 'Same source address'; + 'Same source address'; }, NAMESERVER05 => sub { __x # NAMESERVER:NAMESERVER05 - 'Behaviour against AAAA query'; + 'Behaviour against AAAA query'; }, NAMESERVER06 => sub { __x # NAMESERVER:NAMESERVER06 - 'NS can be resolved'; + 'NS can be resolved'; }, NAMESERVER07 => sub { __x # NAMESERVER:NAMESERVER07 - 'To check whether authoritative name servers return an upward referral'; + 'To check whether authoritative name servers return an upward referral'; }, NAMESERVER08 => sub { __x # NAMESERVER:NAMESERVER08 - 'Testing QNAME case insensitivity'; + 'Testing QNAME case insensitivity'; }, NAMESERVER09 => sub { __x # NAMESERVER:NAMESERVER09 - 'Testing QNAME case sensitivity'; + 'Testing QNAME case sensitivity'; }, NAMESERVER10 => sub { __x # NAMESERVER:NAMESERVER10 - 'Test for undefined EDNS version'; + 'Test for undefined EDNS version'; }, NAMESERVER11 => sub { __x # NAMESERVER:NAMESERVER11 - 'Test for unknown EDNS OPTION-CODE'; + 'Test for unknown EDNS OPTION-CODE'; }, NAMESERVER12 => sub { __x # NAMESERVER:NAMESERVER12 - 'Test for unknown EDNS flags'; + 'Test for unknown EDNS flags'; }, NAMESERVER13 => sub { __x # NAMESERVER:NAMESERVER13 - 'Test for truncated response on EDNS query'; + 'Test for truncated response on EDNS query'; }, NAMESERVER15 => sub { __x # NAMESERVER:NAMESERVER15 - 'Checking for revealed software version'; + 'Checking for revealed software version'; }, AAAA_BAD_RDATA => sub { __x # NAMESERVER:AAAA_BAD_RDATA - 'Nameserver {ns} answered AAAA query with an unexpected RDATA length ({length} instead of 16).', @_; + 'Nameserver {ns} answered AAAA query with an unexpected RDATA length ({length} instead of 16).', @_; }, AAAA_QUERY_DROPPED => sub { __x # NAMESERVER:AAAA_QUERY_DROPPED @@ -360,7 +360,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CASE_QUERIES_RESULTS_DIFFER => sub { __x # NAMESERVER:CASE_QUERIES_RESULTS_DIFFER - 'When asked for {type} records on "{domain}" with different cases, all servers do not reply consistently.', @_; + 'When asked for {type} records on "{domain}" with different cases, all servers do not reply consistently.', + @_; }, CASE_QUERIES_RESULTS_OK => sub { __x # NAMESERVER:CASE_QUERIES_RESULTS_OK @@ -368,8 +369,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CASE_QUERY_DIFFERENT_ANSWER => sub { __x # NAMESERVER:CASE_QUERY_DIFFERENT_ANSWER - 'When asked for {type} records on "{query1}" and "{query2}", ' - . 'nameserver {ns} returns different answers.', + 'When asked for {type} records on "{query1}" and "{query2}", ' . 'nameserver {ns} returns different answers.', @_; }, CASE_QUERY_DIFFERENT_RC => sub { @@ -384,8 +384,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, CASE_QUERY_SAME_ANSWER => sub { __x # NAMESERVER:CASE_QUERY_SAME_ANSWER - 'When asked for {type} records on "{query1}" and "{query2}", nameserver {ns} returns same answers.', - @_; + 'When asked for {type} records on "{query1}" and "{query2}", nameserver {ns} returns same answers.', @_; }, CASE_QUERY_SAME_RC => sub { __x # NAMESERVER:CASE_QUERY_SAME_RC @@ -453,7 +452,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, N10_EDNS_RESPONSE_ERROR => sub { __x # NAMESERVER:N10_EDNS_RESPONSE_ERROR - 'Expected RCODE but received erroneous response to an EDNS version 1 query. Fetched from the nameservers with IP addresses {ns_ip_list}', @_; +'Expected RCODE but received erroneous response to an EDNS version 1 query. Fetched from the nameservers with IP addresses {ns_ip_list}', + @_; }, N10_NO_RESPONSE_EDNS1_QUERY => sub { __x # NAMESERVER:N10_NO_RESPONSE_EDNS1_QUERY @@ -461,11 +461,13 @@ Readonly my %TAG_DESCRIPTIONS => ( }, N10_UNEXPECTED_RCODE => sub { __x # NAMESERVER:N10_UNEXPECTED_RCODE - 'Erroneous RCODE ("{rcode}") in response to an EDNS version 1 query. Fetched from the nameservers with IP addresses {ns_ip_list}', @_; +'Erroneous RCODE ("{rcode}") in response to an EDNS version 1 query. Fetched from the nameservers with IP addresses {ns_ip_list}', + @_; }, N11_NO_EDNS => sub { __x # NAMESERVER:N11_NO_EDNS - 'The DNS response, on query with unknown EDNS option-code, does not contain any EDNS from name servers "{ns_ip_list}".', @_; +'The DNS response, on query with unknown EDNS option-code, does not contain any EDNS from name servers "{ns_ip_list}".', + @_; }, N11_NO_RESPONSE => sub { __x # NAMESERVER:N11_NO_RESPONSE @@ -477,31 +479,38 @@ Readonly my %TAG_DESCRIPTIONS => ( }, N11_UNEXPECTED_ANSWER_SECTION => sub { __x # NAMESERVER:N11_UNEXPECTED_ANSWER_SECTION - 'The DNS response, on query with unknown EDNS option-code, does not contain the expected SOA record in the answer section from name servers "{ns_ip_list}".', @_; +'The DNS response, on query with unknown EDNS option-code, does not contain the expected SOA record in the answer section from name servers "{ns_ip_list}".', + @_; }, N11_UNEXPECTED_RCODE => sub { __x # NAMESERVER:N11_UNEXPECTED_RCODE - 'The DNS response, on query with unknown EDNS option-code, has unexpected RCODE name "{rcode}" from name servers "{ns_ip_list}".', @_; +'The DNS response, on query with unknown EDNS option-code, has unexpected RCODE name "{rcode}" from name servers "{ns_ip_list}".', + @_; }, N11_UNSET_AA => sub { __x # NAMESERVER:N11_UNSET_AA - 'The DNS response, on query with unknown EDNS option-code, is unexpectedly not authoritative from name servers "{ns_ip_list}".', @_; +'The DNS response, on query with unknown EDNS option-code, is unexpectedly not authoritative from name servers "{ns_ip_list}".', + @_; }, N15_ERROR_ON_VERSION_QUERY => sub { __x # NAMESERVER:N15_ERROR_ON_VERSION_QUERY - 'The following name server(s) do not respond or respond with SERVFAIL to software version query "{query_name}". Returned from name servers: "{ns_list}"', @_; +'The following name server(s) do not respond or respond with SERVFAIL to software version query "{query_name}". Returned from name servers: "{ns_list}"', + @_; }, N15_NO_VERSION_REVEALED => sub { __x # NAMESERVER:N15_NO_VERSION_REVEALED - 'The following name server(s) do not reveal the software version. Returned from name servers: "{ns_list}"', @_; + 'The following name server(s) do not reveal the software version. Returned from name servers: "{ns_list}"', + @_; }, N15_SOFTWARE_VERSION => sub { __x # NAMESERVER:N15_SOFTWARE_VERSION - 'The following name server(s) respond to software version query "{query_name}" with string "{string}". Returned from name servers: "{ns_list}"', @_; +'The following name server(s) respond to software version query "{query_name}" with string "{string}". Returned from name servers: "{ns_list}"', + @_; }, N15_WRONG_CLASS => sub { __x # NAMESERVER:N15_WRONG_CLASS - 'The following name server(s) do not return CH class record(s) on CH class query. Returned from name servers: "{ns_list}"', @_; +'The following name server(s) do not return CH class record(s) on CH class query. Returned from name servers: "{ns_list}"', + @_; }, QNAME_CASE_INSENSITIVE => sub { __x # NAMESERVER:QNAME_CASE_INSENSITIVE @@ -611,27 +620,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -661,7 +656,7 @@ sub nameserver01 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Nameserver01'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; for my $ns ( @nss ) { @@ -734,7 +729,7 @@ sub nameserver02 { my %nsnames_and_ip; my $n_error = 0; - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { next if ( _ip_disabled_message( \@results, $local_ns, q{SOA} ) ); @@ -743,11 +738,15 @@ sub nameserver02 { my $p = $local_ns->query( $zone->name, q{SOA}, { edns_details => { version => 0 } } ); if ( $p ) { - if ( $p->rcode eq q{FORMERR} and not $p->has_edns) { + if ( $p->rcode eq q{FORMERR} and not $p->has_edns ) { push @results, _emit_log( NO_EDNS_SUPPORT => { ns => $local_ns->string } ); $n_error++; } - elsif ( $p->rcode eq q{NOERROR} and not $p->edns_rcode and $p->get_records( q{SOA}, q{answer} ) and $p->edns_version == 0 ) { + elsif ( $p->rcode eq q{NOERROR} + and not $p->edns_rcode + and $p->get_records( q{SOA}, q{answer} ) + and $p->edns_version == 0 ) + { $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; next; } @@ -775,7 +774,7 @@ sub nameserver02 { push @results, _emit_log( NS_ERROR => { ns => $local_ns->string } ); $n_error++; } - } + } ## end if ( $p ) else { my $p2 = $local_ns->query( $zone->name, q{SOA} ); if ( $p2 ) { @@ -798,10 +797,10 @@ sub nameserver02 { ); $n_error++; } - } + } ## end else [ if ( $p ) ] $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } ## end foreach my $local_ns ( @nss) if ( scalar keys %nsnames_and_ip and not $n_error ) { push @results, @@ -838,7 +837,7 @@ sub nameserver03 { push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); my %nsnames_and_ip; - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { @@ -859,7 +858,7 @@ sub nameserver03 { } $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } ## end foreach my $local_ns ( @nss) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub nameserver03 @@ -888,7 +887,7 @@ sub nameserver04 { my %nsnames_and_ip; my $n_error = 0; - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { @@ -910,9 +909,9 @@ sub nameserver04 { } } $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } ## end foreach my $local_ns ( @nss) - if ( scalar keys %nsnames_and_ip and not $n_error) { + if ( scalar keys %nsnames_and_ip and not $n_error ) { push @results, _emit_log( SAME_SOURCE_IP => { @@ -949,7 +948,7 @@ sub nameserver05 { my $aaaa_issue = 0; my @aaaa_ok; - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $ns ( @nss ) { @@ -983,8 +982,7 @@ sub nameserver05 { $p = $ns->query( $zone->name, q{AAAA}, { usevc => 0 } ); if ( not $p ) { - push @results, - _emit_log( AAAA_QUERY_DROPPED => { ns => $ns->string } ); + push @results, _emit_log( AAAA_QUERY_DROPPED => { ns => $ns->string } ); $aaaa_issue++; } elsif ( $p->rcode ne q{NOERROR} ) { @@ -999,7 +997,7 @@ sub nameserver05 { } else { foreach my $rr ( $p->get_records( q{AAAA}, q{answer} ) ) { - if ( length($rr->rdf(0)) != 16 ) { + if ( length( $rr->rdf( 0 ) ) != 16 ) { push @results, _emit_log( AAAA_BAD_RDATA => { @@ -1014,8 +1012,8 @@ sub nameserver05 { } } } - } - } + } ## end else [ if ( not $p ) ] + } ## end foreach my $ns ( @nss ) if ( scalar @aaaa_ok and not $aaaa_issue ) { push @results, @@ -1052,7 +1050,8 @@ sub nameserver06 { push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); my @all_nsnames = uniq map { lc( $_->string ) } @{ Zonemaster::Engine::TestMethods->method2( $zone ) }, @{ Zonemaster::Engine::TestMethods->method3( $zone ) }; - my @all_nsnames_with_ip = uniq map { lc( $_->name->string ) } @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @all_nsnames_with_ip = + uniq map { lc( $_->name->string ) } @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; my @all_nsnames_without_ip; my %diff; @@ -1112,7 +1111,7 @@ sub nameserver07 { push @results, _emit_log( UPWARD_REFERRAL_IRRELEVANT => {} ); } else { - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { next if ( _ip_disabled_message( \@results, $local_ns, q{NS} ) ); @@ -1129,7 +1128,7 @@ sub nameserver07 { } $nsnames{ $local_ns->name }++; $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } if ( scalar keys %nsnames_and_ip and not $n_error ) { push @results, @@ -1175,7 +1174,7 @@ sub nameserver08 { $randomized_uc_name = scramble_case $original_name; } while ( $randomized_uc_name eq $original_name ); - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { @@ -1208,7 +1207,7 @@ sub nameserver08 { } } ## end if ( $p and my ( $qrr ...)) $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } ## end foreach my $local_ns ( @nss) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub nameserver08 @@ -1251,7 +1250,7 @@ sub nameserver09 { $randomized_uc_name2 = scramble_case $original_name; } while ( $randomized_uc_name2 eq $original_name or $randomized_uc_name2 eq $randomized_uc_name1 ); - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; foreach my $local_ns ( @nss ) { @@ -1264,7 +1263,7 @@ sub nameserver09 { my $answer1_string = q{}; my $answer2_string = q{}; - my $json = JSON::PP->new->canonical->pretty; + my $json = JSON::PP->new->canonical->pretty; if ( $p1 and scalar $p1->answer ) { my @answer1 = map { lc $_->string } sort $p1->answer; @@ -1344,7 +1343,7 @@ sub nameserver09 { } $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++; - } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...}) + } ## end foreach my $local_ns ( @nss) if ( $all_results_match ) { push @results, @@ -1394,7 +1393,7 @@ sub nameserver10 { my %unexpected_rcode; my @edns_response_error; - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; for my $ns ( @nss ) { @@ -1402,14 +1401,17 @@ sub nameserver10 { my $p = $ns->query( $zone->name, q{SOA}, { edns_details => { version => 0 } } ); - if ( $p and $p->rcode eq q{NOERROR} ){ + if ( $p and $p->rcode eq q{NOERROR} ) { my $p2 = $ns->query( $zone->name, q{SOA}, { edns_details => { version => 1 } } ); if ( $p2 ) { - if ( ($p2->rcode ne q{NOERROR} and $p2->edns_rcode != 1) ) { - push @{ $unexpected_rcode{$p->rcode} }, $ns->address->short; + if ( ( $p2->rcode ne q{NOERROR} and $p2->edns_rcode != 1 ) ) { + push @{ $unexpected_rcode{ $p->rcode } }, $ns->address->short; } - elsif ( ($p2->rcode eq q{NOERROR} and $p2->edns_rcode == 1) and $p2->edns_version == 0 and not scalar $p2->answer){ + elsif ( ( $p2->rcode eq q{NOERROR} and $p2->edns_rcode == 1 ) + and $p2->edns_version == 0 + and not scalar $p2->answer ) + { next; } else { @@ -1419,36 +1421,36 @@ sub nameserver10 { else { push @no_response_edns1, $ns->address->short; } - } - } + } ## end if ( $p and $p->rcode ...) + } ## end for my $ns ( @nss ) - if ( scalar @no_response_edns1 ){ + if ( scalar @no_response_edns1 ) { push @results, - _emit_log( - N10_NO_RESPONSE_EDNS1_QUERY => { - ns_ip_list => join ( q{;}, uniq sort @no_response_edns1 ) - } - ); + _emit_log( + N10_NO_RESPONSE_EDNS1_QUERY => { + ns_ip_list => join( q{;}, uniq sort @no_response_edns1 ) + } + ); } - if ( scalar keys %unexpected_rcode ){ + if ( scalar keys %unexpected_rcode ) { push @results, map { _emit_log( N10_UNEXPECTED_RCODE => { - rcode => $_, - ns_ip_list => join( q{;}, uniq sort @{ $unexpected_rcode{$_} } ) + rcode => $_, + ns_ip_list => join( q{;}, uniq sort @{ $unexpected_rcode{$_} } ), } ) } keys %unexpected_rcode; } - if ( scalar @edns_response_error ){ + if ( scalar @edns_response_error ) { push @results, - _emit_log( - N10_EDNS_RESPONSE_ERROR => { - ns_ip_list => join ( q{;}, uniq sort @edns_response_error ) - } - ); + _emit_log( + N10_EDNS_RESPONSE_ERROR => { + ns_ip_list => join( q{;}, uniq sort @edns_response_error ) + } + ); } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); @@ -1485,10 +1487,10 @@ sub nameserver11 { # Choose an unassigned EDNS0 Option Codes # values 15-26945 are Unassigned. Let's say we use 137 ??? - my $opt_code = 137; - my $opt_data = q{}; - my $opt_length = length($opt_data); - my $rdata = $opt_code*65536 + $opt_length; + my $opt_code = 137; + my $opt_data = q{}; + my $opt_length = length( $opt_data ); + my $rdata = $opt_code * 65536 + $opt_length; foreach my $ns ( @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) } ) { @@ -1496,7 +1498,12 @@ sub nameserver11 { my $p = $ns->query( $zone->name, q{SOA}, { edns_details => { version => 0 } } ); - if ( not $p or not $p->has_edns or $p->rcode ne q{NOERROR} or not $p->aa or not $p->get_records_for_name(q{SOA}, $zone->name, q{answer}) ) { + if ( not $p + or not $p->has_edns + or $p->rcode ne q{NOERROR} + or not $p->aa + or not $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ) + { next; } @@ -1504,14 +1511,14 @@ sub nameserver11 { if ( $p ) { if ( $p->rcode ne q{NOERROR} ) { - push @{ $unexpected_rcode{$p->rcode} }, $ns->address->short; + push @{ $unexpected_rcode{ $p->rcode } }, $ns->address->short; } elsif ( not $p->has_edns ) { push @no_edns, $ns->address->short; } - elsif ( not $p->get_records_for_name(q{SOA}, $zone->name, q{answer}) ) { + elsif ( not $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ) { push @unexpected_answer, $ns->address->short; } @@ -1528,7 +1535,7 @@ sub nameserver11 { # in "network" (big-endian) order (OPTION-LENGTH), and # - Remaining data, if any (i.e., other OPTIONS) - my @unpacked_opt = eval { unpack("(n n/a)*", $p_opt) }; + my @unpacked_opt = eval { unpack( "(n n/a)*", $p_opt ) }; while ( my ( $p_opt_code, $p_opt_data, @next_data ) = @unpacked_opt ) { if ( $p_opt_code == $opt_code ) { @@ -1538,12 +1545,12 @@ sub nameserver11 { @unpacked_opt = @next_data; } - } - } - else{ + } ## end elsif ( defined $p->edns_data) + } ## end if ( $p ) + else { push @no_response, $ns->address->short; } - } + } ## end foreach my $ns ( @{ Zonemaster::Engine::TestMethods...}) if ( scalar @no_response ) { push @results, _emit_log( N11_NO_RESPONSE => { ns_ip_list => join( q{;}, uniq sort @no_response ) } ); @@ -1551,12 +1558,12 @@ sub nameserver11 { if ( scalar keys %unexpected_rcode ) { push @results, map { - _emit_log( - N11_UNEXPECTED_RCODE => { - rcode => $_, - ns_ip_list => join( q{;}, uniq sort @{ $unexpected_rcode{$_} } ) - } - ) + _emit_log( + N11_UNEXPECTED_RCODE => { + rcode => $_, + ns_ip_list => join( q{;}, uniq sort @{ $unexpected_rcode{$_} } ), + } + ) } keys %unexpected_rcode; } @@ -1565,7 +1572,8 @@ sub nameserver11 { } if ( scalar @unexpected_answer ) { - push @results, _emit_log( N11_UNEXPECTED_ANSWER_SECTION => { ns_ip_list => join( q{;}, uniq sort @unexpected_answer ) } ); + push @results, + _emit_log( N11_UNEXPECTED_ANSWER_SECTION => { ns_ip_list => join( q{;}, uniq sort @unexpected_answer ) } ); } if ( scalar @unset_aa ) { @@ -1573,7 +1581,8 @@ sub nameserver11 { } if ( scalar @unknown_opt_code ) { - push @results, _emit_log( N11_RETURNS_UNKNOWN_OPTION_CODE => { ns_ip_list => join( q{;}, uniq sort @unknown_opt_code ) } ); + push @results, + _emit_log( N11_RETURNS_UNKNOWN_OPTION_CODE => { ns_ip_list => join( q{;}, uniq sort @unknown_opt_code ) } ); } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); @@ -1601,7 +1610,7 @@ sub nameserver12 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Nameserver12'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; for my $ns ( @nss ) { @@ -1616,7 +1625,12 @@ sub nameserver12 { elsif ( $p->edns_z ) { push @results, _emit_log( Z_FLAGS_NOTCLEAR => { ns => $ns->string } ); } - elsif ( $p->rcode eq q{NOERROR} and not $p->edns_rcode and $p->edns_version == 0 and $p->edns_z == 0 and $p->get_records( q{SOA}, q{answer} ) ) { + elsif ( $p->rcode eq q{NOERROR} + and not $p->edns_rcode + and $p->edns_version == 0 + and $p->edns_z == 0 + and $p->get_records( q{SOA}, q{answer} ) ) + { next; } else { @@ -1632,7 +1646,7 @@ sub nameserver12 { } ); } - } + } ## end for my $ns ( @nss ) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub nameserver12 @@ -1659,17 +1673,20 @@ sub nameserver13 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Nameserver13'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; + my @nss = @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) }; for my $ns ( @nss ) { next if ( _ip_disabled_message( \@results, $ns, q{DNSKEY} ) ); - my $p = $ns->query( $zone->name, q{DNSKEY}, { usevc => 0, fallback => 0, edns_details => { version => 0, do => 1, size => 512 } } ); + my $p = + $ns->query( $zone->name, q{DNSKEY}, + { usevc => 0, fallback => 0, edns_details => { version => 0, do => 1, size => 512 } }, + ); if ( $p ) { if ( $p->rcode eq q{FORMERR} and not $p->edns_rcode ) { - push @results, _emit_log( NO_EDNS_SUPPORT => { ns => $ns->string, } ); + push @results, _emit_log( NO_EDNS_SUPPORT => { ns => $ns->string } ); } elsif ( $p->tc and not $p->has_edns ) { push @results, _emit_log( MISSING_OPT_IN_TRUNCATED => { ns => $ns->string } ); @@ -1690,7 +1707,7 @@ sub nameserver13 { } ); } - } + } ## end for my $ns ( @nss ) return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub nameserver13 @@ -1739,7 +1756,7 @@ sub nameserver15 { next; } - my @rrs_txt = $p_txt->get_records_for_name(q{TXT}, $query_name, q{answer}); + my @rrs_txt = $p_txt->get_records_for_name( q{TXT}, $query_name, q{answer} ); if ( scalar @rrs_txt ) { foreach my $rr ( @rrs_txt ) { @@ -1747,8 +1764,8 @@ sub nameserver15 { push @wrong_record_class, $ns; } - my $string = escape_unprintable($rr->txtdata); - $string =~ s/^\s+|\s+$//g; # Remove leading and trailing spaces + my $string = escape_unprintable( $rr->txtdata ); + $string =~ s/^\s+|\s+$//g; # Remove leading and trailing spaces if ( $string ne "" ) { push @{ $txt_data{$string}{$query_name} }, $ns; @@ -1756,31 +1773,31 @@ sub nameserver15 { } } } - } - } + } ## end foreach my $query_name ( q{version.bind}...) + } ## end foreach my $ns ( @{ Zonemaster::Engine::TestMethods...}) if ( scalar keys %txt_data ) { foreach my $string ( keys %txt_data ) { push @results, map { - _emit_log( - N15_SOFTWARE_VERSION => { - string => $string, - query_name => $_, - ns_list => join( q{;}, sort @{ $txt_data{$string}{$_} } ) - } - ) + _emit_log( + N15_SOFTWARE_VERSION => { + string => $string, + query_name => $_, + ns_list => join( q{;}, sort @{ $txt_data{$string}{$_} } ), + } + ) } keys %{ $txt_data{$string} }; } } if ( scalar keys %error_on_version_query ) { push @results, map { - _emit_log( - N15_ERROR_ON_VERSION_QUERY => { - query_name => $_, - ns_list => join( q{;}, sort @{ $error_on_version_query{$_} } ) - } - ) + _emit_log( + N15_ERROR_ON_VERSION_QUERY => { + query_name => $_, + ns_list => join( q{;}, sort @{ $error_on_version_query{$_} } ), + } + ) } keys %error_on_version_query; } @@ -1788,7 +1805,7 @@ sub nameserver15 { push @results, _emit_log( N15_NO_VERSION_REVEALED => { - ns_list => join( q{;}, sort keys %sending_version_query ) + ns_list => join( q{;}, sort keys %sending_version_query ) } ); } @@ -1797,7 +1814,7 @@ sub nameserver15 { push @results, _emit_log( N15_WRONG_CLASS => { - ns_list => join( q{;}, sort @wrong_record_class ) + ns_list => join( q{;}, sort @wrong_record_class ) } ); } diff --git a/lib/Zonemaster/Engine/Test/Syntax.pm b/lib/Zonemaster/Engine/Test/Syntax.pm index 7638054e3..b66afba8d 100644 --- a/lib/Zonemaster/Engine/Test/Syntax.pm +++ b/lib/Zonemaster/Engine/Test/Syntax.pm @@ -7,7 +7,7 @@ use version; our $VERSION = version->declare( "v1.0.10" ); use Carp; use Email::Valid; -use List::MoreUtils qw[uniq none any]; +use List::MoreUtils qw[uniq none any]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; use Time::Local; @@ -113,7 +113,7 @@ sub metadata { NON_ALLOWED_CHARS TEST_CASE_END TEST_CASE_START - ) + ) ], syntax02 => [ qw( @@ -122,7 +122,7 @@ sub metadata { NO_ENDING_HYPHENS TEST_CASE_END TEST_CASE_START - ) + ) ], syntax03 => [ qw( @@ -130,7 +130,7 @@ sub metadata { NO_DOUBLE_DASH TEST_CASE_END TEST_CASE_START - ) + ) ], syntax04 => [ qw( @@ -140,7 +140,7 @@ sub metadata { NAMESERVER_SYNTAX_OK TEST_CASE_END TEST_CASE_START - ) + ) ], syntax05 => [ qw( @@ -149,7 +149,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], syntax06 => [ qw( @@ -162,7 +162,7 @@ sub metadata { RNAME_RFC822_VALID TEST_CASE_END TEST_CASE_START - ) + ) ], syntax07 => [ qw( @@ -173,7 +173,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], syntax08 => [ qw( @@ -184,7 +184,7 @@ sub metadata { NO_RESPONSE_MX_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], }; } ## end sub metadata @@ -346,7 +346,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, RNAME_RFC822_INVALID => sub { __x # SYNTAX:RNAME_RFC822_INVALID - "Illegal character(s) found in SOA RNAME field ({rname}).", @_; + "Illegal character(s) found in SOA RNAME field ({rname}).", @_; }, RNAME_RFC822_VALID => sub { __x # SYNTAX:RNAME_RFC822_VALID @@ -440,27 +440,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -830,7 +816,7 @@ sub syntax04 { foreach my $local_nsname ( uniq( @{ Zonemaster::Engine::TestMethods->method2( $zone ) }, - @{ Zonemaster::Engine::TestMethods->method3( $zone ) } + @{ Zonemaster::Engine::TestMethods->method3( $zone ) }, ) ) { @@ -964,7 +950,7 @@ sub syntax06 { } my $domain = name( ( $rname =~ s/.*@//r ) ); - my $p_mx = Zonemaster::Engine::Recursor->recurse( $domain, q{MX} ); + my $p_mx = Zonemaster::Engine::Recursor->recurse( $domain, q{MX} ); if ( not $p_mx or $p_mx->rcode ne 'NOERROR' ) { push @results, _emit_log( RNAME_MAIL_DOMAIN_INVALID => { domain => $domain } ); @@ -972,10 +958,10 @@ sub syntax06 { } # Retrieve followed CNAME, if any - if ( $domain ne ($p_mx->question)[0]->owner ) { # CNAME was followed in a new recursive query - $domain = name( ($p_mx->question)[0]->owner ); + if ( $domain ne ( $p_mx->question )[0]->owner ) { # CNAME was followed in a new recursive query + $domain = name( ( $p_mx->question )[0]->owner ); } - elsif ( scalar $p_mx->get_records( q{CNAME}, q{answer} ) ) { # CNAME was followed in the same query + elsif ( scalar $p_mx->get_records( q{CNAME}, q{answer} ) ) { # CNAME was followed in the same query my %cnames = map { name( $_->owner ) => name( $_->cname ) } $p_mx->get_records( q{CNAME}, q{answer} ); $domain = $cnames{$domain} while $cnames{$domain}; } @@ -1007,7 +993,9 @@ sub syntax06 { my @rrs_a = grep { $_->owner eq $mail_server } $p_a->get_records( q{A}, q{answer} ); if ( grep { $_->address eq q{127.0.0.1} } @rrs_a ) { - push @results, _emit_log( RNAME_MAIL_DOMAIN_LOCALHOST => { domain => $mail_server, localhost => q{127.0.0.1} } ); + push @results, + _emit_log( + RNAME_MAIL_DOMAIN_LOCALHOST => { domain => $mail_server, localhost => q{127.0.0.1} } ); } elsif ( @rrs_a ) { $exchange_valid = 1; @@ -1024,8 +1012,9 @@ sub syntax06 { else { my @rrs_aaaa = grep { $_->owner eq $mail_server } $p_aaaa->get_records( q{AAAA}, q{answer} ); - if ( grep { $_->address eq q{::1} } @rrs_aaaa) { - push @results, _emit_log( RNAME_MAIL_DOMAIN_LOCALHOST => { domain => $mail_server, localhost => q{::1} } ); + if ( grep { $_->address eq q{::1} } @rrs_aaaa ) { + push @results, + _emit_log( RNAME_MAIL_DOMAIN_LOCALHOST => { domain => $mail_server, localhost => q{::1} } ); } elsif ( @rrs_aaaa ) { $exchange_valid = 1; @@ -1055,7 +1044,7 @@ sub syntax06 { ) for keys %rname_candidates; } - return ( @results, _emit_log( TEST_CASE_END => { testcase => (split /::/, (caller(0))[3])[-1] } ) ); + return ( @results, _emit_log( TEST_CASE_END => { testcase => ( split /::/, ( caller( 0 ) )[3] )[-1] } ) ); } ## end sub syntax06 =over @@ -1129,6 +1118,6 @@ sub syntax08 { } return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); -} +} ## end sub syntax08 1; diff --git a/lib/Zonemaster/Engine/Test/Zone.pm b/lib/Zonemaster/Engine/Test/Zone.pm index 2083c027e..4553d1853 100644 --- a/lib/Zonemaster/Engine/Test/Zone.pm +++ b/lib/Zonemaster/Engine/Test/Zone.pm @@ -6,8 +6,8 @@ use warnings; use version; our $VERSION = version->declare( "v1.0.14" ); use Carp; -use List::MoreUtils qw[uniq none]; -use List::Util qw[max]; +use List::MoreUtils qw[uniq none]; +use List::Util qw[max]; use Locale::TextDomain qw[Zonemaster-Engine]; use Readonly; use JSON::PP; @@ -105,7 +105,7 @@ sub metadata { Z01_MNAME_UNEXPECTED_RCODE TEST_CASE_END TEST_CASE_START - ) + ) ], zone02 => [ qw( @@ -114,7 +114,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone03 => [ qw( @@ -123,7 +123,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone04 => [ qw( @@ -132,7 +132,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone05 => [ qw( @@ -142,7 +142,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone06 => [ qw( @@ -152,7 +152,7 @@ sub metadata { NO_RESPONSE_SOA_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone07 => [ qw( @@ -162,7 +162,7 @@ sub metadata { MNAME_HAS_NO_ADDRESS TEST_CASE_END TEST_CASE_START - ) + ) ], zone08 => [ qw( @@ -171,7 +171,7 @@ sub metadata { NO_RESPONSE_MX_QUERY TEST_CASE_END TEST_CASE_START - ) + ) ], zone09 => [ qw( @@ -194,7 +194,7 @@ sub metadata { Z09_VALID_NULL_MX TEST_CASE_END TEST_CASE_START - ) + ) ], zone10 => [ qw( @@ -205,7 +205,7 @@ sub metadata { WRONG_SOA TEST_CASE_END TEST_CASE_START - ) + ) ], zone11 => [ qw( @@ -219,7 +219,7 @@ sub metadata { Z11_SPF_SYNTAX_ERROR Z11_SPF_SYNTAX_OK Z11_UNABLE_TO_CHECK_FOR_SPF - ) + ) ], }; } ## end sub metadata @@ -291,7 +291,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, REFRESH_MINIMUM_VALUE_OK => sub { __x # ZONE:REFRESH_MINIMUM_VALUE_OK - 'SOA \'refresh\' value ({refresh}) is at least equal to the minimum recommended value ({required_refresh}).', @_; + 'SOA \'refresh\' value ({refresh}) is at least equal to the minimum recommended value ({required_refresh}).', + @_; }, EXPIRE_LOWER_THAN_REFRESH => sub { __x # ZONE:EXPIRE_LOWER_THAN_REFRESH @@ -389,7 +390,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z01_MNAME_IS_DOT => sub { __x # ZONE:Z01_MNAME_IS_DOT - 'SOA MNAME is specified as "." which usually means "no server". Fetched from name servers "{ns_ip_list}".', @_; + 'SOA MNAME is specified as "." which usually means "no server". Fetched from name servers "{ns_ip_list}".', + @_; }, Z01_MNAME_IS_LOCALHOST => sub { __x # ZONE:Z01_MNAME_IS_LOCALHOST @@ -417,7 +419,8 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z01_MNAME_NOT_MASTER => sub { __x # ZONE:Z01_MNAME_NOT_MASTER - 'SOA MNAME name server(s) "{ns_list}" do not have the highest SOA SERIAL (expected "{soaserial}" but got "{soaserial_list}")', @_; +'SOA MNAME name server(s) "{ns_list}" do not have the highest SOA SERIAL (expected "{soaserial}" but got "{soaserial_list}")', + @_; }, Z01_MNAME_NOT_RESOLVE => sub { __x # ZONE:Z01_MNAME_NOT_RESOLVE @@ -497,8 +500,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z11_DIFFERENT_SPF_POLICIES_FOUND => sub { __x # ZONE:Z11_DIFFERENT_SPF_POLICIES_FOUND - 'The following name servers returned the same SPF policy. Name servers: {ns_list}.', - @_; + 'The following name servers returned the same SPF policy. Name servers: {ns_list}.', @_; }, Z11_INCONSISTENT_SPF_POLICIES => sub { __ # ZONE:Z11_INCONSISTENT_SPF_POLICIES @@ -506,8 +508,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z11_NO_SPF_FOUND => sub { __x # ZONE:Z11_NO_SPF_FOUND - 'No SPF policy was found for {domain}.', - @_; + 'No SPF policy was found for {domain}.', @_; }, Z11_NO_SPF_NON_MAIL_DOMAIN => sub { __x # ZONE:Z11_NO_SPF_NON_MAIL_DOMAIN @@ -529,8 +530,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z11_SPF_MULTIPLE_RECORDS => sub { __x # ZONE:Z11_SPF_MULTIPLE_RECORDS - 'The following name servers returned more than one SPF policy. Name servers: {ns_list}.', - @_; + 'The following name servers returned more than one SPF policy. Name servers: {ns_list}.', @_; }, Z11_SPF_SYNTAX_ERROR => sub { __x # ZONE:Z11_SPF_SYNTAX_ERROR @@ -539,8 +539,7 @@ Readonly my %TAG_DESCRIPTIONS => ( }, Z11_SPF_SYNTAX_OK => sub { __x # ZONE:Z11_SPF_SYNTAX_OK - 'The SPF policy of {domain} has correct syntax.', - @_; + 'The SPF policy of {domain} has correct syntax.', @_; }, Z11_UNABLE_TO_CHECK_FOR_SPF => sub { __ # ZONE:Z11_UNABLE_TO_CHECK_FOR_SPF @@ -622,27 +621,13 @@ Returns a boolean. sub _ip_disabled_message { my ( $results_array, $ns, @rrtypes ) = @_; - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv6}) and $ns->address->version == $IP_VERSION_6 ) { - push @$results_array, map { - _emit_log( - IPV6_DISABLED => { - ns => $ns->string, - rrtype => $_ - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) and $ns->address->version == $IP_VERSION_6 ) { + push @$results_array, map { _emit_log( IPV6_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } - if ( not Zonemaster::Engine::Profile->effective->get(q{net.ipv4}) and $ns->address->version == $IP_VERSION_4 ) { - push @$results_array, map { - _emit_log( - IPV4_DISABLED => { - ns => $ns->string, - rrtype => $_, - } - ) - } @rrtypes; + if ( not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) and $ns->address->version == $IP_VERSION_4 ) { + push @$results_array, map { _emit_log( IPV4_DISABLED => { ns => $ns->string, rrtype => $_ } ) } @rrtypes; return 1; } return 0; @@ -724,7 +709,7 @@ sub _spf_syntax_ok { my $spf = shift; try { - Mail::SPF::v1::Record->new_from_string($spf); + Mail::SPF::v1::Record->new_from_string( $spf ); } } @@ -759,73 +744,73 @@ sub zone01 { my @mname_localhost; my @mname_dot; - foreach my $ns ( @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) } ){ - if ( _ip_disabled_message( \@results, $ns, q{SOA} ) ){ + foreach my $ns ( @{ Zonemaster::Engine::TestMethods->method4and5( $zone ) } ) { + if ( _ip_disabled_message( \@results, $ns, q{SOA} ) ) { next; } my $p = $ns->query( $zone->name, q{SOA} ); - if ( not $p or $p->rcode ne q{NOERROR} or not $p->aa or not $p->get_records_for_name( q{SOA}, $zone->name ) ){ + if ( not $p or $p->rcode ne q{NOERROR} or not $p->aa or not $p->get_records_for_name( q{SOA}, $zone->name ) ) { next; } - foreach my $soa_rr ( $p->get_records_for_name( q{SOA}, $zone->name ) ){ - my $soa_mname = lc($soa_rr->mname); + foreach my $soa_rr ( $p->get_records_for_name( q{SOA}, $zone->name ) ) { + my $soa_mname = lc( $soa_rr->mname ); $soa_mname =~ s/[.]\z//smx; - if ( $soa_mname eq 'localhost' ){ + if ( $soa_mname eq 'localhost' ) { push @mname_localhost, $ns->address->short; } - elsif ( not $soa_mname ){ + elsif ( not $soa_mname ) { push @mname_dot, $ns->address->short; } - else{ + else { $mname_ns{$soa_mname} = undef; } push @serial_ns, $soa_rr->serial; } - } + } ## end foreach my $ns ( @{ Zonemaster::Engine::TestMethods...}) - if ( scalar @mname_localhost ){ + if ( scalar @mname_localhost ) { push @results, _emit_log( Z01_MNAME_IS_LOCALHOST => { ns_ip_list => join( q{;}, @mname_localhost ) } ); } - if ( scalar @mname_dot ){ + if ( scalar @mname_dot ) { push @results, _emit_log( Z01_MNAME_IS_DOT => { ns_ip_list => join( q{;}, @mname_dot ) } ); } - my $found_ip = 0; + my $found_ip = 0; my $found_serial = 0; - foreach my $mname ( keys %mname_ns ){ - if ( none { $_ eq $mname } @{ Zonemaster::Engine::TestMethods->method3( $zone ) } ){ + foreach my $mname ( keys %mname_ns ) { + if ( none { $_ eq $mname } @{ Zonemaster::Engine::TestMethods->method3( $zone ) } ) { push @results, _emit_log( Z01_MNAME_NOT_IN_NS_LIST => { nsname => $mname } ); } - foreach my $ip ( Zonemaster::Engine::Recursor->get_addresses_for( $mname ) ){ + foreach my $ip ( Zonemaster::Engine::Recursor->get_addresses_for( $mname ) ) { $found_ip++; - $mname_ns{$mname}{$ip->short} = undef; + $mname_ns{$mname}{ $ip->short } = undef; } - if ( $found_ip ){ - foreach my $ip ( keys %{ $mname_ns{$mname} } ){ - if ( $ip eq '127.0.0.1' or $ip eq '::1' ){ + if ( $found_ip ) { + foreach my $ip ( keys %{ $mname_ns{$mname} } ) { + if ( $ip eq '127.0.0.1' or $ip eq '::1' ) { push @results, _emit_log( Z01_MNAME_HAS_LOCALHOST_ADDR => { nsname => $mname, ns_ip => $ip } ); } - else{ + else { my $ns = Zonemaster::Engine::Nameserver->new( { name => $mname, address => $ip } ); - if ( _ip_disabled_message( \@results, $ns, q{SOA} ) ){ - next; + if ( _ip_disabled_message( \@results, $ns, q{SOA} ) ) { + next; } my $p = $ns->query( $zone->name, q{SOA} ); - if ( $p ){ - if ( $p->rcode eq q{NOERROR} and $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ){ - if ( not $p->aa ){ + if ( $p ) { + if ( $p->rcode eq q{NOERROR} and $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ) { + if ( not $p->aa ) { push @results, _emit_log( Z01_MNAME_NOT_AUTHORITATIVE => { ns => $ns->string } ); } else { @@ -834,72 +819,73 @@ sub zone01 { $mname_ns{$mname}{$ip} = $rr->serial; } } - elsif ( $p->rcode ne q{NOERROR} ){ - push @results, _emit_log( Z01_MNAME_UNEXPECTED_RCODE => { ns => $ns->string, rcode => $p->rcode } ); + elsif ( $p->rcode ne q{NOERROR} ) { + push @results, + _emit_log( Z01_MNAME_UNEXPECTED_RCODE => { ns => $ns->string, rcode => $p->rcode } ); } - elsif ( not $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ){ + elsif ( not $p->get_records_for_name( q{SOA}, $zone->name, q{answer} ) ) { push @results, _emit_log( Z01_MNAME_MISSING_SOA_RECORD => { ns => $ns->string } ); } } else { push @results, _emit_log( Z01_MNAME_NO_RESPONSE => { ns => $ns->string } ); } - } - } - } - else{ + } ## end else [ if ( $ip eq '127.0.0.1'...)] + } ## end foreach my $ip ( keys %{ $mname_ns...}) + } ## end if ( $found_ip ) + else { push @results, _emit_log( Z01_MNAME_NOT_RESOLVE => { nsname => $mname } ); } - } + } ## end foreach my $mname ( keys %mname_ns) - if ( $found_serial ){ - foreach my $mname ( keys %mname_ns ){ - MNAME_IP: foreach my $mname_ip ( keys %{ $mname_ns{$mname} } ){ + if ( $found_serial ) { + foreach my $mname ( keys %mname_ns ) { + MNAME_IP: foreach my $mname_ip ( keys %{ $mname_ns{$mname} } ) { my $mname_serial = $mname_ns{$mname}{$mname_ip}; - if ( not defined($mname_serial) ){ + if ( not defined( $mname_serial ) ) { next; } - foreach my $serial ( uniq @serial_ns ){ - if ( Zonemaster::Engine::Util::serial_gt( $serial, $mname_serial ) ){ + foreach my $serial ( uniq @serial_ns ) { + if ( Zonemaster::Engine::Util::serial_gt( $serial, $mname_serial ) ) { $mname_not_master{$mname}{$mname_ip} = $mname_serial; next MNAME_IP; } } - push @mname_master, $mname . '/' . $mname_ip ; + push @mname_master, $mname . '/' . $mname_ip; } } - if ( %mname_not_master ){ - push @results, - _emit_log( - Z01_MNAME_NOT_MASTER => { - ns_list => join( q{;}, sort map - { - my $mname = $_; - map { "$mname/$_" } keys %{ $mname_not_master{$_} } - } - keys %mname_not_master - ), - soaserial => max( uniq map { values %{ $mname_not_master{$_} } } keys %mname_not_master ), - soaserial_list => join( q{;}, uniq @serial_ns ) - } - ); + if ( %mname_not_master ) { + push @results, _emit_log( + Z01_MNAME_NOT_MASTER => { + ns_list => join( + q{;}, + sort map { + my $mname = $_; + map { "$mname/$_" } keys %{ $mname_not_master{$_} } + } + keys %mname_not_master, + ), + soaserial => max( uniq map { values %{ $mname_not_master{$_} } } keys %mname_not_master ), + soaserial_list => join( q{;}, uniq @serial_ns ), + } + ); } - if ( @mname_master ){ + if ( @mname_master ) { push @results, - _emit_log( - Z01_MNAME_IS_MASTER => { - ns_list => join( q{;}, sort @mname_master ) - } - ); + _emit_log( + Z01_MNAME_IS_MASTER => { + ns_list => join( q{;}, sort @mname_master ) + } + ); } - } + } ## end if ( $found_serial ) - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone01 =over @@ -926,7 +912,8 @@ sub zone02 { my $p = _retrieve_record_from_zone( \@results, $zone, $zone->name, q{SOA} ); - my $soa_refresh_minimum_value = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone02.SOA_REFRESH_MINIMUM_VALUE} ); + my $soa_refresh_minimum_value = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone02.SOA_REFRESH_MINIMUM_VALUE} ); if ( $p and my ( $soa ) = $p->get_records( q{SOA}, q{answer} ) ) { my $soa_refresh = $soa->refresh; @@ -953,7 +940,7 @@ sub zone02 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone02 =over @@ -1006,7 +993,7 @@ sub zone03 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone03 =over @@ -1033,7 +1020,8 @@ sub zone04 { my $p = _retrieve_record_from_zone( \@results, $zone, $zone->name, q{SOA} ); - my $soa_retry_minimum_value = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone04.SOA_RETRY_MINIMUM_VALUE} ); + my $soa_retry_minimum_value = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone04.SOA_RETRY_MINIMUM_VALUE} ); if ( $p and my ( $soa ) = $p->get_records( q{SOA}, q{answer} ) ) { my $soa_retry = $soa->retry; @@ -1060,7 +1048,7 @@ sub zone04 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone04 =over @@ -1087,7 +1075,8 @@ sub zone05 { my $p = _retrieve_record_from_zone( \@results, $zone, $zone->name, q{SOA} ); - my $soa_expire_minimum_value = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone05.SOA_EXPIRE_MINIMUM_VALUE} ); + my $soa_expire_minimum_value = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone05.SOA_EXPIRE_MINIMUM_VALUE} ); if ( $p and my ( $soa ) = $p->get_records( q{SOA}, q{answer} ) ) { my $soa_expire = $soa->expire; @@ -1125,7 +1114,7 @@ sub zone05 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone05 =over @@ -1152,8 +1141,10 @@ sub zone06 { my $p = _retrieve_record_from_zone( \@results, $zone, $zone->name, q{SOA} ); - my $soa_default_ttl_maximum_value = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MAXIMUM_VALUE} ); - my $soa_default_ttl_minimum_value = Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MINIMUM_VALUE} ); + my $soa_default_ttl_maximum_value = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MAXIMUM_VALUE} ); + my $soa_default_ttl_minimum_value = + Zonemaster::Engine::Profile->effective->get( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MINIMUM_VALUE} ); if ( $p and my ( $soa ) = $p->get_records( q{SOA}, q{answer} ) ) { my $soa_minimum = $soa->minimum; @@ -1190,7 +1181,7 @@ sub zone06 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone06 =over @@ -1225,9 +1216,12 @@ sub zone07 { foreach my $address_type ( q{A}, q{AAAA} ) { my $p_mname = Zonemaster::Engine::Recursor->recurse( $soa_mname, $address_type ); if ( $p_mname ) { - my $final_name = name( ($p_mname->question)[0]->owner ); # In case CNAME was followed during the recursive lookup + my $final_name = + name( ( $p_mname->question )[0]->owner ); # In case CNAME was followed during the recursive lookup - if ( $p_mname->has_rrs_of_type_for_name( $address_type, $soa_mname ) or $p_mname->has_rrs_of_type_for_name( $address_type, $final_name ) ) { + if ( $p_mname->has_rrs_of_type_for_name( $address_type, $soa_mname ) + or $p_mname->has_rrs_of_type_for_name( $address_type, $final_name ) ) + { $addresses_nb++; } @@ -1263,7 +1257,7 @@ sub zone07 { push @results, _emit_log( NO_RESPONSE_SOA_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone07 =over @@ -1307,7 +1301,7 @@ sub zone08 { push @results, _emit_log( NO_RESPONSE_MX_QUERY => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone08 =over @@ -1330,9 +1324,7 @@ sub zone09 { my ( $class, $zone ) = @_; state sub sort_mx_records { - sort { - $a->preference() <=> $b->preference() or fc $a->exchange() cmp fc $b->exchange() - } @_; + sort { $a->preference() <=> $b->preference() or fc $a->exchange() cmp fc $b->exchange() } @_; } state sub mx_record_to_string { @@ -1340,7 +1332,7 @@ sub zone09 { } state sub sort_unique_mx_records { - my %mx_hash = map { mx_record_to_string($_) => $_ } @_; + my %mx_hash = map { mx_record_to_string( $_ ) => $_ } @_; sort_mx_records( values %mx_hash ); } @@ -1351,10 +1343,10 @@ sub zone09 { local $Zonemaster::Engine::Logger::TEST_CASE_NAME = 'Zone09'; push my @results, _emit_log( TEST_CASE_START => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ); - my @nss = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @nss = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); my %ip_already_processed; @@ -1364,7 +1356,6 @@ sub zone09 { my @no_mx_set; my %mx_set; - foreach my $ns ( @nss ) { my $ns_ip = $ns->address->short; @@ -1377,24 +1368,28 @@ sub zone09 { my $p1 = $ns->query( $zone->name, q{SOA} ); - if ( not $p1 or $p1->rcode ne q{NOERROR} or not $p1->aa or not $p1->has_rrs_of_type_for_name(q{SOA}, $zone->name) ){ + if ( not $p1 + or $p1->rcode ne q{NOERROR} + or not $p1->aa + or not $p1->has_rrs_of_type_for_name( q{SOA}, $zone->name ) ) + { next; } my $p2 = $ns->query( $zone->name, q{MX} ); - if ( not $p2 ){ + if ( not $p2 ) { push @no_response_mx, $ns; } elsif ( $p2->rcode ne q{NOERROR} ) { - push @{ $unexpected_rcode_mx{$p2->rcode} }, $ns; + push @{ $unexpected_rcode_mx{ $p2->rcode } }, $ns; } elsif ( not $p2->aa ) { push @non_authoritative_mx, $ns; } else { - my @sorted_mx_rrs = sort_unique_mx_records( $p2->get_records_for_name( q{MX}, $zone->name, q{answer} ) ); - my $mx_rrset_string = join ';', map mx_record_to_string($_), @sorted_mx_rrs; + my @sorted_mx_rrs = sort_unique_mx_records( $p2->get_records_for_name( q{MX}, $zone->name, q{answer} ) ); + my $mx_rrset_string = join ';', map mx_record_to_string( $_ ), @sorted_mx_rrs; if ( !scalar @sorted_mx_rrs ) { push @no_mx_set, $ns; @@ -1402,46 +1397,58 @@ sub zone09 { elsif ( not exists $mx_set{$mx_rrset_string} ) { $mx_set{$mx_rrset_string} = { ns => [ $ns->string ], - mx => \@sorted_mx_rrs + mx => \@sorted_mx_rrs, }; } else { push @{ $mx_set{$mx_rrset_string}{ns} }, $ns->string; } } - } + } ## end foreach my $ns ( @nss ) if ( scalar @no_response_mx ) { - push @results, _emit_log( Z09_NO_RESPONSE_MX_QUERY => { - ns_list => ns_list( @no_response_mx ) - } ); + push @results, + _emit_log( + Z09_NO_RESPONSE_MX_QUERY => { + ns_list => ns_list( @no_response_mx ) + } + ); } foreach my $rcode ( keys %unexpected_rcode_mx ) { - push @results, _emit_log( Z09_UNEXPECTED_RCODE_MX => { - rcode => $rcode, - ns_list => ns_list( @{ $unexpected_rcode_mx{$rcode} } ) - } ); + push @results, + _emit_log( + Z09_UNEXPECTED_RCODE_MX => { + rcode => $rcode, + ns_list => ns_list( @{ $unexpected_rcode_mx{$rcode} } ), + } + ); } if ( scalar @non_authoritative_mx ) { - push @results, _emit_log( Z09_NON_AUTH_MX_RESPONSE => { - ns_list => ns_list( @non_authoritative_mx ) - } ); + push @results, + _emit_log( + Z09_NON_AUTH_MX_RESPONSE => { + ns_list => ns_list( @non_authoritative_mx ) + } + ); } foreach my $mx_string ( keys %mx_set ) { - push @results, _emit_log( Z09_MX_DATA => { - ns_list => ns_list( @{ $mx_set{$mx_string}{ns} } ), - mxrdata_list => $mx_string - } ); + push @results, + _emit_log( + Z09_MX_DATA => { + ns_list => ns_list( @{ $mx_set{$mx_string}{ns} } ), + mxrdata_list => $mx_string, + } + ); } if ( scalar @no_mx_set and scalar %mx_set ) { push @results, - _emit_log( Z09_INCONSISTENT_MX => {} ), - _emit_log( Z09_NO_MX_FOUND => { ns_list => ns_list( @no_mx_set ) } ), - _emit_log( Z09_MX_FOUND => { ns_list => ns_list( map @{$_->{ns}}, values %mx_set ) } ); + _emit_log( Z09_INCONSISTENT_MX => {} ), + _emit_log( Z09_NO_MX_FOUND => { ns_list => ns_list( @no_mx_set ) } ), + _emit_log( Z09_MX_FOUND => { ns_list => ns_list( map @{ $_->{ns} }, values %mx_set ) } ); } if ( scalar keys %mx_set > 1 ) { @@ -1473,10 +1480,10 @@ sub zone09 { push @results, _emit_log( Z09_ARPA_EMAIL_DOMAIN => {} ); } } - } + } ## end elsif ( scalar keys %mx_set...) if ( scalar @no_mx_set and !scalar %mx_set ) { - if ( _is_non_mail_domain($zone->name) ) { + if ( _is_non_mail_domain( $zone->name ) ) { push @results, _emit_log( Z09_NO_MX_FOUND_OR_EXPECTED => {} ); } else { @@ -1488,7 +1495,7 @@ sub zone09 { push @results, _emit_log( Z09_NO_SERVERS_MX_RESPONSE => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone09 =over @@ -1558,7 +1565,7 @@ sub zone10 { push @results, _emit_log( ONE_SOA => {} ); } - return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, _emit_log( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone10 =over @@ -1589,10 +1596,10 @@ sub zone11 { my %ns_spf; - my @nss = uniq grep { $_->isa('Zonemaster::Engine::Nameserver') } ( - @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, - @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] } - ); + my @nss = uniq grep { $_->isa( 'Zonemaster::Engine::Nameserver' ) } ( + @{ Zonemaster::Engine::TestMethodsV2->get_del_ns_names_and_ips( $zone ) // [] }, + @{ Zonemaster::Engine::TestMethodsV2->get_zone_ns_names_and_ips( $zone ) // [] }, + ); my %ip_already_processed; foreach my $ns ( @nss ) { @@ -1608,13 +1615,13 @@ sub zone11 { my $p = $ns->query( $zone->name, q{TXT} ); if ( $p and $p->rcode eq q{NOERROR} and $p->aa ) { - my @txt_rrs = $p->get_records_for_name( q{TXT}, $zone->name ); - my @txt_rdata = map { lc $_->txtdata() } @txt_rrs; + my @txt_rrs = $p->get_records_for_name( q{TXT}, $zone->name ); + my @txt_rdata = map { lc $_->txtdata() } @txt_rrs; my @spf1_policies = grep /\Av=spf1(?:\Z|\s+)/, @txt_rdata; $ns_spf{$ns_ip} = \@spf1_policies; } - } + } ## end foreach my $ns ( @nss ) # At this point, the values of %ns_spf contain *lists* of SPF policies. # There should be at most one item in each of those lists, but zones may @@ -1629,8 +1636,8 @@ sub zone11 { my %spf_ns = (); for my $ns_ip ( keys %ns_spf ) { my @matching_nss = @{ $ip_already_processed{$ns_ip} }; - my $mangled_spfs = join '', map { sprintf '<%d>%s', length $_, $_ } sort @{$ns_spf{$ns_ip}}; - push @{$spf_ns{$mangled_spfs}}, @matching_nss; + my $mangled_spfs = join '', map { sprintf '<%d>%s', length $_, $_ } sort @{ $ns_spf{$ns_ip} }; + push @{ $spf_ns{$mangled_spfs} }, @matching_nss; } if ( not scalar %ns_spf ) { @@ -1651,17 +1658,22 @@ sub zone11 { push @results, _emit_log( Z11_DIFFERENT_SPF_POLICIES_FOUND => { ns_list => join( q{;}, sort @$ns ) } ); } } - elsif ( my @bad_ips = grep { scalar @{$ns_spf{$_}} > 1 } keys %ns_spf ) { - push @results, _emit_log( Z11_SPF_MULTIPLE_RECORDS => { ns_list => join( q{;}, sort map { @{ $ip_already_processed{$_} } } @bad_ips ) } ); + elsif ( my @bad_ips = grep { scalar @{ $ns_spf{$_} } > 1 } keys %ns_spf ) { + push @results, + _emit_log( Z11_SPF_MULTIPLE_RECORDS => + { ns_list => join( q{;}, sort map { @{ $ip_already_processed{$_} } } @bad_ips ) } ); } else { - my $spf_text = (values %ns_spf)[0][0]; + my $spf_text = ( values %ns_spf )[0][0]; if ( not _spf_syntax_ok( $spf_text ) ) { - push @results, _emit_log( Z11_SPF_SYNTAX_ERROR => { - ns_list => join( q{;}, sort map { @{ $ip_already_processed{$_} } } keys %ns_spf ), - domain => $zone->name - } ); + push @results, + _emit_log( + Z11_SPF_SYNTAX_ERROR => { + ns_list => join( q{;}, sort map { @{ $ip_already_processed{$_} } } keys %ns_spf ), + domain => $zone->name, + } + ); } elsif ( not _is_non_mail_domain( $zone->name ) ) { push @results, _emit_log( Z11_SPF_SYNTAX_OK => { domain => $zone->name } ); @@ -1672,9 +1684,9 @@ sub zone11 { else { push @results, _emit_log( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN => { domain => $zone->name } ); } - } + } ## end else [ if ( not scalar %ns_spf)] - return ( @results, info( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ) + return ( @results, info( TEST_CASE_END => { testcase => $Zonemaster::Engine::Logger::TEST_CASE_NAME } ) ); } ## end sub zone11 1; diff --git a/lib/Zonemaster/Engine/TestMethods.pm b/lib/Zonemaster/Engine/TestMethods.pm index e980f1bc1..08ee80143 100644 --- a/lib/Zonemaster/Engine/TestMethods.pm +++ b/lib/Zonemaster/Engine/TestMethods.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::TestMethods; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.3"); +use version; our $VERSION = version->declare( "v1.0.3" ); use List::MoreUtils qw[uniq]; use Zonemaster::Engine::Util; diff --git a/lib/Zonemaster/Engine/TestMethodsV2.pm b/lib/Zonemaster/Engine/TestMethodsV2.pm index 4d320fb00..fe43c8a54 100644 --- a/lib/Zonemaster/Engine/TestMethodsV2.pm +++ b/lib/Zonemaster/Engine/TestMethodsV2.pm @@ -3,7 +3,7 @@ package Zonemaster::Engine::TestMethodsV2; use v5.26.0; use warnings; -use version; our $VERSION = version->declare("v1.0.0"); +use version; our $VERSION = version->declare( "v1.0.0" ); use Carp; use List::MoreUtils qw[uniq]; @@ -57,7 +57,7 @@ sub get_parent_ns_names_and_ips { my %rrs_ns; my $type_soa = q{SOA}; - my $type_ns = q{NS}; + my $type_ns = q{NS}; my %remaining_servers = ( '.' => [ Zonemaster::Engine::Recursor->root_servers ] ); @@ -71,9 +71,8 @@ sub get_parent_ns_names_and_ips { } } - while ( my $zone_name = ( sort keys %remaining_servers )[0] ) { - CUR_SERVERS: + CUR_SERVERS: while ( my $ns = shift @{ $remaining_servers{$zone_name} } ) { my $addr = $ns->address->short; if ( exists $handled_servers{$zone_name}{"$ns"} ) { @@ -82,30 +81,40 @@ sub get_parent_ns_names_and_ips { } $handled_servers{$zone_name}{"$ns"} = 1; - if ( ( $ns->address->version == 4 and not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) ) - or ( $ns->address->version == 6 and not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) ) { + if ( ( $ns->address->version == 4 and not Zonemaster::Engine::Profile->effective->get( q{net.ipv4} ) ) + or ( $ns->address->version == 6 and not Zonemaster::Engine::Profile->effective->get( q{net.ipv6} ) ) ) + { next CUR_SERVERS; } my $p_soa = $ns->query( $zone_name, $type_soa ); - unless ( $p_soa and $p_soa->rcode eq 'NOERROR' and $p_soa->aa and scalar $p_soa->get_records_for_name( $type_soa, $zone_name, 'answer' ) == 1 ) { + unless ($p_soa + and $p_soa->rcode eq 'NOERROR' + and $p_soa->aa + and scalar $p_soa->get_records_for_name( $type_soa, $zone_name, 'answer' ) == 1 ) + { next CUR_SERVERS; } my $p_ns = $ns->query( $zone_name, $type_ns ); - unless ( $p_ns and $p_ns->rcode eq 'NOERROR' and $p_ns->aa and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 - and scalar $p_ns->get_records( $type_ns, 'answer' ) == scalar $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ) - ) { + unless ($p_ns + and $p_ns->rcode eq 'NOERROR' + and $p_ns->aa + and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 + and scalar $p_ns->get_records( $type_ns, 'answer' ) == + scalar $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ) ) + { next CUR_SERVERS; } - %rrs_ns = map { name( $_->nsdname )->string => [] } $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ); + %rrs_ns = + map { name( $_->nsdname )->string => [] } $p_ns->get_records_for_name( $type_ns, $zone_name, 'answer' ); foreach my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns{name( $rr->owner )->string} ) { - push @{ $rrs_ns{name( $rr->owner )->string} }, $rr->address; + if ( exists $rrs_ns{ name( $rr->owner )->string } ) { + push @{ $rrs_ns{ name( $rr->owner )->string } }, $rr->address; } } @@ -126,26 +135,30 @@ sub get_parent_ns_names_and_ips { } my $intermediate_query_name = name( $zone_name ); - my $loop_zone_name = $zone_name; - my $loop_counter = 0; + my $loop_zone_name = $zone_name; + my $loop_counter = 0; - LOOP: - while() { + LOOP: + while () { $loop_counter += 1; if ( $loop_counter >= 1000 ) { - Zonemaster::Engine->logger->add( LOOP_PROTECTION => { - caller => 'Zonemaster::Engine::TestMethodsV2->get_parent_ns_ips', - child_zone_name => $zone->name, - name => $loop_zone_name, - intermediate_query_name => $intermediate_query_name - } + Zonemaster::Engine->logger->add( + LOOP_PROTECTION => { + caller => 'Zonemaster::Engine::TestMethodsV2->get_parent_ns_ips', + child_zone_name => $zone->name, + name => $loop_zone_name, + intermediate_query_name => $intermediate_query_name, + } ); return undef; } last if scalar @{ $intermediate_query_name->labels } >= scalar @{ $zone->name->labels }; - $intermediate_query_name = name( @{ $zone->name->labels }[ ( scalar @{ $zone->name->labels } - scalar @{ $intermediate_query_name->labels } ) - 1 ] . '.' . $intermediate_query_name->string ); + $intermediate_query_name = + name( @{ $zone->name->labels } + [ ( scalar @{ $zone->name->labels } - scalar @{ $intermediate_query_name->labels } ) - 1 ] . '.' + . $intermediate_query_name->string ); $p_soa = $ns->query( $intermediate_query_name, $type_soa ); @@ -153,24 +166,34 @@ sub get_parent_ns_names_and_ips { next CUR_SERVERS; } - if ( $p_soa->rcode eq 'NOERROR' and $p_soa->aa and scalar $p_soa->get_records_for_name( $type_soa, $intermediate_query_name, 'answer' ) == 1 ) { + if ( $p_soa->rcode eq 'NOERROR' + and $p_soa->aa + and scalar $p_soa->get_records_for_name( $type_soa, $intermediate_query_name, 'answer' ) == 1 ) + { if ( $intermediate_query_name->string eq $zone->name->string ) { push @parent_ns, $ns; } else { $p_ns = $ns->query( $intermediate_query_name, $type_ns ); - unless ( $p_ns and $p_ns->rcode eq 'NOERROR' and $p_ns->aa and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 - and scalar $p_ns->get_records( $type_ns, 'answer' ) == scalar $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ) - ) { + unless ($p_ns + and $p_ns->rcode eq 'NOERROR' + and $p_ns->aa + and scalar $p_ns->get_records( $type_ns, 'answer' ) > 0 + and scalar $p_ns->get_records( $type_ns, 'answer' ) == + scalar $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ) ) + { next CUR_SERVERS; } - my %rrs_ns_bis = map { name( $_->nsdname )->string => [] } $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ); + my %rrs_ns_bis = map { name( $_->nsdname )->string => [] } + $p_ns->get_records_for_name( $type_ns, $intermediate_query_name, 'answer' ); - foreach my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns_bis{name( $rr->owner )->string} ) { - push @{ $rrs_ns_bis{name( $rr->owner )->string} }, $rr->address; + foreach + my $rr ( $p_ns->get_records( 'A', 'additional' ), $p_ns->get_records( 'AAAA', 'additional' ) ) + { + if ( exists $rrs_ns_bis{ name( $rr->owner )->string } ) { + push @{ $rrs_ns_bis{ name( $rr->owner )->string } }, $rr->address; } } @@ -180,7 +203,8 @@ sub get_parent_ns_names_and_ips { my $p = Zonemaster::Engine::Recursor->recurse( $ns_name, $qtype ); if ( $p and $p->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p->get_records_for_name( $qtype, $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p->get_records_for_name( $qtype, $ns_name ); } } } @@ -192,18 +216,23 @@ sub get_parent_ns_names_and_ips { $loop_zone_name = $intermediate_query_name->string; next LOOP; - } - } - elsif ( $p_soa->is_redirect and scalar $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ) ) { + } ## end else [ if ( $intermediate_query_name...)] + } ## end if ( $p_soa->rcode eq ...) + elsif ( $p_soa->is_redirect + and scalar $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ) ) + { if ( $intermediate_query_name->string eq $zone->name->string ) { push @parent_ns, $ns; } else { - my %rrs_ns_bis = map { name( $_->nsdname )->string => [] } $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ); - - foreach my $rr ( $p_soa->get_records( 'A', 'additional' ), $p_soa->get_records( 'AAAA', 'additional' ) ) { - if ( exists $rrs_ns_bis{name( $rr->owner )->string} ) { - push @{ $rrs_ns_bis{name( $rr->owner )->string} }, $rr->address; + my %rrs_ns_bis = map { name( $_->nsdname )->string => [] } + $p_soa->get_records_for_name( $type_ns, $intermediate_query_name, 'authority' ); + + foreach my $rr ( $p_soa->get_records( 'A', 'additional' ), + $p_soa->get_records( 'AAAA', 'additional' ), ) + { + if ( exists $rrs_ns_bis{ name( $rr->owner )->string } ) { + push @{ $rrs_ns_bis{ name( $rr->owner )->string } }, $rr->address; } } @@ -213,7 +242,8 @@ sub get_parent_ns_names_and_ips { my $p = Zonemaster::Engine::Recursor->recurse( $ns_name, $qtype ); if ( $p and $p->rcode eq 'NOERROR' ) { - push @{ $rrs_ns_bis{$ns_name} }, $_->address for $p->get_records_for_name( $qtype, $ns_name ); + push @{ $rrs_ns_bis{$ns_name} }, $_->address + for $p->get_records_for_name( $qtype, $ns_name ); } } } @@ -222,35 +252,37 @@ sub get_parent_ns_names_and_ips { push_to_remaining_servers ns( $ns_name, $ns_ip ), $intermediate_query_name; } } - } - } + } ## end else [ if ( $intermediate_query_name...)] + } ## end elsif ( $p_soa->is_redirect...) elsif ( $p_soa->rcode eq 'NOERROR' and $p_soa->aa ) { next LOOP if $intermediate_query_name->string ne $zone->name->string; } next CUR_SERVERS; - } - } + } ## end LOOP: while () + } ## end CUR_SERVERS: while ( my $ns = shift @{...}) delete $remaining_servers{$zone_name}; - } + } ## end while ( my $zone_name = (...)) if ( scalar @parent_ns ) { - return [ uniq sort @parent_ns ] + return [ uniq sort @parent_ns ]; } else { return undef; } -} +} ## end sub get_parent_ns_names_and_ips # Memoize get_parent_ns_names_and_ips() because it is expensive and gets called a few # times with identical parameters. -memoize('get_parent_ns_names_and_ips', - NORMALIZER => sub { - my ( $class, $zone ) = @_; - join "\034", ( $class, $zone->name ); - }); +memoize( + 'get_parent_ns_names_and_ips', + NORMALIZER => sub { + my ( $class, $zone ) = @_; + join "\034", ( $class, $zone->name ); + }, +); =over @@ -287,7 +319,7 @@ sub get_parent_ns_ips { } return [ sort values %ns_by_ip ]; -} +} ## end sub get_parent_ns_ips =over @@ -309,7 +341,7 @@ and L objects for each name server name that could sub _get_oob_ips { my ( $class, $zone, $ns_names_ref ) = @_; - unless ( defined $ns_names_ref and scalar @{ $ns_names_ref } ) { + unless ( defined $ns_names_ref and scalar @{$ns_names_ref} ) { return []; } @@ -317,12 +349,15 @@ sub _get_oob_ips { my @oob_ns; my $found_ip; - for my $ns_name ( @{ $ns_names_ref } ) { + for my $ns_name ( @{$ns_names_ref} ) { $found_ip = 0; unless ( $zone->name->is_in_bailiwick( $ns_name ) ) { - if ( $is_undelegated and scalar Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name->string, $ns_name->string ) ) { - for my $ip ( Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name->string, $ns_name->string ) ) { + if ( $is_undelegated + and scalar Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name->string, $ns_name->string ) ) + { + for my $ip ( Zonemaster::Engine::Recursor->get_fake_addresses( $zone->name->string, $ns_name->string ) ) + { push @oob_ns, ns( $ns_name->string, $ip ); $found_ip = 1; } @@ -333,7 +368,8 @@ sub _get_oob_ips { if ( $p and $p->rcode eq q{NOERROR} ) { if ( $p->has_rrs_of_type_for_name( q{CNAME}, $ns_name, q{answer} ) ) { - my %cnames = map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); + my %cnames = + map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); my $target = $ns_name; $target = $cnames{$target} while $cnames{$target}; @@ -343,12 +379,19 @@ sub _get_oob_ips { } } # CNAME was followed in a new recursive query - elsif ( name( ($p->question)[0]->owner ) ne $ns_name and grep { $_->tag eq 'CNAME_FOLLOWED_OUT_OF_ZONE' and grep /^$ns_name$/, values %{ $_->args } } @{ Zonemaster::Engine->logger->entries } ) { - my $cname_ns_name = name( ($p->question)[0]->owner ); - my $target = $cname_ns_name; + elsif ( + name( ( $p->question )[0]->owner ) ne $ns_name + and + grep { $_->tag eq 'CNAME_FOLLOWED_OUT_OF_ZONE' and grep /^$ns_name$/, values %{ $_->args } } + @{ Zonemaster::Engine->logger->entries } + ) + { + my $cname_ns_name = name( ( $p->question )[0]->owner ); + my $target = $cname_ns_name; if ( $p->has_rrs_of_type_for_name( q{CNAME}, $cname_ns_name, q{answer} ) ) { - my %cnames = map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); + my %cnames = + map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); $target = $cnames{$target} while $cnames{$target}; } @@ -356,23 +399,23 @@ sub _get_oob_ips { push @oob_ns, ns( $ns_name, $rr->address ); $found_ip = 1; } - } + } ## end elsif ( name( ( $p->question...))) elsif ( $p->has_rrs_of_type_for_name( $qtype, $ns_name ) ) { for my $rr ( $p->get_records_for_name( $qtype, $ns_name ) ) { push @oob_ns, ns( $ns_name, $rr->address ); $found_ip = 1; } } - } - } - } + } ## end if ( $p and $p->rcode ...) + } ## end for my $qtype ( q{A}, q{AAAA}) + } ## end else [ if ( $is_undelegated and...)] push @oob_ns, $ns_name unless $found_ip; - } - } + } ## end unless ( $zone->name->is_in_bailiwick...) + } ## end for my $ns_name ( @{$ns_names_ref...}) return [ uniq sort @oob_ns ]; -} +} ## end sub _get_oob_ips =over @@ -402,32 +445,30 @@ sub _get_delegation { my ( $p, $ns_section ) = @_; # Set of NS names from $ns_section ('authority' or 'additional') section - my %ns_names = map { lc name( $_->nsdname() ) => 1 } - $p->get_records_for_name( 'NS', $zone, $ns_section ); + my %ns_names = map { lc name( $_->nsdname() ) => 1 } $p->get_records_for_name( 'NS', $zone, $ns_section ); # List of A/AAAA records from additional section for NS names # that are in-domain wrt. the zone name my @additional = - map { - my $name = name( $_->owner() ); - - # Filters out A and AAAA records with invalid IP addresses - my $addr = Net::IP::XS->new( $_->address ); - ( defined $addr ) ? ns( $name, $addr ) : () - } - grep { - my $name = name( lc $_->owner() ); - exists $ns_names{$name} and - $zone->name->is_in_bailiwick($name) and - ( $_->type eq 'A' or $_->type eq 'AAAA' ) - } - $p->additional; + map { + my $name = name( $_->owner() ); + + # Filters out A and AAAA records with invalid IP addresses + my $addr = Net::IP::XS->new( $_->address ); + ( defined $addr ) ? ns( $name, $addr ) : () + } + grep { + my $name = name( lc $_->owner() ); + exists $ns_names{$name} + and $zone->name->is_in_bailiwick( $name ) + and ( $_->type eq 'A' or $_->type eq 'AAAA' ) + } $p->additional; return Zonemaster::Engine::NameserverSet->new( keys %ns_names, @additional ); - } + } ## end sub packet_ns_names_and_in_domain_ips my $is_undelegated = Zonemaster::Engine::Recursor->has_fake_addresses( $zone->name->string ); - my $result = Zonemaster::Engine::NameserverSet->new(); + my $result = Zonemaster::Engine::NameserverSet->new(); if ( $is_undelegated ) { for my $ns_name ( Zonemaster::Engine::Recursor->get_fake_names( $zone->name->string ) ) { @@ -448,7 +489,7 @@ sub _get_delegation { return undef unless defined $parent_ref; - for my $ns ( @{ $parent_ref } ) { + for my $ns ( @{$parent_ref} ) { my $p = $ns->query( $zone->name, q{NS} ); next unless $p and $p->rcode eq q{NOERROR}; @@ -469,24 +510,22 @@ sub _get_delegation { # That QNAME might be different from $ns_name if, to follow the CNAME chain # to the end, the recursor had to restart the query multiple times. This can # happen if CNAME chains cross zones. - my %cnames = map { - lc name( $_->owner ) => lc name( $_->cname ) - } $p->get_records( q{CNAME}, q{answer} ); + my %cnames = + map { lc name( $_->owner ) => lc name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); - my $target = name( ($p->question)[0]->owner ); + my $target = name( ( $p->question )[0]->owner ); $target = $cnames{$target} while exists $cnames{$target}; - $result->push( - map { ns( $ns_name, $_->address ) } - $p->get_records_for_name( $qtype, $target ) ); + $result->push( map { ns( $ns_name, $_->address ) } + $p->get_records_for_name( $qtype, $target ) ); } - } - } - } - } + } ## end for my $ns_name ( grep ...) + } ## end elsif ( $p->aa and scalar...) + } ## end for my $ns ( @{$parent_ref...}) + } ## end else [ if ( $is_undelegated )] return [ $result->items() ]; -} +} ## end sub _get_delegation =over @@ -514,7 +553,7 @@ sub get_del_ns_names_and_ips { return undef unless defined $ns_ref; - my @ns_names = grep { $_->isa('Zonemaster::Engine::DNSName') and ! $zone->name->is_in_bailiwick( $_ ) } @{ $ns_ref }; + my @ns_names = grep { $_->isa( 'Zonemaster::Engine::DNSName' ) and !$zone->name->is_in_bailiwick( $_ ) } @{$ns_ref}; my $oob_ns_ref = $class->_get_oob_ips( $zone, \@ns_names ); @@ -544,7 +583,7 @@ sub get_del_ns_names { return undef unless defined $ns_ref; - return [ uniq sort map { $_->isa('Zonemaster::Engine::Nameserver') ? $_->name : $_ } @{ $ns_ref } ]; + return [ uniq sort map { $_->isa( 'Zonemaster::Engine::Nameserver' ) ? $_->name : $_ } @{$ns_ref} ]; } =over @@ -578,13 +617,13 @@ sub get_del_ns_ips { my %ns_by_ip = (); foreach my $ns ( @$nameservers ) { - next if ! $ns->isa('Zonemaster::Engine::Nameserver'); + next if !$ns->isa( 'Zonemaster::Engine::Nameserver' ); my $ip = $ns->address->short; $ns_by_ip{$ip} = $ns unless exists $ns_by_ip{$ip}; } return [ sort values %ns_by_ip ]; -} +} ## end sub get_del_ns_ips =over @@ -605,15 +644,15 @@ Returns an arrayref of strings, or C if no parent zone was found. sub get_zone_ns_names { my ( $class, $zone ) = @_; - # 'get_del_ns_names_and_ips' instead of 'get_del_ns_ips', because we need Zonemaster::Engine::Nameserver objects to be able to do queries. +# 'get_del_ns_names_and_ips' instead of 'get_del_ns_ips', because we need Zonemaster::Engine::Nameserver objects to be able to do queries. my $ns_ref = $class->get_del_ns_names_and_ips( $zone ); return undef unless defined $ns_ref; my @ns_names; - for my $ns ( @{ $ns_ref } ) { - if ( $ns->isa('Zonemaster::Engine::Nameserver') ) { + for my $ns ( @{$ns_ref} ) { + if ( $ns->isa( 'Zonemaster::Engine::Nameserver' ) ) { my $p = $ns->query( $zone->name, q{NS} ); if ( $p and $p->aa and $p->rcode eq q{NOERROR} ) { @@ -623,7 +662,7 @@ sub get_zone_ns_names { } return [ uniq sort map { name( lc( $_->nsdname ) ) } @ns_names ]; -} +} ## end sub get_zone_ns_names =over @@ -644,25 +683,30 @@ Returns an arrayref of L objects, or C if sub _get_ib_addr_in_zone { my ( $class, $zone ) = @_; - # 'get_del_ns_names_and_ips' instead of 'get_del_ns_ips', because we need Zonemaster::Engine::Nameserver objects to be able to do queries. - my $del_ips_ref = $class->get_del_ns_names_and_ips( $zone ); +# 'get_del_ns_names_and_ips' instead of 'get_del_ns_ips', because we need Zonemaster::Engine::Nameserver objects to be able to do queries. + my $del_ips_ref = $class->get_del_ns_names_and_ips( $zone ); my $ns_names_ref = $class->get_zone_ns_names( $zone ); - return undef unless defined $del_ips_ref or defined $ns_names_ref or scalar @{ $del_ips_ref } or scalar @{ $ns_names_ref }; + return undef + unless defined $del_ips_ref + or defined $ns_names_ref + or scalar @{$del_ips_ref} + or scalar @{$ns_names_ref}; - return [] unless scalar grep { $zone->name->is_in_bailiwick( $_ ) } @{ $ns_names_ref }; + return [] unless scalar grep { $zone->name->is_in_bailiwick( $_ ) } @{$ns_names_ref}; my %ib_ns; - for my $ns_name ( @{ $ns_names_ref } ) { + for my $ns_name ( @{$ns_names_ref} ) { if ( $zone->name->is_in_bailiwick( $ns_name ) ) { - for my $ns ( @{ $del_ips_ref } ) { + for my $ns ( @{$del_ips_ref} ) { for my $qtype ( q{A}, q{AAAA} ) { - my $p = Zonemaster::Engine::Recursor->recurse( $ns_name, $qtype, q{IN}, [ $ns ] ); + my $p = Zonemaster::Engine::Recursor->recurse( $ns_name, $qtype, q{IN}, [$ns] ); if ( $p and $p->aa and $p->rcode eq q{NOERROR} ) { if ( $p->has_rrs_of_type_for_name( q{CNAME}, $ns_name, q{answer} ) ) { - my %cnames = map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); + my %cnames = + map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); my $target = $ns_name; $target = $cnames{$target} while $cnames{$target}; @@ -671,29 +715,36 @@ sub _get_ib_addr_in_zone { } } # CNAME was followed in a new recursive query - elsif ( name( ($p->question)[0]->owner ) ne $ns_name and grep { $_->tag eq 'CNAME_FOLLOWED_OUT_OF_ZONE' and grep /^$ns_name$/, values %{ $_->args } } @{ Zonemaster::Engine->logger->entries } ) { - my $cname_ns_name = name( ($p->question)[0]->owner ); - my $target = $cname_ns_name; + elsif ( + name( ( $p->question )[0]->owner ) ne $ns_name + and + grep { $_->tag eq 'CNAME_FOLLOWED_OUT_OF_ZONE' and grep /^$ns_name$/, values %{ $_->args } } + @{ Zonemaster::Engine->logger->entries } + ) + { + my $cname_ns_name = name( ( $p->question )[0]->owner ); + my $target = $cname_ns_name; if ( $p->has_rrs_of_type_for_name( q{CNAME}, $cname_ns_name, q{answer} ) ) { - my %cnames = map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); + my %cnames = + map { name( $_->owner ) => name( $_->cname ) } $p->get_records( q{CNAME}, q{answer} ); $target = $cnames{$target} while $cnames{$target}; } for my $rr ( $p->get_records_for_name( $qtype, $target ) ) { push @{ $ib_ns{$ns_name} }, $rr->address; } - } + } ## end elsif ( name( ( $p->question...))) elsif ( $p->has_rrs_of_type_for_name( $qtype, $ns_name ) ) { for my $rr ( $p->get_records_for_name( $qtype, $ns_name ) ) { push @{ $ib_ns{$ns_name} }, $rr->address; } } - } - } - } - } - } + } ## end if ( $p and $p->aa and...) + } ## end for my $qtype ( q{A}, q{AAAA}) + } ## end for my $ns ( @{$del_ips_ref...}) + } ## end if ( $zone->name->is_in_bailiwick...) + } ## end for my $ns_name ( @{$ns_names_ref...}) my @ib_ns_array; @@ -704,7 +755,7 @@ sub _get_ib_addr_in_zone { } return [ uniq sort @ib_ns_array ]; -} +} ## end sub _get_ib_addr_in_zone =over @@ -731,19 +782,19 @@ sub get_zone_ns_names_and_ips { return undef unless defined $ns_names_ref; - return [] unless scalar @{ $ns_names_ref }; + return [] unless scalar @{$ns_names_ref}; - my $ib_ns_ref = $class->_get_ib_addr_in_zone( $zone ); + my $ib_ns_ref = $class->_get_ib_addr_in_zone( $zone ); my $oob_ns_ref = $class->_get_oob_ips( $zone, $ns_names_ref ); my @zone_ns; - for my $ns_name ( @{ $ns_names_ref } ) { + for my $ns_name ( @{$ns_names_ref} ) { if ( $zone->name->is_in_bailiwick( $ns_name ) ) { - if ( $ib_ns_ref and scalar @{ $ib_ns_ref } ) { - for my $ib_ns ( @{ $ib_ns_ref } ) { + if ( $ib_ns_ref and scalar @{$ib_ns_ref} ) { + for my $ib_ns ( @{$ib_ns_ref} ) { if ( $ns_name->string eq $ib_ns->name->string ) { - push @zone_ns, ns( $ns_name, $ib_ns->address->short); + push @zone_ns, ns( $ns_name, $ib_ns->address->short ); } } } @@ -752,12 +803,14 @@ sub get_zone_ns_names_and_ips { } } else { - if ( $oob_ns_ref and scalar @{ $oob_ns_ref } ) { - for my $oob_ns ( @{ $oob_ns_ref } ) { - if ( $oob_ns->isa('Zonemaster::Engine::Nameserver') and $ns_name->string eq $oob_ns->name->string ) { + if ( $oob_ns_ref and scalar @{$oob_ns_ref} ) { + for my $oob_ns ( @{$oob_ns_ref} ) { + if ( $oob_ns->isa( 'Zonemaster::Engine::Nameserver' ) + and $ns_name->string eq $oob_ns->name->string ) + { push @zone_ns, ns( $ns_name, $oob_ns->address->short ); } - elsif ( $oob_ns->isa('Zonemaster::Engine::DNSName') and $ns_name->string eq $oob_ns->string ) { + elsif ( $oob_ns->isa( 'Zonemaster::Engine::DNSName' ) and $ns_name->string eq $oob_ns->string ) { push @zone_ns, $ns_name; } } @@ -766,10 +819,10 @@ sub get_zone_ns_names_and_ips { push @zone_ns, $ns_name; } } - } + } ## end for my $ns_name ( @{$ns_names_ref...}) return [ uniq sort @zone_ns ]; -} +} ## end sub get_zone_ns_names_and_ips =over @@ -796,7 +849,7 @@ sub get_zone_ns_ips { my %ns_by_ip = (); foreach my $ns ( @$nameservers ) { - next if ! $ns->isa('Zonemaster::Engine::Nameserver'); + next if !$ns->isa( 'Zonemaster::Engine::Nameserver' ); my $ip = $ns->address->short; $ns_by_ip{$ip} = $ns unless exists $ns_by_ip{$ip}; } @@ -804,7 +857,6 @@ sub get_zone_ns_ips { return [ sort values %ns_by_ip ]; } - =over =item clear_cache() @@ -816,7 +868,7 @@ Clears previously cached results of the C method. =cut sub clear_cache() { - Memoize::flush_cache(\&get_parent_ns_names_and_ips); + Memoize::flush_cache( \&get_parent_ns_names_and_ips ); } 1; diff --git a/lib/Zonemaster/Engine/Translator.pm b/lib/Zonemaster/Engine/Translator.pm index acd9e7776..b78479d2e 100644 --- a/lib/Zonemaster/Engine/Translator.pm +++ b/lib/Zonemaster/Engine/Translator.pm @@ -3,12 +3,12 @@ package Zonemaster::Engine::Translator; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.8"); +use version; our $VERSION = version->declare( "v1.0.8" ); -use Carp qw[confess croak]; -use Locale::Messages qw[textdomain]; +use Carp qw[confess croak]; +use Locale::Messages qw[textdomain]; use Locale::TextDomain qw[Zonemaster-Engine]; -use POSIX qw[setlocale LC_MESSAGES]; +use POSIX qw[setlocale LC_MESSAGES]; use Readonly; use Zonemaster::Engine::Test; @@ -141,7 +141,7 @@ sub initialize { $instance = bless $obj, $class; return; -} +} ## end sub initialize ### ### Builder Methods @@ -176,7 +176,7 @@ sub _init_locale { } return $locale; -} +} ## end sub _init_locale sub _load_data { my $self = shift; @@ -205,7 +205,7 @@ sub _build_all_tag_descriptions { $all_tag_descriptions{System} = \%TAG_DESCRIPTIONS; foreach my $mod ( Zonemaster::Engine::Test->modules ) { my $module = 'Zonemaster::Engine::Test::' . $mod; - $all_tag_descriptions{ $mod } = $module->tag_descriptions; + $all_tag_descriptions{$mod} = $module->tag_descriptions; } return \%all_tag_descriptions; @@ -263,7 +263,7 @@ sub locale { } ## end if ( @args ) return $self->{_locale}; -}; +} ## end sub locale sub to_string { my ( $self, $entry ) = @_; @@ -277,7 +277,6 @@ sub translate_tag { return $self->_translate_tag( $entry->module, $entry->tag, $entry->printable_args ) // $entry->string; } - sub test_case_description { my ( $self, $test_name ) = @_; diff --git a/lib/Zonemaster/Engine/Util.pm b/lib/Zonemaster/Engine/Util.pm index 657edffc8..35c592cd0 100644 --- a/lib/Zonemaster/Engine/Util.pm +++ b/lib/Zonemaster/Engine/Util.pm @@ -3,9 +3,10 @@ package Zonemaster::Engine::Util; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.1.13"); +use version; our $VERSION = version->declare( "v1.1.13" ); use Exporter 'import'; + BEGIN { our @EXPORT_OK = qw[ escape_unprintable @@ -169,21 +170,22 @@ sub parse_hints { # Extract hint data my %hints; - for my $rr ( @{ $rrs } ) { + for my $rr ( @{$rrs} ) { if ( $rr->type eq 'A' or $rr->type eq 'AAAA' ) { - push @{ $hints{$rr->owner} }, $rr->address; + push @{ $hints{ $rr->owner } }, $rr->address; } } return \%hints; -} +} ## end sub parse_hints sub serial_gt { my ( $sa, $sb ) = @_; - return ( ( $sa < $sb and ( ($sb - $sa) > 2**( $SERIAL_BITS - 1 ) ) ) or - ( $sa > $sb and ( ($sa - $sb) < 2**( $SERIAL_BITS - 1 ) ) ) - ); + return ( + ( $sa < $sb and ( ( $sb - $sa ) > 2**( $SERIAL_BITS - 1 ) ) ) + or ( $sa > $sb and ( ( $sa - $sb ) < 2**( $SERIAL_BITS - 1 ) ) ) + ); } { @@ -199,21 +201,21 @@ sub serial_gt { # . my @substitution_table = map { if ( $_ == 92 ) { - '\\\\' + '\\\\'; } elsif ( $_ >= 32 and $_ <= 126 ) { - chr $_ + chr $_; } else { - sprintf '\%03d', $_ + sprintf '\%03d', $_; } - } 0..255; + } 0 .. 255; sub escape_unprintable { my ( $input ) = @_; my $output = ''; - $output .= $substitution_table[$_] foreach (unpack "C*", $input); + $output .= $substitution_table[$_] foreach ( unpack "C*", $input ); return $output; } diff --git a/lib/Zonemaster/Engine/Validation.pm b/lib/Zonemaster/Engine/Validation.pm index 9d17fb3f7..b1c0d01c1 100644 --- a/lib/Zonemaster/Engine/Validation.pm +++ b/lib/Zonemaster/Engine/Validation.pm @@ -3,9 +3,10 @@ package Zonemaster::Engine::Validation; use v5.16.0; use warnings; -use version; our $VERSION = version->declare("v1.0.0"); +use version; our $VERSION = version->declare( "v1.0.0" ); use Exporter 'import'; + BEGIN { our @EXPORT_OK = qw[ validate_ipv4 @@ -14,7 +15,7 @@ BEGIN { our %EXPORT_TAGS = ( all => \@EXPORT_OK ); ## no critic (Modules::ProhibitAutomaticExportation) - our @EXPORT = qw[ + our @EXPORT = qw[ validate_ipv4 validate_ipv6 ]; @@ -31,7 +32,7 @@ Readonly our $IPV6_RE => qr/^[0-9a-f:]*:[0-9a-f:]+(:[0-9]{1,3}\.[0-9]{1,3}\.[0-9 sub validate_ipv4 { my ( $ip ) = @_; - if ( defined $ip and $ip ne '') { + if ( defined $ip and $ip ne '' ) { if ( Net::IP::XS->new( $ip ) ) { if ( Net::IP::XS::ip_is_ipv4( $ip ) and $ip =~ /($IPV4_RE)/ ) { return 1; diff --git a/share/json2yaml.pl b/share/json2yaml.pl index 0a4d6be75..40ffd31e9 100755 --- a/share/json2yaml.pl +++ b/share/json2yaml.pl @@ -9,10 +9,10 @@ use Zonemaster::Engine::Profile; -my $json_file = @ARGV ? $ARGV[0] : dist_file( 'Zonemaster-Engine', 'profile.json'); -my $json = read_file( $json_file ); -my $profile = Zonemaster::Engine::Profile->from_json( $json ); -my $yaml = $profile->to_yaml(); +my $json_file = @ARGV ? $ARGV[0] : dist_file( 'Zonemaster-Engine', 'profile.json' ); +my $json = read_file( $json_file ); +my $profile = Zonemaster::Engine::Profile->from_json( $json ); +my $yaml = $profile->to_yaml(); say $yaml; =head1 NAME diff --git a/t/Test-address.t b/t/Test-address.t index da62fbaa6..faff4a846 100644 --- a/t/Test-address.t +++ b/t/Test-address.t @@ -14,51 +14,47 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my $json = read_file( "t/profiles/Test-address-all.json" ); -my $profile_test = Zonemaster::Engine::Profile->from_json( $json ); +my $json = read_file( "t/profiles/Test-address-all.json" ); +my $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my @special_addresses = qw(0.255.255.255 - 10.255.255.255 - 192.168.255.255 - 172.17.255.255 - 100.65.255.255 - 127.255.255.255 - 169.254.255.255 - 192.0.0.255 - 192.0.0.7 - 192.0.0.170 - 192.0.0.171 - 192.0.2.255 - 198.51.100.255 - 203.0.113.255 - 192.88.99.255 - 198.19.255.255 - 240.255.255.255 - 255.255.255.255 - ::1 - :: - ::ffff:cafe:cafe - 64:ff9b::cafe:cafe - 100::cafe:cafe:cafe:cafe - 2001:1ff:cafe:cafe:cafe:cafe:cafe:cafe - 2001::cafe:cafe:cafe:cafe:cafe:cafe - 2001:2::cafe:cafe:cafe:cafe:cafe - 2001:db8:cafe:cafe:cafe:cafe:cafe:cafe - 2001:1f::cafe:cafe:cafe:cafe:cafe - 2002:cafe:cafe:cafe:cafe:cafe:cafe:cafe - fdff:cafe:cafe:cafe:cafe:cafe:cafe:cafe - febf:cafe:cafe:cafe:cafe:cafe:cafe:cafe + 10.255.255.255 + 192.168.255.255 + 172.17.255.255 + 100.65.255.255 + 127.255.255.255 + 169.254.255.255 + 192.0.0.255 + 192.0.0.7 + 192.0.0.170 + 192.0.0.171 + 192.0.2.255 + 198.51.100.255 + 203.0.113.255 + 192.88.99.255 + 198.19.255.255 + 240.255.255.255 + 255.255.255.255 + ::1 + :: + ::ffff:cafe:cafe + 64:ff9b::cafe:cafe + 100::cafe:cafe:cafe:cafe + 2001:1ff:cafe:cafe:cafe:cafe:cafe:cafe + 2001::cafe:cafe:cafe:cafe:cafe:cafe + 2001:2::cafe:cafe:cafe:cafe:cafe + 2001:db8:cafe:cafe:cafe:cafe:cafe:cafe + 2001:1f::cafe:cafe:cafe:cafe:cafe + 2002:cafe:cafe:cafe:cafe:cafe:cafe:cafe + fdff:cafe:cafe:cafe:cafe:cafe:cafe:cafe + febf:cafe:cafe:cafe:cafe:cafe:cafe:cafe ); foreach my $addr ( @special_addresses ) { ok( - defined( - Zonemaster::Engine::Test::Address->_find_special_address( - Net::IP::XS->new( $addr ) - ) - ), - "Special address: $addr" + defined( Zonemaster::Engine::Test::Address->_find_special_address( Net::IP::XS->new( $addr ) ) ), + "Special address: $addr", ); } @@ -87,8 +83,11 @@ ok( $res{NAMESERVERS_IP_WITH_REVERSE}, q{Reverse DNS entry exist for all Nameser ok( $res{NAMESERVER_IP_WITHOUT_REVERSE}, q{Nameserver IP without PTR} ); my $zone = Zonemaster::Engine->zone( q{torsas.se} ); -my @res = Zonemaster::Engine->test_method( q{Address}, q{address02}, $zone ); -ok( !( grep { $_->tag eq 'NAMESERVER_IP_WITHOUT_REVERSE' } @res ), 'Classless in-addr.arpa properly handled when querying PTR.' ); +my @res = Zonemaster::Engine->test_method( q{Address}, q{address02}, $zone ); +ok( + !( grep { $_->tag eq 'NAMESERVER_IP_WITHOUT_REVERSE' } @res ), + 'Classless in-addr.arpa properly handled when querying PTR.', +); ########### # address03 @@ -97,7 +96,10 @@ ok( !( grep { $_->tag eq 'NAMESERVER_IP_WITHOUT_REVERSE' } @res ), 'Classless in ok( $res{NAMESERVER_IP_PTR_MATCH}, q{All reverse DNS entry matches name server name} ); @res = Zonemaster::Engine->test_method( q{Address}, q{address03}, $zone ); -ok( !( grep { $_->tag eq 'NAMESERVER_IP_WITHOUT_REVERSE' } @res ), 'Classless in-addr.arpa properly handled when querying PTR.' ); +ok( + !( grep { $_->tag eq 'NAMESERVER_IP_WITHOUT_REVERSE' } @res ), + 'Classless in-addr.arpa properly handled when querying PTR.', +); ########### diff --git a/t/Test-address01.t b/t/Test-address01.t index 617dc09c0..8a286bb14 100644 --- a/t/Test-address01.t +++ b/t/Test-address01.t @@ -16,20 +16,22 @@ BEGIN { ########### # address01 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Address-TP/address01.md my $test_module = 'Address'; -my $test_case = 'address01'; -my @all_tags = qw(A01_ADDR_NOT_GLOBALLY_REACHABLE - A01_DOCUMENTATION_ADDR - A01_GLOBALLY_REACHABLE_ADDR - A01_LOCAL_USE_ADDR - A01_NO_GLOBALLY_REACHABLE_ADDR - A01_NO_NAME_SERVERS_FOUND); +my $test_case = 'address01'; +my @all_tags = qw(A01_ADDR_NOT_GLOBALLY_REACHABLE + A01_DOCUMENTATION_ADDR + A01_GLOBALLY_REACHABLE_ADDR + A01_LOCAL_USE_ADDR + A01_NO_GLOBALLY_REACHABLE_ADDR + A01_NO_NAME_SERVERS_FOUND); # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -47,18 +49,11 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'GOOD-1' => [ - 1, - q(good-1.address01.xa), - [ qw(A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], - ], + 'GOOD-1' => [ 1, q(good-1.address01.xa), [qw(A01_GLOBALLY_REACHABLE_ADDR)], undef, [], [] ], 'ALL-NON-REACHABLE' => [ 1, q(all-non-reachable.address01.xa), - [ qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_NO_GLOBALLY_REACHABLE_ADDR) ], + [qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_NO_GLOBALLY_REACHABLE_ADDR)], undef, [], [], @@ -66,80 +61,55 @@ my %subtests = ( 'MIXED-LOCAL-DOC-1' => [ 1, q(mixed-local-doc-1.address01.xa), - [ qw(A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-LOCAL-DOC-2' => [ 1, q(mixed-local-doc-2.address01.xa), - [ qw(A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_LOCAL_USE_ADDR A01_DOCUMENTATION_ADDR A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-LOCAL-OTHER-1' => [ 1, q(mixed-local-other-1.address01.xa), - [ qw(A01_LOCAL_USE_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_LOCAL_USE_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-LOCAL-OTHER-2' => [ 1, q(mixed-local-other-2.address01.xa), - [ qw(A01_LOCAL_USE_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_LOCAL_USE_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-DOC-OTHER-1' => [ 1, q(mixed-doc-other-1.address01.xa), - [ qw(A01_DOCUMENTATION_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_DOCUMENTATION_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-DOC-OTHER-2' => [ 1, q(mixed-doc-other-2.address01.xa), - [ qw(A01_DOCUMENTATION_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + [qw(A01_DOCUMENTATION_ADDR A01_ADDR_NOT_GLOBALLY_REACHABLE A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-ALL-1' => [ - 1, - q(mixed-all-1.address01.xa), - [ qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_DOCUMENTATION_ADDR A01_LOCAL_USE_ADDR A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + 1, q(mixed-all-1.address01.xa), + [qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_DOCUMENTATION_ADDR A01_LOCAL_USE_ADDR A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], 'MIXED-ALL-2' => [ - 1, - q(mixed-all-2.address01.xa), - [ qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_DOCUMENTATION_ADDR A01_LOCAL_USE_ADDR A01_GLOBALLY_REACHABLE_ADDR) ], - undef, - [], - [], + 1, q(mixed-all-2.address01.xa), + [qw(A01_ADDR_NOT_GLOBALLY_REACHABLE A01_DOCUMENTATION_ADDR A01_LOCAL_USE_ADDR A01_GLOBALLY_REACHABLE_ADDR)], + undef, [], [], ], - 'NO-NAME-SERVERS' => [ - 1, - q(no-name-servers.address01.xa), - [ qw(A01_NO_NAME_SERVERS_FOUND) ], - undef, - [], - [], - ] + 'NO-NAME-SERVERS' => [ 1, q(no-name-servers.address01.xa), [qw(A01_NO_NAME_SERVERS_FOUND)], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -147,9 +117,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-address03.t b/t/Test-address03.t index e82144845..4f24ae319 100644 --- a/t/Test-address03.t +++ b/t/Test-address03.t @@ -1,58 +1,59 @@ -use strict; -use warnings; - -use File::Basename; -use File::Spec::Functions qw( rel2abs ); -use lib dirname( rel2abs( $0 ) ); -use TestUtil::DSL; - -testing_test_case 'Address', 'address03'; - -all_tags qw(NAMESERVER_IP_PTR_MATCH - NAMESERVER_IP_PTR_MISMATCH - NAMESERVER_IP_WITHOUT_REVERSE - NO_RESPONSE_PTR_QUERY); - -# Common hint file (test-zone-data/COMMON/hintfile) -root_hints 'ns1' => [ qw(127.1.0.1 fda1:b2:c3::127:1:0:1) ], - 'ns2' => [ qw(127.1.0.2 fda1:b2:c3::127:1:0:2) ]; - -zone_name_template '{SCENARIO}.{TESTCASE}.xa'; - -# Test zone scenarios -scenario 'ALL-NS-HAVE-PTR-{1..2}' => sub { - expect 'NAMESERVER_IP_PTR_MATCH'; - forbid_others; -}; - -scenario 'NO-NS-HAVE-PTR' => sub { - expect 'NAMESERVER_IP_WITHOUT_REVERSE'; - forbid_others; -}; - -scenario 'INCOMPLETE-PTR-{1..2}' => sub { - expect 'NAMESERVER_IP_WITHOUT_REVERSE'; - forbid_others; -}; - -scenario 'NON-MATCHING-NAMES' => sub { - expect 'NAMESERVER_IP_PTR_MISMATCH'; - forbid_others; -}; - -scenario 'PTR-IS-GOOD-CNAME-{1..2}' => sub { - expect 'NAMESERVER_IP_PTR_MATCH'; - forbid_others; -}; - -scenario 'PTR-IS-DANGLING-CNAME' => sub { - expect 'NAMESERVER_IP_WITHOUT_REVERSE'; - forbid_others; -}; - -scenario 'PTR-IS-ILLEGAL-CNAME' => sub { - expect 'NAMESERVER_IP_WITHOUT_REVERSE'; - forbid 'NAMESERVER_IP_PTR_MATCH'; -}; - -no_more_scenarios; +use strict; +use warnings; + +use File::Basename; +use File::Spec::Functions qw( rel2abs ); +use lib dirname( rel2abs( $0 ) ); +use TestUtil::DSL; + +testing_test_case 'Address', 'address03'; + +all_tags qw(NAMESERVER_IP_PTR_MATCH + NAMESERVER_IP_PTR_MISMATCH + NAMESERVER_IP_WITHOUT_REVERSE + NO_RESPONSE_PTR_QUERY); + +# Common hint file (test-zone-data/COMMON/hintfile) +root_hints + 'ns1' => [qw(127.1.0.1 fda1:b2:c3::127:1:0:1)], + 'ns2' => [qw(127.1.0.2 fda1:b2:c3::127:1:0:2)]; + +zone_name_template '{SCENARIO}.{TESTCASE}.xa'; + +# Test zone scenarios +scenario 'ALL-NS-HAVE-PTR-{1..2}' => sub { + expect 'NAMESERVER_IP_PTR_MATCH'; + forbid_others; +}; + +scenario 'NO-NS-HAVE-PTR' => sub { + expect 'NAMESERVER_IP_WITHOUT_REVERSE'; + forbid_others; +}; + +scenario 'INCOMPLETE-PTR-{1..2}' => sub { + expect 'NAMESERVER_IP_WITHOUT_REVERSE'; + forbid_others; +}; + +scenario 'NON-MATCHING-NAMES' => sub { + expect 'NAMESERVER_IP_PTR_MISMATCH'; + forbid_others; +}; + +scenario 'PTR-IS-GOOD-CNAME-{1..2}' => sub { + expect 'NAMESERVER_IP_PTR_MATCH'; + forbid_others; +}; + +scenario 'PTR-IS-DANGLING-CNAME' => sub { + expect 'NAMESERVER_IP_WITHOUT_REVERSE'; + forbid_others; +}; + +scenario 'PTR-IS-ILLEGAL-CNAME' => sub { + expect 'NAMESERVER_IP_WITHOUT_REVERSE'; + forbid 'NAMESERVER_IP_PTR_MATCH'; +}; + +no_more_scenarios; diff --git a/t/Test-basic.t b/t/Test-basic.t index fb6b76ac3..c69e8b04c 100644 --- a/t/Test-basic.t +++ b/t/Test-basic.t @@ -30,7 +30,8 @@ sub zone_gives { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( ( grep { $_->tag eq $gives } @res ), $zone->name->string . " gives $gives" ); } @@ -41,7 +42,8 @@ sub zone_gives_not { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( !( grep { $_->tag eq $gives } @res ), $zone->name->string . " does not give $gives" ); } @@ -55,7 +57,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); $json = read_file( 't/profiles/Test-basic-all.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); @@ -72,8 +74,8 @@ if ( $ENV{ZONEMASTER_RECORD} ) { } Zonemaster::Engine::Profile->effective->set( q{no_network}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); $zone = Zonemaster::Engine->zone( q{afnic.fr} ); zone_gives( q{basic02}, $zone, [qw{NO_NETWORK}] ); @@ -94,8 +96,8 @@ TODO: { #basic03 ok( $tag{A_QUERY_NO_RESPONSES}, q{A_QUERY_NO_RESPONSES} ); - ok( $tag{HAS_A_RECORDS}, q{HAS_A_RECORDS} ); - ok( $tag{NO_A_RECORDS}, q{NO_A_RECORDS} ); + ok( $tag{HAS_A_RECORDS}, q{HAS_A_RECORDS} ); + ok( $tag{NO_A_RECORDS}, q{NO_A_RECORDS} ); } done_testing; diff --git a/t/Test-basic01.t b/t/Test-basic01.t index cb5e36f7e..f86848f77 100644 --- a/t/Test-basic01.t +++ b/t/Test-basic01.t @@ -11,20 +11,21 @@ use TestUtil::DSL; testing_test_case 'Basic', 'basic01'; all_tags qw(B01_CHILD_IS_ALIAS - B01_CHILD_FOUND - B01_INCONSISTENT_ALIAS - B01_INCONSISTENT_DELEGATION - B01_NO_CHILD - B01_PARENT_DISREGARDED - B01_PARENT_FOUND - B01_PARENT_NOT_FOUND - B01_PARENT_UNDETERMINED - B01_ROOT_HAS_NO_PARENT - B01_SERVER_ZONE_ERROR); + B01_CHILD_FOUND + B01_INCONSISTENT_ALIAS + B01_INCONSISTENT_DELEGATION + B01_NO_CHILD + B01_PARENT_DISREGARDED + B01_PARENT_FOUND + B01_PARENT_NOT_FOUND + B01_PARENT_UNDETERMINED + B01_ROOT_HAS_NO_PARENT + B01_SERVER_ZONE_ERROR); # Common hint file (test-zone-data/COMMON/hintfile) -root_hints 'ns1' => [ qw(127.1.0.1 fda1:b2:c3::127:1:0:1) ], - 'ns2' => [ qw(127.1.0.2 fda1:b2:c3::127:1:0:2) ]; +root_hints + 'ns1' => [qw(127.1.0.1 fda1:b2:c3::127:1:0:1)], + 'ns2' => [qw(127.1.0.2 fda1:b2:c3::127:1:0:2)]; # Test zone scenarios zone_name_template 'child.parent.{SCENARIO}.{TESTCASE}.xa'; @@ -108,7 +109,7 @@ scenario 'CHILD-ALIAS-1' => sub { scenario 'CHILD-ALIAS-2' => sub { expect qw(B01_CHILD_IS_ALIAS B01_NO_CHILD B01_INCONSISTENT_ALIAS - B01_PARENT_FOUND); + B01_PARENT_FOUND); forbid_others; }; diff --git a/t/Test-basic02.t b/t/Test-basic02.t index ca1076933..0509cf444 100644 --- a/t/Test-basic02.t +++ b/t/Test-basic02.t @@ -11,17 +11,18 @@ use TestUtil::DSL; testing_test_case 'Basic', 'basic02'; all_tags qw(B02_AUTH_RESPONSE_SOA - B02_NO_DELEGATION - B02_NO_WORKING_NS - B02_NS_BROKEN - B02_NS_NOT_AUTH - B02_NS_NO_IP_ADDR - B02_NS_NO_RESPONSE - B02_UNEXPECTED_RCODE); + B02_NO_DELEGATION + B02_NO_WORKING_NS + B02_NS_BROKEN + B02_NS_NOT_AUTH + B02_NS_NO_IP_ADDR + B02_NS_NO_RESPONSE + B02_UNEXPECTED_RCODE); # Specific hint file (test-zone-data/Basic-TP/basic02/hintfile.zone) -root_hints 'root-ns1.xa' => [ qw(127.12.2.23 fda1:b2:c3::127:12:2:23) ], - 'root-ns2.xa' => [ qw(127.12.2.24 fda1:b2:c3::127:12:2:24) ]; +root_hints + 'root-ns1.xa' => [qw(127.12.2.23 fda1:b2:c3::127:12:2:23)], + 'root-ns2.xa' => [qw(127.12.2.24 fda1:b2:c3::127:12:2:24)]; zone_name_template '{SCENARIO}.{TESTCASE}.xa'; diff --git a/t/Test-connectivity.t b/t/Test-connectivity.t index 61af58571..f2b0d553c 100644 --- a/t/Test-connectivity.t +++ b/t/Test-connectivity.t @@ -18,18 +18,18 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); foreach my $testcase ( qw{connectivity01 connectivity02 connectivity03 connectivity04} ) { - $json = read_file( 't/profiles/Test-'.$testcase.'-only.json' ); - $profile_test = Zonemaster::Engine::Profile->from_json( $json ); + $json = read_file( 't/profiles/Test-' . $testcase . '-only.json' ); + $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my %testcases; foreach my $result ( Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ) ) { if ( $result->testcase && $result->testcase ne 'Unspecified' ) { - $testcases{$result->testcase} = 1; + $testcases{ $result->testcase } = 1; } } - eq_or_diff( [ map { lc $_ } keys %testcases ], [ $testcase ], 'expected test-case ('. $testcase .')' ); + eq_or_diff( [ map { lc $_ } keys %testcases ], [$testcase], 'expected test-case (' . $testcase . ')' ); } $json = read_file( 't/profiles/Test-connectivity-all.json' ); @@ -40,7 +40,7 @@ my @res; my %res; my %should_emit; -my $metadata = Zonemaster::Engine::Test::Connectivity->metadata(); +my $metadata = Zonemaster::Engine::Test::Connectivity->metadata(); my $test_levels = Zonemaster::Engine::Profile->effective->{profile}->{test_levels}->{CONNECTIVITY}; sub check_output_connectivity_testcase { @@ -52,7 +52,8 @@ sub check_output_connectivity_testcase { next if ( $test_levels->{$key} =~ q/DEBUG/ ); if ( $should_emit->{$key} ) { ok( $res->{$key}, "Should emit $key" ); - } else { + } + else { ok( !$res->{$key}, "Should NOT emit $key" ); } } @@ -71,10 +72,10 @@ subtest 'All good' => sub { %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ); ok( !$res{MODULE_ERROR}, q{Test module completes normally} ); %should_emit = ( - IPV4_DIFFERENT_ASN => 1, - IPV6_DIFFERENT_ASN => 1, + IPV4_DIFFERENT_ASN => 1, + IPV6_DIFFERENT_ASN => 1, CN04_IPV4_DIFFERENT_PREFIX => 1, - CN04_IPV6_DIFFERENT_PREFIX => 1 + CN04_IPV6_DIFFERENT_PREFIX => 1, ); check_output_connectivity_all( \%res, \%should_emit ); }; @@ -86,9 +87,7 @@ subtest 'No IPv6 (profile with IPv4 only)' => sub { %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ); subtest 'UDP' => sub { - %should_emit = ( - CN01_IPV6_DISABLED => 1 - ); + %should_emit = ( CN01_IPV6_DISABLED => 1 ); check_output_connectivity_testcase( 'connectivity01', \%res, \%should_emit ); }; @@ -107,9 +106,7 @@ subtest 'No IPv4 (profile with IPv6 only)' => sub { %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ); subtest 'UDP' => sub { - %should_emit = ( - CN01_IPV4_DISABLED => 1 - ); + %should_emit = ( CN01_IPV4_DISABLED => 1 ); check_output_connectivity_testcase( 'connectivity01', \%res, \%should_emit ); }; @@ -125,7 +122,7 @@ subtest 'No network' => sub { Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); - %res = map{ $_->tag => 1 } Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ); + %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{connectivity}, q{afnic.fr} ); ok( $res{NO_NETWORK}, 'IPv6 and IPv4 disabled' ); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 1 ); diff --git a/t/Test-connectivity03.t b/t/Test-connectivity03.t index 76802b845..d27c0e850 100644 --- a/t/Test-connectivity03.t +++ b/t/Test-connectivity03.t @@ -12,13 +12,14 @@ BEGIN { } my $checking_module = q{Connectivity}; -my $testcase = 'connectivity03'; -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $testcase = 'connectivity03'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; sub zone_gives { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( ( grep { $_->tag eq $gives } @res ), $zone->name->string . " gives $gives" ); } @@ -29,7 +30,8 @@ sub zone_gives_not { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( !( grep { $_->tag eq $gives } @res ), $zone->name->string . " does not give $gives" ); } @@ -42,7 +44,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); $json = qq({ "test_cases": [ "$testcase" ] }); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); @@ -50,20 +52,30 @@ Zonemaster::Engine::Profile->effective->merge( $profile_test ); ### my $zone = Zonemaster::Engine->zone( q{001.re} ); zone_gives( $testcase, $zone, [qw{IPV4_ONE_ASN IPV6_ONE_ASN}] ); -zone_gives_not( $testcase, $zone, [qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_DIFFERENT_ASN IPV4_SAME_ASN IPV6_DIFFERENT_ASN IPV6_SAME_ASN}] ); +zone_gives_not( $testcase, $zone, + [qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_DIFFERENT_ASN IPV4_SAME_ASN IPV6_DIFFERENT_ASN IPV6_SAME_ASN}], +); $zone = Zonemaster::Engine->zone( q{zonemaster.net} ); zone_gives( $testcase, $zone, [qw{IPV4_DIFFERENT_ASN IPV6_DIFFERENT_ASN}] ); -zone_gives_not( $testcase, $zone, [qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_SAME_ASN IPV6_SAME_ASN IPV4_ONE_ASN IPV6_ONE_ASN}] ); +zone_gives_not( $testcase, $zone, + [qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_SAME_ASN IPV6_SAME_ASN IPV4_ONE_ASN IPV6_ONE_ASN}], +); $zone = Zonemaster::Engine->zone( q{zut-root.rd.nic.fr} ); zone_gives( $testcase, $zone, [qw{IPV4_ONE_ASN}] ); -zone_gives_not( $testcase, $zone, [qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_DIFFERENT_ASN IPV4_SAME_ASN IPV6_DIFFERENT_ASN IPV6_ONE_ASN IPV6_SAME_ASN}] ); +zone_gives_not( + $testcase, + $zone, + [ + qw{EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_DIFFERENT_ASN IPV4_SAME_ASN IPV6_DIFFERENT_ASN IPV6_ONE_ASN IPV6_SAME_ASN} + ], +); TODO: { my @missing = qw( EMPTY_ASN_SET ERROR_ASN_DATABASE IPV4_SAME_ASN IPV6_SAME_ASN ); local $TODO = "Need to find/create zones with those errors: "; - warn $TODO, "\n\t", join("\n\t", @missing), "\n"; + warn $TODO, "\n\t", join( "\n\t", @missing ), "\n"; } ### diff --git a/t/Test-connectivity04.t b/t/Test-connectivity04.t index c4ccd884c..65f041884 100644 --- a/t/Test-connectivity04.t +++ b/t/Test-connectivity04.t @@ -11,17 +11,18 @@ use TestUtil::DSL; testing_test_case 'Connectivity', 'connectivity04'; all_tags qw(CN04_EMPTY_PREFIX_SET - CN04_ERROR_PREFIX_DATABASE - CN04_IPV4_DIFFERENT_PREFIX - CN04_IPV4_SAME_PREFIX - CN04_IPV4_SINGLE_PREFIX - CN04_IPV6_DIFFERENT_PREFIX - CN04_IPV6_SAME_PREFIX - CN04_IPV6_SINGLE_PREFIX); + CN04_ERROR_PREFIX_DATABASE + CN04_IPV4_DIFFERENT_PREFIX + CN04_IPV4_SAME_PREFIX + CN04_IPV4_SINGLE_PREFIX + CN04_IPV6_DIFFERENT_PREFIX + CN04_IPV6_SAME_PREFIX + CN04_IPV6_SINGLE_PREFIX); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/Connectivity-TP/connectivity04/hintfile.zone) -root_hints 'root-ns1.xa' => [ qw(127.13.4.23 fda1:b2:c3::127:13:4:23) ], - 'root-ns2.xa' => [ qw(127.13.4.24 fda1:b2:c3::127:13:4:24) ]; +root_hints + 'root-ns1.xa' => [qw(127.13.4.23 fda1:b2:c3::127:13:4:23)], + 'root-ns2.xa' => [qw(127.13.4.24 fda1:b2:c3::127:13:4:24)]; # Test zone scenarios zone_name_template '{SCENARIO}.{TESTCASE}.xa'; diff --git a/t/Test-consistency.t b/t/Test-consistency.t index 90cd679c0..17a606d49 100644 --- a/t/Test-consistency.t +++ b/t/Test-consistency.t @@ -17,19 +17,19 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); foreach my $testcase ( qw{consistency01 consistency02 consistency03 consistency04} ) { - $json = read_file( 't/profiles/Test-'.$testcase.'-only.json' ); + $json = read_file( 't/profiles/Test-' . $testcase . '-only.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my %testcases; Zonemaster::Engine->logger->clear_history(); foreach my $result ( Zonemaster::Engine->test_module( q{consistency}, q{afnic.fr} ) ) { if ( $result->testcase && $result->testcase ne 'Unspecified' ) { - $testcases{$result->testcase} = 1; + $testcases{ $result->testcase } = 1; } } - eq_or_diff( [ map { lc $_ } keys %testcases ], [ $testcase ], 'expected test-case ('. $testcase .')' ); + eq_or_diff( [ map { lc $_ } keys %testcases ], [$testcase], 'expected test-case (' . $testcase . ')' ); } $json = read_file( 't/profiles/Test-consistency-all.json' ); @@ -67,26 +67,25 @@ if ( $ENV{ZONEMASTER_RECORD} ) { } Zonemaster::Engine::Profile->effective->set( q{no_network}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); @res = Zonemaster::Engine->test_method( 'Consistency', 'consistency01', Zonemaster::Engine->zone( q{afnic.fr} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); @res = Zonemaster::Engine->test_method( 'Consistency', 'consistency02', Zonemaster::Engine->zone( q{afnic.fr} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); @res = Zonemaster::Engine->test_method( 'Consistency', 'consistency03', Zonemaster::Engine->zone( q{afnic.fr} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); @res = Zonemaster::Engine->test_method( 'Consistency', 'consistency04', Zonemaster::Engine->zone( q{afnic.fr} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); - Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); done_testing; diff --git a/t/Test-consistency06.t b/t/Test-consistency06.t index 42d8bdd63..1cc7b9997 100644 --- a/t/Test-consistency06.t +++ b/t/Test-consistency06.t @@ -12,13 +12,14 @@ use TestUtil::DSL; testing_test_case 'Consistency', 'consistency06'; all_tags qw(ONE_SOA_MNAME - NO_RESPONSE - NO_RESPONSE_SOA_QUERY - MULTIPLE_SOA_MNAMES); + NO_RESPONSE + NO_RESPONSE_SOA_QUERY + MULTIPLE_SOA_MNAMES); # Common hint file (test-zone-data/COMMON/hintfile) -root_hints 'ns1' => [ qw(127.1.0.1 fda1:b2:c3::127:1:0:1) ], - 'ns2' => [ qw(127.1.0.2 fda1:b2:c3::127:1:0:2) ]; +root_hints + 'ns1' => [qw(127.1.0.1 fda1:b2:c3::127:1:0:1)], + 'ns2' => [qw(127.1.0.2 fda1:b2:c3::127:1:0:2)]; zone_name_template '{SCENARIO}.{TESTCASE}.xa'; diff --git a/t/Test-delegation.t b/t/Test-delegation.t index 165302ced..2ba4ea72f 100644 --- a/t/Test-delegation.t +++ b/t/Test-delegation.t @@ -16,7 +16,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); $json = read_file( 't/profiles/Test-delegation-all.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); @@ -26,15 +26,15 @@ my %res; my $iis = Zonemaster::Engine->zone( q{iis.se} ); %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Delegation->all( $iis ); -ok( $res{NAMES_MATCH}, q{NAMES_MATCH} ); +ok( $res{NAMES_MATCH}, q{NAMES_MATCH} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{delegation}, q{krtgroupe.fr} ); -ok( $res{EXTRA_NAME_PARENT}, q{EXTRA_NAME_PARENT} ); -ok( $res{EXTRA_NAME_CHILD}, q{EXTRA_NAME_CHILD} ); -ok( $res{TOTAL_NAME_MISMATCH}, q{TOTAL_NAME_MISMATCH} ); -ok( $res{NO_NS_CNAME}, q{NO_NS_CNAME} ); -ok( $res{SOA_EXISTS}, q{SOA_EXISTS} ); -ok( $res{ARE_AUTHORITATIVE}, q{ARE_AUTHORITATIVE} ); +ok( $res{EXTRA_NAME_PARENT}, q{EXTRA_NAME_PARENT} ); +ok( $res{EXTRA_NAME_CHILD}, q{EXTRA_NAME_CHILD} ); +ok( $res{TOTAL_NAME_MISMATCH}, q{TOTAL_NAME_MISMATCH} ); +ok( $res{NO_NS_CNAME}, q{NO_NS_CNAME} ); +ok( $res{SOA_EXISTS}, q{SOA_EXISTS} ); +ok( $res{ARE_AUTHORITATIVE}, q{ARE_AUTHORITATIVE} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{delegation}, q{critere.fr} ); ok( $res{SOA_NOT_EXISTS}, q{SOA_NOT_EXISTS} ); @@ -49,18 +49,17 @@ if ( $ENV{ZONEMASTER_RECORD} ) { } Zonemaster::Engine::Profile->effective->set( q{no_network}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); @res = Zonemaster::Engine->test_method( 'Delegation', 'delegation04', Zonemaster::Engine->zone( q{iis.se} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); @res = Zonemaster::Engine->test_method( 'Delegation', 'delegation06', Zonemaster::Engine->zone( q{iis.se} ) ); -ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); +ok( ( any { $_->tag eq 'NO_NETWORK' } @res ), 'IPv6 and IPv4 disabled' ); ok( ( none { $_->tag eq 'IPV6_DISABLED' } @res ), 'No network' ); ok( ( none { $_->tag eq 'IPV4_DISABLED' } @res ), 'No network' ); - Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); done_testing; diff --git a/t/Test-delegation01.t b/t/Test-delegation01.t index 482c3d4e0..e4df9d22b 100644 --- a/t/Test-delegation01.t +++ b/t/Test-delegation01.t @@ -11,126 +11,127 @@ use TestUtil::DSL; testing_test_case 'Delegation', 'delegation01'; all_tags qw(ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV4_NS_DEL - ENOUGH_IPV6_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL - NOT_ENOUGH_IPV4_NS_CHILD - NOT_ENOUGH_IPV4_NS_DEL - NOT_ENOUGH_IPV6_NS_CHILD - NOT_ENOUGH_IPV6_NS_DEL - NOT_ENOUGH_NS_CHILD - NOT_ENOUGH_NS_DEL - NO_IPV4_NS_CHILD - NO_IPV4_NS_DEL - NO_IPV6_NS_CHILD - NO_IPV6_NS_DEL); + ENOUGH_IPV4_NS_DEL + ENOUGH_IPV6_NS_CHILD + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL + NOT_ENOUGH_IPV4_NS_CHILD + NOT_ENOUGH_IPV4_NS_DEL + NOT_ENOUGH_IPV6_NS_CHILD + NOT_ENOUGH_IPV6_NS_DEL + NOT_ENOUGH_NS_CHILD + NOT_ENOUGH_NS_DEL + NO_IPV4_NS_CHILD + NO_IPV4_NS_DEL + NO_IPV6_NS_CHILD + NO_IPV6_NS_DEL); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/Delegation-TP/delegation01/hintfile.zone) -root_hints 'root-ns1.xa' => [ qw(127.16.1.27 fda1:b2:c3::127:16:1:27) ], - 'root-ns2.xa' => [ qw(127.16.1.28 fda1:b2:c3::127:16:1:28) ]; +root_hints + 'root-ns1.xa' => [qw(127.16.1.27 fda1:b2:c3::127:16:1:27)], + 'root-ns2.xa' => [qw(127.16.1.28 fda1:b2:c3::127:16:1:28)]; zone_name_template '{SCENARIO}.{TESTCASE}.xa'; # Test zone scenarios scenario 'ENOUGH-{1..3}' => sub { expect qw(ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV4_NS_DEL - ENOUGH_IPV6_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL); + ENOUGH_IPV4_NS_DEL + ENOUGH_IPV6_NS_CHILD + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL); forbid_others; }; scenario 'ENOUGH-DEL-NOT-CHILD' => sub { - todo; # FIXME: why? + todo; # FIXME: why? expect qw(ENOUGH_IPV4_NS_DEL - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_DEL - NOT_ENOUGH_IPV4_NS_CHILD - NOT_ENOUGH_IPV6_NS_CHILD - NOT_ENOUGH_NS_CHILD); + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_DEL + NOT_ENOUGH_IPV4_NS_CHILD + NOT_ENOUGH_IPV6_NS_CHILD + NOT_ENOUGH_NS_CHILD); forbid_others; }; scenario 'ENOUGH-CHILD-NOT-DEL' => sub { expect qw(ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV6_NS_CHILD - ENOUGH_NS_CHILD - NOT_ENOUGH_IPV4_NS_DEL - NOT_ENOUGH_IPV6_NS_DEL - NOT_ENOUGH_NS_DEL); + ENOUGH_IPV6_NS_CHILD + ENOUGH_NS_CHILD + NOT_ENOUGH_IPV4_NS_DEL + NOT_ENOUGH_IPV6_NS_DEL + NOT_ENOUGH_NS_DEL); forbid_others; }; scenario 'IPV6-AND-DEL-OK-NO-IPV4-CHILD' => sub { - todo; # FIXME: why? + todo; # FIXME: why? expect qw(ENOUGH_IPV4_NS_DEL - ENOUGH_IPV6_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL - NO_IPV4_NS_CHILD); + ENOUGH_IPV6_NS_CHILD + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL + NO_IPV4_NS_CHILD); forbid_others; }; scenario 'IPV4-AND-DEL-OK-NO-IPV6-CHILD' => sub { - todo; # FIXME: why? - + todo; # FIXME: why? + expect qw(ENOUGH_IPV4_NS_DEL - ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL - NO_IPV6_NS_CHILD); + ENOUGH_IPV4_NS_CHILD + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL + NO_IPV6_NS_CHILD); forbid_others; }; scenario 'NO-IPV4-{1..3}' => sub { expect qw(ENOUGH_IPV6_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL - NO_IPV4_NS_CHILD - NO_IPV4_NS_DEL); + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL + NO_IPV4_NS_CHILD + NO_IPV4_NS_DEL); forbid_others; }; scenario 'NO-IPV6-{1..3}' => sub { expect qw(ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV4_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL - NO_IPV6_NS_CHILD - NO_IPV6_NS_DEL); + ENOUGH_IPV4_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL + NO_IPV6_NS_CHILD + NO_IPV6_NS_DEL); forbid_others; }; scenario 'MISMATCH-DELEGATION-CHILD-1' => sub { - todo; # FIXME: why? + todo; # FIXME: why? expect qw(ENOUGH_IPV4_NS_CHILD - NOT_ENOUGH_IPV4_NS_DEL - ENOUGH_IPV6_NS_CHILD - NOT_ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL); + NOT_ENOUGH_IPV4_NS_DEL + ENOUGH_IPV6_NS_CHILD + NOT_ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL); forbid_others; }; scenario 'MISMATCH-DELEGATION-CHILD-2' => sub { - todo; # FIXME: why? + todo; # FIXME: why? expect qw(NOT_ENOUGH_IPV4_NS_CHILD - ENOUGH_IPV4_NS_DEL - NOT_ENOUGH_IPV6_NS_CHILD - ENOUGH_IPV6_NS_DEL - ENOUGH_NS_CHILD - ENOUGH_NS_DEL); + ENOUGH_IPV4_NS_DEL + NOT_ENOUGH_IPV6_NS_CHILD + ENOUGH_IPV6_NS_DEL + ENOUGH_NS_CHILD + ENOUGH_NS_DEL); forbid_others; }; diff --git a/t/Test-delegation02.t b/t/Test-delegation02.t index 2e031e0f2..2a30ee035 100644 --- a/t/Test-delegation02.t +++ b/t/Test-delegation02.t @@ -15,20 +15,22 @@ BEGIN { ########### # Delegation02 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Delegation-TP/delegation02.md my $test_module = 'Delegation'; -my $test_case = 'delegation02'; -my @all_tags = qw( - DEL_DISTINCT_NS_IP - CHILD_DISTINCT_NS_IP - DEL_NS_SAME_IP - CHILD_NS_SAME_IP - ); +my $test_case = 'delegation02'; +my @all_tags = qw( + DEL_DISTINCT_NS_IP + CHILD_DISTINCT_NS_IP + DEL_NS_SAME_IP + CHILD_NS_SAME_IP +); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/Delegation-TP/delegation02/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'root-ns1.xa' => [ '127.16.2.27', 'fda1:b2:c3::127:16:2:27' ], - 'root-ns2.xa' => [ '127.16.2.28', 'fda1:b2:c3::127:16:2:28' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'root-ns1.xa' => [ '127.16.2.27', 'fda1:b2:c3::127:16:2:27' ], + 'root-ns2.xa' => [ '127.16.2.28', 'fda1:b2:c3::127:16:2:28' ], + }, ); # Test zone scenarios @@ -46,112 +48,80 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'ALL-DISTINCT-1' => - [ - 1, - q(all-distinct-1.delegation02.xa), - [ qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP ) ], - undef, - [], - [], - ], - 'ALL-DISTINCT-2' => - [ - 1, - q(all-distinct-2.delegation02.xa), - [ qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP ) ], - undef, - [], - [], - ], - 'ALL-DISTINCT-3' => - [ - 1, - q(all-distinct-3.delegation02.xa), - [ qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP ) ], - undef, - [], - [], - ], - 'DEL-NON-DISTINCT' => - [ - 0, - q(del-non-distinct.delegation02.xa), - [ qw( DEL_NS_SAME_IP CHILD_DISTINCT_NS_IP ) ], - undef, - [], - [], - ], - 'DEL-NON-DISTINCT-UND' => - [ - 1, - q(del-non-distinct.delegation02.xa), - [ qw( DEL_NS_SAME_IP CHILD_DISTINCT_NS_IP ) ], - undef, - [ qw( - ns1a.del-non-distinct-und.delegation02.xa/127.16.2.31 - ns1a.del-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 - ns1b.del-non-distinct-und.delegation02.xa/127.16.2.31 - ns1b.del-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 - ) - ], - [], - ], - 'CHILD-NON-DISTINCT' => - [ - 0, - q(child-non-distinct.delegation02.xa), - [ qw( DEL_DISTINCT_NS_IP CHILD_NS_SAME_IP ) ], - undef, - [], - [], - ], - 'CHILD-NON-DISTINCT-UND' => - [ - 1, - q(child-non-distinct.delegation02.xa), - [ qw( DEL_DISTINCT_NS_IP CHILD_NS_SAME_IP ) ], - undef, - [ qw( - ns1a.child-non-distinct-und.delegation02.xa/127.16.2.31 - ns1a.child-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 - ns1b.child-non-distinct-und.delegation02.xa/127.16.2.32 - ns1b.child-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:32 - ) - ], - [], - ], - 'NON-DISTINCT-1' => - [ - 1, - q(non-distinct-1.delegation02.xa), - [ qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP ) ], - undef, - [], - [], - ], - 'NON-DISTINCT-2' => - [ - 1, - q(non-distinct-2.delegation02.xa), - [ qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP ) ], - undef, - [], - [], - ], - 'NON-DISTINCT-3' => - [ - 1, - q(non-distinct-3.delegation02.xa), - [ qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP ) ], - undef, - [], - [], - ], - ); + 'ALL-DISTINCT-1' => + [ 1, q(all-distinct-1.delegation02.xa), [qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP )], undef, [], [] ], + 'ALL-DISTINCT-2' => + [ 1, q(all-distinct-2.delegation02.xa), [qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP )], undef, [], [] ], + 'ALL-DISTINCT-3' => + [ 1, q(all-distinct-3.delegation02.xa), [qw( DEL_DISTINCT_NS_IP CHILD_DISTINCT_NS_IP )], undef, [], [] ], + 'DEL-NON-DISTINCT' => + [ 0, q(del-non-distinct.delegation02.xa), [qw( DEL_NS_SAME_IP CHILD_DISTINCT_NS_IP )], undef, [], [] ], + 'DEL-NON-DISTINCT-UND' => [ + 1, + q(del-non-distinct.delegation02.xa), + [qw( DEL_NS_SAME_IP CHILD_DISTINCT_NS_IP )], + undef, + [ + qw( + ns1a.del-non-distinct-und.delegation02.xa/127.16.2.31 + ns1a.del-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 + ns1b.del-non-distinct-und.delegation02.xa/127.16.2.31 + ns1b.del-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 + ) + ], + [], + ], + 'CHILD-NON-DISTINCT' => [ + 0, + q(child-non-distinct.delegation02.xa), + [qw( DEL_DISTINCT_NS_IP CHILD_NS_SAME_IP )], + undef, + [], + [], + ], + 'CHILD-NON-DISTINCT-UND' => [ + 1, + q(child-non-distinct.delegation02.xa), + [qw( DEL_DISTINCT_NS_IP CHILD_NS_SAME_IP )], + undef, + [ + qw( + ns1a.child-non-distinct-und.delegation02.xa/127.16.2.31 + ns1a.child-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:31 + ns1b.child-non-distinct-und.delegation02.xa/127.16.2.32 + ns1b.child-non-distinct-und.delegation02.xa/fda1:b2:c3:0:127:16:2:32 + ) + ], + [], + ], + 'NON-DISTINCT-1' => [ + 1, + q(non-distinct-1.delegation02.xa), + [qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP )], + undef, + [], + [], + ], + 'NON-DISTINCT-2' => [ + 1, + q(non-distinct-2.delegation02.xa), + [qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP )], + undef, + [], + [], + ], + 'NON-DISTINCT-3' => [ + 1, + q(non-distinct-3.delegation02.xa), + [qw( DEL_NS_SAME_IP CHILD_NS_SAME_IP )], + undef, + [], + [], + ], +); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -159,9 +129,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-delegation03.t b/t/Test-delegation03.t index e63858813..94ede19e2 100644 --- a/t/Test-delegation03.t +++ b/t/Test-delegation03.t @@ -15,18 +15,20 @@ BEGIN { ########### # Delegation03 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Delegation-TP/delegation03.md my $test_module = 'Delegation'; -my $test_case = 'delegation03'; -my @all_tags = qw( - REFERRAL_SIZE_OK - REFERRAL_SIZE_TOO_LARGE - ); +my $test_case = 'delegation03'; +my @all_tags = qw( + REFERRAL_SIZE_OK + REFERRAL_SIZE_TOO_LARGE +); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/Delegation-TP/delegation03/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'root-ns1.xa' => [ '127.16.3.27', 'fda1:b2:c3::127:16:3:27' ], - 'root-ns2.xa' => [ '127.16.3.28', 'fda1:b2:c3::127:16:3:28' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'root-ns1.xa' => [ '127.16.3.27', 'fda1:b2:c3::127:16:3:27' ], + 'root-ns2.xa' => [ '127.16.3.28', 'fda1:b2:c3::127:16:3:28' ], + }, ); # Test zone scenarios @@ -44,46 +46,16 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'REFERRAL-SIZE-OK-1' => - [ - 1, - q(referral-size-ok-1.delegation03.xa.), - [ qw( REFERRAL_SIZE_OK ) ], - undef, - [], - [], - ], - 'REFERRAL-SIZE-OK-2' => - [ - 1, - q(referral-size-ok-2.delegation03.xa.), - [ qw( REFERRAL_SIZE_OK ) ], - undef, - [], - [], - ], - 'REFERRAL-SIZE-TOO-LARGE-1' => - [ - 1, - q(referral-size-too-large-1.delegation03.xa), - [ qw( REFERRAL_SIZE_TOO_LARGE ) ], - undef, - [], - [], - ], - 'REFERRAL-SIZE-TOO-LARGE-2' => - [ - 1, - q(referral-size-too-large-2.delegation03.xa), - [ qw( REFERRAL_SIZE_TOO_LARGE ) ], - undef, - [], - [], - ], - ); + 'REFERRAL-SIZE-OK-1' => [ 1, q(referral-size-ok-1.delegation03.xa.), [qw( REFERRAL_SIZE_OK )], undef, [], [] ], + 'REFERRAL-SIZE-OK-2' => [ 1, q(referral-size-ok-2.delegation03.xa.), [qw( REFERRAL_SIZE_OK )], undef, [], [] ], + 'REFERRAL-SIZE-TOO-LARGE-1' => + [ 1, q(referral-size-too-large-1.delegation03.xa), [qw( REFERRAL_SIZE_TOO_LARGE )], undef, [], [] ], + 'REFERRAL-SIZE-TOO-LARGE-2' => + [ 1, q(referral-size-too-large-2.delegation03.xa), [qw( REFERRAL_SIZE_TOO_LARGE )], undef, [], [] ], +); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -91,9 +63,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec-more.t b/t/Test-dnssec-more.t index 7ed18bd58..7bc749cee 100644 --- a/t/Test-dnssec-more.t +++ b/t/Test-dnssec-more.t @@ -37,7 +37,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); $json = read_file( 't/profiles/Test-dnssec-more-all.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); @@ -61,13 +61,13 @@ SKIP: { skip "Need to configure another zone for this test cases.", 3; $zone = Zonemaster::Engine->zone( 'wwwyahoo.se' ); - zone_gives( 'dnssec10', $zone, ['INVALID_NAME_RCODE']); + zone_gives( 'dnssec10', $zone, ['INVALID_NAME_RCODE'] ); $zone = Zonemaster::Engine->zone( 'denki.se' ); - zone_gives( 'dnssec10', $zone, ['NSEC3_COVERS_NOT']); + zone_gives( 'dnssec10', $zone, ['NSEC3_COVERS_NOT'] ); $zone = Zonemaster::Engine->zone( 'retailacademicsconsulting.se' ); - zone_gives( 'dnssec10', $zone, ['NSEC3_SIG_VERIFY_ERROR']); + zone_gives( 'dnssec10', $zone, ['NSEC3_SIG_VERIFY_ERROR'] ); } $zone = Zonemaster::Engine->zone( 'y.nu' ); diff --git a/t/Test-dnssec.t b/t/Test-dnssec.t index 1e6406efc..be1b794c4 100644 --- a/t/Test-dnssec.t +++ b/t/Test-dnssec.t @@ -23,7 +23,8 @@ sub zone_gives { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( ( grep { $_->tag eq $gives } @res ), $zone->name->string . " gives $gives" ); } @@ -34,7 +35,8 @@ sub zone_gives_not { my ( $test, $zone, $gives_ref ) = @_; Zonemaster::Engine->logger->clear_history(); - my @res = grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); + my @res = + grep { $_->tag !~ /^TEST_CASE_(END|START)$/ } Zonemaster::Engine->test_method( $checking_module, $test, $zone ); foreach my $gives ( @{$gives_ref} ) { ok( !( grep { $_->tag eq $gives } @res ), $zone->name->string . " does not give $gives" ); } @@ -49,19 +51,22 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { } # Find a way for dnssec06 which has a dependence... -my ($json, $profile_test); -foreach my $testcase ( qw{dnssec01 dnssec02 dnssec04 dnssec05 dnssec07 dnssec08 dnssec09 dnssec10 dnssec11 dnssec13 dnssec14 dnssec15 dnssec17 dnssec18} ) { - $json = read_file( 't/profiles/Test-'.$testcase.'-only.json' ); +my ( $json, $profile_test ); +foreach my $testcase ( + qw{dnssec01 dnssec02 dnssec04 dnssec05 dnssec07 dnssec08 dnssec09 dnssec10 dnssec11 dnssec13 dnssec14 dnssec15 dnssec17 dnssec18} + ) +{ + $json = read_file( 't/profiles/Test-' . $testcase . '-only.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my %testcases; Zonemaster::Engine->logger->clear_history(); foreach my $result ( Zonemaster::Engine->test_module( q{dnssec}, q{se} ) ) { if ( $result->testcase && $result->testcase ne 'Unspecified' ) { - $testcases{$result->testcase} = 1; + $testcases{ $result->testcase } = 1; } } - eq_or_diff( [ map { lc $_ } keys %testcases ], [ $testcase ], 'expected test-case ('. $testcase .')' ); + eq_or_diff( [ map { lc $_ } keys %testcases ], [$testcase], 'expected test-case (' . $testcase . ')' ); } $json = read_file( 't/profiles/Test-dnssec-all.json' ); @@ -86,23 +91,55 @@ zone_gives( 'dnssec06', $zone, [q{EXTRA_PROCESSING_OK}] ); ########### $zone = Zonemaster::Engine->zone( 'dnssec02-dnskey-ksk-not-sep.zut-root.rd.nic.fr' ); zone_gives( 'dnssec02', $zone, [qw{DS02_DNSKEY_NOT_SEP}] ); -zone_gives_not( 'dnssec02', $zone, [qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCHING_DNSKEY_RRSIG DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}] ); +zone_gives_not( + 'dnssec02', + $zone, + [ + qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCHING_DNSKEY_RRSIG DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec02-no-common-keytags.zut-root.rd.nic.fr' ); zone_gives( 'dnssec02', $zone, [qw{DS02_NO_DNSKEY_FOR_DS DS02_NO_VALID_DNSKEY_FOR_ANY_DS}] ); -zone_gives_not( 'dnssec02', $zone, [qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_MATCHING_DNSKEY_RRSIG DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}] ); +zone_gives_not( + 'dnssec02', + $zone, + [ + qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_MATCHING_DNSKEY_RRSIG DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-not-signed.zut-root.rd.nic.fr' ); zone_gives( 'dnssec02', $zone, [qw{DS02_NO_MATCHING_DNSKEY_RRSIG DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}] ); -zone_gives_not( 'dnssec02', $zone, [qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS}] ); +zone_gives_not( + 'dnssec02', + $zone, + [ + qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCH_DS_DNSKEY DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec02-ds-does-not-match-dnskey.zut-root.rd.nic.fr' ); zone_gives( 'dnssec02', $zone, [qw{DS02_NO_MATCH_DS_DNSKEY}] ); -zone_gives_not( 'dnssec02', $zone, [qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCHING_DNSKEY_RRSIG DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}] ); +zone_gives_not( + 'dnssec02', + $zone, + [ + qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCHING_DNSKEY_RRSIG DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-signature-not-ok-broken.zut-root.rd.nic.fr' ); -zone_gives( 'dnssec02', $zone, [qw{DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_MATCHING_DNSKEY_RRSIG DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}] ); -zone_gives_not( 'dnssec02', $zone, [qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCH_DS_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS}] ); +zone_gives( 'dnssec02', $zone, + [qw{DS02_RRSIG_NOT_VALID_BY_DNSKEY DS02_NO_MATCHING_DNSKEY_RRSIG DS02_DNSKEY_NOT_SIGNED_BY_ANY_DS}], +); +zone_gives_not( + 'dnssec02', + $zone, + [ + qw{DS02_ALGO_NOT_SUPPORTED_BY_ZM DS02_DNSKEY_NOT_FOR_ZONE_SIGNING DS02_DNSKEY_NOT_SEP DS02_NO_DNSKEY_FOR_DS DS02_NO_MATCH_DS_DNSKEY DS02_NO_VALID_DNSKEY_FOR_ANY_DS} + ], +); ########### # dnssec04 @@ -137,45 +174,105 @@ zone_gives_not( 'dnssec06', $zone, [q{EXTRA_PROCESSING_OK}] ); ########### $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-signature-not-ok-broken.zut-root.rd.nic.fr' ); zone_gives( 'dnssec08', $zone, [qw{DS08_DNSKEY_RRSIG_EXPIRED DS08_RRSIG_NOT_VALID_BY_DNSKEY}] ); -zone_gives_not( 'dnssec08', $zone, [qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY}] ); +zone_gives_not( + 'dnssec08', + $zone, + [ + qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-signature-not-ok.zut-root.rd.nic.fr' ); -zone_gives_not( 'dnssec08', $zone, [qw{DS08_DNSKEY_RRSIG_EXPIRED DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY}] ); +zone_gives_not( + 'dnssec08', + $zone, + [ + qw{DS08_DNSKEY_RRSIG_EXPIRED DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-not-signed.zut-root.rd.nic.fr' ); zone_gives( 'dnssec08', $zone, [q{DS08_MISSING_RRSIG_IN_RESPONSE}] ); -zone_gives_not( 'dnssec08', $zone, [qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY}] ); +zone_gives_not( + 'dnssec08', + $zone, + [ + qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-dnskey-rrsig-not-yet-valid.zft-root.rd.nic.fr' ); zone_gives( 'dnssec08', $zone, [q{DS08_DNSKEY_RRSIG_NOT_YET_VALID}] ); -zone_gives_not( 'dnssec08', $zone, [qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY}] ); +zone_gives_not( + 'dnssec08', + $zone, + [ + qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_MISSING_RRSIG_IN_RESPONSE DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec08-rrsig-no-matching-dnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec08', $zone, [qw{DS08_NO_MATCHING_DNSKEY DS08_RRSIG_NOT_VALID_BY_DNSKEY}] ); -zone_gives_not( 'dnssec08', $zone, [qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE}] ); +zone_gives_not( + 'dnssec08', + $zone, + [ + qw{DS08_ALGO_NOT_SUPPORTED_BY_ZM DS08_DNSKEY_RRSIG_EXPIRED DS08_DNSKEY_RRSIG_NOT_YET_VALID DS08_MISSING_RRSIG_IN_RESPONSE} + ], +); ########### # dnssec09 ########### $zone = Zonemaster::Engine->zone( 'dnssec09-soa-rrsig-not-yet-valid.zft-root.rd.nic.fr' ); zone_gives( 'dnssec09', $zone, [qw{DS09_SOA_RRSIG_NOT_YET_VALID}] ); -zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED}] ); +zone_gives_not( + 'dnssec09', + $zone, + [ + qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec09-rrsig-no-matching-dnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec09', $zone, [qw{DS09_NO_MATCHING_DNSKEY}] ); -zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID}] ); +zone_gives_not( + 'dnssec09', + $zone, + [ + qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec09-soa-not-signed.zft-root.rd.nic.fr' ); zone_gives( 'dnssec09', $zone, [qw{DS09_MISSING_RRSIG_IN_RESPONSE}] ); -zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID}] ); +zone_gives_not( + 'dnssec09', + $zone, + [ + qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec09-soa-rrsig-expired.zft-root.rd.nic.fr' ); zone_gives( 'dnssec09', $zone, [qw{DS09_SOA_RRSIG_EXPIRED}] ); -zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_NOT_YET_VALID}] ); +zone_gives_not( + 'dnssec09', + $zone, + [ + qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_RRSIG_NOT_VALID_BY_DNSKEY DS09_SOA_RRSIG_NOT_YET_VALID} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec09-rrsig-not-valid-by-dnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec09', $zone, [qw{DS09_RRSIG_NOT_VALID_BY_DNSKEY}] ); -zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID}] ); +zone_gives_not( + 'dnssec09', + $zone, + [ + qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSING_RRSIG_IN_RESPONSE DS09_NO_MATCHING_DNSKEY DS09_SOA_RRSIG_EXPIRED DS09_SOA_RRSIG_NOT_YET_VALID} + ], +); ########### # dnssec10 -- See t/Test-dnssec10.t instead. @@ -195,37 +292,62 @@ zone_gives_not( 'dnssec09', $zone, [qw{DS09_ALGO_NOT_SUPPORTED_BY_ZM DS09_MISSIN ########### $zone = Zonemaster::Engine->zone( 'zone-does-not-exist.zut-root.rd.nic.fr' ); zone_gives( 'dnssec11', $zone, [qw{DS11_UNDETERMINED_DS}] ); -zone_gives_not( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_DS DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_DS_BUT_UNSIGNED_ZONE}] ); +zone_gives_not( + 'dnssec11', + $zone, + [ + qw{DS11_INCONSISTENT_DS DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_DS_BUT_UNSIGNED_ZONE} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec11-inconsistent-ds.dnssec11-parent.zft-root.rd.nic.fr' ); zone_gives( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_DS DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS}] ); -zone_gives_not( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_DS_BUT_UNSIGNED_ZONE}] ); +zone_gives_not( + 'dnssec11', + $zone, + [ + qw{DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_DS_BUT_UNSIGNED_ZONE} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec11-ds-but-unsigned.zft-root.rd.nic.fr' ); zone_gives( 'dnssec11', $zone, [qw{DS11_DS_BUT_UNSIGNED_ZONE}] ); -zone_gives_not( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_DS DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE}] ); +zone_gives_not( + 'dnssec11', + $zone, + [ + qw{DS11_INCONSISTENT_DS DS11_INCONSISTENT_SIGNED_ZONE DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_NS_WITH_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec11-inconsistent-dnskey.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_NS_WITH_SIGNED_ZONE}] ); -zone_gives_not( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_DS DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_DS_BUT_UNSIGNED_ZONE}] ); +zone_gives( 'dnssec11', $zone, [qw{DS11_INCONSISTENT_SIGNED_ZONE DS11_NS_WITH_UNSIGNED_ZONE DS11_NS_WITH_SIGNED_ZONE}], +); +zone_gives_not( + 'dnssec11', + $zone, + [ + qw{DS11_INCONSISTENT_DS DS11_UNDETERMINED_DS DS11_UNDETERMINED_SIGNED_ZONE DS11_PARENT_WITHOUT_DS DS11_PARENT_WITH_DS DS11_DS_BUT_UNSIGNED_ZONE} + ], +); ########### # dnssec13 ########### $zone = Zonemaster::Engine->zone( 'dnssec13-algo-not-signed-dnskey.zft-root.rd.nic.fr' ); -zone_gives_not('dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_NS DS13_ALGO_NOT_SIGNED_SOA}] ); +zone_gives_not( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_NS DS13_ALGO_NOT_SIGNED_SOA}] ); $zone = Zonemaster::Engine->zone( 'dnssec13-algo-not-signed-ns.zft-root.rd.nic.fr' ); zone_gives( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_NS}] ); -zone_gives_not('dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_SOA}] ); +zone_gives_not( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_SOA}] ); $zone = Zonemaster::Engine->zone( 'dnssec13-algo-not-signed-soa.zft-root.rd.nic.fr' ); zone_gives( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_SOA}] ); -zone_gives_not('dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_NS}] ); +zone_gives_not( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_NS}] ); $zone = Zonemaster::Engine->zone( 'afnic.fr' ); -zone_gives_not('dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_NS DS13_ALGO_NOT_SIGNED_SOA}] ); +zone_gives_not( 'dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_SIGNED_NS DS13_ALGO_NOT_SIGNED_SOA}] ); ########### # dnssec15 @@ -233,63 +355,153 @@ zone_gives_not('dnssec13', $zone, [qw{DS13_ALGO_NOT_SIGNED_DNSKEY DS13_ALGO_NOT_ $zone = Zonemaster::Engine->zone( 'dnssec15-no-cds-no-cdnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_NO_CDS_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-cds-no-cdnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_HAS_CDS_NO_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-cdnskey-no-cds.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_HAS_CDNSKEY_NO_CDS}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-cds-cdnskey-01.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_HAS_CDS_AND_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-cds-cdnskey-02.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_HAS_CDS_AND_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-cds-cdnskey-03.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [q{DS15_HAS_CDS_AND_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cds-01.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cds-02.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cds-03.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cds-04.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_AND_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cdnskey-01.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_INCONSISTENT_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cdnskey-02.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_INCONSISTENT_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cdnskey-03.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_INCONSISTENT_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-inconsistent-cdnskey-04.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_INCONSISTENT_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDS_AND_CDNSKEY DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDS DS15_MISMATCH_CDS_CDNSKEY DS15_NO_CDS_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec15-mismatch-cds-cdnskey.zft-root.rd.nic.fr' ); zone_gives( 'dnssec15', $zone, [qw{DS15_HAS_CDS_AND_CDNSKEY DS15_MISMATCH_CDS_CDNSKEY}] ); -zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_NO_CDS_CDNSKEY}] ); +zone_gives_not( + 'dnssec15', + $zone, + [ + qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CDNSKEY DS15_INCONSISTENT_CDNSKEY DS15_INCONSISTENT_CDS DS15_NO_CDS_CDNSKEY} + ], +); ########### # dnssec16 -- See t/Test-dnssec16.t instead. @@ -300,84 +512,151 @@ zone_gives_not('dnssec15', $zone, [qw{DS15_HAS_CDNSKEY_NO_CDS DS15_HAS_CDS_NO_CD ########### $zone = Zonemaster::Engine->zone( 'dnssec16-cds-cdnskey-signed.zft-root.rd.nic.fr' ); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec16-cds-cdnskey-unsigned.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [qw{DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [qw{DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec16-cds-cdnskey-invalid-rrsig-01.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_INVALID_RRSIG}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_INVALID_RRSIG}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec16-cds-cdnskey-invalid-rrsig-02.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_INVALID_RRSIG}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_INVALID_RRSIG}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-cdnskey-unsigned.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [qw{DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_UNSIGNED}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, + [qw{DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_UNSIGNED}], +); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec16-cds-without-dnskey.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_WITHOUT_DNSKEY}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_WITHOUT_DNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-cdnskey-signed-by-unknown-dnskey.zft-root.rd.nic.fr' ); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-cdnskey-matches-no-dnskey.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [qw{DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_IS_NON_SEP}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [qw{DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_IS_NON_SEP}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-delete-cdnskey.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_DELETE_CDNSKEY}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_DELETE_CDNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-mixed-delete-cdnskey.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_MIXED_DELETE_CDNSKEY}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_IS_NON_ZONE DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY} + ], +); $zone = Zonemaster::Engine->zone( 'dnssec17-cdnskey-is-non-zone.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_IS_NON_ZONE}]); -zone_gives_not('dnssec17', $zone, [qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY}] ); +zone_gives( 'dnssec17', $zone, [q{DS17_CDNSKEY_IS_NON_ZONE}] ); +zone_gives_not( + 'dnssec17', + $zone, + [ + qw{DS17_CDNSKEY_INVALID_RRSIG DS17_CDNSKEY_IS_NON_SEP DS17_CDNSKEY_MATCHES_NO_DNSKEY DS17_CDNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY DS17_CDNSKEY_UNSIGNED DS17_CDNSKEY_WITHOUT_DNSKEY DS17_DELETE_CDNSKEY DS17_DNSKEY_NOT_SIGNED_BY_CDNSKEY DS17_MIXED_DELETE_CDNSKEY} + ], +); ########### # dnssec18 ########### $zone = Zonemaster::Engine->zone( 'dnssec18-no-match-cds-rrsig-ds.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDS_RRSIG_DS}]); -zone_gives_not( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDNSKEY_RRSIG_DS}]); +zone_gives( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDS_RRSIG_DS}] ); +zone_gives_not( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDNSKEY_RRSIG_DS}] ); $zone = Zonemaster::Engine->zone( 'dnssec18-no-match-cdnskey-rrsig-ds.zft-root.rd.nic.fr' ); -zone_gives( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDNSKEY_RRSIG_DS}]); -zone_gives_not( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDS_RRSIG_DS}]); +zone_gives( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDNSKEY_RRSIG_DS}] ); +zone_gives_not( 'dnssec18', $zone, [q{DS18_NO_MATCH_CDS_RRSIG_DS}] ); TODO: { local $TODO = "Need to find/create zones with that error"; # dnssec02 - ok( $tag{DS02_ALGO_NOT_SUPPORTED_BY_ZM}, q{DS02_ALGO_NOT_SUPPORTED_BY_ZM} ); + ok( $tag{DS02_ALGO_NOT_SUPPORTED_BY_ZM}, q{DS02_ALGO_NOT_SUPPORTED_BY_ZM} ); ok( $tag{DS02_DNSKEY_NOT_FOR_ZONE_SIGNING}, q{DS02_DNSKEY_NOT_FOR_ZONE_SIGNING} ); # dnssec06 ok( $tag{EXTRA_PROCESSING_BROKEN}, q{EXTRA_PROCESSING_BROKEN} ); local $TODO = "Need to check these zones with that error"; - # dnssec08: dnssec08-dnskey-signature-not-ok.zut-root.rd.nic.fr - # Commented out for now because zone doesn't give this message tag anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 - ok( $tag{DS08_RRSIG_NOT_VALID_BY_DNSKEY}, q{DS08_RRSIG_NOT_VALID_BY_DNSKEY}); +# dnssec08: dnssec08-dnskey-signature-not-ok.zut-root.rd.nic.fr +# Commented out for now because zone doesn't give this message tag anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 + ok( $tag{DS08_RRSIG_NOT_VALID_BY_DNSKEY}, q{DS08_RRSIG_NOT_VALID_BY_DNSKEY} ); - # dnssec13: dnssec13-algo-not-signed-dnskey.zft-root.rd.nic.fr - # Commented out for now because zone doesn't give this message tag anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 +# dnssec13: dnssec13-algo-not-signed-dnskey.zft-root.rd.nic.fr +# Commented out for now because zone doesn't give this message tag anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 ok( $tag{DS13_ALGO_NOT_SIGNED_DNSKEY}, q{DS13_ALGO_NOT_SIGNED_DNSKEY} ); - # dnssec17: dnssec17-cdnskey-signed-by-unknown-dnskey.zft-root.rd.nic.fr - # Commented out for now because zone doesn't give these message tags anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 - ok( $tag{DS17_CDNSKEY_IS_NON_SEP}, q{DS17_CDNSKEY_IS_NON_SEP} ); +# dnssec17: dnssec17-cdnskey-signed-by-unknown-dnskey.zft-root.rd.nic.fr +# Commented out for now because zone doesn't give these message tags anymore. Reason unknown, investigation required. See https://github.com/zonemaster/zonemaster-engine/pull/1147#issuecomment-1318896623 + ok( $tag{DS17_CDNSKEY_IS_NON_SEP}, q{DS17_CDNSKEY_IS_NON_SEP} ); ok( $tag{DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY}, q{DS17_CDNSKEY_SIGNED_BY_UNKNOWN_DNSKEY} ); - -} +} ## end TODO: if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec01.t b/t/Test-dnssec01.t index 3274ddc7f..ef1199e1b 100644 --- a/t/Test-dnssec01.t +++ b/t/Test-dnssec01.t @@ -15,28 +15,30 @@ BEGIN { ########### # DNSSEC01 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec01.md my $test_module = 'DNSSEC'; -my $test_case = 'dnssec01'; -my @all_tags = qw( - DS01_DS_ALGO_2_MISSING - DS01_DS_ALGO_DEPRECATED - DS01_DS_ALGO_NOT_DS - DS01_DS_ALGO_OK - DS01_DS_ALGO_PRIVATE - DS01_DS_ALGO_RESERVED - DS01_DS_ALGO_UNASSIGNED - DS01_NO_RESPONSE - DS01_PARENT_SERVER_NO_DS - DS01_PARENT_ZONE_NO_DS - DS01_ROOT_N_NO_UNDEL_DS - DS01_UNDEL_N_NO_UNDEL_DS - ); +my $test_case = 'dnssec01'; +my @all_tags = qw( + DS01_DS_ALGO_2_MISSING + DS01_DS_ALGO_DEPRECATED + DS01_DS_ALGO_NOT_DS + DS01_DS_ALGO_OK + DS01_DS_ALGO_PRIVATE + DS01_DS_ALGO_RESERVED + DS01_DS_ALGO_UNASSIGNED + DS01_NO_RESPONSE + DS01_PARENT_SERVER_NO_DS + DS01_PARENT_ZONE_NO_DS + DS01_ROOT_N_NO_UNDEL_DS + DS01_UNDEL_N_NO_UNDEL_DS +); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/DNSSEC-TP/dnssec01/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'root-ns1.xa' => [ '127.15.1.27', 'fda1:b2:c3::127:15:1:27' ], - 'root-ns2.xa' => [ '127.15.1.28', 'fda1:b2:c3::127:15:1:28' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'root-ns1.xa' => [ '127.15.1.27', 'fda1:b2:c3::127:15:1:27' ], + 'root-ns2.xa' => [ '127.15.1.28', 'fda1:b2:c3::127:15:1:28' ], + }, ); # Test zone scenarios @@ -54,218 +56,71 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'ALGO-DEPRECATED-1' => [ - 1, - q(algo-deprecated-1.dnssec01.xa), - [ qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-3' => [ - 1, - q(algo-deprecated-3.dnssec01.xa), - [ qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-NOT-DS-0' => [ - 1, - q(algo-not-ds-0.dnssec01.xa), - [ qw( DS01_DS_ALGO_NOT_DS DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-OK-2' => [ - 1, - q(algo-ok-2.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-4' => [ - 1, - q(algo-ok-4.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-OK-5' => [ - 1, - q(algo-ok-5.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-OK-6' => [ - 1, - q(algo-ok-6.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-PRIVATE-253' => [ - 1, - q(algo-private-253.dnssec01.xa), - [ qw( DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-PRIVATE-254' => [ - 1, - q(algo-private-254.dnssec01.xa), - [ qw( DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-128' => [ - 1, - q(algo-reserved-128.dnssec01.xa), - [ qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-188' => [ - 1, - q(algo-reserved-188.dnssec01.xa), - [ qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-252' => [ - 1, - q(algo-reserved-252.dnssec01.xa), - [ qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-UNASSIGNED-7' => [ - 1, - q(algo-unassigned-7.dnssec01.xa), - [ qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-UNASSIGNED-67' => [ - 1, - q(algo-unassigned-67.dnssec01.xa), - [ qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], - 'ALGO-UNASSIGNED-127' => [ - 1, - q(algo-unassigned-127.dnssec01.xa), - [ qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING ) ], - undef, - [], - [], - ], + 'ALGO-DEPRECATED-1' => + [ 1, q(algo-deprecated-1.dnssec01.xa), [qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-DEPRECATED-3' => + [ 1, q(algo-deprecated-3.dnssec01.xa), [qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-NOT-DS-0' => + [ 1, q(algo-not-ds-0.dnssec01.xa), [qw( DS01_DS_ALGO_NOT_DS DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-OK-2' => [ 1, q(algo-ok-2.dnssec01.xa), [qw( DS01_DS_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-4' => [ 1, q(algo-ok-4.dnssec01.xa), [qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-OK-5' => [ 1, q(algo-ok-5.dnssec01.xa), [qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-OK-6' => [ 1, q(algo-ok-6.dnssec01.xa), [qw( DS01_DS_ALGO_OK DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-PRIVATE-253' => + [ 1, q(algo-private-253.dnssec01.xa), [qw( DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-PRIVATE-254' => + [ 1, q(algo-private-254.dnssec01.xa), [qw( DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-RESERVED-128' => + [ 1, q(algo-reserved-128.dnssec01.xa), [qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-RESERVED-188' => + [ 1, q(algo-reserved-188.dnssec01.xa), [qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-RESERVED-252' => + [ 1, q(algo-reserved-252.dnssec01.xa), [qw( DS01_DS_ALGO_RESERVED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-UNASSIGNED-7' => + [ 1, q(algo-unassigned-7.dnssec01.xa), [qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-UNASSIGNED-67' => + [ 1, q(algo-unassigned-67.dnssec01.xa), [qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], + 'ALGO-UNASSIGNED-127' => + [ 1, q(algo-unassigned-127.dnssec01.xa), [qw( DS01_DS_ALGO_UNASSIGNED DS01_DS_ALGO_2_MISSING )], undef, [], [] ], 'MIXED-ALGO-1' => [ - 1, - q(mixed-algo-1.dnssec01.xa), - [ qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_OK ) ], - undef, - [], - [], - ], - 'SHARED-IP-1' => [ - 1, - q(child.shared-ip-1.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK ) ], - undef, - [], - [], - ], - 'SHARED-IP-2' => [ - 1, - q(child.shared-ip-2.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK ) ], - undef, - [], - [], - ], - 'NO-RESPONSE-1' => [ - 1, - q(child.no-response-1.dnssec01.xa), - [ qw( DS01_NO_RESPONSE ) ], - undef, - [], - [], - ], - 'NO-VALID-RESPONSE-1' => [ - 1, - q(child.no-valid-response-1.dnssec01.xa), - [ qw( DS01_NO_RESPONSE ) ], - undef, - [], - [], + 1, q(mixed-algo-1.dnssec01.xa), [qw( DS01_DS_ALGO_DEPRECATED DS01_DS_ALGO_PRIVATE DS01_DS_ALGO_OK )], + undef, [], [], ], + 'SHARED-IP-1' => [ 1, q(child.shared-ip-1.dnssec01.xa), [qw( DS01_DS_ALGO_OK )], undef, [], [] ], + 'SHARED-IP-2' => [ 1, q(child.shared-ip-2.dnssec01.xa), [qw( DS01_DS_ALGO_OK )], undef, [], [] ], + 'NO-RESPONSE-1' => [ 1, q(child.no-response-1.dnssec01.xa), [qw( DS01_NO_RESPONSE )], undef, [], [] ], + 'NO-VALID-RESPONSE-1' => [ 1, q(child.no-valid-response-1.dnssec01.xa), [qw( DS01_NO_RESPONSE )], undef, [], [] ], 'PARENT-SERVER-NO-DS-1' => [ 1, q(child.parent-server-no-ds-1.dnssec01.xa), - [ qw( DS01_PARENT_SERVER_NO_DS DS01_DS_ALGO_OK ) ], - undef, - [], - [], - ], - 'PARENT-ZONE-NO-DS-1' => [ - 1, - q(parent-zone-no-ds-1.dnssec01.xa), - [ qw( DS01_PARENT_ZONE_NO_DS ) ], - undef, - [], - [], + [qw( DS01_PARENT_SERVER_NO_DS DS01_DS_ALGO_OK )], + undef, [], [], ], + 'PARENT-ZONE-NO-DS-1' => [ 1, q(parent-zone-no-ds-1.dnssec01.xa), [qw( DS01_PARENT_ZONE_NO_DS )], undef, [], [] ], 'UNDEL-NO-UNDEL-DS-1' => [ 1, q(undel-no-undel-ds-1.dnssec01.xa), - [ qw( DS01_UNDEL_N_NO_UNDEL_DS ) ], + [qw( DS01_UNDEL_N_NO_UNDEL_DS )], undef, - [ qw( ns1.undel-no-undel-ds-1.dnssec01.xa/127.15.1.41 ns1.undel-no-undel-ds-1.dnssec01.xa/fda1:b2:c3:0:127:15:1:41 ns2.undel-no-undel-ds-1.dnssec01.xa/127.15.1.42 ns2.undel-no-undel-ds-1.dnssec01.xa/fda1:b2:c3:0:127:15:1:42 ) ], + [ + qw( ns1.undel-no-undel-ds-1.dnssec01.xa/127.15.1.41 ns1.undel-no-undel-ds-1.dnssec01.xa/fda1:b2:c3:0:127:15:1:41 ns2.undel-no-undel-ds-1.dnssec01.xa/127.15.1.42 ns2.undel-no-undel-ds-1.dnssec01.xa/fda1:b2:c3:0:127:15:1:42 ) + ], [], ], 'UNDEL-WITH-UNDEL-DS-1' => [ - 1, - q(undel-with-undel-ds-1.dnssec01.xa), - [ qw( DS01_DS_ALGO_OK ) ], - undef, - [], - [ '42581,13,2,F28391C1ED4DC0F151EDD251A3103DCE0B9A5A251ACF6E24073771D71F3C40F9' ], - ], - 'ROOT-NO-UNDEL-DS-1' => [ - 1, - q(.), - [ qw( DS01_ROOT_N_NO_UNDEL_DS ) ], - undef, - [], - [], + 1, q(undel-with-undel-ds-1.dnssec01.xa), + [qw( DS01_DS_ALGO_OK )], undef, [], + ['42581,13,2,F28391C1ED4DC0F151EDD251A3103DCE0B9A5A251ACF6E24073771D71F3C40F9'], ], + 'ROOT-NO-UNDEL-DS-1' => [ 1, q(.), [qw( DS01_ROOT_N_NO_UNDEL_DS )], undef, [], [] ], 'ROOT-WITH-UNDEL-DS-1' => [ - 1, - q(.), - [ qw( DS01_DS_ALGO_OK ) ], - undef, - [], - [ '42581,13,2,F28391C1ED4DC0F151EDD251A3103DCE0B9A5A251ACF6E24073771D71F3C40F9' ], + 1, q(.), [qw( DS01_DS_ALGO_OK )], undef, [], + ['42581,13,2,F28391C1ED4DC0F151EDD251A3103DCE0B9A5A251ACF6E24073771D71F3C40F9'], ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -273,9 +128,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec03.t b/t/Test-dnssec03.t index ad619e16d..ef0f1d44e 100644 --- a/t/Test-dnssec03.t +++ b/t/Test-dnssec03.t @@ -16,35 +16,37 @@ BEGIN { ########### # dnssec03 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec03.md my $test_module = q{DNSSEC}; -my $test_case = 'dnssec03'; -my @all_tags = qw(DS03_NO_DNSSEC_SUPPORT - DS03_ERR_MULT_NSEC3 - DS03_ILLEGAL_HASH_ALGO - DS03_ILLEGAL_ITERATION_VALUE - DS03_ILLEGAL_SALT_LENGTH - DS03_INCONSISTENT_HASH_ALGO - DS03_INCONSISTENT_ITERATION - DS03_INCONSISTENT_NSEC3_FLAGS - DS03_INCONSISTENT_SALT_LENGTH - DS03_LEGAL_EMPTY_SALT - DS03_LEGAL_HASH_ALGO - DS03_LEGAL_ITERATION_VALUE - DS03_NO_NSEC3 - DS03_NSEC3_OPT_OUT_DISABLED - DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD - DS03_NSEC3_OPT_OUT_ENABLED_TLD - DS03_SERVER_NO_DNSSEC_SUPPORT - DS03_SERVER_NO_NSEC3 - DS03_UNASSIGNED_FLAG_USED - DS03_ERROR_RESPONSE_NSEC_QUERY - DS03_NO_RESPONSE_NSEC_QUERY); +my $test_case = 'dnssec03'; +my @all_tags = qw(DS03_NO_DNSSEC_SUPPORT + DS03_ERR_MULT_NSEC3 + DS03_ILLEGAL_HASH_ALGO + DS03_ILLEGAL_ITERATION_VALUE + DS03_ILLEGAL_SALT_LENGTH + DS03_INCONSISTENT_HASH_ALGO + DS03_INCONSISTENT_ITERATION + DS03_INCONSISTENT_NSEC3_FLAGS + DS03_INCONSISTENT_SALT_LENGTH + DS03_LEGAL_EMPTY_SALT + DS03_LEGAL_HASH_ALGO + DS03_LEGAL_ITERATION_VALUE + DS03_NO_NSEC3 + DS03_NSEC3_OPT_OUT_DISABLED + DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD + DS03_NSEC3_OPT_OUT_ENABLED_TLD + DS03_SERVER_NO_DNSSEC_SUPPORT + DS03_SERVER_NO_NSEC3 + DS03_UNASSIGNED_FLAG_USED + DS03_ERROR_RESPONSE_NSEC_QUERY + DS03_NO_RESPONSE_NSEC_QUERY); # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -62,114 +64,109 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'NO-DNSSEC-SUPPORT' => [ - 1, - q(no-dnssec-support.dnssec03.xa), - [ qw(DS03_NO_DNSSEC_SUPPORT) ], - undef, - [], - [] - ], - 'NO-NSEC3' => [ - 1, - q(no-nsec3.dnssec03.xa), - [ qw(DS03_NO_NSEC3) ], - undef, - [], - [] - ], - 'GOOD-VALUES' => [ - 1, - q(good-values.dnssec03.xa), - [ qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) ], - undef, - [], - [] + 'NO-DNSSEC-SUPPORT' => [ 1, q(no-dnssec-support.dnssec03.xa), [qw(DS03_NO_DNSSEC_SUPPORT)], undef, [], [] ], + 'NO-NSEC3' => [ 1, q(no-nsec3.dnssec03.xa), [qw(DS03_NO_NSEC3)], undef, [], [] ], + 'GOOD-VALUES' => [ + 1, q(good-values.dnssec03.xa), + [qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED)], + undef, [], [], ], 'ERR-MULT-NSEC3' => [ 1, q(err-mult-nsec3.dnssec03.xa), - [ qw(DS03_ERR_MULT_NSEC3 DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) ], + [ + qw(DS03_ERR_MULT_NSEC3 DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) + ], undef, [], - [] + [], ], 'BAD-VALUES' => [ 1, q(bad-values.dnssec03.xa), - [ qw(DS03_ILLEGAL_HASH_ALGO DS03_ILLEGAL_ITERATION_VALUE DS03_ILLEGAL_SALT_LENGTH DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD) ], + [ + qw(DS03_ILLEGAL_HASH_ALGO DS03_ILLEGAL_ITERATION_VALUE DS03_ILLEGAL_SALT_LENGTH DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD) + ], undef, [], - [] + [], ], 'INCONSISTENT-VALUES' => [ 1, q(inconsistent-values.dnssec03.xa), undef, - [ qw(DS03_ERR_MULT_NSEC3 DS03_NO_DNSSEC_SUPPORT DS03_NO_NSEC3 DS03_NSEC3_OPT_OUT_ENABLED_TLD DS03_SERVER_NO_DNSSEC_SUPPORT DS03_SERVER_NO_NSEC3 DS03_UNASSIGNED_FLAG_USED DS03_ERROR_RESPONSE_NSEC_QUERY DS03_NO_RESPONSE_NSEC_QUERY) ], + [ + qw(DS03_ERR_MULT_NSEC3 DS03_NO_DNSSEC_SUPPORT DS03_NO_NSEC3 DS03_NSEC3_OPT_OUT_ENABLED_TLD DS03_SERVER_NO_DNSSEC_SUPPORT DS03_SERVER_NO_NSEC3 DS03_UNASSIGNED_FLAG_USED DS03_ERROR_RESPONSE_NSEC_QUERY DS03_NO_RESPONSE_NSEC_QUERY) + ], + [], [], - [] ], 'NSEC3-OPT-OUT-ENABLED-TLD' => [ 1, q(nsec3-opt-out-enabled-tld-dnssec03), - [ qw(DS03_NSEC3_OPT_OUT_ENABLED_TLD DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE) ], - undef, - [], - [] + [qw(DS03_NSEC3_OPT_OUT_ENABLED_TLD DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE)], + undef, [], [], ], 'SERVER-NO-DNSSEC-SUPPORT' => [ 1, q(server-no-dnssec-support.dnssec03.xa), - [ qw(DS03_SERVER_NO_DNSSEC_SUPPORT DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) ], + [ + qw(DS03_SERVER_NO_DNSSEC_SUPPORT DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) + ], undef, [], - [] + [], ], 'SERVER-NO-NSEC3' => [ 1, q(server-no-nsec3.dnssec03.xa), - [ qw(DS03_SERVER_NO_NSEC3 DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) ], + [ + qw(DS03_SERVER_NO_NSEC3 DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) + ], undef, [], - [] + [], ], 'UNASSIGNED-FLAG-USED' => [ 1, q(unassigned-flag-used.dnssec03.xa), - [ qw(DS03_UNASSIGNED_FLAG_USED DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) ], + [ + qw(DS03_UNASSIGNED_FLAG_USED DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED) + ], undef, [], - [] + [], ], 'ERROR-RESPONSE-NSEC-QUERY' => [ 1, q(error-response-nsec-query.dnssec03.xa), - [ qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED DS03_ERROR_RESPONSE_NSEC_QUERY) ], + [ + qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED DS03_ERROR_RESPONSE_NSEC_QUERY) + ], undef, [], - [] + [], ], 'NO-RESPONSE-NSEC-QUERY' => [ 1, q(no-response-nsec-query.dnssec03.xa), - [ qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED DS03_NO_RESPONSE_NSEC_QUERY) ], + [ + qw(DS03_LEGAL_EMPTY_SALT DS03_LEGAL_HASH_ALGO DS03_LEGAL_ITERATION_VALUE DS03_NSEC3_OPT_OUT_DISABLED DS03_NO_RESPONSE_NSEC_QUERY) + ], undef, [], - [] + [], ], 'ERROR-NSEC-QUERY' => [ 1, q(error-nsec-query.dnssec03.xa), - [ qw(DS03_ERROR_RESPONSE_NSEC_QUERY DS03_NO_RESPONSE_NSEC_QUERY) ], - undef, - [], - [] - ] + [qw(DS03_ERROR_RESPONSE_NSEC_QUERY DS03_NO_RESPONSE_NSEC_QUERY)], + undef, [], [], + ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -177,9 +174,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec05.t b/t/Test-dnssec05.t index 649febe42..45a79abcd 100644 --- a/t/Test-dnssec05.t +++ b/t/Test-dnssec05.t @@ -15,26 +15,28 @@ BEGIN { ########### # DNSSEC05 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec05.md my $test_module = 'DNSSEC'; -my $test_case = 'dnssec05'; -my @all_tags = qw( - DS05_ALGO_DEPRECATED - DS05_ALGO_NOT_RECOMMENDED - DS05_ALGO_NOT_ZONE_SIGN - DS05_ALGO_OK - DS05_ALGO_PRIVATE - DS05_ALGO_RESERVED - DS05_ALGO_UNASSIGNED - DS05_NO_RESPONSE - DS05_SERVER_NO_DNSSEC - DS05_ZONE_NO_DNSSEC - ); +my $test_case = 'dnssec05'; +my @all_tags = qw( + DS05_ALGO_DEPRECATED + DS05_ALGO_NOT_RECOMMENDED + DS05_ALGO_NOT_ZONE_SIGN + DS05_ALGO_OK + DS05_ALGO_PRIVATE + DS05_ALGO_RESERVED + DS05_ALGO_UNASSIGNED + DS05_NO_RESPONSE + DS05_SERVER_NO_DNSSEC + DS05_ZONE_NO_DNSSEC +); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/DNSSEC-TP/dnssec05/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'root-ns1.xa' => [ '127.15.5.27', 'fda1:b2:c3::127:15:5:27' ], - 'root-ns2.xa' => [ '127.15.5.28', 'fda1:b2:c3::127:15:5:28' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'root-ns1.xa' => [ '127.15.5.27', 'fda1:b2:c3::127:15:5:27' ], + 'root-ns2.xa' => [ '127.15.5.28', 'fda1:b2:c3::127:15:5:28' ], + }, ); # Test zone scenarios @@ -52,274 +54,51 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'ALGO-DEPRECATED-1' => [ - 1, - q(algo-deprecated-1.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-3' => [ - 1, - q(algo-deprecated-3.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-5' => [ - 1, - q(algo-deprecated-5.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-6' => [ - 1, - q(algo-deprecated-6.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-7' => [ - 1, - q(algo-deprecated-7.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-DEPRECATED-12' => [ - 1, - q(algo-deprecated-12.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED ) ], - undef, - [], - [], - ], - 'ALGO-NOT-RECOMMENDED-10' => [ - 1, - q(algo-not-recommended-10.dnssec05.xa), - [ qw( DS05_ALGO_NOT_RECOMMENDED ) ], - undef, - [], - [], - ], - 'ALGO-NOT-ZONE-SIGN-0' => [ - 1, - q(algo-not-zone-sign-0.dnssec05.xa), - [ qw( DS05_ALGO_NOT_ZONE_SIGN ) ], - undef, - [], - [], - ], - 'ALGO-NOT-ZONE-SIGN-2' => [ - 1, - q(algo-not-zone-sign-2.dnssec05.xa), - [ qw( DS05_ALGO_NOT_ZONE_SIGN ) ], - undef, - [], - [], - ], - 'ALGO-NOT-ZONE-SIGN-252' => [ - 1, - q(algo-not-zone-sign-252.dnssec05.xa), - [ qw( DS05_ALGO_NOT_ZONE_SIGN ) ], - undef, - [], - [], - ], - 'ALGO-OK-8' => [ - 1, - q(algo-ok-8.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-13' => [ - 1, - q(algo-ok-13.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-14' => [ - 1, - q(algo-ok-14.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-15' => [ - 1, - q(algo-ok-15.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-16' => [ - 1, - q(algo-ok-16.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-17' => [ - 1, - q(algo-ok-17.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-OK-23' => [ - 1, - q(algo-ok-23.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ALGO-PRIVATE-253' => [ - 1, - q(algo-private-253.dnssec05.xa), - [ qw( DS05_ALGO_PRIVATE ) ], - undef, - [], - [], - ], - 'ALGO-PRIVATE-254' => [ - 1, - q(algo-private-254.dnssec05.xa), - [ qw( DS05_ALGO_PRIVATE ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-4' => [ - 1, - q(algo-reserved-4.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-9' => [ - 1, - q(algo-reserved-9.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-11' => [ - 1, - q(algo-reserved-11.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-123' => [ - 1, - q(algo-reserved-123.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-251' => [ - 1, - q(algo-reserved-251.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-RESERVED-255' => [ - 1, - q(algo-reserved-255.dnssec05.xa), - [ qw( DS05_ALGO_RESERVED ) ], - undef, - [], - [], - ], - 'ALGO-UNASSIGNED-20' => [ - 1, - q(algo-unassigned-20.dnssec05.xa), - [ qw( DS05_ALGO_UNASSIGNED ) ], - undef, - [], - [], - ], - 'ALGO-UNASSIGNED-122' => [ - 1, - q(algo-unassigned-122.dnssec05.xa), - [ qw( DS05_ALGO_UNASSIGNED ) ], - undef, - [], - [], - ], - 'MIXED-ALGO-1' => [ - 1, - q(mixed-algo-1.dnssec05.xa), - [ qw( DS05_ALGO_DEPRECATED DS05_ALGO_NOT_RECOMMENDED DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'NO-RESPONSE-1' => [ - 1, - q(no-response-1.dnssec05.xa), - [ qw( DS05_NO_RESPONSE ) ], - undef, - [], - [], - ], - 'NO-RESPONSE-2' => [ - 1, - q(no-response-2.dnssec05.xa), - [ qw( DS05_NO_RESPONSE ) ], - undef, - [], - [], - ], - 'SERVER-NO-DNSSEC-1' => [ - 1, - q(server-no-dnssec-1.dnssec05.xa), - [ qw( DS05_SERVER_NO_DNSSEC DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'SHARED-IP-1' => [ - 1, - q(shared-ip-1.dnssec05.xa), - [ qw( DS05_ALGO_OK ) ], - undef, - [], - [], - ], - 'ZONE-NO-DNSSEC-1' => [ - 1, - q(zone-no-dnssec-1.dnssec05.xa), - [ qw( DS05_ZONE_NO_DNSSEC ) ], - undef, - [], - [], - ], + 'ALGO-DEPRECATED-1' => [ 1, q(algo-deprecated-1.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-DEPRECATED-3' => [ 1, q(algo-deprecated-3.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-DEPRECATED-5' => [ 1, q(algo-deprecated-5.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-DEPRECATED-6' => [ 1, q(algo-deprecated-6.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-DEPRECATED-7' => [ 1, q(algo-deprecated-7.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-DEPRECATED-12' => [ 1, q(algo-deprecated-12.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED )], undef, [], [] ], + 'ALGO-NOT-RECOMMENDED-10' => + [ 1, q(algo-not-recommended-10.dnssec05.xa), [qw( DS05_ALGO_NOT_RECOMMENDED )], undef, [], [] ], + 'ALGO-NOT-ZONE-SIGN-0' => + [ 1, q(algo-not-zone-sign-0.dnssec05.xa), [qw( DS05_ALGO_NOT_ZONE_SIGN )], undef, [], [] ], + 'ALGO-NOT-ZONE-SIGN-2' => + [ 1, q(algo-not-zone-sign-2.dnssec05.xa), [qw( DS05_ALGO_NOT_ZONE_SIGN )], undef, [], [] ], + 'ALGO-NOT-ZONE-SIGN-252' => + [ 1, q(algo-not-zone-sign-252.dnssec05.xa), [qw( DS05_ALGO_NOT_ZONE_SIGN )], undef, [], [] ], + 'ALGO-OK-8' => [ 1, q(algo-ok-8.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-13' => [ 1, q(algo-ok-13.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-14' => [ 1, q(algo-ok-14.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-15' => [ 1, q(algo-ok-15.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-16' => [ 1, q(algo-ok-16.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-17' => [ 1, q(algo-ok-17.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-OK-23' => [ 1, q(algo-ok-23.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ALGO-PRIVATE-253' => [ 1, q(algo-private-253.dnssec05.xa), [qw( DS05_ALGO_PRIVATE )], undef, [], [] ], + 'ALGO-PRIVATE-254' => [ 1, q(algo-private-254.dnssec05.xa), [qw( DS05_ALGO_PRIVATE )], undef, [], [] ], + 'ALGO-RESERVED-4' => [ 1, q(algo-reserved-4.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-RESERVED-9' => [ 1, q(algo-reserved-9.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-RESERVED-11' => [ 1, q(algo-reserved-11.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-RESERVED-123' => [ 1, q(algo-reserved-123.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-RESERVED-251' => [ 1, q(algo-reserved-251.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-RESERVED-255' => [ 1, q(algo-reserved-255.dnssec05.xa), [qw( DS05_ALGO_RESERVED )], undef, [], [] ], + 'ALGO-UNASSIGNED-20' => [ 1, q(algo-unassigned-20.dnssec05.xa), [qw( DS05_ALGO_UNASSIGNED )], undef, [], [] ], + 'ALGO-UNASSIGNED-122' => [ 1, q(algo-unassigned-122.dnssec05.xa), [qw( DS05_ALGO_UNASSIGNED )], undef, [], [] ], + 'MIXED-ALGO-1' => [ + 1, q(mixed-algo-1.dnssec05.xa), [qw( DS05_ALGO_DEPRECATED DS05_ALGO_NOT_RECOMMENDED DS05_ALGO_OK )], + undef, [], [], + ], + 'NO-RESPONSE-1' => [ 1, q(no-response-1.dnssec05.xa), [qw( DS05_NO_RESPONSE )], undef, [], [] ], + 'NO-RESPONSE-2' => [ 1, q(no-response-2.dnssec05.xa), [qw( DS05_NO_RESPONSE )], undef, [], [] ], + 'SERVER-NO-DNSSEC-1' => + [ 1, q(server-no-dnssec-1.dnssec05.xa), [qw( DS05_SERVER_NO_DNSSEC DS05_ALGO_OK )], undef, [], [] ], + 'SHARED-IP-1' => [ 1, q(shared-ip-1.dnssec05.xa), [qw( DS05_ALGO_OK )], undef, [], [] ], + 'ZONE-NO-DNSSEC-1' => [ 1, q(zone-no-dnssec-1.dnssec05.xa), [qw( DS05_ZONE_NO_DNSSEC )], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -327,9 +106,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec07.t b/t/Test-dnssec07.t index 5db4bf258..864ae0402 100644 --- a/t/Test-dnssec07.t +++ b/t/Test-dnssec07.t @@ -15,29 +15,31 @@ BEGIN { ########### # DNSSEC07 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec07.md my $test_module = 'DNSSEC'; -my $test_case = 'dnssec07'; -my @all_tags = qw( - DS07_DS_FOR_SIGNED_ZONE - DS07_DS_ON_PARENT_SERVER - DS07_INCONSISTENT_DS - DS07_INCONSISTENT_SIGNED - DS07_NON_AUTH_RESPONSE_DNSKEY - DS07_NOT_SIGNED - DS07_NOT_SIGNED_ON_SERVER - DS07_NO_DS_ON_PARENT_SERVER - DS07_NO_DS_FOR_SIGNED_ZONE - DS07_NO_RESPONSE_DNSKEY - DS07_SIGNED - DS07_SIGNED_ON_SERVER - DS07_UNEXP_RCODE_RESP_DNSKEY - ); +my $test_case = 'dnssec07'; +my @all_tags = qw( + DS07_DS_FOR_SIGNED_ZONE + DS07_DS_ON_PARENT_SERVER + DS07_INCONSISTENT_DS + DS07_INCONSISTENT_SIGNED + DS07_NON_AUTH_RESPONSE_DNSKEY + DS07_NOT_SIGNED + DS07_NOT_SIGNED_ON_SERVER + DS07_NO_DS_ON_PARENT_SERVER + DS07_NO_DS_FOR_SIGNED_ZONE + DS07_NO_RESPONSE_DNSKEY + DS07_SIGNED + DS07_SIGNED_ON_SERVER + DS07_UNEXP_RCODE_RESP_DNSKEY +); # Specific hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/DNSSEC-TP/dnssec07/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'root-ns1.xa' => [ '127.15.7.27', 'fda1:b2:c3::127:15:7:27' ], - 'root-ns2.xa' => [ '127.15.7.28', 'fda1:b2:c3::127:15:7:28' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'root-ns1.xa' => [ '127.15.7.27', 'fda1:b2:c3::127:15:7:27' ], + 'root-ns2.xa' => [ '127.15.7.28', 'fda1:b2:c3::127:15:7:28' ], + }, ); # Test zone scenarios @@ -58,63 +60,46 @@ my %subtests = ( 'SIGNED-AND-DS-1' => [ 1, q(signed-and-ds-1.dnssec07.xa), - [ qw( DS07_DS_FOR_SIGNED_ZONE DS07_DS_ON_PARENT_SERVER DS07_SIGNED DS07_SIGNED_ON_SERVER ) ], - undef, - [], - [], + [qw( DS07_DS_FOR_SIGNED_ZONE DS07_DS_ON_PARENT_SERVER DS07_SIGNED DS07_SIGNED_ON_SERVER )], + undef, [], [], ], 'SIGNED-NO-DS-1' => [ - 1, - q(signed-no-ds-1.dnssec07.xa), - [ qw( DS07_NO_DS_ON_PARENT_SERVER DS07_NO_DS_FOR_SIGNED_ZONE DS07_SIGNED DS07_SIGNED_ON_SERVER ) ], - undef, - [], - [], + 1, q(signed-no-ds-1.dnssec07.xa), + [qw( DS07_NO_DS_ON_PARENT_SERVER DS07_NO_DS_FOR_SIGNED_ZONE DS07_SIGNED DS07_SIGNED_ON_SERVER )], + undef, [], [], ], 'INCONSIST-SIGNED-AND-DS-1' => [ 1, q(inconsist-signed-and-ds-1.dnssec07.xa), - [ qw( DS07_DS_ON_PARENT_SERVER DS07_INCONSISTENT_SIGNED DS07_NOT_SIGNED_ON_SERVER DS07_SIGNED_ON_SERVER ) ], - undef, - [], - [], + [qw( DS07_DS_ON_PARENT_SERVER DS07_INCONSISTENT_SIGNED DS07_NOT_SIGNED_ON_SERVER DS07_SIGNED_ON_SERVER )], + undef, [], [], ], 'INCONSIST-SIGNED-NO-DS-1' => [ 1, q(inconsist-signed-no-ds-1.dnssec07.xa), - [ qw( DS07_INCONSISTENT_SIGNED DS07_NOT_SIGNED_ON_SERVER DS07_NO_DS_ON_PARENT_SERVER DS07_SIGNED_ON_SERVER ) ], - undef, - [], - [], + [qw( DS07_INCONSISTENT_SIGNED DS07_NOT_SIGNED_ON_SERVER DS07_NO_DS_ON_PARENT_SERVER DS07_SIGNED_ON_SERVER )], + undef, [], [], ], 'SIGNED-AND-INCONSIST-DS-1' => [ 1, q(child.signed-and-inconsist-ds-1.dnssec07.xa), - [ qw( DS07_DS_ON_PARENT_SERVER DS07_INCONSISTENT_DS DS07_NO_DS_ON_PARENT_SERVER DS07_SIGNED DS07_SIGNED_ON_SERVER ) ], - undef, - [], - [], - ], - 'UNSIGNED-AND-DS-1' => [ - 1, - q(unsigned-and-ds-1.dnssec07.xa), - [ qw( DS07_NOT_SIGNED DS07_NOT_SIGNED_ON_SERVER ) ], - undef, - [], - [], - ], - 'UNSIGNED-NO-DS-1' => [ - 1, - q(unsigned-no-ds-1.dnssec07.xa), - [ qw( DS07_NOT_SIGNED DS07_NOT_SIGNED_ON_SERVER ) ], + [ + qw( DS07_DS_ON_PARENT_SERVER DS07_INCONSISTENT_DS DS07_NO_DS_ON_PARENT_SERVER DS07_SIGNED DS07_SIGNED_ON_SERVER ) + ], undef, [], [], ], + 'UNSIGNED-AND-DS-1' => + [ 1, q(unsigned-and-ds-1.dnssec07.xa), [qw( DS07_NOT_SIGNED DS07_NOT_SIGNED_ON_SERVER )], undef, [], [] ], + 'UNSIGNED-NO-DS-1' => + [ 1, q(unsigned-no-ds-1.dnssec07.xa), [qw( DS07_NOT_SIGNED DS07_NOT_SIGNED_ON_SERVER )], undef, [], [] ], 'NON-AUTH-RESPONSE-DNSKEY-1' => [ 1, q(non-auth-response-dnskey-1.dnssec07.xa), - [ qw( DS07_NON_AUTH_RESPONSE_DNSKEY DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) ], + [ + qw( DS07_NON_AUTH_RESPONSE_DNSKEY DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) + ], undef, [], [], @@ -122,7 +107,9 @@ my %subtests = ( 'NO-RESPONSE-DNSKEY-1' => [ 1, q(no-response-dnskey-1.dnssec07.xa), - [ qw( DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_NO_RESPONSE_DNSKEY DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) ], + [ + qw( DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_NO_RESPONSE_DNSKEY DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) + ], undef, [], [], @@ -130,7 +117,9 @@ my %subtests = ( 'UNEXP-RCODE-RESP-DNSKEY-1' => [ 1, q(unexp-rcode-resp-dnskey-1.dnssec07.xa), - [ qw( DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_UNEXP_RCODE_RESP_DNSKEY DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) ], + [ + qw( DS07_SIGNED DS07_SIGNED_ON_SERVER DS07_UNEXP_RCODE_RESP_DNSKEY DS07_DS_ON_PARENT_SERVER DS07_DS_FOR_SIGNED_ZONE ) + ], undef, [], [], @@ -138,7 +127,7 @@ my %subtests = ( ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -146,9 +135,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec10.t b/t/Test-dnssec10.t index fe6f5a026..ca5b15b2f 100644 --- a/t/Test-dnssec10.t +++ b/t/Test-dnssec10.t @@ -15,54 +15,56 @@ BEGIN { ########### # DNSSEC10 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec10.md my $test_module = 'DNSSEC'; -my $test_case = 'dnssec10'; -my @all_tags = qw( - DS10_ALGO_NOT_SUPPORTED_BY_ZM - DS10_ERR_MULT_NSEC - DS10_ERR_MULT_NSEC3 - DS10_EXPECTED_NSEC_NSEC3_MISSING - DS10_HAS_NSEC - DS10_HAS_NSEC3 - DS10_INCONSISTENT_NSEC - DS10_INCONSISTENT_NSEC3 - DS10_INCONSISTENT_NSEC_NSEC3 - DS10_MIXED_NSEC_NSEC3 - DS10_NONSTANDARD_NSEC_RESPONSE - DS10_NSEC3PARAM_GIVES_ERR_ANSWER - DS10_NSEC3PARAM_MISMATCHES_APEX - DS10_NSEC3PARAM_QUERY_RESPONSE_ERR - DS10_NSEC3_ERR_TYPE_LIST - DS10_NSEC3_MISMATCHES_APEX - DS10_NSEC3_MISSING_SIGNATURE - DS10_NSEC3_NODATA_MISSING_SOA - DS10_NSEC3_NODATA_WRONG_SOA - DS10_NSEC3_NO_VERIFIED_SIGNATURE - DS10_NSEC3_RRSIG_EXPIRED - DS10_NSEC3_RRSIG_NOT_YET_VALID - DS10_NSEC3_RRSIG_NO_DNSKEY - DS10_NSEC3_RRSIG_VERIFY_ERROR - DS10_NSEC_ERR_TYPE_LIST - DS10_NSEC_GIVES_ERR_ANSWER - DS10_NSEC_MISMATCHES_APEX - DS10_NSEC_MISSING_SIGNATURE - DS10_NSEC_NODATA_MISSING_SOA - DS10_NSEC_NODATA_WRONG_SOA - DS10_NSEC_NO_VERIFIED_SIGNATURE - DS10_NSEC_QUERY_RESPONSE_ERR - DS10_NSEC_RRSIG_EXPIRED - DS10_NSEC_RRSIG_NOT_YET_VALID - DS10_NSEC_RRSIG_NO_DNSKEY - DS10_NSEC_RRSIG_VERIFY_ERROR - DS10_SERVER_NO_DNSSEC - DS10_ZONE_NO_DNSSEC - ); +my $test_case = 'dnssec10'; +my @all_tags = qw( + DS10_ALGO_NOT_SUPPORTED_BY_ZM + DS10_ERR_MULT_NSEC + DS10_ERR_MULT_NSEC3 + DS10_EXPECTED_NSEC_NSEC3_MISSING + DS10_HAS_NSEC + DS10_HAS_NSEC3 + DS10_INCONSISTENT_NSEC + DS10_INCONSISTENT_NSEC3 + DS10_INCONSISTENT_NSEC_NSEC3 + DS10_MIXED_NSEC_NSEC3 + DS10_NONSTANDARD_NSEC_RESPONSE + DS10_NSEC3PARAM_GIVES_ERR_ANSWER + DS10_NSEC3PARAM_MISMATCHES_APEX + DS10_NSEC3PARAM_QUERY_RESPONSE_ERR + DS10_NSEC3_ERR_TYPE_LIST + DS10_NSEC3_MISMATCHES_APEX + DS10_NSEC3_MISSING_SIGNATURE + DS10_NSEC3_NODATA_MISSING_SOA + DS10_NSEC3_NODATA_WRONG_SOA + DS10_NSEC3_NO_VERIFIED_SIGNATURE + DS10_NSEC3_RRSIG_EXPIRED + DS10_NSEC3_RRSIG_NOT_YET_VALID + DS10_NSEC3_RRSIG_NO_DNSKEY + DS10_NSEC3_RRSIG_VERIFY_ERROR + DS10_NSEC_ERR_TYPE_LIST + DS10_NSEC_GIVES_ERR_ANSWER + DS10_NSEC_MISMATCHES_APEX + DS10_NSEC_MISSING_SIGNATURE + DS10_NSEC_NODATA_MISSING_SOA + DS10_NSEC_NODATA_WRONG_SOA + DS10_NSEC_NO_VERIFIED_SIGNATURE + DS10_NSEC_QUERY_RESPONSE_ERR + DS10_NSEC_RRSIG_EXPIRED + DS10_NSEC_RRSIG_NOT_YET_VALID + DS10_NSEC_RRSIG_NO_DNSKEY + DS10_NSEC_RRSIG_VERIFY_ERROR + DS10_SERVER_NO_DNSSEC + DS10_ZONE_NO_DNSSEC +); # Common hint file (https://github.com/zonemaster/zonemaster/blob/master/test-zone-data/COMMON/hintfile.zone) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -80,178 +82,51 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'GOOD-NSEC-1' => [ - 1, - q(good-nsec-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'GOOD-NSEC-2' => [ - 1, - q(good-nsec-2.dnssec10.xa), - [ qw( DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'GOOD-NSEC-3' => [ - 1, - q(good-nsec-3.dnssec10.xa), - [ qw( DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'GOOD-NSEC3-1' => [ - 1, - q(good-nsec3-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'GOOD-NSEC3-2' => [ - 1, - q(good-nsec3-2.dnssec10.xa), - [ qw( DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'GOOD-NSEC3-3' => [ - 1, - q(good-nsec3-3.dnssec10.xa), - [ qw( DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'ALGO-NOT-SUPP-BY-ZM-1' => [ - 1, - q(algo-not-supp-by-zm-1.dnssec10.xa), - [ qw( DS10_ALGO_NOT_SUPPORTED_BY_ZM DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'ALGO-NOT-SUPP-BY-ZM-2' => [ - 1, - q(algo-not-supp-by-zm-2.dnssec10.xa), - [ qw( DS10_ALGO_NOT_SUPPORTED_BY_ZM DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'BAD-SERVERS-BUT-GOOD-NSEC-1' => [ - 1, - q(bad-servers-but-good-nsec-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'ERR-MULT-NSEC-1' => [ - 1, - q(err-mult-nsec-1.dnssec10.xa), - [ qw( DS10_ERR_MULT_NSEC DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'ERR-MULT-NSEC-2' => [ - 1, - q(err-mult-nsec-2.dnssec10.xa), - [ qw( DS10_ERR_MULT_NSEC DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'ERR-MULT-NSEC3-1' => [ - 1, - q(err-mult-nsec3-1.dnssec10.xa), - [ qw( DS10_ERR_MULT_NSEC3 DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'MULT-NSEC3PARAM-1' => [ - 1, - q(mult-nsec3param-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'EXP-NSEC-NSEC3-MISS-1' => [ - 1, - q(exp-nsec-nsec3-miss-1.dnssec10.xa), - [ qw( DS10_EXPECTED_NSEC_NSEC3_MISSING ) ], - undef, - [], - [], - ], - 'INCONSISTENT-NSEC-1' => [ - 1, - q(inconsistent-nsec-1.dnssec10.xa), - [ qw( DS10_INCONSISTENT_NSEC DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'INCONSISTENT-NSEC3-1' => [ - 1, - q(inconsistent-nsec3-1.dnssec10.xa), - [ qw( DS10_INCONSISTENT_NSEC3 DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'INCONSIST-NSEC-NSEC3-1' => [ - 1, - q(inconsist-nsec-nsec3-1.dnssec10.xa), - [ qw( DS10_INCONSISTENT_NSEC_NSEC3 ) ], - undef, - [], - [], - ], + 'GOOD-NSEC-1' => [ 1, q(good-nsec-1.dnssec10.xa), [qw( DS10_HAS_NSEC )], undef, [], [] ], + 'GOOD-NSEC-2' => [ 1, q(good-nsec-2.dnssec10.xa), [qw( DS10_HAS_NSEC )], undef, [], [] ], + 'GOOD-NSEC-3' => [ 1, q(good-nsec-3.dnssec10.xa), [qw( DS10_HAS_NSEC )], undef, [], [] ], + 'GOOD-NSEC3-1' => [ 1, q(good-nsec3-1.dnssec10.xa), [qw( DS10_HAS_NSEC3 )], undef, [], [] ], + 'GOOD-NSEC3-2' => [ 1, q(good-nsec3-2.dnssec10.xa), [qw( DS10_HAS_NSEC3 )], undef, [], [] ], + 'GOOD-NSEC3-3' => [ 1, q(good-nsec3-3.dnssec10.xa), [qw( DS10_HAS_NSEC3 )], undef, [], [] ], + 'ALGO-NOT-SUPP-BY-ZM-1' => + [ 1, q(algo-not-supp-by-zm-1.dnssec10.xa), [qw( DS10_ALGO_NOT_SUPPORTED_BY_ZM DS10_HAS_NSEC )], undef, [], [] ], + 'ALGO-NOT-SUPP-BY-ZM-2' => + [ 1, q(algo-not-supp-by-zm-2.dnssec10.xa), [qw( DS10_ALGO_NOT_SUPPORTED_BY_ZM DS10_HAS_NSEC3 )], undef, [], [] ], + 'BAD-SERVERS-BUT-GOOD-NSEC-1' => + [ 1, q(bad-servers-but-good-nsec-1.dnssec10.xa), [qw( DS10_HAS_NSEC )], undef, [], [] ], + 'ERR-MULT-NSEC-1' => [ 1, q(err-mult-nsec-1.dnssec10.xa), [qw( DS10_ERR_MULT_NSEC DS10_HAS_NSEC )], undef, [], [] ], + 'ERR-MULT-NSEC-2' => [ 1, q(err-mult-nsec-2.dnssec10.xa), [qw( DS10_ERR_MULT_NSEC DS10_HAS_NSEC )], undef, [], [] ], + 'ERR-MULT-NSEC3-1' => + [ 1, q(err-mult-nsec3-1.dnssec10.xa), [qw( DS10_ERR_MULT_NSEC3 DS10_HAS_NSEC3 )], undef, [], [] ], + 'MULT-NSEC3PARAM-1' => [ 1, q(mult-nsec3param-1.dnssec10.xa), [qw( DS10_HAS_NSEC3 )], undef, [], [] ], + 'EXP-NSEC-NSEC3-MISS-1' => + [ 1, q(exp-nsec-nsec3-miss-1.dnssec10.xa), [qw( DS10_EXPECTED_NSEC_NSEC3_MISSING )], undef, [], [] ], + 'INCONSISTENT-NSEC-1' => + [ 1, q(inconsistent-nsec-1.dnssec10.xa), [qw( DS10_INCONSISTENT_NSEC DS10_HAS_NSEC )], undef, [], [] ], + 'INCONSISTENT-NSEC3-1' => + [ 1, q(inconsistent-nsec3-1.dnssec10.xa), [qw( DS10_INCONSISTENT_NSEC3 DS10_HAS_NSEC3 )], undef, [], [] ], + 'INCONSIST-NSEC-NSEC3-1' => + [ 1, q(inconsist-nsec-nsec3-1.dnssec10.xa), [qw( DS10_INCONSISTENT_NSEC_NSEC3 )], undef, [], [] ], 'INCONSIST-NSEC-NSEC3-2' => [ 1, q(inconsist-nsec-nsec3-2.dnssec10.xa), - [ qw( DS10_INCONSISTENT_NSEC_NSEC3 DS10_INCONSISTENT_NSEC DS10_INCONSISTENT_NSEC3 ) ], - undef, - [], - [], - ], - 'MIXED-NSEC-NSEC3-1' => [ - 1, - q(mixed-nsec-nsec3-1.dnssec10.xa), - [ qw( DS10_MIXED_NSEC_NSEC3 ) ], - undef, - [], - [], - ], - 'MIXED-NSEC-NSEC3-2' => [ - 1, - q(mixed-nsec-nsec3-2.dnssec10.xa), - [ qw( DS10_MIXED_NSEC_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_INCONSISTENT_NSEC_NSEC3 DS10_INCONSISTENT_NSEC DS10_INCONSISTENT_NSEC3 )], + undef, [], [], ], + 'MIXED-NSEC-NSEC3-1' => [ 1, q(mixed-nsec-nsec3-1.dnssec10.xa), [qw( DS10_MIXED_NSEC_NSEC3 )], undef, [], [] ], + 'MIXED-NSEC-NSEC3-2' => [ 1, q(mixed-nsec-nsec3-2.dnssec10.xa), [qw( DS10_MIXED_NSEC_NSEC3 )], undef, [], [] ], 'NSEC3PARAM-GIVES-ERR-ANSWER-1' => [ 1, q(nsec3param-gives-err-answer-1.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_GIVES_ERR_ANSWER DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3PARAM_GIVES_ERR_ANSWER DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 )], + undef, [], [], ], 'NSEC3PARAM-GIVES-ERR-ANSWER-2' => [ 1, q(nsec3param-gives-err-answer-2.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_GIVES_ERR_ANSWER DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC3 DS10_HAS_NSEC3 ) ], + [ + qw( DS10_NSEC3PARAM_GIVES_ERR_ANSWER DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC3 DS10_HAS_NSEC3 ) + ], undef, [], [], @@ -259,343 +134,203 @@ my %subtests = ( 'NSEC3PARAM-MISMATCHES-APEX-1' => [ 1, q(nsec3param-mismatches-apex-1.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_MISMATCHES_APEX DS10_HAS_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3PARAM_MISMATCHES_APEX DS10_HAS_NSEC3 )], + undef, [], [], ], 'NSEC3PARAM-Q-RESPONSE-ERR-1' => [ 1, q(nsec3param-q-response-err-1.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 )], + undef, [], [], ], 'NSEC3PARAM-Q-RESPONSE-ERR-2' => [ 1, q(nsec3param-q-response-err-2.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_HAS_NSEC3 DS10_INCONSISTENT_NSEC3 )], + undef, [], [], ], 'NSEC3PARAM-Q-RESPONSE-ERR-3' => [ 0, q(nsec3param-q-response-err-3.dnssec10.xa), - [ qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC3 ) ], - undef, - [], - [], - ], - 'NSEC3-ERR-TYPE-LIST-1' => [ - 1, - q(nsec3-err-type-list-1.dnssec10.xa), - [ qw( DS10_NSEC3_ERR_TYPE_LIST DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'NSEC3-ERR-TYPE-LIST-2' => [ - 1, - q(nsec3-err-type-list-2.dnssec10.xa), - [ qw( DS10_NSEC3_ERR_TYPE_LIST DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'NSEC3-MISMATCHES-APEX-1' => [ - 1, - q(nsec3-mismatches-apex-1.dnssec10.xa), - [ qw( DS10_NSEC3_MISMATCHES_APEX DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], + [qw( DS10_NSEC3PARAM_QUERY_RESPONSE_ERR DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC3 )], + undef, [], [], + ], + 'NSEC3-ERR-TYPE-LIST-1' => + [ 1, q(nsec3-err-type-list-1.dnssec10.xa), [qw( DS10_NSEC3_ERR_TYPE_LIST DS10_HAS_NSEC3 )], undef, [], [] ], + 'NSEC3-ERR-TYPE-LIST-2' => + [ 1, q(nsec3-err-type-list-2.dnssec10.xa), [qw( DS10_NSEC3_ERR_TYPE_LIST DS10_HAS_NSEC3 )], undef, [], [] ], + 'NSEC3-MISMATCHES-APEX-1' => + [ 1, q(nsec3-mismatches-apex-1.dnssec10.xa), [qw( DS10_NSEC3_MISMATCHES_APEX DS10_HAS_NSEC3 )], undef, [], [] ], 'NSEC3-MISSING-SIGNATURE-1' => [ 1, q(nsec3-missing-signature-1.dnssec10.xa), - [ qw( DS10_NSEC3_MISSING_SIGNATURE DS10_HAS_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3_MISSING_SIGNATURE DS10_HAS_NSEC3 )], + undef, [], [], ], 'NSEC3-NODATA-MISSING-SOA-1' => [ 1, q(nsec3-nodata-missing-soa-1.dnssec10.xa), - [ qw( DS10_NSEC3_NODATA_MISSING_SOA DS10_HAS_NSEC3 ) ], - undef, - [], - [], + [qw( DS10_NSEC3_NODATA_MISSING_SOA DS10_HAS_NSEC3 )], + undef, [], [], ], 'NSEC3-NODATA-WRONG-SOA-1' => [ - 1, - q(nsec3-nodata-wrong-soa-1.dnssec10.xa), - [ qw( DS10_NSEC3_NODATA_WRONG_SOA DS10_HAS_NSEC3 ) ], - undef, - [], - [], + 1, q(nsec3-nodata-wrong-soa-1.dnssec10.xa), [qw( DS10_NSEC3_NODATA_WRONG_SOA DS10_HAS_NSEC3 )], undef, [], [], ], 'NSEC3-NO-VERIFIED-SIGNATURE-1' => [ 1, q(nsec3-no-verified-signature-1.dnssec10.xa), - [ qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_NO_DNSKEY ) ], - undef, - [], - [], + [qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_NO_DNSKEY )], + undef, [], [], ], 'NSEC3-NO-VERIFIED-SIGNATURE-2' => [ 1, q(nsec3-no-verified-signature-2.dnssec10.xa), - [ qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_EXPIRED ) ], - undef, - [], - [], + [qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_EXPIRED )], + undef, [], [], ], 'NSEC3-NO-VERIFIED-SIGNATURE-3' => [ 1, q(nsec3-no-verified-signature-3.dnssec10.xa), - [ qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_NOT_YET_VALID ) ], - undef, - [], - [], + [qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_NOT_YET_VALID )], + undef, [], [], ], 'NSEC3-NO-VERIFIED-SIGNATURE-4' => [ 1, q(nsec3-no-verified-signature-4.dnssec10.xa), - [ qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_VERIFY_ERROR ) ], - undef, - [], - [], - ], - 'NSEC-ERR-TYPE-LIST-1' => [ - 1, - q(nsec-err-type-list-1.dnssec10.xa), - [ qw( DS10_NSEC_ERR_TYPE_LIST DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'NSEC-ERR-TYPE-LIST-2' => [ - 1, - q(nsec-err-type-list-2.dnssec10.xa), - [ qw( DS10_NSEC_ERR_TYPE_LIST DS10_HAS_NSEC ) ], - undef, - [], - [], + [qw( DS10_NSEC3_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC3 DS10_NSEC3_RRSIG_VERIFY_ERROR )], + undef, [], [], ], + 'NSEC-ERR-TYPE-LIST-1' => + [ 1, q(nsec-err-type-list-1.dnssec10.xa), [qw( DS10_NSEC_ERR_TYPE_LIST DS10_HAS_NSEC )], undef, [], [] ], + 'NSEC-ERR-TYPE-LIST-2' => + [ 1, q(nsec-err-type-list-2.dnssec10.xa), [qw( DS10_NSEC_ERR_TYPE_LIST DS10_HAS_NSEC )], undef, [], [] ], 'NSEC-GIVES-ERR-ANSWER-1' => [ 1, q(nsec-gives-err-answer-1.dnssec10.xa), - [ qw( DS10_NSEC_GIVES_ERR_ANSWER DS10_HAS_NSEC DS10_INCONSISTENT_NSEC ) ], - undef, - [], - [], + [qw( DS10_NSEC_GIVES_ERR_ANSWER DS10_HAS_NSEC DS10_INCONSISTENT_NSEC )], + undef, [], [], ], 'NSEC-GIVES-ERR-ANSWER-2' => [ 1, q(nsec-gives-err-answer-2.dnssec10.xa), - [ qw( DS10_NSEC_GIVES_ERR_ANSWER DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'NSEC-MISMATCHES-APEX-1' => [ - 1, - q(nsec-mismatches-apex-1.dnssec10.xa), - [ qw( DS10_NSEC_MISMATCHES_APEX DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'NSEC-MISMATCHES-APEX-2' => [ - 1, - q(nsec-mismatches-apex-2.dnssec10.xa), - [ qw( DS10_NSEC_MISMATCHES_APEX DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'NSEC-MISSING-SIGNATURE-1' => [ - 1, - q(nsec-missing-signature-1.dnssec10.xa), - [ qw( DS10_NSEC_MISSING_SIGNATURE DS10_HAS_NSEC ) ], - undef, - [], - [], - ], + [qw( DS10_NSEC_GIVES_ERR_ANSWER DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC DS10_HAS_NSEC )], + undef, [], [], + ], + 'NSEC-MISMATCHES-APEX-1' => + [ 1, q(nsec-mismatches-apex-1.dnssec10.xa), [qw( DS10_NSEC_MISMATCHES_APEX DS10_HAS_NSEC )], undef, [], [] ], + 'NSEC-MISMATCHES-APEX-2' => + [ 1, q(nsec-mismatches-apex-2.dnssec10.xa), [qw( DS10_NSEC_MISMATCHES_APEX DS10_HAS_NSEC )], undef, [], [] ], + 'NSEC-MISSING-SIGNATURE-1' => + [ 1, q(nsec-missing-signature-1.dnssec10.xa), [qw( DS10_NSEC_MISSING_SIGNATURE DS10_HAS_NSEC )], undef, [], [] ], 'NSEC-NODATA-MISSING-SOA-1' => [ 1, q(nsec-nodata-missing-soa-1.dnssec10.xa), - [ qw( DS10_NSEC_NODATA_MISSING_SOA DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'NSEC-NODATA-WRONG-SOA-1' => [ - 1, - q(nsec-nodata-wrong-soa-1.dnssec10.xa), - [ qw( DS10_NSEC_NODATA_WRONG_SOA DS10_HAS_NSEC ) ], - undef, - [], - [], + [qw( DS10_NSEC_NODATA_MISSING_SOA DS10_HAS_NSEC )], + undef, [], [], ], + 'NSEC-NODATA-WRONG-SOA-1' => + [ 1, q(nsec-nodata-wrong-soa-1.dnssec10.xa), [qw( DS10_NSEC_NODATA_WRONG_SOA DS10_HAS_NSEC )], undef, [], [] ], 'NSEC-NO-VERIFIED-SIGNATURE-1' => [ 1, q(nsec-no-verified-signature-1.dnssec10.xa), - [ qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_NO_DNSKEY ) ], - undef, - [], - [], + [qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_NO_DNSKEY )], + undef, [], [], ], 'NSEC-NO-VERIFIED-SIGNATURE-2' => [ 1, q(nsec-no-verified-signature-2.dnssec10.xa), - [ qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_EXPIRED ) ], - undef, - [], - [], + [qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_EXPIRED )], + undef, [], [], ], 'NSEC-NO-VERIFIED-SIGNATURE-3' => [ 1, q(nsec-no-verified-signature-3.dnssec10.xa), - [ qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_NOT_YET_VALID ) ], - undef, - [], - [], + [qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_NOT_YET_VALID )], + undef, [], [], ], 'NSEC-NO-VERIFIED-SIGNATURE-4' => [ 1, q(nsec-no-verified-signature-4.dnssec10.xa), - [ qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_VERIFY_ERROR ) ], - undef, - [], - [], + [qw( DS10_NSEC_NO_VERIFIED_SIGNATURE DS10_HAS_NSEC DS10_NSEC_RRSIG_VERIFY_ERROR )], + undef, [], [], ], 'NSEC-QUERY-RESPONSE-ERR-1' => [ 1, q(nsec-query-response-err-1.dnssec10.xa), - [ qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_HAS_NSEC DS10_INCONSISTENT_NSEC ) ], - undef, - [], - [], + [qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_HAS_NSEC DS10_INCONSISTENT_NSEC )], + undef, [], [], ], 'NSEC-QUERY-RESPONSE-ERR-2' => [ 1, q(nsec-query-response-err-2.dnssec10.xa), - [ qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_HAS_NSEC DS10_INCONSISTENT_NSEC ) ], - undef, - [], - [], + [qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_HAS_NSEC DS10_INCONSISTENT_NSEC )], + undef, [], [], ], 'NSEC-QUERY-RESPONSE-ERR-3' => [ 0, q(nsec-query-response-err-3.dnssec10.xa), - [ qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC ) ], - undef, - [], - [], - ], - 'NS-NSEC-RESP-1' => [ - 1, - q(ns-nsec-resp-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE ) ], - undef, - [], - [], + [qw( DS10_NSEC_QUERY_RESPONSE_ERR DS10_EXPECTED_NSEC_NSEC3_MISSING DS10_INCONSISTENT_NSEC )], + undef, [], [], ], + 'NS-NSEC-RESP-1' => + [ 1, q(ns-nsec-resp-1.dnssec10.xa), [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE )], undef, [], [] ], 'NS-NSEC-RESP-MISS-SOA-1' => [ 1, q(ns-nsec-resp-miss-soa-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_NODATA_MISSING_SOA ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_NODATA_MISSING_SOA )], + undef, [], [], ], 'NS-NSEC-RESP-WRONG-SOA-1' => [ 1, q(ns-nsec-resp-wrong-soa-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_NODATA_WRONG_SOA ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_NODATA_WRONG_SOA )], + undef, [], [], ], 'NS-NSEC-RESP-MULT-NSEC-1' => [ 1, q(ns-nsec-resp-mult-nsec-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_ERR_MULT_NSEC ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_ERR_MULT_NSEC )], + undef, [], [], ], 'NS-NSEC-RESP-NSEC-MM-APEX-1' => [ 1, q(ns-nsec-resp-nsec-mm-apex-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_MISMATCHES_APEX ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_MISMATCHES_APEX )], + undef, [], [], ], 'NS-NSEC-RESP-ERR-TP-1' => [ 1, q(ns-nsec-resp-err-tp-1.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST )], + undef, [], [], ], 'NS-NSEC-RESP-ERR-TP-2' => [ 1, q(ns-nsec-resp-err-tp-2.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST )], + undef, [], [], ], 'NS-NSEC-RESP-ERR-TP-3' => [ 1, q(ns-nsec-resp-err-tp-3.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST ) ], - undef, - [], - [], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST )], + undef, [], [], ], 'NS-NSEC-RESP-ERR-TP-4' => [ 1, q(ns-nsec-resp-err-tp-4.dnssec10.xa), - [ qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST ) ], - undef, - [], - [], - ], - 'SERVER-NO-DNSSEC-1' => [ - 1, - q(server-no-dnssec-1.dnssec10.xa), - [ qw( DS10_SERVER_NO_DNSSEC DS10_HAS_NSEC ) ], - undef, - [], - [], - ], - 'SERVER-NO-DNSSEC-2' => [ - 1, - q(server-no-dnssec-2.dnssec10.xa), - [ qw( DS10_SERVER_NO_DNSSEC DS10_HAS_NSEC3 ) ], - undef, - [], - [], - ], - 'ZONE-NO-DNSSEC-1' => [ - 1, - q(zone-no-dnssec-1.dnssec10.xa), - [ qw( DS10_ZONE_NO_DNSSEC ) ], - undef, - [], - [], - ], + [qw( DS10_HAS_NSEC DS10_NONSTANDARD_NSEC_RESPONSE DS10_NSEC_ERR_TYPE_LIST )], + undef, [], [], + ], + 'SERVER-NO-DNSSEC-1' => + [ 1, q(server-no-dnssec-1.dnssec10.xa), [qw( DS10_SERVER_NO_DNSSEC DS10_HAS_NSEC )], undef, [], [] ], + 'SERVER-NO-DNSSEC-2' => + [ 1, q(server-no-dnssec-2.dnssec10.xa), [qw( DS10_SERVER_NO_DNSSEC DS10_HAS_NSEC3 )], undef, [], [] ], + 'ZONE-NO-DNSSEC-1' => [ 1, q(zone-no-dnssec-1.dnssec10.xa), [qw( DS10_ZONE_NO_DNSSEC )], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -603,9 +338,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-dnssec16.t b/t/Test-dnssec16.t index f69551256..ac1b37380 100644 --- a/t/Test-dnssec16.t +++ b/t/Test-dnssec16.t @@ -16,25 +16,27 @@ BEGIN { ########### # dnssec16 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/DNSSEC-TP/dnssec16.md my $test_module = q{DNSSEC}; -my $test_case = 'dnssec16'; -my @all_tags = qw(DS16_CDS_INVALID_RRSIG - DS16_CDS_MATCHES_NON_SEP_DNSKEY - DS16_CDS_MATCHES_NON_ZONE_DNSKEY - DS16_CDS_MATCHES_NO_DNSKEY - DS16_CDS_NOT_SIGNED_BY_CDS - DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY - DS16_CDS_UNSIGNED - DS16_CDS_WITHOUT_DNSKEY - DS16_DELETE_CDS - DS16_DNSKEY_NOT_SIGNED_BY_CDS - DS16_MIXED_DELETE_CDS); +my $test_case = 'dnssec16'; +my @all_tags = qw(DS16_CDS_INVALID_RRSIG + DS16_CDS_MATCHES_NON_SEP_DNSKEY + DS16_CDS_MATCHES_NON_ZONE_DNSKEY + DS16_CDS_MATCHES_NO_DNSKEY + DS16_CDS_NOT_SIGNED_BY_CDS + DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY + DS16_CDS_UNSIGNED + DS16_CDS_WITHOUT_DNSKEY + DS16_DELETE_CDS + DS16_DNSKEY_NOT_SIGNED_BY_CDS + DS16_MIXED_DELETE_CDS); # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -52,122 +54,31 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'CDS-INVALID-RRSIG' => [ - 1, - q(cds-invalid-rrsig.dnssec16.xa), - [ qw(DS16_CDS_INVALID_RRSIG) ], - undef, - [], - [] - ], - 'CDS-MATCHES-NO-DNSKEY' => [ - 1, - q(cds-matches-no-dnskey.dnssec16.xa), - [ qw(DS16_CDS_MATCHES_NO_DNSKEY) ], - undef, - [], - [] - ], - 'CDS-MATCHES-NON-SEP-DNSKEY' => [ - 1, - q(cds-matches-non-sep-dnskey.dnssec16.xa), - [ qw(DS16_CDS_MATCHES_NON_SEP_DNSKEY) ], - undef, - [], - [] - ], - 'CDS-MATCHES-NON-ZONE-DNSKEY' => [ - 1, - q(cds-matches-non-zone-dnskey.dnssec16.xa), - [ qw(DS16_CDS_MATCHES_NON_ZONE_DNSKEY) ], - undef, - [], - [] - ], - 'CDS-NOT-SIGNED-BY-CDS' => [ - 1, - q(cds-not-signed-by-cds.dnssec16.xa), - [ qw(DS16_CDS_NOT_SIGNED_BY_CDS) ], - undef, - [], - [] - ], - 'CDS-SIGNED-BY-UNKNOWN-DNSKEY' => [ - 1, - q(cds-signed-by-unknown-dnskey.dnssec16.xa), - [ qw(DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY) ], - undef, - [], - [] - ], - 'CDS-UNSIGNED' => [ - 1, - q(cds-unsigned.dnssec16.xa), - [ qw(DS16_CDS_UNSIGNED DS16_CDS_NOT_SIGNED_BY_CDS) ], - undef, - [], - [] - ], - 'CDS-WITHOUT-DNSKEY' => [ - 1, - q(cds-without-dnskey.dnssec16.xa), - [ qw(DS16_CDS_WITHOUT_DNSKEY) ], - undef, - [], - [] - ], - 'DELETE-CDS' => [ - 1, - q(delete-cds.dnssec16.xa), - [ qw(DS16_DELETE_CDS) ], - undef, - [], - [] - ], - 'DNSKEY-NOT-SIGNED-BY-CDS' => [ - 1, - q(dnskey-not-signed-by-cds.dnssec16.xa), - [ qw(DS16_DNSKEY_NOT_SIGNED_BY_CDS) ], - undef, - [], - [] - ], - 'MIXED-DELETE-CDS' => [ - 1, - q(mixed-delete-cds.dnssec16.xa), - [ qw(DS16_MIXED_DELETE_CDS) ], - undef, - [], - [] - ], - 'NO-CDS' => [ - 1, - q(no-cds.dnssec16.xa), - [], - undef, - [], - [] - ], - 'NOT-AA' => [ - 1, - q(not-aa.dnssec16.xa), - [], - undef, - [], - [] - ], - 'VALID-CDS' => [ - 1, - q(valid-cds.dnssec16.xa), - [], - undef, - [], - [] - ] + 'CDS-INVALID-RRSIG' => [ 1, q(cds-invalid-rrsig.dnssec16.xa), [qw(DS16_CDS_INVALID_RRSIG)], undef, [], [] ], + 'CDS-MATCHES-NO-DNSKEY' => + [ 1, q(cds-matches-no-dnskey.dnssec16.xa), [qw(DS16_CDS_MATCHES_NO_DNSKEY)], undef, [], [] ], + 'CDS-MATCHES-NON-SEP-DNSKEY' => + [ 1, q(cds-matches-non-sep-dnskey.dnssec16.xa), [qw(DS16_CDS_MATCHES_NON_SEP_DNSKEY)], undef, [], [] ], + 'CDS-MATCHES-NON-ZONE-DNSKEY' => + [ 1, q(cds-matches-non-zone-dnskey.dnssec16.xa), [qw(DS16_CDS_MATCHES_NON_ZONE_DNSKEY)], undef, [], [] ], + 'CDS-NOT-SIGNED-BY-CDS' => + [ 1, q(cds-not-signed-by-cds.dnssec16.xa), [qw(DS16_CDS_NOT_SIGNED_BY_CDS)], undef, [], [] ], + 'CDS-SIGNED-BY-UNKNOWN-DNSKEY' => + [ 1, q(cds-signed-by-unknown-dnskey.dnssec16.xa), [qw(DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY)], undef, [], [] ], + 'CDS-UNSIGNED' => + [ 1, q(cds-unsigned.dnssec16.xa), [qw(DS16_CDS_UNSIGNED DS16_CDS_NOT_SIGNED_BY_CDS)], undef, [], [] ], + 'CDS-WITHOUT-DNSKEY' => [ 1, q(cds-without-dnskey.dnssec16.xa), [qw(DS16_CDS_WITHOUT_DNSKEY)], undef, [], [] ], + 'DELETE-CDS' => [ 1, q(delete-cds.dnssec16.xa), [qw(DS16_DELETE_CDS)], undef, [], [] ], + 'DNSKEY-NOT-SIGNED-BY-CDS' => + [ 1, q(dnskey-not-signed-by-cds.dnssec16.xa), [qw(DS16_DNSKEY_NOT_SIGNED_BY_CDS)], undef, [], [] ], + 'MIXED-DELETE-CDS' => [ 1, q(mixed-delete-cds.dnssec16.xa), [qw(DS16_MIXED_DELETE_CDS)], undef, [], [] ], + 'NO-CDS' => [ 1, q(no-cds.dnssec16.xa), [], undef, [], [] ], + 'NOT-AA' => [ 1, q(not-aa.dnssec16.xa), [], undef, [], [] ], + 'VALID-CDS' => [ 1, q(valid-cds.dnssec16.xa), [], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -175,9 +86,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-nameserver.t b/t/Test-nameserver.t index 2d5c7caa2..b02593d90 100644 --- a/t/Test-nameserver.t +++ b/t/Test-nameserver.t @@ -41,21 +41,24 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); -my @testcases_with_network = (qw{nameserver01 nameserver02 nameserver06 nameserver07 nameserver08 nameserver09}); -foreach my $testcase ( qw{nameserver01 nameserver02 nameserver03 nameserver04 nameserver05 nameserver06 nameserver07 nameserver08 nameserver09} ) { +my ( $json, $profile_test ); +my @testcases_with_network = ( qw{nameserver01 nameserver02 nameserver06 nameserver07 nameserver08 nameserver09} ); +foreach my $testcase ( + qw{nameserver01 nameserver02 nameserver03 nameserver04 nameserver05 nameserver06 nameserver07 nameserver08 nameserver09} + ) +{ next if grep { $_ eq $testcase } @testcases_with_network; - $json = read_file( 't/profiles/Test-'.$testcase.'-only.json' ); + $json = read_file( 't/profiles/Test-' . $testcase . '-only.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my %testcases; Zonemaster::Engine->logger->clear_history(); foreach my $result ( Zonemaster::Engine->test_module( q{nameserver}, q{afnic.fr} ) ) { if ( $result->testcase && $result->testcase ne 'Unspecified' ) { - $testcases{$result->testcase} = 1; + $testcases{ $result->testcase } = 1; } } - eq_or_diff( [ map { lc $_ } keys %testcases ], [ $testcase ], 'expected test-case ('. $testcase .')' ); + eq_or_diff( [ map { lc $_ } keys %testcases ], [$testcase], 'expected test-case (' . $testcase . ')' ); } $json = read_file( 't/profiles/Test-nameserver-all.json' ); @@ -73,7 +76,7 @@ zone_gives_not( 'nameserver01', $zone, [q{IS_A_RECURSOR}] ); # nameserver02 $zone = Zonemaster::Engine->zone( 'flagday.rootcanary.net' ); -zone_gives( 'nameserver02', $zone, ['BREAKS_ON_EDNS']); +zone_gives( 'nameserver02', $zone, ['BREAKS_ON_EDNS'] ); $zone = Zonemaster::Engine->zone( 'dyad.se' ); zone_gives( 'nameserver02', $zone, ['EDNS0_SUPPORT'] ); @@ -91,8 +94,7 @@ $zone = Zonemaster::Engine->zone( 'afnic.fr' ); zone_gives( 'nameserver05', $zone, [q{AAAA_WELL_PROCESSED}] ); SKIP: { - skip "Zone does not actually have tested problem", 1, - $zone = Zonemaster::Engine->zone( 'uddevallafiber.se' ); + skip "Zone does not actually have tested problem", 1, $zone = Zonemaster::Engine->zone( 'uddevallafiber.se' ); zone_gives( 'nameserver05', $zone, ['QUERY_DROPPED'] ); } @@ -116,15 +118,16 @@ zone_gives_not( 'nameserver07', $zone, [qw{UPWARD_REFERRAL NO_UPWARD_REFERRAL}] # nameserver11 $zone = Zonemaster::Engine->zone( 'bemacom.se' ); zone_gives( 'nameserver11', $zone, [q{N11_UNEXPECTED_RCODE}] ); -zone_gives_not( 'nameserver11', $zone, [qw{N11_NO_EDNS N11_NO_RESPONSE N11_RETURNS_UNKNOWN_OPTION_CODE N11_UNEXPECTED_ANSWER_SECTION N11_UNSET_AA}] ); +zone_gives_not( 'nameserver11', $zone, + [qw{N11_NO_EDNS N11_NO_RESPONSE N11_RETURNS_UNKNOWN_OPTION_CODE N11_UNEXPECTED_ANSWER_SECTION N11_UNSET_AA}], +); # nameserver{12,13,14} -- no unit tests yet, see https://github.com/zonemaster/zonemaster-engine/issues/1146 # nameserver15 -- see t/Test-nameserver15.t instead. SKIP: { - skip "Zone does not actually have tested problem", 1, - $zone = Zonemaster::Engine->zone( 'escargot.se' ); + skip "Zone does not actually have tested problem", 1, $zone = Zonemaster::Engine->zone( 'escargot.se' ); zone_gives( 'nameserver05', $zone, ['AAAA_UNEXPECTED_RCODE'] ); } @@ -135,12 +138,12 @@ TODO: { ok( $tag{DIFFERENT_SOURCE_IP}, q{DIFFERENT_SOURCE_IP} ); # nameserver07 - ok( $tag{UPWARD_REFERRAL}, q{UPWARD_REFERRAL} ); + ok( $tag{UPWARD_REFERRAL}, q{UPWARD_REFERRAL} ); ok( $tag{NO_UPWARD_REFERRAL}, q{NO_UPWARD_REFERRAL} ); # nameserver08 ok( $tag{QNAME_CASE_INSENSITIVE}, q{QNAME_CASE_INSENSITIVE} ); - ok( $tag{QNAME_CASE_SENSITIVE}, q{QNAME_CASE_SENSITIVE} ); + ok( $tag{QNAME_CASE_SENSITIVE}, q{QNAME_CASE_SENSITIVE} ); } SKIP: { @@ -150,8 +153,8 @@ SKIP: { # AXFR results not well cached. Cannot test cases where AXFR is available # without network, even in case of ZONEMASTER_RECORD is not set. -# $zone = Zonemaster::Engine->zone( 'nameserver03-axfr-available.zut-root.rd.nic.fr' ); -# zone_gives( 'nameserver03', $zone, [q{AXFR_AVAILABLE}] ); + # $zone = Zonemaster::Engine->zone( 'nameserver03-axfr-available.zut-root.rd.nic.fr' ); + # zone_gives( 'nameserver03', $zone, [q{AXFR_AVAILABLE}] ); $zone = Zonemaster::Engine->zone( 'arpa' ); zone_gives( 'nameserver03', $zone, [q{AXFR_AVAILABLE}] ); zone_gives( 'nameserver03', $zone, [q{AXFR_FAILURE}] ); @@ -162,8 +165,8 @@ if ( $ENV{ZONEMASTER_RECORD} ) { } Zonemaster::Engine::Profile->effective->set( q{no_network}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); -Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); +Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); $zone = Zonemaster::Engine->zone( 'fr' ); zone_gives( 'nameserver01', $zone, [q{NO_NETWORK}] ); zone_gives_not( 'nameserver01', $zone, [qw{NO_RECURSOR IS_A_RECURSOR}] ); diff --git a/t/Test-nameserver15.t b/t/Test-nameserver15.t index b5f3ec5f8..9b6aa592f 100644 --- a/t/Test-nameserver15.t +++ b/t/Test-nameserver15.t @@ -16,18 +16,20 @@ BEGIN { ########### # nameserver15 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Nameserver-TP/nameserver15.md my $test_module = 'Nameserver'; -my $test_case = 'nameserver15'; -my @all_tags = qw(N15_NO_VERSION_REVEALED - N15_ERROR_ON_VERSION_QUERY - N15_SOFTWARE_VERSION - N15_WRONG_CLASS); +my $test_case = 'nameserver15'; +my @all_tags = qw(N15_NO_VERSION_REVEALED + N15_ERROR_ON_VERSION_QUERY + N15_SOFTWARE_VERSION + N15_WRONG_CLASS); # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -45,106 +47,40 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'NO-VERSION-REVEALED-1' => [ - 1, - q(no-version-revealed-1.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'NO-VERSION-REVEALED-2' => [ - 1, - q(no-version-revealed-2.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'NO-VERSION-REVEALED-3' => [ - 1, - q(no-version-revealed-3.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'NO-VERSION-REVEALED-4' => [ - 1, - q(no-version-revealed-4.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'NO-VERSION-REVEALED-5' => [ - 1, - q(no-version-revealed-5.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'NO-VERSION-REVEALED-6' => [ - 1, - q(no-version-revealed-6.nameserver15.xa), - [ qw(N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], + 'NO-VERSION-REVEALED-1' => + [ 1, q(no-version-revealed-1.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], + 'NO-VERSION-REVEALED-2' => + [ 1, q(no-version-revealed-2.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], + 'NO-VERSION-REVEALED-3' => + [ 1, q(no-version-revealed-3.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], + 'NO-VERSION-REVEALED-4' => + [ 1, q(no-version-revealed-4.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], + 'NO-VERSION-REVEALED-5' => + [ 1, q(no-version-revealed-5.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], + 'NO-VERSION-REVEALED-6' => + [ 1, q(no-version-revealed-6.nameserver15.xa), [qw(N15_NO_VERSION_REVEALED)], undef, [], [] ], 'ERROR-ON-VERSION-QUERY-1' => [ 1, q(error-on-version-query-1.nameserver15.xa), - [ qw(N15_ERROR_ON_VERSION_QUERY N15_NO_VERSION_REVEALED) ], - undef, - [], - [] + [qw(N15_ERROR_ON_VERSION_QUERY N15_NO_VERSION_REVEALED)], + undef, [], [], ], 'ERROR-ON-VERSION-QUERY-2' => [ 1, q(error-on-version-query-2.nameserver15.xa), - [ qw(N15_ERROR_ON_VERSION_QUERY N15_NO_VERSION_REVEALED) ], - undef, - [], - [] - ], - 'SOFTWARE-VERSION-1' => [ - 1, - q(software-version-1.nameserver15.xa), - [ qw(N15_SOFTWARE_VERSION) ], - undef, - [], - [] - ], - 'SOFTWARE-VERSION-2' => [ - 1, - q(software-version-2.nameserver15.xa), - [ qw(N15_SOFTWARE_VERSION) ], - undef, - [], - [] - ], - 'WRONG-CLASS-1' => [ - 1, - q(wrong-class-1.nameserver15.xa), - [ qw(N15_SOFTWARE_VERSION N15_WRONG_CLASS) ], - undef, - [], - [] + [qw(N15_ERROR_ON_VERSION_QUERY N15_NO_VERSION_REVEALED)], + undef, [], [], ], - 'WRONG-CLASS-2' => [ - 1, - q(wrong-class-2.nameserver15.xa), - [ qw(N15_SOFTWARE_VERSION N15_WRONG_CLASS) ], - undef, - [], - [] - ] + 'SOFTWARE-VERSION-1' => [ 1, q(software-version-1.nameserver15.xa), [qw(N15_SOFTWARE_VERSION)], undef, [], [] ], + 'SOFTWARE-VERSION-2' => [ 1, q(software-version-2.nameserver15.xa), [qw(N15_SOFTWARE_VERSION)], undef, [], [] ], + 'WRONG-CLASS-1' => + [ 1, q(wrong-class-1.nameserver15.xa), [qw(N15_SOFTWARE_VERSION N15_WRONG_CLASS)], undef, [], [] ], + 'WRONG-CLASS-2' => + [ 1, q(wrong-class-2.nameserver15.xa), [qw(N15_SOFTWARE_VERSION N15_WRONG_CLASS)], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -152,9 +88,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-syntax.t b/t/Test-syntax.t index a54e17356..25a4f4dcf 100644 --- a/t/Test-syntax.t +++ b/t/Test-syntax.t @@ -34,18 +34,18 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { } # Find a way with dependences for syntax04 syntax05 syntax06 syntax07 syntax08 -my ($json, $profile_test); +my ( $json, $profile_test ); foreach my $testcase ( qw{syntax01 syntax02 syntax03} ) { - $json = read_file( 't/profiles/Test-'.$testcase.'-only.json' ); + $json = read_file( 't/profiles/Test-' . $testcase . '-only.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); my %testcases; foreach my $result ( Zonemaster::Engine->test_module( q{syntax}, q{afnic.fr} ) ) { if ( $result->testcase && $result->testcase ne 'Unspecified' ) { - $testcases{$result->testcase} = 1; + $testcases{ $result->testcase } = 1; } } - eq_or_diff( [ map { lc $_ } keys %testcases ], [ $testcase ], 'expected test-case ('. $testcase .')' ); + eq_or_diff( [ map { lc $_ } keys %testcases ], [$testcase], 'expected test-case (' . $testcase . ')' ); } $json = read_file( 't/profiles/Test-syntax-all.json' ); @@ -81,20 +81,20 @@ zone_gives( q{syntax03}, $dn_ok, q{NO_DOUBLE_DASH} ); zone_gives( q{syntax03}, $dn_idn_ok, q{NO_DOUBLE_DASH} ); my $zone_double_dash = Zonemaster::Engine->zone( q{ns1.ns--nic.fr} ); -zone_gives_not( q{syntax04}, $ns_ok, q{NAMESERVER_DISCOURAGED_DOUBLE_DASH} ); +zone_gives_not( q{syntax04}, $ns_ok, q{NAMESERVER_DISCOURAGED_DOUBLE_DASH} ); zone_gives_not( q{syntax04}, $zone_double_dash, q{NAMESERVER_DISCOURAGED_DOUBLE_DASH} ); SKIP: { skip "need test zone", 1; - my $ns_num_tld; # TODO specify test zone + my $ns_num_tld; # TODO specify test zone zone_gives( q{syntax04}, $ns_num_tld, q{NAMESERVER_NUMERIC_TLD} ); } my $zone_num_tld = Zonemaster::Engine->zone( q{ns1.nic.47} ); -zone_gives_not( q{syntax04}, $ns_ok, q{NAMESERVER_NUMERIC_TLD} ); +zone_gives_not( q{syntax04}, $ns_ok, q{NAMESERVER_NUMERIC_TLD} ); zone_gives_not( q{syntax04}, $zone_num_tld, q{NAMESERVER_NUMERIC_TLD} ); SKIP: { skip "need test zone", 1; - my $ns_double_dash; # TODO specify test zone + my $ns_double_dash; # TODO specify test zone zone_gives( q{syntax04}, $ns_double_dash, q{NAMESERVER_DISCOURAGED_DOUBLE_DASH} ); } @@ -132,7 +132,7 @@ zone_gives( q{syntax08}, $zone, q{MX_DISCOURAGED_DOUBLE_DASH} ); zone_gives_not( q{syntax08}, $zone, q{NO_RESPONSE_MX_QUERY} ); $zone = Zonemaster::Engine->zone( 'name.doesnotexist' ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Syntax}, q{syntax05}, $zone ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Syntax}, q{syntax05}, $zone ); ok( $res{NO_RESPONSE_SOA_QUERY}, q{No response from nameserver(s) on SOA queries} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Syntax}, q{syntax07}, $zone ); ok( $res{NO_RESPONSE_SOA_QUERY}, q{No response from nameserver(s) on SOA queries} ); diff --git a/t/Test-syntax06-A.t b/t/Test-syntax06-A.t index 6a17f5bce..4b9779174 100644 --- a/t/Test-syntax06-A.t +++ b/t/Test-syntax06-A.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{a.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-B.t b/t/Test-syntax06-B.t index ffb73ce59..3eef0d07e 100644 --- a/t/Test-syntax06-B.t +++ b/t/Test-syntax06-B.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{b.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( $res{NO_RESPONSE}, q{should emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( $res{NO_RESPONSE}, q{should emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-C.t b/t/Test-syntax06-C.t index 910670293..bea64db20 100644 --- a/t/Test-syntax06-C.t +++ b/t/Test-syntax06-C.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{c.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( $res{NO_RESPONSE_SOA_QUERY}, q{should emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( $res{NO_RESPONSE_SOA_QUERY}, q{should emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-D.t b/t/Test-syntax06-D.t index e02e05c58..b651b6daf 100644 --- a/t/Test-syntax06-D.t +++ b/t/Test-syntax06-D.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{d.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( $res{RNAME_RFC822_INVALID}, q{should emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( $res{RNAME_RFC822_INVALID}, q{should emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-E.t b/t/Test-syntax06-E.t index 47f588842..40e11370b 100644 --- a/t/Test-syntax06-E.t +++ b/t/Test-syntax06-E.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{e.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-F.t b/t/Test-syntax06-F.t index 9d1bb38b8..8696f6ed0 100644 --- a/t/Test-syntax06-F.t +++ b/t/Test-syntax06-F.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{f.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-G.t b/t/Test-syntax06-G.t index fdc7c4561..aaa221567 100644 --- a/t/Test-syntax06-G.t +++ b/t/Test-syntax06-G.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{g.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-I.t b/t/Test-syntax06-I.t index 5207e6d6b..94ed5bf87 100644 --- a/t/Test-syntax06-I.t +++ b/t/Test-syntax06-I.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{i.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( $res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-J.t b/t/Test-syntax06-J.t index 0bc65a236..6c92f254d 100644 --- a/t/Test-syntax06-J.t +++ b/t/Test-syntax06-J.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{j.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( $res{RNAME_MAIL_DOMAIN_INVALID}, q{should emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( !$res{RNAME_RFC822_VALID}, q{should not emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( $res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-K.t b/t/Test-syntax06-K.t index 0c72499eb..d52519772 100644 --- a/t/Test-syntax06-K.t +++ b/t/Test-syntax06-K.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{k.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-syntax06-L.t b/t/Test-syntax06-L.t index 705e0113b..aac2a7dc3 100644 --- a/t/Test-syntax06-L.t +++ b/t/Test-syntax06-L.t @@ -26,11 +26,11 @@ my $zone = Zonemaster::Engine->zone( q{l.syntax06.exempelvis.se} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Syntax->syntax06( $zone ); -ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); -ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); -ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); -ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); -ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); +ok( !$res{NO_RESPONSE}, q{should not emit NO_RESPONSE} ); +ok( !$res{NO_RESPONSE_SOA_QUERY}, q{should not emit NO_RESPONSE_SOA_QUERY} ); +ok( !$res{RNAME_RFC822_INVALID}, q{should not emit RNAME_RFC822_INVALID} ); +ok( !$res{RNAME_MAIL_DOMAIN_INVALID}, q{should not emit RNAME_MAIL_DOMAIN_INVALID} ); +ok( $res{RNAME_RFC822_VALID}, q{should emit RNAME_RFC822_VALID} ); ok( !$res{RNAME_MAIL_ILLEGAL_CNAME}, q{should not emit RNAME_MAIL_ILLEGAL_CNAME} ); ok( !$res{RNAME_MAIL_DOMAIN_LOCALHOST}, q{should not emit RNAME_MAIL_DOMAIN_LOCALHOST} ); diff --git a/t/Test-zone.t b/t/Test-zone.t index 5d686a9fb..8f850edfe 100644 --- a/t/Test-zone.t +++ b/t/Test-zone.t @@ -15,7 +15,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_test); +my ( $json, $profile_test ); $json = read_file( 't/profiles/Test-zone-all.json' ); $profile_test = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_test ); @@ -26,18 +26,20 @@ my $zone; %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{afnic.fr} ); ok( $res{RETRY_MINIMUM_VALUE_LOWER}, q{SOA 'Retry' value is too low} ); ok( $res{REFRESH_MINIMUM_VALUE_LOWER}, q{SOA 'Refresh' value is too low} ); -ok( $res{Z01_MNAME_NO_RESPONSE}, q{SOA 'mname' nameserver does not respond} ); +ok( $res{Z01_MNAME_NO_RESPONSE}, q{SOA 'mname' nameserver does not respond} ); ok( $res{MNAME_IS_NOT_CNAME}, q{SOA 'mname' value refers to a NS which is not an alias} ); -ok( $res{Z01_MNAME_NOT_IN_NS_LIST}, q{SOA 'mname' nameserver is not listed in "parent" NS records for tested zone} ); +ok( $res{Z01_MNAME_NOT_IN_NS_LIST}, q{SOA 'mname' nameserver is not listed in "parent" NS records for tested zone} ); ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_OK}, q{SOA 'minimum' value is between the recommended ones} ); ok( $res{REFRESH_HIGHER_THAN_RETRY}, q{SOA 'refresh' value is higher than the SOA 'retry' value} ); -ok( $res{EXPIRE_MINIMUM_VALUE_OK}, - q{SOA 'expire' value is higher than the minimum recommended value and lower than 'refresh' value} ); +ok( + $res{EXPIRE_MINIMUM_VALUE_OK}, + q{SOA 'expire' value is higher than the minimum recommended value and lower than 'refresh' value}, +); ok( $res{MX_RECORD_IS_NOT_CNAME}, q{MX record for the domain is not pointing to a CNAME} ); -ok( $res{ONE_SOA} , q{Unique SOA returned} ); +ok( $res{ONE_SOA}, q{Unique SOA returned} ); $zone = Zonemaster::Engine->zone( q{zone01.zut-root.rd.nic.fr} ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone01}, $zone ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone01}, $zone ); ok( $res{Z01_MNAME_IS_DOT}, q{SOA 'mname' is dot ('.')} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{zone07.zut-root.rd.nic.fr} ); @@ -47,26 +49,26 @@ ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_LOWER}, q{SOA 'minimum' value is too low} # zone08 # $zone = Zonemaster::Engine->zone( q{zone08-mx-are-cname.zut-root.rd.nic.fr} ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); -ok( $res{MX_RECORD_IS_CNAME}, q{MX records are CNAME} ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); +ok( $res{MX_RECORD_IS_CNAME}, q{MX records are CNAME} ); ok( !$res{MX_RECORD_IS_NOT_CNAME}, q{MX records are CNAME (only CNAME found)} ); $zone = Zonemaster::Engine->zone( q{zone08-mx-are-not-cname.zut-root.rd.nic.fr} ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); ok( $res{MX_RECORD_IS_NOT_CNAME}, q{MX records are NOT_CNAME} ); -ok( !$res{MX_RECORD_IS_CNAME}, q{MX records are NOT_CNAME (no CNAME found)} ); +ok( !$res{MX_RECORD_IS_CNAME}, q{MX records are NOT_CNAME (no CNAME found)} ); $zone = Zonemaster::Engine->zone( q{zone08-one-mx-is-cname.zut-root.rd.nic.fr} ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); -ok( $res{MX_RECORD_IS_CNAME}, q{mixed MX records are partially CNAME} ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone08}, $zone ); +ok( $res{MX_RECORD_IS_CNAME}, q{mixed MX records are partially CNAME} ); ok( $res{MX_RECORD_IS_NOT_CNAME}, q{mixed MX records are partially NOT CNAME} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{zone02.zut-root.rd.nic.fr} ); -ok( $res{Z01_MNAME_MISSING_SOA_RECORD}, q{SOA 'mname' nameserver is not authoritative for zone} ); -ok( $res{RETRY_MINIMUM_VALUE_OK}, q{SOA 'retry' value is more than the minimum recommended value} ); -ok( $res{REFRESH_MINIMUM_VALUE_OK}, q{SOA 'refresh' value is higher than the minimum recommended value} ); -ok( $res{EXPIRE_LOWER_THAN_REFRESH}, q{SOA 'expire' value is lower than the SOA 'refresh' value} ); -ok( $res{EXPIRE_MINIMUM_VALUE_LOWER}, q{SOA 'expire' value is less than the recommended one} ); +ok( $res{Z01_MNAME_MISSING_SOA_RECORD}, q{SOA 'mname' nameserver is not authoritative for zone} ); +ok( $res{RETRY_MINIMUM_VALUE_OK}, q{SOA 'retry' value is more than the minimum recommended value} ); +ok( $res{REFRESH_MINIMUM_VALUE_OK}, q{SOA 'refresh' value is higher than the minimum recommended value} ); +ok( $res{EXPIRE_LOWER_THAN_REFRESH}, q{SOA 'expire' value is lower than the SOA 'refresh' value} ); +ok( $res{EXPIRE_MINIMUM_VALUE_LOWER}, q{SOA 'expire' value is less than the recommended one} ); ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_OK}, q{SOA 'minimum' value is between the recommended ones} ); subtest 'user defined SOA values' => sub { @@ -77,25 +79,28 @@ subtest 'user defined SOA values' => sub { my $new_retry = 7200; my $new_expire = 86400; - Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone02.SOA_REFRESH_MINIMUM_VALUE}, $new_refresh ); - Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone04.SOA_RETRY_MINIMUM_VALUE}, $new_retry ); + Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone02.SOA_REFRESH_MINIMUM_VALUE}, + $new_refresh, ); + Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone04.SOA_RETRY_MINIMUM_VALUE}, $new_retry ); Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone05.SOA_EXPIRE_MINIMUM_VALUE}, $new_expire ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, $zone ); ok( $res{REFRESH_MINIMUM_VALUE_LOWER}, q{SOA 'refresh' value is lower than the minimum user defined value} ); - ok( $res{RETRY_MINIMUM_VALUE_LOWER}, q{SOA 'retry' value is lower than the minimum user defined value} ); - ok( $res{EXPIRE_MINIMUM_VALUE_LOWER}, q{SOA 'expire' value is lower than the minimum user defined value} ); + ok( $res{RETRY_MINIMUM_VALUE_LOWER}, q{SOA 'retry' value is lower than the minimum user defined value} ); + ok( $res{EXPIRE_MINIMUM_VALUE_LOWER}, q{SOA 'expire' value is lower than the minimum user defined value} ); }; subtest 'SOA minimum TTL' => sub { my $new_ttl_min = 7200; my $new_ttl_max = 3600; - Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MINIMUM_VALUE}, $new_ttl_min ); + Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MINIMUM_VALUE}, + $new_ttl_min, ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone06}, $zone ); ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_LOWER}, q{SOA 'minimum' value is too low} ); - Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MAXIMUM_VALUE}, $new_ttl_max ); + Zonemaster::Engine::Profile->effective->set( q{test_cases_vars.zone06.SOA_DEFAULT_TTL_MAXIMUM_VALUE}, + $new_ttl_max, ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone06}, $zone ); ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_HIGHER}, q{SOA 'minimum' value is too high} ); }; @@ -105,17 +110,16 @@ subtest 'user defined SOA values' => sub { Zonemaster::Engine::Profile->effective->merge( $profile_test ); }; - %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{zone03.zut-root.rd.nic.fr} ); ok( $res{MNAME_IS_CNAME}, q{SOA 'mname' value refers to a NS which is an alias (CNAME)} ); ok( $res{REFRESH_LOWER_THAN_RETRY}, q{SOA 'refresh' value is lower than the SOA 'retry' value} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{google.tf} ); ok( $res{SOA_DEFAULT_TTL_MAXIMUM_VALUE_HIGHER}, q{SOA 'minimum' value is too high} ); -ok( $res{Z01_MNAME_IS_MASTER}, q{SOA 'mname' is authoritative master nameserver} ); +ok( $res{Z01_MNAME_IS_MASTER}, q{SOA 'mname' is authoritative master nameserver} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_module( q{Zone}, q{zone04.zut-root.rd.nic.fr} ); -ok( $res{MNAME_HAS_NO_ADDRESS}, q{No IP address found for SOA 'mname' nameserver} ); +ok( $res{MNAME_HAS_NO_ADDRESS}, q{No IP address found for SOA 'mname' nameserver} ); ok( $res{Z01_MNAME_NOT_RESOLVE}, q{No IP address found for SOA 'mname' nameserver} ); # $zone = Zonemaster::Engine->zone( 'alcatel.se' ); @@ -127,7 +131,7 @@ ok( $res{Z01_MNAME_NOT_RESOLVE}, q{No IP address found for SOA 'mname' nameserve # ok( $res{NO_RESPONSE_MX_QUERY}, q{No response from nameserver(s) on MX queries} ); $zone = Zonemaster::Engine->zone( 'name.doesnotexist' ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone02}, $zone ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone02}, $zone ); ok( $res{NO_RESPONSE_SOA_QUERY}, q{No response from nameserver(s) on SOA queries} ); %res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone03}, $zone ); ok( $res{NO_RESPONSE_SOA_QUERY}, q{No response from nameserver(s) on SOA queries} ); @@ -144,18 +148,18 @@ Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 1 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); $zone = Zonemaster::Engine->zone( q{zonemaster.net} ); -%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone01}, $zone ); +%res = map { $_->tag => 1 } Zonemaster::Engine->test_method( q{Zone}, q{zone01}, $zone ); ok( $res{Z01_MNAME_IS_MASTER}, q{SOA 'mname' is authoritative master nameserver} ); TODO: { local $TODO = "Need to find/create zones with that error"; - + # zone01 ok( $tag{Z01_MNAME_HAS_LOCALHOST_ADDR}, q{Z01_MNAME_HAS_LOCALHOST_ADDR} ); - ok( $tag{Z01_MNAME_IS_LOCALHOST}, q{Z01_MNAME_IS_LOCALHOST} ); - ok( $tag{Z01_MNAME_NOT_AUTHORITATIVE}, q{Z01_MNAME_NOT_AUTHORITATIVE} ); - ok( $tag{Z01_MNAME_NOT_MASTER}, q{Z01_MNAME_NOT_MASTER} ); - ok( $tag{Z01_MNAME_UNEXPECTED_RCODE}, q{Z01_MNAME_UNEXPECTED_RCODE} ); + ok( $tag{Z01_MNAME_IS_LOCALHOST}, q{Z01_MNAME_IS_LOCALHOST} ); + ok( $tag{Z01_MNAME_NOT_AUTHORITATIVE}, q{Z01_MNAME_NOT_AUTHORITATIVE} ); + ok( $tag{Z01_MNAME_NOT_MASTER}, q{Z01_MNAME_NOT_MASTER} ); + ok( $tag{Z01_MNAME_UNEXPECTED_RCODE}, q{Z01_MNAME_UNEXPECTED_RCODE} ); } if ( $ENV{ZONEMASTER_RECORD} ) { diff --git a/t/Test-zone01-A.t b/t/Test-zone01-A.t index 7686da14f..df22690c9 100644 --- a/t/Test-zone01-A.t +++ b/t/Test-zone01-A.t @@ -27,17 +27,17 @@ my $zone = Zonemaster::Engine->zone( q{mname-not-master.zone01.xa} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Zone->zone01( $zone ); -ok( !$res{Z01_MNAME_HAS_LOCALHOST_ADDR}, q{should not emit Z01_MNAME_HAS_LOCALHOST_ADDR} ); -ok( !$res{Z01_MNAME_IS_DOT}, q{should not emit Z01_MNAME_IS_DOT} ); -ok( !$res{Z01_MNAME_IS_LOCALHOST}, q{should not emit Z01_MNAME_IS_LOCALHOST} ); -ok( !$res{Z01_MNAME_IS_MASTER}, q{should not emit Z01_MNAME_IS_MASTER} ); -ok( !$res{Z01_MNAME_MISSING_SOA_RECORD}, q{should not emit Z01_MNAME_MISSING_SOA_RECORD} ); -ok( !$res{Z01_MNAME_NO_RESPONSE}, q{should not emit Z01_MNAME_NO_RESPONSE} ); -ok( !$res{Z01_MNAME_NOT_AUTHORITATIVE}, q{should not emit Z01_MNAME_NOT_AUTHORITATIVE} ); -ok( !$res{Z01_MNAME_NOT_IN_NS_LIST}, q{should not emit Z01_MNAME_NOT_IN_NS_LIST} ); -ok( $res{Z01_MNAME_NOT_MASTER}, q{should emit Z01_MNAME_NOT_MASTER} ); -ok( !$res{Z01_MNAME_NOT_RESOLVE}, q{should not emit Z01_MNAME_NOT_RESOLVE} ); -ok( !$res{Z01_MNAME_UNEXPECTED_RCODE}, q{should not emit Z01_MNAME_UNEXPECTED_RCODE} ); +ok( !$res{Z01_MNAME_HAS_LOCALHOST_ADDR}, q{should not emit Z01_MNAME_HAS_LOCALHOST_ADDR} ); +ok( !$res{Z01_MNAME_IS_DOT}, q{should not emit Z01_MNAME_IS_DOT} ); +ok( !$res{Z01_MNAME_IS_LOCALHOST}, q{should not emit Z01_MNAME_IS_LOCALHOST} ); +ok( !$res{Z01_MNAME_IS_MASTER}, q{should not emit Z01_MNAME_IS_MASTER} ); +ok( !$res{Z01_MNAME_MISSING_SOA_RECORD}, q{should not emit Z01_MNAME_MISSING_SOA_RECORD} ); +ok( !$res{Z01_MNAME_NO_RESPONSE}, q{should not emit Z01_MNAME_NO_RESPONSE} ); +ok( !$res{Z01_MNAME_NOT_AUTHORITATIVE}, q{should not emit Z01_MNAME_NOT_AUTHORITATIVE} ); +ok( !$res{Z01_MNAME_NOT_IN_NS_LIST}, q{should not emit Z01_MNAME_NOT_IN_NS_LIST} ); +ok( $res{Z01_MNAME_NOT_MASTER}, q{should emit Z01_MNAME_NOT_MASTER} ); +ok( !$res{Z01_MNAME_NOT_RESOLVE}, q{should not emit Z01_MNAME_NOT_RESOLVE} ); +ok( !$res{Z01_MNAME_UNEXPECTED_RCODE}, q{should not emit Z01_MNAME_UNEXPECTED_RCODE} ); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-zone01-B.t b/t/Test-zone01-B.t index 55067d0ac..03b61d67a 100644 --- a/t/Test-zone01-B.t +++ b/t/Test-zone01-B.t @@ -27,17 +27,17 @@ my $zone = Zonemaster::Engine->zone( q{multi-mname-not-master.zone01.xa} ); my %res = map { $_->tag => $_ } Zonemaster::Engine::Test::Zone->zone01( $zone ); -ok( !$res{Z01_MNAME_HAS_LOCALHOST_ADDR}, q{should not emit Z01_MNAME_HAS_LOCALHOST_ADDR} ); -ok( !$res{Z01_MNAME_IS_DOT}, q{should not emit Z01_MNAME_IS_DOT} ); -ok( !$res{Z01_MNAME_IS_LOCALHOST}, q{should not emit Z01_MNAME_IS_LOCALHOST} ); -ok( $res{Z01_MNAME_IS_MASTER}, q{should emit Z01_MNAME_IS_MASTER} ); -ok( !$res{Z01_MNAME_MISSING_SOA_RECORD}, q{should not emit Z01_MNAME_MISSING_SOA_RECORD} ); -ok( !$res{Z01_MNAME_NO_RESPONSE}, q{should not emit Z01_MNAME_NO_RESPONSE} ); -ok( !$res{Z01_MNAME_NOT_AUTHORITATIVE}, q{should not emit Z01_MNAME_NOT_AUTHORITATIVE} ); -ok( !$res{Z01_MNAME_NOT_IN_NS_LIST}, q{should not emit Z01_MNAME_NOT_IN_NS_LIST} ); -ok( $res{Z01_MNAME_NOT_MASTER}, q{should emit Z01_MNAME_NOT_MASTER} ); -ok( !$res{Z01_MNAME_NOT_RESOLVE}, q{should not emit Z01_MNAME_NOT_RESOLVE} ); -ok( !$res{Z01_MNAME_UNEXPECTED_RCODE}, q{should not emit Z01_MNAME_UNEXPECTED_RCODE} ); +ok( !$res{Z01_MNAME_HAS_LOCALHOST_ADDR}, q{should not emit Z01_MNAME_HAS_LOCALHOST_ADDR} ); +ok( !$res{Z01_MNAME_IS_DOT}, q{should not emit Z01_MNAME_IS_DOT} ); +ok( !$res{Z01_MNAME_IS_LOCALHOST}, q{should not emit Z01_MNAME_IS_LOCALHOST} ); +ok( $res{Z01_MNAME_IS_MASTER}, q{should emit Z01_MNAME_IS_MASTER} ); +ok( !$res{Z01_MNAME_MISSING_SOA_RECORD}, q{should not emit Z01_MNAME_MISSING_SOA_RECORD} ); +ok( !$res{Z01_MNAME_NO_RESPONSE}, q{should not emit Z01_MNAME_NO_RESPONSE} ); +ok( !$res{Z01_MNAME_NOT_AUTHORITATIVE}, q{should not emit Z01_MNAME_NOT_AUTHORITATIVE} ); +ok( !$res{Z01_MNAME_NOT_IN_NS_LIST}, q{should not emit Z01_MNAME_NOT_IN_NS_LIST} ); +ok( $res{Z01_MNAME_NOT_MASTER}, q{should emit Z01_MNAME_NOT_MASTER} ); +ok( !$res{Z01_MNAME_NOT_RESOLVE}, q{should not emit Z01_MNAME_NOT_RESOLVE} ); +ok( !$res{Z01_MNAME_UNEXPECTED_RCODE}, q{should not emit Z01_MNAME_UNEXPECTED_RCODE} ); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-zone09.t b/t/Test-zone09.t index f8dae1f40..34c6dc833 100644 --- a/t/Test-zone09.t +++ b/t/Test-zone09.t @@ -1,7 +1,7 @@ use strict; use warnings; -use File::Basename qw( dirname ); +use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); use lib dirname( rel2abs( $0 ) ); use TestUtil::DSL; @@ -9,56 +9,53 @@ use TestUtil::DSL; testing_test_case 'Zone', 'zone09'; all_tags qw(Z09_ARPA_EMAIL_DOMAIN - Z09_INCONSISTENT_MX - Z09_INCONSISTENT_MX_DATA - Z09_MISSING_MAIL_EXCHANGE - Z09_MX_DATA - Z09_MX_FOUND - Z09_NON_AUTH_MX_RESPONSE - Z09_NO_MX_FOUND - Z09_NO_MX_FOUND_OR_EXPECTED - Z09_NO_SERVERS_MX_RESPONSE - Z09_NO_RESPONSE_MX_QUERY - Z09_NULL_MX_NON_ZERO_PREF - Z09_NULL_MX_WITH_OTHER_MX - Z09_ROOT_EMAIL_DOMAIN - Z09_TLD_EMAIL_DOMAIN - Z09_UNEXPECTED_RCODE_MX - Z09_VALID_NULL_MX); - -root_hints 'ns1' => [ qw(127.19.9.61 fda1:b2:c3::127:19:9:61) ], - 'ns2' => [ qw(127.19.9.62 fda1:b2:c3::127:19:9:62) ]; + Z09_INCONSISTENT_MX + Z09_INCONSISTENT_MX_DATA + Z09_MISSING_MAIL_EXCHANGE + Z09_MX_DATA + Z09_MX_FOUND + Z09_NON_AUTH_MX_RESPONSE + Z09_NO_MX_FOUND + Z09_NO_MX_FOUND_OR_EXPECTED + Z09_NO_SERVERS_MX_RESPONSE + Z09_NO_RESPONSE_MX_QUERY + Z09_NULL_MX_NON_ZERO_PREF + Z09_NULL_MX_WITH_OTHER_MX + Z09_ROOT_EMAIL_DOMAIN + Z09_TLD_EMAIL_DOMAIN + Z09_UNEXPECTED_RCODE_MX + Z09_VALID_NULL_MX); + +root_hints + 'ns1' => [qw(127.19.9.61 fda1:b2:c3::127:19:9:61)], + 'ns2' => [qw(127.19.9.62 fda1:b2:c3::127:19:9:62)]; zone_name_template '{SCENARIO}.{TESTCASE}.xa'; scenario 'NO-RESPONSE-MX-QUERY-1' => sub { - expect Z09_NO_RESPONSE_MX_QUERY => { - ns_list => 'ns2.no-response-mx-query-1.zone09.xa/127.19.9.32;' - . 'ns2.no-response-mx-query-1.zone09.xa/fda1:b2:c3:0:127:19:9:32' - }; + expect Z09_NO_RESPONSE_MX_QUERY => { ns_list => 'ns2.no-response-mx-query-1.zone09.xa/127.19.9.32;' + . 'ns2.no-response-mx-query-1.zone09.xa/fda1:b2:c3:0:127:19:9:32' }; expect Z09_MX_DATA => { mxrdata_list => '10 mail.no-response-mx-query-1.zone09.xa', - ns_list => 'ns1.no-response-mx-query-1.zone09.xa/127.19.9.31;' - . 'ns1.no-response-mx-query-1.zone09.xa/fda1:b2:c3:0:127:19:9:31' + ns_list => 'ns1.no-response-mx-query-1.zone09.xa/127.19.9.31;' + . 'ns1.no-response-mx-query-1.zone09.xa/fda1:b2:c3:0:127:19:9:31', }; forbid_others; }; scenario 'NO-RESPONSE-MX-QUERY-2' => sub { - expect Z09_NO_RESPONSE_MX_QUERY => { - ns_list => 'ns1.no-response-mx-query-2.zone09.xa/127.19.9.31;' - . 'ns1.no-response-mx-query-2.zone09.xa/fda1:b2:c3:0:127:19:9:31;' - . 'ns2.no-response-mx-query-2.zone09.xa/127.19.9.32;' - . 'ns2.no-response-mx-query-2.zone09.xa/fda1:b2:c3:0:127:19:9:32' - }; + expect Z09_NO_RESPONSE_MX_QUERY => { ns_list => 'ns1.no-response-mx-query-2.zone09.xa/127.19.9.31;' + . 'ns1.no-response-mx-query-2.zone09.xa/fda1:b2:c3:0:127:19:9:31;' + . 'ns2.no-response-mx-query-2.zone09.xa/127.19.9.32;' + . 'ns2.no-response-mx-query-2.zone09.xa/fda1:b2:c3:0:127:19:9:32' }; expect 'Z09_NO_SERVERS_MX_RESPONSE'; forbid_others; }; scenario 'UNEXPECTED-RCODE-MX' => sub { expect Z09_UNEXPECTED_RCODE_MX => { - rcode => 'NOTIMPL', + rcode => 'NOTIMPL', ns_list => 'ns1.unexpected-rcode-mx.zone09.xa/127.19.9.31;' - . 'ns1.unexpected-rcode-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31' + . 'ns1.unexpected-rcode-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31', }; expect 'Z09_MISSING_MAIL_EXCHANGE'; forbid_others; @@ -67,31 +64,25 @@ scenario 'UNEXPECTED-RCODE-MX' => sub { scenario 'NON-AUTH-MX-RESPONSE' => sub { not_testable 'see https://github.com/zonemaster/zonemaster/pull/1517#discussion_r3595385839'; - expect Z09_NON_AUTH_MX_RESPONSE => { - ns_list => 'ns4.non-auth-mx-response.zone09.xa/127.19.9.34;' - . 'ns4.non-auth-mx-response.zone09.xa/fda1:b2:c3:0:127:19:9:34' - }; + expect Z09_NON_AUTH_MX_RESPONSE => { ns_list => 'ns4.non-auth-mx-response.zone09.xa/127.19.9.34;' + . 'ns4.non-auth-mx-response.zone09.xa/fda1:b2:c3:0:127:19:9:34' }; expect Z09_MX_DATA => { mxrdata_list => '10 mail.non-auth-mx-response.zone09.xa', - ns_list => sub { split(/;/, $_->{args}{ns_list}) == 4 } + ns_list => sub { split( /;/, $_->{args}{ns_list} ) == 4 }, }; forbid_others; }; scenario 'INCONSISTENT-MX' => sub { expect 'Z09_INCONSISTENT_MX'; - expect Z09_MX_FOUND => { - ns_list => 'ns1.inconsistent-mx.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31' - }; - expect Z09_NO_MX_FOUND => { - ns_list => 'ns2.inconsistent-mx.zone09.xa/127.19.9.32;' - . 'ns2.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:32' - }; + expect Z09_MX_FOUND => { ns_list => 'ns1.inconsistent-mx.zone09.xa/127.19.9.31;' + . 'ns1.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31' }; + expect Z09_NO_MX_FOUND => { ns_list => 'ns2.inconsistent-mx.zone09.xa/127.19.9.32;' + . 'ns2.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:32' }; expect Z09_MX_DATA => { ns_list => 'ns1.inconsistent-mx.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31', - mxrdata_list => '10 mail.inconsistent-mx.zone09.xa' + . 'ns1.inconsistent-mx.zone09.xa/fda1:b2:c3:0:127:19:9:31', + mxrdata_list => '10 mail.inconsistent-mx.zone09.xa', }; forbid_others; @@ -101,14 +92,13 @@ scenario 'INCONSISTENT-MX-DATA-1' => sub { expect 'Z09_INCONSISTENT_MX_DATA'; expect Z09_MX_DATA => { ns_list => 'ns1.inconsistent-mx-data-1.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx-data-1.zone09.xa/fda1:b2:c3:0:127:19:9:31', - mxrdata_list => '10 mail.inconsistent-mx-data-1.zone09.xa;' - . '10 mail2.inconsistent-mx-data-1.zone09.xa' + . 'ns1.inconsistent-mx-data-1.zone09.xa/fda1:b2:c3:0:127:19:9:31', + mxrdata_list => '10 mail.inconsistent-mx-data-1.zone09.xa;' . '10 mail2.inconsistent-mx-data-1.zone09.xa', }; expect Z09_MX_DATA => { ns_list => 'ns2.inconsistent-mx-data-1.zone09.xa/127.19.9.32;' - . 'ns2.inconsistent-mx-data-1.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '10 mail2.inconsistent-mx-data-1.zone09.xa' + . 'ns2.inconsistent-mx-data-1.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '10 mail2.inconsistent-mx-data-1.zone09.xa', }; forbid_others; }; @@ -117,13 +107,13 @@ scenario 'INCONSISTENT-MX-DATA-2' => sub { expect 'Z09_INCONSISTENT_MX_DATA'; expect Z09_MX_DATA => { ns_list => 'ns1.inconsistent-mx-data-2.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx-data-2.zone09.xa/fda1:b2:c3:0:127:19:9:31', - mxrdata_list => '20 mail2.inconsistent-mx-data-2.zone09.xa' + . 'ns1.inconsistent-mx-data-2.zone09.xa/fda1:b2:c3:0:127:19:9:31', + mxrdata_list => '20 mail2.inconsistent-mx-data-2.zone09.xa', }; expect Z09_MX_DATA => { ns_list => 'ns2.inconsistent-mx-data-2.zone09.xa/127.19.9.32;' - . 'ns2.inconsistent-mx-data-2.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '10 mail2.inconsistent-mx-data-2.zone09.xa' + . 'ns2.inconsistent-mx-data-2.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '10 mail2.inconsistent-mx-data-2.zone09.xa', }; forbid_others; }; @@ -132,15 +122,13 @@ scenario 'INCONSISTENT-MX-DATA-3' => sub { expect 'Z09_INCONSISTENT_MX_DATA'; expect Z09_MX_DATA => { ns_list => 'ns1.inconsistent-mx-data-3.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx-data-3.zone09.xa/fda1:b2:c3:0:127:19:9:31', - mxrdata_list => '10 mail.inconsistent-mx-data-3.zone09.xa;' - . '20 mail2.inconsistent-mx-data-3.zone09.xa' + . 'ns1.inconsistent-mx-data-3.zone09.xa/fda1:b2:c3:0:127:19:9:31', + mxrdata_list => '10 mail.inconsistent-mx-data-3.zone09.xa;' . '20 mail2.inconsistent-mx-data-3.zone09.xa', }; expect Z09_MX_DATA => { ns_list => 'ns2.inconsistent-mx-data-3.zone09.xa/127.19.9.32;' - . 'ns2.inconsistent-mx-data-3.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '10 mail2.inconsistent-mx-data-3.zone09.xa;' - . '20 mail.inconsistent-mx-data-3.zone09.xa' + . 'ns2.inconsistent-mx-data-3.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '10 mail2.inconsistent-mx-data-3.zone09.xa;' . '20 mail.inconsistent-mx-data-3.zone09.xa', }; forbid_others; }; @@ -149,14 +137,13 @@ scenario 'INCONSISTENT-MX-DATA-4' => sub { expect 'Z09_INCONSISTENT_MX_DATA'; expect Z09_MX_DATA => { ns_list => 'ns1.inconsistent-mx-data-4.zone09.xa/127.19.9.31;' - . 'ns1.inconsistent-mx-data-4.zone09.xa/fda1:b2:c3:0:127:19:9:31', - mxrdata_list => '10 mail.inconsistent-mx-data-4.zone09.xa;' - . '20 mail.inconsistent-mx-data-4.zone09.xa' + . 'ns1.inconsistent-mx-data-4.zone09.xa/fda1:b2:c3:0:127:19:9:31', + mxrdata_list => '10 mail.inconsistent-mx-data-4.zone09.xa;' . '20 mail.inconsistent-mx-data-4.zone09.xa', }; expect Z09_MX_DATA => { ns_list => 'ns2.inconsistent-mx-data-4.zone09.xa/127.19.9.32;' - . 'ns2.inconsistent-mx-data-4.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '10 mail.inconsistent-mx-data-4.zone09.xa' + . 'ns2.inconsistent-mx-data-4.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '10 mail.inconsistent-mx-data-4.zone09.xa', }; forbid_others; }; @@ -164,11 +151,10 @@ scenario 'INCONSISTENT-MX-DATA-4' => sub { scenario 'MIXED-CASE-RDATA-1' => sub { expect Z09_MX_DATA => { ns_list => 'ns1.mixed-case-rdata-1.zone09.xa/127.19.9.31;' - . 'ns1.mixed-case-rdata-1.zone09.xa/fda1:b2:c3:0:127:19:9:31;' - . 'ns2.mixed-case-rdata-1.zone09.xa/127.19.9.32;' - . 'ns2.mixed-case-rdata-1.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '10 mail.mixed-case-rdata-1.zone09.xa;' - . '20 mail2.mixed-case-rdata-1.zone09.xa' + . 'ns1.mixed-case-rdata-1.zone09.xa/fda1:b2:c3:0:127:19:9:31;' + . 'ns2.mixed-case-rdata-1.zone09.xa/127.19.9.32;' + . 'ns2.mixed-case-rdata-1.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '10 mail.mixed-case-rdata-1.zone09.xa;' . '20 mail2.mixed-case-rdata-1.zone09.xa', }; forbid_others; }; @@ -180,10 +166,10 @@ scenario 'MIXED-CASE-RDATA-2' => sub { expect Z09_MX_DATA => { ns_list => 'ns1.mixed-case-rdata-2.zone09.xa/127.19.9.31;' - . 'ns1.mixed-case-rdata-2.zone09.xa/fda1:b2:c3:0:127:19:9:31;' - . 'ns2.mixed-case-rdata-2.zone09.xa/127.19.9.32;' - . 'ns2.mixed-case-rdata-2.zone09.xa/fda1:b2:c3:0:127:19:9:32', - mxrdata_list => '20 mail2.mixed-case-rdata-2.zone09.xa' + . 'ns1.mixed-case-rdata-2.zone09.xa/fda1:b2:c3:0:127:19:9:31;' + . 'ns2.mixed-case-rdata-2.zone09.xa/127.19.9.32;' + . 'ns2.mixed-case-rdata-2.zone09.xa/fda1:b2:c3:0:127:19:9:32', + mxrdata_list => '20 mail2.mixed-case-rdata-2.zone09.xa', }; forbid_others; }; @@ -278,8 +264,9 @@ scenario 'NO-MX-ROOT' => sub { # Override root hints for scenario ROOT-EMAIL-DOMAIN -root_hints 'ns1' => [ qw(127.19.9.63 fda1:b2:c3::127:19:9:63) ], - 'ns2' => [ qw(127.19.9.64 fda1:b2:c3::127:19:9:64) ]; +root_hints + 'ns1' => [qw(127.19.9.63 fda1:b2:c3::127:19:9:63)], + 'ns2' => [qw(127.19.9.64 fda1:b2:c3::127:19:9:64)]; scenario 'ROOT-EMAIL-DOMAIN' => sub { expect 'Z09_ROOT_EMAIL_DOMAIN'; @@ -289,8 +276,9 @@ scenario 'ROOT-EMAIL-DOMAIN' => sub { # Override root hints for scenario NULL-MX-ROOT -root_hints 'ns1' => [ qw(127.19.9.65 fda1:b2:c3::127:19:9:65) ], - 'ns2' => [ qw(127.19.9.66 fda1:b2:c3::127:19:9:66) ]; +root_hints + 'ns1' => [qw(127.19.9.65 fda1:b2:c3::127:19:9:65)], + 'ns2' => [qw(127.19.9.66 fda1:b2:c3::127:19:9:66)]; scenario 'NULL-MX-ROOT' => sub { expect 'Z09_VALID_NULL_MX'; @@ -298,5 +286,4 @@ scenario 'NULL-MX-ROOT' => sub { forbid_others; }; - no_more_scenarios; diff --git a/t/Test-zone11-1.t b/t/Test-zone11-1.t index 1a0700833..e9f2fa220 100644 --- a/t/Test-zone11-1.t +++ b/t/Test-zone11-1.t @@ -16,24 +16,26 @@ BEGIN { ########### # Zone11 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Zone-TP/zone11.md my $test_module = q{Zone}; -my $test_case = 'zone11'; -my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND - Z11_INCONSISTENT_SPF_POLICIES - Z11_NO_SPF_FOUND - Z11_NO_SPF_NON_MAIL_DOMAIN - Z11_NON_NULL_SPF_NON_MAIL_DOMAIN - Z11_NULL_SPF_NON_MAIL_DOMAIN - Z11_SPF_MULTIPLE_RECORDS - Z11_SPF_SYNTAX_ERROR - Z11_SPF_SYNTAX_OK - Z11_UNABLE_TO_CHECK_FOR_SPF); +my $test_case = 'zone11'; +my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND + Z11_INCONSISTENT_SPF_POLICIES + Z11_NO_SPF_FOUND + Z11_NO_SPF_NON_MAIL_DOMAIN + Z11_NON_NULL_SPF_NON_MAIL_DOMAIN + Z11_NULL_SPF_NON_MAIL_DOMAIN + Z11_SPF_MULTIPLE_RECORDS + Z11_SPF_SYNTAX_ERROR + Z11_SPF_SYNTAX_OK + Z11_UNABLE_TO_CHECK_FOR_SPF); # Specific hint file (test-zone-data/Zone-TP/zone11/no-spf.hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.19.11.41', 'fda1:b2:c3::127:19:11:41' ], - 'ns2' => [ '127.19.11.42', 'fda1:b2:c3::127:19:11:42' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.19.11.41', 'fda1:b2:c3::127:19:11:41' ], + 'ns2' => [ '127.19.11.42', 'fda1:b2:c3::127:19:11:42' ], + }, ); # Test zone scenarios @@ -50,20 +52,11 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # - One of MANDATORY_MESSAGE_TAGS and FORBIDDEN_MESSAGE_TAGS may be undefined. # See documentation for the meaning of that. -my %subtests = ( - 'NO-SPF-ROOT-ZONE' => [ - 1, - q(.), - [ qw( Z11_NO_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ] -); +my %subtests = ( 'NO-SPF-ROOT-ZONE' => [ 1, q(.), [qw( Z11_NO_SPF_NON_MAIL_DOMAIN )], undef, [], [] ] ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -71,9 +64,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-zone11-2.t b/t/Test-zone11-2.t index 8c41c844c..dedb89ee6 100644 --- a/t/Test-zone11-2.t +++ b/t/Test-zone11-2.t @@ -16,24 +16,26 @@ BEGIN { ########### # Zone11 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Zone-TP/zone11.md my $test_module = q{Zone}; -my $test_case = 'zone11'; -my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND - Z11_INCONSISTENT_SPF_POLICIES - Z11_NO_SPF_FOUND - Z11_NO_SPF_NON_MAIL_DOMAIN - Z11_NON_NULL_SPF_NON_MAIL_DOMAIN - Z11_NULL_SPF_NON_MAIL_DOMAIN - Z11_SPF_MULTIPLE_RECORDS - Z11_SPF_SYNTAX_ERROR - Z11_SPF_SYNTAX_OK - Z11_UNABLE_TO_CHECK_FOR_SPF); +my $test_case = 'zone11'; +my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND + Z11_INCONSISTENT_SPF_POLICIES + Z11_NO_SPF_FOUND + Z11_NO_SPF_NON_MAIL_DOMAIN + Z11_NON_NULL_SPF_NON_MAIL_DOMAIN + Z11_NULL_SPF_NON_MAIL_DOMAIN + Z11_SPF_MULTIPLE_RECORDS + Z11_SPF_SYNTAX_ERROR + Z11_SPF_SYNTAX_OK + Z11_UNABLE_TO_CHECK_FOR_SPF); # Specific hint file (test-zone-data/Zone-TP/zone11/null-spf.hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.19.11.43', 'fda1:b2:c3::127:19:11:43' ], - 'ns2' => [ '127.19.11.44', 'fda1:b2:c3::127:19:11:44' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.19.11.43', 'fda1:b2:c3::127:19:11:43' ], + 'ns2' => [ '127.19.11.44', 'fda1:b2:c3::127:19:11:44' ], + }, ); # Test zone scenarios @@ -50,20 +52,11 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # - One of MANDATORY_MESSAGE_TAGS and FORBIDDEN_MESSAGE_TAGS may be undefined. # See documentation for the meaning of that. -my %subtests = ( - 'NULL-SPF-ROOT-ZONE' => [ - 1, - q(.), - [ qw( Z11_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ] -); +my %subtests = ( 'NULL-SPF-ROOT-ZONE' => [ 1, q(.), [qw( Z11_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ] ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -71,9 +64,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-zone11-3.t b/t/Test-zone11-3.t index fabc35a33..bf172aae5 100644 --- a/t/Test-zone11-3.t +++ b/t/Test-zone11-3.t @@ -16,24 +16,26 @@ BEGIN { ########### # Zone11 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Zone-TP/zone11.md my $test_module = q{Zone}; -my $test_case = 'zone11'; -my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND - Z11_INCONSISTENT_SPF_POLICIES - Z11_NO_SPF_FOUND - Z11_NO_SPF_NON_MAIL_DOMAIN - Z11_NON_NULL_SPF_NON_MAIL_DOMAIN - Z11_NULL_SPF_NON_MAIL_DOMAIN - Z11_SPF_MULTIPLE_RECORDS - Z11_SPF_SYNTAX_ERROR - Z11_SPF_SYNTAX_OK - Z11_UNABLE_TO_CHECK_FOR_SPF); +my $test_case = 'zone11'; +my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND + Z11_INCONSISTENT_SPF_POLICIES + Z11_NO_SPF_FOUND + Z11_NO_SPF_NON_MAIL_DOMAIN + Z11_NON_NULL_SPF_NON_MAIL_DOMAIN + Z11_NULL_SPF_NON_MAIL_DOMAIN + Z11_SPF_MULTIPLE_RECORDS + Z11_SPF_SYNTAX_ERROR + Z11_SPF_SYNTAX_OK + Z11_UNABLE_TO_CHECK_FOR_SPF); # Specific hint file (test-zone-data/Zone-TP/zone11/non-null-spf.hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.19.11.45', 'fda1:b2:c3::127:19:11:45' ], - 'ns2' => [ '127.19.11.46', 'fda1:b2:c3::127:19:11:46' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.19.11.45', 'fda1:b2:c3::127:19:11:45' ], + 'ns2' => [ '127.19.11.46', 'fda1:b2:c3::127:19:11:46' ], + }, ); # Test zone scenarios @@ -50,20 +52,11 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # - One of MANDATORY_MESSAGE_TAGS and FORBIDDEN_MESSAGE_TAGS may be undefined. # See documentation for the meaning of that. -my %subtests = ( - 'NON-NULL-SPF-ROOT-ZONE' => [ - 1, - q(.), - [ qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ] -); +my %subtests = ( 'NON-NULL-SPF-ROOT-ZONE' => [ 1, q(.), [qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ] ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -71,9 +64,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test-zone11.t b/t/Test-zone11.t index 70fcf6083..4e47cb991 100644 --- a/t/Test-zone11.t +++ b/t/Test-zone11.t @@ -16,24 +16,26 @@ BEGIN { ########### # Zone11 - https://github.com/zonemaster/zonemaster/blob/master/docs/public/specifications/test-zones/Zone-TP/zone11.md my $test_module = q{Zone}; -my $test_case = 'zone11'; -my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND - Z11_INCONSISTENT_SPF_POLICIES - Z11_NO_SPF_FOUND - Z11_NO_SPF_NON_MAIL_DOMAIN - Z11_NON_NULL_SPF_NON_MAIL_DOMAIN - Z11_NULL_SPF_NON_MAIL_DOMAIN - Z11_SPF_MULTIPLE_RECORDS - Z11_SPF_SYNTAX_ERROR - Z11_SPF_SYNTAX_OK - Z11_UNABLE_TO_CHECK_FOR_SPF); +my $test_case = 'zone11'; +my @all_tags = qw(Z11_DIFFERENT_SPF_POLICIES_FOUND + Z11_INCONSISTENT_SPF_POLICIES + Z11_NO_SPF_FOUND + Z11_NO_SPF_NON_MAIL_DOMAIN + Z11_NON_NULL_SPF_NON_MAIL_DOMAIN + Z11_NULL_SPF_NON_MAIL_DOMAIN + Z11_SPF_MULTIPLE_RECORDS + Z11_SPF_SYNTAX_ERROR + Z11_SPF_SYNTAX_OK + Z11_UNABLE_TO_CHECK_FOR_SPF); # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -51,180 +53,55 @@ Zonemaster::Engine::Recursor->add_fake_addresses( '.', # See documentation for the meaning of that. my %subtests = ( - 'GOOD-SPF-1' => [ - 1, - q(good-spf-1.zone11.xa), - [ qw( Z11_SPF_SYNTAX_OK ) ], - undef, - [], - [] - ], - 'GOOD-SPF-2' => [ - 1, - q(good-spf-2.zone11.xa), - [ qw( Z11_SPF_SYNTAX_OK ) ], - undef, - [], - [] - ], - 'SAME-SPF-DIFFERENT-TXT' => [ - 1, - q(same-spf-different-txt.zone11.xa), - [ qw( Z11_SPF_SYNTAX_OK ) ], - undef, - [], - [] - ], - 'NO-TXT' => [ - 1, - q(no-txt.zone11.xa), - [ qw( Z11_NO_SPF_FOUND ) ], - undef, - [], - [] - ], - 'NO-SPF-TXT' => [ - 1, - q(no-spf-txt.zone11.xa), - [ qw( Z11_NO_SPF_FOUND ) ], - undef, - [], - [] - ], + 'GOOD-SPF-1' => [ 1, q(good-spf-1.zone11.xa), [qw( Z11_SPF_SYNTAX_OK )], undef, [], [] ], + 'GOOD-SPF-2' => [ 1, q(good-spf-2.zone11.xa), [qw( Z11_SPF_SYNTAX_OK )], undef, [], [] ], + 'SAME-SPF-DIFFERENT-TXT' => [ 1, q(same-spf-different-txt.zone11.xa), [qw( Z11_SPF_SYNTAX_OK )], undef, [], [] ], + 'NO-TXT' => [ 1, q(no-txt.zone11.xa), [qw( Z11_NO_SPF_FOUND )], undef, [], [] ], + 'NO-SPF-TXT' => [ 1, q(no-spf-txt.zone11.xa), [qw( Z11_NO_SPF_FOUND )], undef, [], [] ], # # NO-SPF-ROOT-ZONE - Tested separately, see Test-zone11-1.t # - 'NO-SPF-TLD-ZONE' => [ - 1, - q(no-spf-zone11), - [ qw( Z11_NO_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], - 'NO-SPF-ARPA-ZONE' => [ - 1, - q(no-spf-arpa-zone.zone11.arpa), - [ qw( Z11_NO_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], + 'NO-SPF-TLD-ZONE' => [ 1, q(no-spf-zone11), [qw( Z11_NO_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], + 'NO-SPF-ARPA-ZONE' => [ 1, q(no-spf-arpa-zone.zone11.arpa), [qw( Z11_NO_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], # # NULL-SPF-ROOT-ZONE - Tested separately, see Test-zone11-2.t # - 'NULL-SPF-TLD-ZONE' => [ - 1, - q(null-spf-zone11), - [ qw( Z11_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], - 'NULL-SPF-ARPA-ZONE' => [ - 1, - q(null-spf-arpa-zone.zone11.arpa), - [ qw( Z11_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], + 'NULL-SPF-TLD-ZONE' => [ 1, q(null-spf-zone11), [qw( Z11_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], + 'NULL-SPF-ARPA-ZONE' => + [ 1, q(null-spf-arpa-zone.zone11.arpa), [qw( Z11_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], # # NON-NULL-SPF-ROOT-ZONE - Tested separately, see Test-zone11-3.t # - 'NON-NULL-SPF-TLD-ZONE' => [ - 1, - q(non-null-spf-zone11), - [ qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], - 'NON-NULL-SPF-ARPA-ZONE' => [ - 1, - q(non-null-spf-arpa-zone.zone11.arpa), - [ qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN ) ], - undef, - [], - [] - ], - 'INVALID-SYNTAX-1' => [ - 1, - q(invalid-syntax-1.zone11.xa), - [ qw( Z11_SPF_SYNTAX_ERROR ) ], - undef, - [], - [] - ], - 'INVALID-SYNTAX-2' => [ - 1, - q(invalid-syntax-2.zone11.xa), - [ qw( Z11_SPF_SYNTAX_ERROR ) ], - undef, - [], - [] - ], - 'INVALID-SYNTAX-3' => [ - 1, - q(invalid-syntax-3.zone11.xa), - [ qw( Z11_SPF_SYNTAX_ERROR ) ], - undef, - [], - [] - ], - 'NON-AUTH-TXT' => [ - 1, - q(non-auth-txt.zone11.xa), - [ qw( Z11_UNABLE_TO_CHECK_FOR_SPF ) ], - undef, - [], - [] - ], - 'SERVFAIL' => [ - 1, - q(servfail.zone11.xa), - [ qw( Z11_UNABLE_TO_CHECK_FOR_SPF ) ], - undef, - [], - [] - ], + 'NON-NULL-SPF-TLD-ZONE' => [ 1, q(non-null-spf-zone11), [qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], + 'NON-NULL-SPF-ARPA-ZONE' => + [ 1, q(non-null-spf-arpa-zone.zone11.arpa), [qw( Z11_NON_NULL_SPF_NON_MAIL_DOMAIN )], undef, [], [] ], + 'INVALID-SYNTAX-1' => [ 1, q(invalid-syntax-1.zone11.xa), [qw( Z11_SPF_SYNTAX_ERROR )], undef, [], [] ], + 'INVALID-SYNTAX-2' => [ 1, q(invalid-syntax-2.zone11.xa), [qw( Z11_SPF_SYNTAX_ERROR )], undef, [], [] ], + 'INVALID-SYNTAX-3' => [ 1, q(invalid-syntax-3.zone11.xa), [qw( Z11_SPF_SYNTAX_ERROR )], undef, [], [] ], + 'NON-AUTH-TXT' => [ 1, q(non-auth-txt.zone11.xa), [qw( Z11_UNABLE_TO_CHECK_FOR_SPF )], undef, [], [] ], + 'SERVFAIL' => [ 1, q(servfail.zone11.xa), [qw( Z11_UNABLE_TO_CHECK_FOR_SPF )], undef, [], [] ], 'INCONSISTENT-SPF' => [ - 1, - q(INCONSISTENT-SPF.zone11.xa), - [ qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND ) ], - undef, - [], - [] + 1, q(INCONSISTENT-SPF.zone11.xa), [qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND )], + undef, [], [], ], 'SPF-MISSING-ON-ONE' => [ 1, q(spf-missing-on-one.zone11.xa), - [ qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND ) ], - undef, - [], - [] + [qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND )], + undef, [], [], ], 'ALL-DIFFERENT-SPF' => [ 1, q(all-different-spf.zone11.xa), - [ qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND ) ], - undef, - [], - [] + [qw( Z11_INCONSISTENT_SPF_POLICIES Z11_DIFFERENT_SPF_POLICIES_FOUND )], + undef, [], [], ], - 'MULTIPLE-SPF-RECORDS' => [ - 1, - q(multiple-spf-records.zone11.xa), - [ qw( Z11_SPF_MULTIPLE_RECORDS ) ], - undef, - [], - [] - ] + 'MULTIPLE-SPF-RECORDS' => [ 1, q(multiple-spf-records.zone11.xa), [qw( Z11_SPF_MULTIPLE_RECORDS )], undef, [], [] ], ); ########### -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die q{Stored data file missing} if not -r $datafile; @@ -232,9 +109,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->merge( Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); +Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": [ "$test_case" ] }) ) ); -perform_testcase_testing( $test_case, $test_module, \@all_tags, \%subtests, $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); +perform_testcase_testing( + $test_case, $test_module, \@all_tags, \%subtests, + $ENV{ZONEMASTER_SELECTED_SCENARIOS}, + $ENV{ZONEMASTER_DISABLED_SCENARIOS}, +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/Test.t b/t/Test.t index 9800398e3..c6a6593c6 100644 --- a/t/Test.t +++ b/t/Test.t @@ -31,41 +31,41 @@ subtest 'Enabling single test cases in profile' => sub { for my $testcase ( @testcases ) { SKIP: { - skip "$testcase, not possible with recorded data due to scrambled case of QNAME", 1 + skip "$testcase, not possible with recorded data due to scrambled case of QNAME", 1 if $testcase =~ '^nameserver(08|09)$' and not $ENV{ZONEMASTER_RECORD}; - subtest "Testcase '$testcase'" => sub { + subtest "Testcase '$testcase'" => sub { - $effective_profile->set( 'test_cases', [$testcase] ); + $effective_profile->set( 'test_cases', [$testcase] ); - my @logentries; - lives_ok { @logentries = Zonemaster::Engine::Test->run_all_for( $zone ) } - "Test suite does not crash when running only this test case"; + my @logentries; + lives_ok { @logentries = Zonemaster::Engine::Test->run_all_for( $zone ) } + "Test suite does not crash when running only this test case"; - my $actual = { - 'A) started testcases' => [ - grep { $_ ne 'unspecified' } - map { fc $_->args->{testcase} } - grep { $_->tag eq 'TEST_CASE_START' } @logentries - ], - 'B) ended testcases' => [ - grep { $_ ne 'unspecified' } - map { fc $_->args->{testcase} } - grep { $_->tag eq 'TEST_CASE_END' } @logentries - ], - 'C) internal errors' => [ - map { $_->args->{msg} =~ s/\n$//r } - grep { $_->tag eq 'MODULE_ERROR' } @logentries - ], - }; - my $expected = { - 'A) started testcases' => [$testcase], - 'B) ended testcases' => [$testcase], - 'C) internal errors' => [], - }; - eq_or_diff $actual, $expected, "Test suite emits expected messages from this testcase and no others"; - }; - }; + my $actual = { + 'A) started testcases' => [ + grep { $_ ne 'unspecified' } + map { fc $_->args->{testcase} } + grep { $_->tag eq 'TEST_CASE_START' } @logentries + ], + 'B) ended testcases' => [ + grep { $_ ne 'unspecified' } + map { fc $_->args->{testcase} } + grep { $_->tag eq 'TEST_CASE_END' } @logentries + ], + 'C) internal errors' => [ + map { $_->args->{msg} =~ s/\n$//r } + grep { $_->tag eq 'MODULE_ERROR' } @logentries + ], + }; + my $expected = { + 'A) started testcases' => [$testcase], + 'B) ended testcases' => [$testcase], + 'C) internal errors' => [], + }; + eq_or_diff $actual, $expected, "Test suite emits expected messages from this testcase and no others"; + }; + } ## end SKIP: } ## end for my $testcase ( @testcases) }; diff --git a/t/TestUtil.pm b/t/TestUtil.pm index a66864a60..abb98a084 100644 --- a/t/TestUtil.pm +++ b/t/TestUtil.pm @@ -8,13 +8,13 @@ use warnings; use Test::More; use Zonemaster::Engine; use Exporter 'import'; -use List::MoreUtils qw[ uniq ]; +use List::MoreUtils qw[ uniq ]; use Zonemaster::Engine::Validation qw( validate_ipv4 validate_ipv6 ); use Carp qw( croak ); BEGIN { - our @EXPORT_OK = qw[ perform_testcase_testing perform_methodsv2_testing ]; + our @EXPORT_OK = qw[ perform_testcase_testing perform_methodsv2_testing ]; our %EXPORT_TAGS = ( all => \@EXPORT_OK ); ## no critic (Modules::ProhibitAutomaticExportation) @@ -165,15 +165,16 @@ Takes a string (scenario name) and a reference to an array of strings (delegatio sub _check_ns_expressions { my ( $scenario, $ns_expressions ) = @_; - return if ! defined $ns_expressions; + return if !defined $ns_expressions; - foreach my $nsexp ( @{ $ns_expressions } ) { + foreach my $nsexp ( @{$ns_expressions} ) { my ( $ns, $ip ) = split m(/), $nsexp; croak "Scenario $scenario: Name server name '$ns' in '$nsexp' is not valid" if $ns !~ /^[0-9A-Za-z-.]+$/; if ( $ip ) { croak "Scenario $scenario: IP address '$ip' in '$nsexp' is not valid" - unless validate_ipv4( $ip ) or validate_ipv6( $ip ); + unless validate_ipv4( $ip ) + or validate_ipv6( $ip ); } } } @@ -181,12 +182,15 @@ sub _check_ns_expressions { sub _check_ds_expressions { my ( $scenario, $ds_expressions ) = @_; - return if ! defined $ds_expressions; + return if !defined $ds_expressions; - foreach my $str ( @{ $ds_expressions } ) { + foreach my $str ( @{$ds_expressions} ) { my ( $tag, $algo, $type, $digest ) = split( /,/, $str ); - croak "Scenario $scenario: DS expression '$str' is not valid" if - $tag !~ /^[0-9]+$/ or $algo !~ /^[0-9]+$/ or $type !~ /^[0-9]+$/ or $digest !~ /^[0-9a-fA-F]{4,}/; + croak "Scenario $scenario: DS expression '$str' is not valid" + if $tag !~ /^[0-9]+$/ + or $algo !~ /^[0-9]+$/ + or $type !~ /^[0-9]+$/ + or $digest !~ /^[0-9a-fA-F]{4,}/; } } @@ -194,13 +198,13 @@ sub perform_methodsv2_testing { my ( $href_subtests, $selected_scenarios, $disabled_scenarios ) = @_; my %subtests = %$href_subtests; - my @selected_scenarios = map {uc} split(/, */, $selected_scenarios) if $selected_scenarios; - my @disabled_scenarios = map {uc} split(/, */, $disabled_scenarios) if $disabled_scenarios; - + my @selected_scenarios = map { uc } split( /, */, $selected_scenarios ) if $selected_scenarios; + my @disabled_scenarios = map { uc } split( /, */, $disabled_scenarios ) if $disabled_scenarios; + my @untested_scenarios = (); if ( $selected_scenarios ) { - foreach my $scen (@selected_scenarios) { + foreach my $scen ( @selected_scenarios ) { unless ( exists $subtests{$scen} ) { croak "Scenario $scen does not exist"; } @@ -213,30 +217,24 @@ sub perform_methodsv2_testing { push @untested_scenarios, $scenario; next; } - - if ( ref( $scenario ) ne '' or $scenario ne uc($scenario) ) { + + if ( ref( $scenario ) ne '' or $scenario ne uc( $scenario ) ) { croak "Scenario $scenario: Key must (i) not be a reference and (ii) be in all uppercase"; } if ( scalar @{ $subtests{$scenario} } != 6 ) { - croak "Scenario $scenario: Incorrect number of values. " . - "Correct format is: { SCENARIO_NAME => [" . - "testable " . - "zone_name, " . - "[ EXPECTED_PARENT_NS ], " . - "[ EXPECTED_DEL_NS ], " . - "[ EXPECTED_ZONE_NS ], " . - "[ UNDELEGATED_NS ], " . - " ] }"; - } - - my ( $testable, - $zone_name, - $expected_parent_ns, - $expected_del_ns, - $expected_zone_ns, - $undelegated_ns, - ) = @{ $subtests{$scenario} }; + croak "Scenario $scenario: Incorrect number of values. " + . "Correct format is: { SCENARIO_NAME => [" + . "testable " + . "zone_name, " + . "[ EXPECTED_PARENT_NS ], " + . "[ EXPECTED_DEL_NS ], " + . "[ EXPECTED_ZONE_NS ], " + . "[ UNDELEGATED_NS ], " . " ] }"; + } + + my ( $testable, $zone_name, $expected_parent_ns, $expected_del_ns, $expected_zone_ns, $undelegated_ns ) = + @{ $subtests{$scenario} }; if ( ref( $testable ) ne '' ) { croak "Scenario $scenario: Type of testable must not be a reference"; @@ -269,7 +267,8 @@ sub perform_methodsv2_testing { } if ( ref( $undelegated_ns ) ne 'ARRAY' ) { - croak "Scenario $scenario: Incorrect reference type of undelegated name servers expressions. Expected: ARRAY"; + croak + "Scenario $scenario: Incorrect reference type of undelegated name servers expressions. Expected: ARRAY"; } _check_ns_expressions( $scenario, $expected_parent_ns ); @@ -301,131 +300,160 @@ sub perform_methodsv2_testing { my $res = Zonemaster::Engine::TestMethodsV2->$method( Zonemaster::Engine->zone( $zone_name ) ); if ( defined $expected_parent_ns ) { ok( defined $res, "Result is defined" ) or diag "Unexpected undefined result"; - foreach my $expected_ns ( @{ $expected_parent_ns } ) { - ok( grep( /^$expected_ns$/, @{ $res } ), "Name server '$expected_ns' is present" ) - or diag "Expected but missing: $expected_ns"; + foreach my $expected_ns ( @{$expected_parent_ns} ) { + ok( grep( /^$expected_ns$/, @{$res} ), "Name server '$expected_ns' is present" ) + or diag "Expected but missing: $expected_ns"; } - ok( scalar @{ $res } == scalar @{ $expected_parent_ns }, "Number of name servers in both arrays match" ) - or diag "Number of name servers in both arrays does not match (found ". scalar @{ $res } . ", expected " . @{ $expected_parent_ns } . ")" - or diag "Got:", explain [ map { "$_" } @$res ]; + ok( scalar @{$res} == scalar @{$expected_parent_ns}, "Number of name servers in both arrays match" ) + or diag "Number of name servers in both arrays does not match (found " + . scalar @{$res} + . ", expected " + . @{$expected_parent_ns} . ")" + or diag "Got:", explain [ map { "$_" } @$res ]; } else { - ok( ! defined $res, "Result is undefined" ) or diag "Unexpected defined result"; + ok( !defined $res, "Result is undefined" ) or diag "Unexpected defined result"; } }; # Methods: get_del_ns_names_and_ips() and get_zone_ns_names_and_ips() - my @method_names = qw( get_del_ns_names_and_ips get_zone_ns_names_and_ips ); + my @method_names = qw( get_del_ns_names_and_ips get_zone_ns_names_and_ips ); my @expected_all_ns = ( $expected_del_ns, $expected_zone_ns ); - foreach my $i ( 0..$#method_names ) { + foreach my $i ( 0 .. $#method_names ) { my $method = $method_names[$i]; subtest $method => sub { my $expected_res = $expected_all_ns[$i]; my $res = Zonemaster::Engine::TestMethodsV2->$method( Zonemaster::Engine->zone( $zone_name ) ); if ( defined $expected_res ) { ok( defined $res, "Result is defined" ) or diag "Unexpected undefined result"; - foreach my $expected_ns ( @{ $expected_res } ) { - ok( grep( /^$expected_ns$/, @{ $res } ), "Name server '$expected_ns' is present" ) - or diag "Expected but missing: $expected_ns"; + foreach my $expected_ns ( @{$expected_res} ) { + ok( grep( /^$expected_ns$/, @{$res} ), "Name server '$expected_ns' is present" ) + or diag "Expected but missing: $expected_ns"; } - foreach my $ns ( @{ $res } ) { - ok( grep( /^$ns$/, @{ $expected_res } ), "Name server '$ns' is expected" ) - or diag "Present but not expected: $ns"; + foreach my $ns ( @{$res} ) { + ok( grep( /^$ns$/, @{$expected_res} ), "Name server '$ns' is expected" ) + or diag "Present but not expected: $ns"; } - ok( scalar @{ $res } == scalar @{ $expected_res }, "Number of name server in both arrays match" ) - or diag "Number of name servers in both arrays does not match (found " . scalar @{ $res } . ", expected " . scalar @{ $expected_res }.")"; + ok( scalar @{$res} == scalar @{$expected_res}, "Number of name server in both arrays match" ) + or diag "Number of name servers in both arrays does not match (found " + . scalar @{$res} + . ", expected " + . scalar @{$expected_res} . ")"; } else { - ok( ! defined $res, "Result is undefined" ) or diag "Unexpected defined result"; + ok( !defined $res, "Result is undefined" ) or diag "Unexpected defined result"; } }; - } + } ## end foreach my $i ( 0 .. $#method_names) # Methods: get_del_ns_names() and get_zone_ns_names() @method_names = qw( get_del_ns_names get_zone_ns_names ); - my $expected_del_ns_names = defined $expected_del_ns ? - [ uniq map { (split( m(/), $_ ))[0] } @{ $expected_del_ns } ] : undef; - my $expected_zone_ns_names = defined $expected_zone_ns ? - [ uniq map { (split( m(/), $_ ))[0] } @{ $expected_zone_ns } ] : undef; + my $expected_del_ns_names = + defined $expected_del_ns ? [ uniq map { ( split( m(/), $_ ) )[0] } @{$expected_del_ns} ] : undef; + my $expected_zone_ns_names = + defined $expected_zone_ns ? [ uniq map { ( split( m(/), $_ ) )[0] } @{$expected_zone_ns} ] : undef; my @expected_ns_names = ( $expected_del_ns_names, $expected_zone_ns_names ); - foreach my $i ( 0..$#method_names ) { + foreach my $i ( 0 .. $#method_names ) { my $method = $method_names[$i]; subtest $method => sub { my $expected_res = $expected_ns_names[$i]; my $res = Zonemaster::Engine::TestMethodsV2->$method( Zonemaster::Engine->zone( $zone_name ) ); if ( defined $expected_res ) { ok( defined $res, "Result is defined" ) or diag "Unexpected undefined result"; - foreach my $expected_name ( @{ $expected_res } ) { - ok( grep( /^$expected_name$/, @{ $res } ), "Name server name '$expected_name' is present" ) - or diag "Expected but missing: $expected_name"; + foreach my $expected_name ( @{$expected_res} ) { + ok( grep( /^$expected_name$/, @{$res} ), "Name server name '$expected_name' is present" ) + or diag "Expected but missing: $expected_name"; } - foreach my $name ( @{ $res } ) { - ok( grep( /^$name$/, @{ $expected_res } ), "Name server name '$name' is expected" ) - or diag "Present but not expected: $name"; + foreach my $name ( @{$res} ) { + ok( grep( /^$name$/, @{$expected_res} ), "Name server name '$name' is expected" ) + or diag "Present but not expected: $name"; } - ok( scalar @{ $res } == scalar @{ $expected_res }, "Number of name server names in both arrays match" ) - or diag "Number of name server names in both arrays does not match (found " . scalar @{ $res } . ", expected " . scalar @{ $expected_res }.")"; + ok( + scalar @{$res} == scalar @{$expected_res}, + "Number of name server names in both arrays match", + ) + or diag "Number of name server names in both arrays does not match (found " + . scalar @{$res} + . ", expected " + . scalar @{$expected_res} . ")"; } else { - ok( ! defined $res, "Result is undefined" ) or diag "Unexpected defined result"; + ok( !defined $res, "Result is undefined" ) or diag "Unexpected defined result"; } }; - } + } ## end foreach my $i ( 0 .. $#method_names) # Methods: get_del_ns_ips() and get_zone_ns_ips() @method_names = qw( get_del_ns_ips get_zone_ns_ips ); - my $expected_del_ns_ips = defined $expected_del_ns ? - [ uniq grep { $_ ne '' } map { (split( m(/), $_ ))[1] ? (split( m(/), $_ ))[1] : '' } @{ $expected_del_ns } ] : undef; - my $expected_zone_ns_ips = defined $expected_zone_ns ? - [ uniq grep { $_ ne '' } map { (split( m(/), $_ ))[1] ? (split( m(/), $_ ))[1] : '' } @{ $expected_zone_ns } ] : undef; - - my @expected_ns_ips = ( $expected_del_ns_ips, $expected_zone_ns_ips ); - foreach my $i ( 0..$#method_names ) { + my $expected_del_ns_ips = + defined $expected_del_ns + ? [ + uniq grep { $_ ne '' } + map { ( split( m(/), $_ ) )[1] ? ( split( m(/), $_ ) )[1] : '' } @{$expected_del_ns} + ] + : undef; + my $expected_zone_ns_ips = + defined $expected_zone_ns + ? [ + uniq grep { $_ ne '' } + map { ( split( m(/), $_ ) )[1] ? ( split( m(/), $_ ) )[1] : '' } @{$expected_zone_ns} + ] + : undef; + + my @expected_ns_ips = ( $expected_del_ns_ips, $expected_zone_ns_ips ); + foreach my $i ( 0 .. $#method_names ) { my $method = $method_names[$i]; subtest $method => sub { my $expected_res = $expected_ns_ips[$i]; my $res = Zonemaster::Engine::TestMethodsV2->$method( Zonemaster::Engine->zone( $zone_name ) ); if ( defined $expected_res ) { ok( defined $res, "Result is defined" ) or diag "Unexpected undefined result"; - foreach my $expected_ip ( @{ $expected_res } ) { - ok( grep( { $_->address()->short eq $expected_ip } @{ $res } ), - "Name server IP '$expected_ip' is present" ) - or diag "Expected but missing: $expected_ip"; + foreach my $expected_ip ( @{$expected_res} ) { + ok( + grep( { $_->address()->short eq $expected_ip } @{$res} ), + "Name server IP '$expected_ip' is present", + ) or diag "Expected but missing: $expected_ip"; } - foreach my $ip ( @{ $res } ) { - ok( grep( { $_ eq $ip->address()->short } @{ $expected_res } ), - "Name server IP '$ip' is expected" ) - or diag "Present but not expected: $ip"; + foreach my $ip ( @{$res} ) { + ok( + grep( { $_ eq $ip->address()->short } @{$expected_res} ), + "Name server IP '$ip' is expected", + ) or diag "Present but not expected: $ip"; } - ok( scalar @{ $res } == scalar @{ $expected_res }, "Number of name server IPs in both arrays match" ) - or diag "Number of name server IPs in both arrays does not match (found " . scalar @{ $res } . ", expected " . scalar @{ $expected_res }.")"; - } + ok( + scalar @{$res} == scalar @{$expected_res}, + "Number of name server IPs in both arrays match", + ) + or diag "Number of name server IPs in both arrays does not match (found " + . scalar @{$res} + . ", expected " + . scalar @{$expected_res} . ")"; + } ## end if ( defined $expected_res) else { - ok( ! defined $res, "Result is undefined" ) or diag "Unexpected defined result"; + ok( !defined $res, "Result is undefined" ) or diag "Unexpected defined result"; } }; - } + } ## end foreach my $i ( 0 .. $#method_names) } - } + } ## end for my $scenario ( sort...) if ( @untested_scenarios ) { warn "Untested scenarios:\n"; warn "\tScenario $_ has been disabled from testing.\n" for @untested_scenarios; } -} - +} ## end sub perform_methodsv2_testing sub perform_testcase_testing { my ( $test_case, $test_module, $aref_alltags, $href_subtests, $selected_scenarios, $disabled_scenarios ) = @_; my %subtests = %$href_subtests; - my @selected_scenarios = map {uc} split(/, */, $selected_scenarios) if $selected_scenarios; - my @disabled_scenarios = map {uc} split(/, */, $disabled_scenarios) if $disabled_scenarios; + my @selected_scenarios = map { uc } split( /, */, $selected_scenarios ) if $selected_scenarios; + my @disabled_scenarios = map { uc } split( /, */, $disabled_scenarios ) if $disabled_scenarios; my @untested_scenarios = (); if ( $selected_scenarios ) { - foreach my $scen (@selected_scenarios) { + foreach my $scen ( @selected_scenarios ) { unless ( exists $subtests{$scen} ) { croak "Scenario $scen does not exist"; } @@ -433,7 +461,7 @@ sub perform_testcase_testing { } if ( ref( $aref_alltags ) ne 'ARRAY' ) { - croak 'All tags array variable must be an array ref' + croak 'All tags array variable must be an array ref'; } foreach my $t ( @$aref_alltags ) { @@ -441,35 +469,29 @@ sub perform_testcase_testing { } for my $scenario ( sort ( keys %subtests ) ) { - next if $selected_scenarios and not grep /^$scenario$/, @selected_scenarios; + next if $selected_scenarios and not grep /^$scenario$/, @selected_scenarios; if ( @disabled_scenarios and grep /^$scenario$/, @disabled_scenarios ) { push @untested_scenarios, $scenario; next; } - if ( ref( $scenario ) ne '' or $scenario ne uc($scenario) ) { + if ( ref( $scenario ) ne '' or $scenario ne uc( $scenario ) ) { croak "Scenario $scenario: Key must (i) not be a reference and (ii) be in all uppercase"; } if ( scalar @{ $subtests{$scenario} } != 6 ) { - croak "Scenario $scenario: Incorrect number of values. " . - "Correct format is: { SCENARIO_NAME => [" . - "testable " . - "zone_name, " . - "[ MANDATORY_MESSAGE_TAGS ], " . - "[ FORBIDDEN_MESSAGE_TAGS ], " . - "[ UNDELEGATED_NS ], " . - "[ UNDELEGATED_DS ], " . - " ] }"; - } - - my ( $testable, - $zone_name, - $mandatory_message_tags, - $forbidden_message_tags, - $undelegated_ns, - $undelegated_ds - ) = @{ $subtests{$scenario} }; + croak "Scenario $scenario: Incorrect number of values. " + . "Correct format is: { SCENARIO_NAME => [" + . "testable " + . "zone_name, " + . "[ MANDATORY_MESSAGE_TAGS ], " + . "[ FORBIDDEN_MESSAGE_TAGS ], " + . "[ UNDELEGATED_NS ], " + . "[ UNDELEGATED_DS ], " . " ] }"; + } + + my ( $testable, $zone_name, $mandatory_message_tags, $forbidden_message_tags, $undelegated_ns, $undelegated_ds ) + = @{ $subtests{$scenario} }; if ( ref( $testable ) ne '' ) { croak "Scenario $scenario: Type of testable must not be a reference"; @@ -489,13 +511,17 @@ sub perform_testcase_testing { croak "Scenario $scenario: Zone name '$zone_name' is not valid"; } - if ( ! defined( $mandatory_message_tags ) and ! defined( $forbidden_message_tags ) ) { + if ( !defined( $mandatory_message_tags ) and !defined( $forbidden_message_tags ) ) { croak "Scenario $scenario: Not both array of mandatory tags and array of forbidden tags can be undefined"; } - if ( defined( $mandatory_message_tags ) and defined( $forbidden_message_tags ) and - not scalar @{ $mandatory_message_tags } and not scalar @{ $forbidden_message_tags } ) { - croak "Scenario $scenario: Not both arrays of mandatory message tags and forbidden message tags, respectively, can be empty"; + if ( defined( $mandatory_message_tags ) + and defined( $forbidden_message_tags ) + and not scalar @{$mandatory_message_tags} + and not scalar @{$forbidden_message_tags} ) + { + croak +"Scenario $scenario: Not both arrays of mandatory message tags and forbidden message tags, respectively, can be empty"; } if ( defined( $mandatory_message_tags ) and ref( $mandatory_message_tags ) ne 'ARRAY' ) { @@ -506,7 +532,7 @@ sub perform_testcase_testing { croak "Scenario $scenario: Incorrect reference type of forbidden message tags. Expected: ARRAY"; } - if ( ! defined( $mandatory_message_tags ) ) { + if ( !defined( $mandatory_message_tags ) ) { my @tags; foreach my $t ( @$aref_alltags ) { push @tags, $t unless grep( /^$t$/, @$forbidden_message_tags ); @@ -514,7 +540,7 @@ sub perform_testcase_testing { $mandatory_message_tags = \@tags; } - if ( ! defined( $forbidden_message_tags ) ) { + if ( !defined( $forbidden_message_tags ) ) { my @tags; foreach my $t ( @$aref_alltags ) { push @tags, $t unless grep( /^$t$/, @$mandatory_message_tags ); @@ -523,7 +549,8 @@ sub perform_testcase_testing { } foreach my $tag ( @$mandatory_message_tags ) { - croak "Scenario $scenario: Invalid message tag in 'mandatory_message_tags': '$tag'" unless $tag =~ /^[A-Z]+[A-Z0-9_]*[A-Z0-9]$/; + croak "Scenario $scenario: Invalid message tag in 'mandatory_message_tags': '$tag'" + unless $tag =~ /^[A-Z]+[A-Z0-9_]*[A-Z0-9]$/; } foreach my $tag ( @$mandatory_message_tags ) { @@ -533,7 +560,8 @@ sub perform_testcase_testing { } foreach my $tag ( @$forbidden_message_tags ) { - croak "Scenario $scenario: Invalid message tag in 'forbidden_message_tags': '$tag'" unless $tag =~ /^[A-Z]+[A-Z0-9_]*[A-Z0-9]$/; + croak "Scenario $scenario: Invalid message tag in 'forbidden_message_tags': '$tag'" + unless $tag =~ /^[A-Z]+[A-Z0-9_]*[A-Z0-9]$/; } foreach my $tag ( @$forbidden_message_tags ) { @@ -543,7 +571,8 @@ sub perform_testcase_testing { } if ( ref( $undelegated_ns ) ne 'ARRAY' ) { - croak "Scenario $scenario: Incorrect reference type of undelegated name servers expressions. Expected: ARRAY"; + croak + "Scenario $scenario: Incorrect reference type of undelegated name servers expressions. Expected: ARRAY"; } if ( ref( $undelegated_ds ) ne 'ARRAY' ) { @@ -563,7 +592,7 @@ sub perform_testcase_testing { if ( @$undelegated_ns ) { my %undel_ns; foreach my $nsexp ( @$undelegated_ns ) { - my ($ns, $ip) = split m(/), $nsexp; + my ( $ns, $ip ) = split m(/), $nsexp; $undel_ns{$ns} //= []; push @{ $undel_ns{$ns} }, $ip if $ip; } @@ -582,30 +611,31 @@ sub perform_testcase_testing { Zonemaster::Engine->add_fake_ds( $zone_name => \@data ); } - my @messages = Zonemaster::Engine->test_method( $test_module, $test_case, Zonemaster::Engine->zone( $zone_name ) ); + my @messages = + Zonemaster::Engine->test_method( $test_module, $test_case, Zonemaster::Engine->zone( $zone_name ) ); my %res = map { $_->tag => 1 } @messages; if ( my ( $error ) = grep { $_->tag eq 'MODULE_ERROR' } @messages ) { - diag("Module died with error: " . $error->args->{"msg"}); - fail("Test case executes properly"); + diag( "Module died with error: " . $error->args->{"msg"} ); + fail( "Test case executes properly" ); } else { - for my $tag ( @{ $mandatory_message_tags } ) { + for my $tag ( @{$mandatory_message_tags} ) { ok( exists $res{$tag}, "Tag $tag is outputted" ) - or diag "Tag '$tag' should have been outputted, but wasn't"; + or diag "Tag '$tag' should have been outputted, but wasn't"; } - for my $tag ( @{ $forbidden_message_tags } ) { + for my $tag ( @{$forbidden_message_tags} ) { ok( !exists $res{$tag}, "Tag $tag is not outputted" ) - or diag "Tag '$tag' was not supposed to be outputted, but it was"; + or diag "Tag '$tag' was not supposed to be outputted, but it was"; } } }; - } + } ## end for my $scenario ( sort...) if ( @untested_scenarios ) { warn "Untested scenarios:\n"; warn "\tScenario $_ cannot be tested.\n" for @untested_scenarios; } -} +} ## end sub perform_testcase_testing 1; diff --git a/t/TestUtil/DSL.pm b/t/TestUtil/DSL.pm index 92a5794b4..0db673d0f 100644 --- a/t/TestUtil/DSL.pm +++ b/t/TestUtil/DSL.pm @@ -1,699 +1,699 @@ -package TestUtil::DSL; - -use warnings; -use strict; -use v5.24; - -use Carp qw(confess croak); - -use TestUtil::DSL::Compiler; - -# This is needed in order to squelch “too late to run INIT block” warnings. -use Zonemaster::Engine (); - -=encoding utf8 - -=head1 NAME - -TestUtil::DSL - a domain-specific language for easy testing of test cases - -=head1 SYNOPSIS - -Because this package lies in the testing directory C, which is not listed in C<@INC> during testing, -it must be loaded using the following code: - - use File::Basename qw( dirname ); - use File::Spec::Functions qw( rel2abs ); - use lib dirname( rel2abs( $0 ) ); - use TestUtil::DSL; - -A test case can then be tested with the following minimal skeleton: - - testing_test_case 'Example', 'example01'; - - all_tags qw(EX01_ALL_GOOD - EX01_MINOR_ISSUE - EX01_SOMETHING_WRONG - EX01_SOME_OTHER_PROBLEM - EX01_BREAKS_ON_SOME_FEATURE); - - root_hints 'ns1' => [ qw(127.1.0.1 fda1:b2:c3::127:1:0:1) ], - 'ns2' => [ qw(127.1.0.2 fda1:b2:c3::127:1:0:2) ]; - zone_name_template '{SCENARIO}.{TESTCASE}.xa'; - - scenario 'GOOD-{1..3}' => sub { - expect EX01_ALL_GOOD; - }; - - # more scenarios here - - no_more_scenarios; - -=cut - -use Exporter 'import'; - -our @EXPORT = qw(all_tags - clear_cache - expect - expect_others - fake_ds - fake_ns - forbid - forbid_others - no_more_scenarios - not_testable - root_hints - scenario - testing_test_case - todo - zone - zone_name_template); - -# Define a stack for internal context objects, some functions to manipulate it, -# and only expose the top of the stack. -{ - my @STACK = (); - - sub STATE () { - $STACK[-1]; - } - - sub check_state ($) { - my ($expected_state) = @_; - - if (defined $expected_state) { - if (scalar @STACK == 0 or $expected_state ne STATE->{_STATE}) { - croak "This keyword is not valid in this context." - } - } - elsif (scalar @STACK != 0) { - croak "This keyword can only be used once"; - } - } - - sub pop_state { - my $result = pop @STACK // croak "Attempted to pop empty stack"; - delete $result->{_STATE}; - return $result; - } - - sub push_state ($) { - push @STACK, { _STATE => $_[0] }; - } -} - -# Internal mechanics - -sub _is_uint_bits { - my ($value, $bits) = @_; - return ($value =~ /^\d+$/a and $value >= 0 and $value < (1 << $bits)); -} - -sub _expand_scenario_names { - my @scenario_names = @_; - my @result; - - for my $name (@scenario_names) { - if ($name=~ /^ (? [^{]*) \{ - (? \d+) \Q..\E (? \d+) - \} $ /x ) { - for my $i ($+{start}..$+{end}) { - push @result, "$+{prefix}$i"; - } - } - else { - push @result, $name; - } - } - - return @result; -} - -=head1 TOP-LEVEL KEYWORDS - -=head2 all_tags - - all_tags qw(SOME_TAG SOME_OTHER_TAG AND_ANOTHER_ONE); - -List all the message tags that the test case being tested is expected to emit. - -=cut - -sub all_tags (@) { - my @tags = @_; - check_state 'testing_test_case'; - - %{STATE->{all_tags}} = map { $_ => 1 } @tags; -} - -=head2 no_more_scenarios - - no_more_scenarios; - -Ends a declaration of a test. Similar to C in L. - -=cut - -sub no_more_scenarios () { - check_state 'testing_test_case'; - my $spec = pop_state; - - # Do not clutter AST with data the compiler does not need - delete $spec->{zone_name_template}; - delete $spec->{all_tags}; - - TestUtil::DSL::Compiler::compile($spec)->(); -} - -=head2 scenario - -Declares one or more scenario blocks. - -A scenario is defined by a name and a set of expectations. The name is used to -derive the name of a zone on which to run the test case being tested. The -result of this run is a collection of messages, which are then compared to the -expected result declared in the scenario block. - -The scenario block body is a special coderef, evaluated in a special context which -gives meaning to a set of scenario-specific keywords. See L for more information on what keywords are valid in a scenario block. - -The C keywords has several legal syntaxes. - -The first form declares a single scenario: - - scenario 'SCENARIO-NAME' => sub { - # scenario declaration here - }; - -The second form declares multiple scenarios, all sharing the same expectations: - - scenario qw(SCENARIO-ONE SCENARIO-TWO) => sub { - # scenario declaration here - }; - -Scenario names may end with a number range expressed as C<{M..N}> where C -and C are integers. This is a shorthand for listing scenarios that all -share the same prefix but differ only by a numbered suffix. This notation -allows for concise declarations of scenarios that may be configured -differently but are expected to yield the same set of messages from the test -case. For example, the following two declarations are equivalent: - - scenario qw(GOOD-{1..2} EXAMPLE-{1..4}) => sub { ... }; - - scenario qw(GOOD-1 GOOD-2 - EXAMPLE-1 EXAMPLE-2 EXAMPLE-3 EXAMPLE-4) => sub { ... }; - - -=cut - -sub scenario (@) { - check_state 'testing_test_case'; - - croak "At least two arguments required" unless scalar @_ >= 2; - croak "A 'root_hints' must appear before a 'scenario' block" - unless exists STATE->{root_hints}; - - my $definition = pop @_; - my @names = _expand_scenario_names(@_); - - my @context = caller(0); - - my $scenario = { - names => \@names, - caller => [ @context[1..2] ], - body => do { - my $PARENT_STATE = STATE; - push_state 'scenario'; - - STATE->{status} = [ 'testable' ]; - - # Keep track of contents of “all_tags” so that expect and forbid - # can raise errors if given a tag not in that list. - STATE->{all_tags} = $PARENT_STATE->{all_tags}; - - # Keep track of keys never mentioned by “expect” or “forbid” respectively - # so that “expect_others” and “forbid_others” can be defined in terms - # of “expect” and “forbid” respectively. - %{STATE->{not_expected}} = map { $_ => 1 } keys %{STATE->{all_tags}}; - %{STATE->{not_forbidden}} = map { $_ => 1 } keys %{STATE->{all_tags}}; - - # Evaluate definition - my $obj = do { $definition->(); pop_state; }; - - # Clean up - delete $obj->{all_tags}; - delete $obj->{not_expected}; - delete $obj->{not_forbidden}; - - # Set default zone name (template) - $obj->{zone} //= STATE->{zone_name_template}; - - # Sanity checks - if (not defined $obj->{zone}) { - croak "No 'zone' keyword in scenario block and no previous " - . "'zone_name_template' seen"; - } - - # TODO do we need more sanity checks? - $obj; - } - }; - - foreach my $name (@{$scenario->{names}}) { - STATE->{scenario_status}{$name} = $scenario->{body}{status}; - } - push @{STATE->{ops}}, [ scenario => $scenario ]; -} - - -=head2 testing_test_case - - testing_test_case 'MyModule' 'mymodule01'; - -Declare a unit test for a test case. The arguments for that keyword are the -name of the test plan, and the name of the test case being tested -respectively. - -The DSL expects this keyword to be used first, before any other keyword. - -=cut - -sub testing_test_case ($$) { - check_state undef; - push_state 'testing_test_case'; - - my ($test_module, $test_case) = @_; - - STATE->{test_module} = $test_module; - STATE->{test_case} = $test_case; -} - - -=head2 root_hints - - root_hints 'ns1.example' => [ qw(198.51.113.10 2001:db8:0:8::53) ], - 'ns2.example' => [ qw(198.51.113.20 2001:db8:0:8::1:53) ]; - -Declare the set of name servers which are authoritative for the root zone. -These root hints apply to all scenarios that follow this keyword. - -This keyword must be used at least one before defining the first scenario -block. - -=cut - -sub root_hints (%) { - my (%root_hints) = @_; - check_state 'testing_test_case'; - STATE->{root_hints} = 1; - - push @{STATE->{ops}}, [ root_hints => \%root_hints ]; -} - -=head2 zone_name_template - - zone_name_template '{SCENARIO}.{TESTCASE}.xa'; - zone_name_template 'child.parent.{SCENARIO}.{TESTCASE}.xa'; - -Declare a default zone name template for the C specifications that follow. - -The string passed as arguments may contain placeholders, such as C<{SCENARIO}> -or C<{TESTCASE}>, that are substituted accordingly. - -=cut - -sub zone_name_template ($) { - my ($template) = @_; - check_state 'testing_test_case'; - STATE->{zone_name_template} = $template; -} - -=head2 clear_cache - - clear_cache; - -Clears the resolver cache for subsequent tests. This might be necessary if -this caching somehow causes negative side effects. - -Note that it is unnecessary to use this keyword right after L, -because L also clears the resolver cache. - -=cut - -sub clear_cache () { - check_state 'testing_test_case'; - push @{STATE->{ops}}, [ "clear_cache" ]; -} - - -=head1 SCENARIO-SPECIFIC KEYWORDS - -=head2 zone - - zone 'myzone.example.xa'; - zone 'myzone.{SCENARIO}.{TESTCASE}.xb'; - -Declare a zone name to be used in the scenario. - -This declaration is optional, because the default value is inherited from the -top-level keyword L. It can be useful for one or two -exceptions to a general rule. - -The same placeholders that are valid for L can also be -used here. - -=cut - -sub zone ($) { - my ($zone) = @_; - check_state 'scenario'; - - # Template expansion is done at a later stage - STATE->{zone} = $zone; -} - -=head2 fake_ds - - fake_ds , , , - fake_ds 51966, 8, 3, 'ABCDABCDABCDABCD'; - -Provide a DS record as part of the fake delegation to be used in the scenario. - -=cut - -sub fake_ds($$$$) { - my ($tag, $algo, $type, $digest) = @_; - - unless ( _is_uint_bits($tag, 16) ) { - croak "$tag: not a valid key tag"; - } - unless ( _is_uint_bits($algo, 8) ) { - croak "$algo: not a valid algorithm"; - } - unless ( _is_uint_bits($type, 8) ) { - croak "$type: not a valid type"; - } - unless ( $digest =~ /^ (?: [0-9a-f]{2} )+ $/ix ) { - croak "$digest: not a valid digest"; - } - - push @{STATE->{fake_ds}}, { - keytag => $tag, - algorithm => $algo, - type => $type, - digest => $digest - }; -} - -=head2 fake_ns - - fake_ns [, ] - -Provide an NS record as part of the fake delegation to be used in the scenario. -The keyword accepts a name server name and optionally a list of IP addresses that -will be used as glue records if given. - -Examples: - - fake_ns 'ns1.example'; - fake_ns 'ns1.example' => '192.0.2.50'; - fake_ns 'ns1.example' => '192.0.2.50', '2001:db8:0:8::53'; - -Passing the same name server name to more than one C keyword is not -allowed and is an error. - -=cut - -sub fake_ns($@) { - my ($name, @ips) = @_; - - if (exists STATE->{fake_ns}{$name}) { - croak "'fake_ns' cannot be used for '$name' more than once"; - } - - STATE->{fake_ns}{$name} = \@ips; -} - -=head2 expect - -List one or more tags that the test case is expected to generate when it is run -on the scenario being defined. - -This keyword allows for multiple syntaxes. - -The first form specifies that at least one message of a certain tag is to be -expected among the test case’s output for the scenario: - - expect ; - -The second form is a shorthand that avoids repeating the C keyword. It -is equivalent to using the first form as many times as there are tags given as -arguments. - - expect , , ...; - -The third form specifies a single tag name and a hashref of keys and criteria. -It specifies that a message whose tag matches the name and whose arguments -exist and match the supplied criteria must exist among the test case’s output. -See L below for a more in-depth explanation of this form. - - expect => { => , ... }; - -The fourth form takes a tag name and a coderef: it searches for all messages -whose tag matches, evaluates the coderef with C<@_> set to the list of -messages matching the tag and expects the coderef to return a true value. This -form is useful for situations where the third form falls short. See L -below for examples. - - expect => sub { my @messages = @_; ... }; - -The C keyword can be used more than once in a scenario. All of the -checks specified by C and C keywords must pass in order for -the scenario to pass. - -=head3 Criteria - -For the third form, arguments can be matched against: - -=over - -=item strings, which are compared with C; - -=item regular expressions; - -=item and coderefs, where C<$_> is bound to the message parameter’s value. - -=back - -The following expects C to be generated with arguments C, -C, C and C. C must -be equal to C, C must match -C, C must be case-insensitively equal to -C and C is only tested for presence. - - expect SOME_TAG => { - ns_list => 'ns1.example/127.0.60.1', - other_argument => qr/^ns2\..*/, - third_argument => sub { fc $_ eq fc 'EXAMPLE' }, - fourth_argument => sub { 1 }, - }; - -Note that if the test case emits C with an argument that is not -listed in the C keyword, it is deemed an error. - -Checking that a message tag has no parameters at all can also be done as -follows: - - expect TAG_WITHOUT_PARAMETERS => {}; - -More free-form criteria can be provided by means of the fourth form. The following -example checks if the scenario generated exactly three times a given message tag: - - expect SOME_TAG => sub { scalar @_ == 3 }; - -The following example ensures that all instances of SOME_TAG have a -C parameter equal to the string C: - - expect SOME_TAG => sub { - my @messages = @_; - for my $m (@messages) { - return 0 if $m->{some_argument} ne 'ns1.example/127.0.60.1'; - } - return 1; - } - -=cut - -sub expect (@) { - if (scalar @_ == 2 and ref $_[1] eq 'HASH') { - # Third form - my ($tag, $args) = @_; - _declare_message_test( expect => $tag, args => $args ); - } - elsif (scalar @_ == 2 and ref $_[1] eq 'CODE') { - # Fourth form - my ($tag, $code) = @_; - _declare_message_test( expect => $tag, code => $code ); - } - elsif (scalar @_ >= 1) { - # First or second form - foreach my $tag (@_) { - _declare_message_test( expect => $tag ); - } - } - else { - croak "Need at least one argument"; - } -} - -=head2 forbid - - forbid , , … - -Specifies that the listed tags are not to be emitted by the test case in the -scenario being defined. In other words, in the messages generated by the test -case, no message should appear whose tags are in the listed tags. - -The C keyword can be used more than once in a scenario. All of the -checks specified by C and C keywords must pass in order for -the scenario to pass. - -=cut - -sub forbid (@) { - my @tags = @_; - - croak "Need at least one argument" unless scalar @tags >= 1; - - foreach my $tag (@_) { - _declare_message_test( forbid => $tag ); - } -} - -sub _declare_message_test { - my ( $type, $tag, %args ) = @_; - my @context = caller(1); - - exists STATE->{all_tags}{$tag} - or croak "Tag '$tag' used in '$type' clause but not declared in 'all_tags'"; - - delete STATE->{not_expected}{$tag} if $type eq 'expect'; - delete STATE->{not_forbidden}{$tag} if $type eq 'forbid'; - - push @{STATE->{message_tests}}, [ $type, [ @context[1..2] ], $tag, %args ]; -} - -=head2 expect_others - - expect_others; - -Specifies that all tags not listed by any C tag in the scenario -definition must appear in the test case’s output for the scenario. - -=cut - -sub expect_others () { - croak "Cannot use expect_others if forbid_others is already given" if STATE->{forbid_others}; - croak "Cannot use expect_others more than once" if STATE->{expect_others}; - STATE->{expect_others} = 1; - - _declare_message_test( expect => $_ ) foreach ( keys %{STATE->{not_forbidden}} ); -} - -=head2 forbid_others - - forbid_others; - -Specifies that all tags not listed by any C tag in the scenario -definition must not appear in the test case’s output for the scenario. - -=cut - -sub forbid_others () { - croak "Cannot use forbid_others if expect_others is already given" if STATE->{expect_others}; - croak "Cannot use forbid_others more than once" if STATE->{forbid_others}; - STATE->{forbid_others} = 1; - - _declare_message_test( forbid => $_ ) foreach ( keys %{STATE->{not_expected}} ); -} - -=head2 not_testable - - not_testable 'optional reason'; - -Mark the scenario as not testable. - -Scenarios marked as not testable are skipped during testing, unless they are -listed explicitly in the C environment variable. - -It is semantically equivalent to L. - -This facility is useful for defining scenarios which cannot be tested because -the infrastructure (e.g. DNS servers, test zones…) needed to elicit the set of -messages expected by the scenario is not yet available. - -No packets related to the scenario are saved to the test’s C<.data> file when -C is set in the environment. This means that no data is -recorded for a test zone that does not reflect the scenario accurately. -Rerecording is only necessary when the C keyword is removed. - -The C keyword should not be used for other reasons than lack of -infrastructure, such as if the test fails because of a known bug in the test -case’s implementation. In those situations, C is more appropriate. - -The optional reason, if supplied, is used in the test harness’s diagnostic -output. It is useful for documenting the exact reason why the test is not -testable, for example by referring to an item on an issue tracker. - -=cut - -sub not_testable (;$) { - if (exists STATE->{todo}) { - croak "'not_testable' cannot be combined with 'todo'"; - } - if (exists STATE->{not_testable}) { - croak "'not_testable' can only be given once"; - } - STATE->{status} = [ 'not_testable', $_[0] ]; -} - -=head2 todo - - todo 'optional reason'; - -Mark the scenario as “to do”. - -Scenarios marked as to do are executed normally during testing, but are -expected to fail. Failing “to do” scenarios do not cause the parent test suite -to fail. - -It is semantically equivalent to L. - -This facility is useful for defining scenarios that are expected to fail -because of a known bug in the test case’s implementation that has not been -fixed yet. - -Packets related to the scenario are saved to the test’s C<.data> file when -C is set in the environment. This means that no rerecord is -necessary when the C keyword is removed or when trying to fix the -implementation. - -The optional reason, if supplied, is used in the test harness’s diagnostic -output. It is useful for documenting the exact reason why the test is expected -to fail, for example by referring to an item on an issue tracker. - -=cut - -sub todo (;$) { - if (exists STATE->{not_testable}) { - croak "'todo' cannot be combined with 'not_testable'"; - } - if (exists STATE->{todo}) { - croak "'todo' can only be given once"; - } - STATE->{status} = [ 'todo', $_[0] ]; -} - -1; +package TestUtil::DSL; + +use warnings; +use strict; +use v5.24; + +use Carp qw(confess croak); + +use TestUtil::DSL::Compiler; + +# This is needed in order to squelch “too late to run INIT block” warnings. +use Zonemaster::Engine (); + +=encoding utf8 + +=head1 NAME + +TestUtil::DSL - a domain-specific language for easy testing of test cases + +=head1 SYNOPSIS + +Because this package lies in the testing directory C, which is not listed in C<@INC> during testing, +it must be loaded using the following code: + + use File::Basename qw( dirname ); + use File::Spec::Functions qw( rel2abs ); + use lib dirname( rel2abs( $0 ) ); + use TestUtil::DSL; + +A test case can then be tested with the following minimal skeleton: + + testing_test_case 'Example', 'example01'; + + all_tags qw(EX01_ALL_GOOD + EX01_MINOR_ISSUE + EX01_SOMETHING_WRONG + EX01_SOME_OTHER_PROBLEM + EX01_BREAKS_ON_SOME_FEATURE); + + root_hints 'ns1' => [ qw(127.1.0.1 fda1:b2:c3::127:1:0:1) ], + 'ns2' => [ qw(127.1.0.2 fda1:b2:c3::127:1:0:2) ]; + zone_name_template '{SCENARIO}.{TESTCASE}.xa'; + + scenario 'GOOD-{1..3}' => sub { + expect EX01_ALL_GOOD; + }; + + # more scenarios here + + no_more_scenarios; + +=cut + +use Exporter 'import'; + +our @EXPORT = qw(all_tags + clear_cache + expect + expect_others + fake_ds + fake_ns + forbid + forbid_others + no_more_scenarios + not_testable + root_hints + scenario + testing_test_case + todo + zone + zone_name_template); + +# Define a stack for internal context objects, some functions to manipulate it, +# and only expose the top of the stack. +{ + my @STACK = (); + + sub STATE () { + $STACK[-1]; + } + + sub check_state ($) { + my ( $expected_state ) = @_; + + if ( defined $expected_state ) { + if ( scalar @STACK == 0 or $expected_state ne STATE->{_STATE} ) { + croak "This keyword is not valid in this context."; + } + } + elsif ( scalar @STACK != 0 ) { + croak "This keyword can only be used once"; + } + } + + sub pop_state { + my $result = pop @STACK // croak "Attempted to pop empty stack"; + delete $result->{_STATE}; + return $result; + } + + sub push_state ($) { + push @STACK, { _STATE => $_[0] }; + } +} + +# Internal mechanics + +sub _is_uint_bits { + my ( $value, $bits ) = @_; + return ( $value =~ /^\d+$/a and $value >= 0 and $value < ( 1 << $bits ) ); +} + +sub _expand_scenario_names { + my @scenario_names = @_; + my @result; + + for my $name ( @scenario_names ) { + if ( + $name =~ /^ (? [^{]*) \{ + (? \d+) \Q..\E (? \d+) + \} $ /x + ) + { + for my $i ( $+{start} .. $+{end} ) { + push @result, "$+{prefix}$i"; + } + } + else { + push @result, $name; + } + } + + return @result; +} ## end sub _expand_scenario_names + +=head1 TOP-LEVEL KEYWORDS + +=head2 all_tags + + all_tags qw(SOME_TAG SOME_OTHER_TAG AND_ANOTHER_ONE); + +List all the message tags that the test case being tested is expected to emit. + +=cut + +sub all_tags (@) { + my @tags = @_; + check_state 'testing_test_case'; + + %{ STATE->{all_tags} } = map { $_ => 1 } @tags; +} + +=head2 no_more_scenarios + + no_more_scenarios; + +Ends a declaration of a test. Similar to C in L. + +=cut + +sub no_more_scenarios () { + check_state 'testing_test_case'; + my $spec = pop_state; + + # Do not clutter AST with data the compiler does not need + delete $spec->{zone_name_template}; + delete $spec->{all_tags}; + + TestUtil::DSL::Compiler::compile( $spec )->(); +} + +=head2 scenario + +Declares one or more scenario blocks. + +A scenario is defined by a name and a set of expectations. The name is used to +derive the name of a zone on which to run the test case being tested. The +result of this run is a collection of messages, which are then compared to the +expected result declared in the scenario block. + +The scenario block body is a special coderef, evaluated in a special context which +gives meaning to a set of scenario-specific keywords. See L for more information on what keywords are valid in a scenario block. + +The C keywords has several legal syntaxes. + +The first form declares a single scenario: + + scenario 'SCENARIO-NAME' => sub { + # scenario declaration here + }; + +The second form declares multiple scenarios, all sharing the same expectations: + + scenario qw(SCENARIO-ONE SCENARIO-TWO) => sub { + # scenario declaration here + }; + +Scenario names may end with a number range expressed as C<{M..N}> where C +and C are integers. This is a shorthand for listing scenarios that all +share the same prefix but differ only by a numbered suffix. This notation +allows for concise declarations of scenarios that may be configured +differently but are expected to yield the same set of messages from the test +case. For example, the following two declarations are equivalent: + + scenario qw(GOOD-{1..2} EXAMPLE-{1..4}) => sub { ... }; + + scenario qw(GOOD-1 GOOD-2 + EXAMPLE-1 EXAMPLE-2 EXAMPLE-3 EXAMPLE-4) => sub { ... }; + + +=cut + +sub scenario (@) { + check_state 'testing_test_case'; + + croak "At least two arguments required" unless scalar @_ >= 2; + croak "A 'root_hints' must appear before a 'scenario' block" + unless exists STATE->{root_hints}; + + my $definition = pop @_; + my @names = _expand_scenario_names( @_ ); + + my @context = caller( 0 ); + + my $scenario = { + names => \@names, + caller => [ @context[ 1 .. 2 ] ], + body => do { + my $PARENT_STATE = STATE; + push_state 'scenario'; + + STATE->{status} = ['testable']; + + # Keep track of contents of “all_tags” so that expect and forbid + # can raise errors if given a tag not in that list. + STATE->{all_tags} = $PARENT_STATE->{all_tags}; + + # Keep track of keys never mentioned by “expect” or “forbid” respectively + # so that “expect_others” and “forbid_others” can be defined in terms + # of “expect” and “forbid” respectively. + %{ STATE->{not_expected} } = map { $_ => 1 } keys %{ STATE->{all_tags} }; + %{ STATE->{not_forbidden} } = map { $_ => 1 } keys %{ STATE->{all_tags} }; + + # Evaluate definition + my $obj = do { $definition->(); pop_state; }; + + # Clean up + delete $obj->{all_tags}; + delete $obj->{not_expected}; + delete $obj->{not_forbidden}; + + # Set default zone name (template) + $obj->{zone} //= STATE->{zone_name_template}; + + # Sanity checks + if ( not defined $obj->{zone} ) { + croak "No 'zone' keyword in scenario block and no previous " . "'zone_name_template' seen"; + } + + # TODO do we need more sanity checks? + $obj; + }, + }; + + foreach my $name ( @{ $scenario->{names} } ) { + STATE->{scenario_status}{$name} = $scenario->{body}{status}; + } + push @{ STATE->{ops} }, [ scenario => $scenario ]; +} ## end sub scenario (@) + +=head2 testing_test_case + + testing_test_case 'MyModule' 'mymodule01'; + +Declare a unit test for a test case. The arguments for that keyword are the +name of the test plan, and the name of the test case being tested +respectively. + +The DSL expects this keyword to be used first, before any other keyword. + +=cut + +sub testing_test_case ($$) { + check_state undef; + push_state 'testing_test_case'; + + my ( $test_module, $test_case ) = @_; + + STATE->{test_module} = $test_module; + STATE->{test_case} = $test_case; +} + +=head2 root_hints + + root_hints 'ns1.example' => [ qw(198.51.113.10 2001:db8:0:8::53) ], + 'ns2.example' => [ qw(198.51.113.20 2001:db8:0:8::1:53) ]; + +Declare the set of name servers which are authoritative for the root zone. +These root hints apply to all scenarios that follow this keyword. + +This keyword must be used at least one before defining the first scenario +block. + +=cut + +sub root_hints (%) { + my ( %root_hints ) = @_; + check_state 'testing_test_case'; + STATE->{root_hints} = 1; + + push @{ STATE->{ops} }, [ root_hints => \%root_hints ]; +} + +=head2 zone_name_template + + zone_name_template '{SCENARIO}.{TESTCASE}.xa'; + zone_name_template 'child.parent.{SCENARIO}.{TESTCASE}.xa'; + +Declare a default zone name template for the C specifications that follow. + +The string passed as arguments may contain placeholders, such as C<{SCENARIO}> +or C<{TESTCASE}>, that are substituted accordingly. + +=cut + +sub zone_name_template ($) { + my ( $template ) = @_; + check_state 'testing_test_case'; + STATE->{zone_name_template} = $template; +} + +=head2 clear_cache + + clear_cache; + +Clears the resolver cache for subsequent tests. This might be necessary if +this caching somehow causes negative side effects. + +Note that it is unnecessary to use this keyword right after L, +because L also clears the resolver cache. + +=cut + +sub clear_cache () { + check_state 'testing_test_case'; + push @{ STATE->{ops} }, ["clear_cache"]; +} + +=head1 SCENARIO-SPECIFIC KEYWORDS + +=head2 zone + + zone 'myzone.example.xa'; + zone 'myzone.{SCENARIO}.{TESTCASE}.xb'; + +Declare a zone name to be used in the scenario. + +This declaration is optional, because the default value is inherited from the +top-level keyword L. It can be useful for one or two +exceptions to a general rule. + +The same placeholders that are valid for L can also be +used here. + +=cut + +sub zone ($) { + my ( $zone ) = @_; + check_state 'scenario'; + + # Template expansion is done at a later stage + STATE->{zone} = $zone; +} + +=head2 fake_ds + + fake_ds , , , + fake_ds 51966, 8, 3, 'ABCDABCDABCDABCD'; + +Provide a DS record as part of the fake delegation to be used in the scenario. + +=cut + +sub fake_ds($$$$) { + my ( $tag, $algo, $type, $digest ) = @_; + + unless ( _is_uint_bits( $tag, 16 ) ) { + croak "$tag: not a valid key tag"; + } + unless ( _is_uint_bits( $algo, 8 ) ) { + croak "$algo: not a valid algorithm"; + } + unless ( _is_uint_bits( $type, 8 ) ) { + croak "$type: not a valid type"; + } + unless ( $digest =~ /^ (?: [0-9a-f]{2} )+ $/ix ) { + croak "$digest: not a valid digest"; + } + + push @{ STATE->{fake_ds} }, + { + keytag => $tag, + algorithm => $algo, + type => $type, + digest => $digest, + }; +} ## end sub fake_ds($$$$) + +=head2 fake_ns + + fake_ns [, ] + +Provide an NS record as part of the fake delegation to be used in the scenario. +The keyword accepts a name server name and optionally a list of IP addresses that +will be used as glue records if given. + +Examples: + + fake_ns 'ns1.example'; + fake_ns 'ns1.example' => '192.0.2.50'; + fake_ns 'ns1.example' => '192.0.2.50', '2001:db8:0:8::53'; + +Passing the same name server name to more than one C keyword is not +allowed and is an error. + +=cut + +sub fake_ns($@) { + my ( $name, @ips ) = @_; + + if ( exists STATE->{fake_ns}{$name} ) { + croak "'fake_ns' cannot be used for '$name' more than once"; + } + + STATE->{fake_ns}{$name} = \@ips; +} + +=head2 expect + +List one or more tags that the test case is expected to generate when it is run +on the scenario being defined. + +This keyword allows for multiple syntaxes. + +The first form specifies that at least one message of a certain tag is to be +expected among the test case’s output for the scenario: + + expect ; + +The second form is a shorthand that avoids repeating the C keyword. It +is equivalent to using the first form as many times as there are tags given as +arguments. + + expect , , ...; + +The third form specifies a single tag name and a hashref of keys and criteria. +It specifies that a message whose tag matches the name and whose arguments +exist and match the supplied criteria must exist among the test case’s output. +See L below for a more in-depth explanation of this form. + + expect => { => , ... }; + +The fourth form takes a tag name and a coderef: it searches for all messages +whose tag matches, evaluates the coderef with C<@_> set to the list of +messages matching the tag and expects the coderef to return a true value. This +form is useful for situations where the third form falls short. See L +below for examples. + + expect => sub { my @messages = @_; ... }; + +The C keyword can be used more than once in a scenario. All of the +checks specified by C and C keywords must pass in order for +the scenario to pass. + +=head3 Criteria + +For the third form, arguments can be matched against: + +=over + +=item strings, which are compared with C; + +=item regular expressions; + +=item and coderefs, where C<$_> is bound to the message parameter’s value. + +=back + +The following expects C to be generated with arguments C, +C, C and C. C must +be equal to C, C must match +C, C must be case-insensitively equal to +C and C is only tested for presence. + + expect SOME_TAG => { + ns_list => 'ns1.example/127.0.60.1', + other_argument => qr/^ns2\..*/, + third_argument => sub { fc $_ eq fc 'EXAMPLE' }, + fourth_argument => sub { 1 }, + }; + +Note that if the test case emits C with an argument that is not +listed in the C keyword, it is deemed an error. + +Checking that a message tag has no parameters at all can also be done as +follows: + + expect TAG_WITHOUT_PARAMETERS => {}; + +More free-form criteria can be provided by means of the fourth form. The following +example checks if the scenario generated exactly three times a given message tag: + + expect SOME_TAG => sub { scalar @_ == 3 }; + +The following example ensures that all instances of SOME_TAG have a +C parameter equal to the string C: + + expect SOME_TAG => sub { + my @messages = @_; + for my $m (@messages) { + return 0 if $m->{some_argument} ne 'ns1.example/127.0.60.1'; + } + return 1; + } + +=cut + +sub expect (@) { + if ( scalar @_ == 2 and ref $_[1] eq 'HASH' ) { + # Third form + my ( $tag, $args ) = @_; + _declare_message_test( expect => $tag, args => $args ); + } + elsif ( scalar @_ == 2 and ref $_[1] eq 'CODE' ) { + # Fourth form + my ( $tag, $code ) = @_; + _declare_message_test( expect => $tag, code => $code ); + } + elsif ( scalar @_ >= 1 ) { + # First or second form + foreach my $tag ( @_ ) { + _declare_message_test( expect => $tag ); + } + } + else { + croak "Need at least one argument"; + } +} ## end sub expect (@) + +=head2 forbid + + forbid , , … + +Specifies that the listed tags are not to be emitted by the test case in the +scenario being defined. In other words, in the messages generated by the test +case, no message should appear whose tags are in the listed tags. + +The C keyword can be used more than once in a scenario. All of the +checks specified by C and C keywords must pass in order for +the scenario to pass. + +=cut + +sub forbid (@) { + my @tags = @_; + + croak "Need at least one argument" unless scalar @tags >= 1; + + foreach my $tag ( @_ ) { + _declare_message_test( forbid => $tag ); + } +} + +sub _declare_message_test { + my ( $type, $tag, %args ) = @_; + my @context = caller( 1 ); + + exists STATE->{all_tags}{$tag} + or croak "Tag '$tag' used in '$type' clause but not declared in 'all_tags'"; + + delete STATE->{not_expected}{$tag} if $type eq 'expect'; + delete STATE->{not_forbidden}{$tag} if $type eq 'forbid'; + + push @{ STATE->{message_tests} }, [ $type, [ @context[ 1 .. 2 ] ], $tag, %args ]; +} + +=head2 expect_others + + expect_others; + +Specifies that all tags not listed by any C tag in the scenario +definition must appear in the test case’s output for the scenario. + +=cut + +sub expect_others () { + croak "Cannot use expect_others if forbid_others is already given" if STATE->{forbid_others}; + croak "Cannot use expect_others more than once" if STATE->{expect_others}; + STATE->{expect_others} = 1; + + _declare_message_test( expect => $_ ) foreach ( keys %{ STATE->{not_forbidden} } ); +} + +=head2 forbid_others + + forbid_others; + +Specifies that all tags not listed by any C tag in the scenario +definition must not appear in the test case’s output for the scenario. + +=cut + +sub forbid_others () { + croak "Cannot use forbid_others if expect_others is already given" if STATE->{expect_others}; + croak "Cannot use forbid_others more than once" if STATE->{forbid_others}; + STATE->{forbid_others} = 1; + + _declare_message_test( forbid => $_ ) foreach ( keys %{ STATE->{not_expected} } ); +} + +=head2 not_testable + + not_testable 'optional reason'; + +Mark the scenario as not testable. + +Scenarios marked as not testable are skipped during testing, unless they are +listed explicitly in the C environment variable. + +It is semantically equivalent to L. + +This facility is useful for defining scenarios which cannot be tested because +the infrastructure (e.g. DNS servers, test zones…) needed to elicit the set of +messages expected by the scenario is not yet available. + +No packets related to the scenario are saved to the test’s C<.data> file when +C is set in the environment. This means that no data is +recorded for a test zone that does not reflect the scenario accurately. +Rerecording is only necessary when the C keyword is removed. + +The C keyword should not be used for other reasons than lack of +infrastructure, such as if the test fails because of a known bug in the test +case’s implementation. In those situations, C is more appropriate. + +The optional reason, if supplied, is used in the test harness’s diagnostic +output. It is useful for documenting the exact reason why the test is not +testable, for example by referring to an item on an issue tracker. + +=cut + +sub not_testable (;$) { + if ( exists STATE->{todo} ) { + croak "'not_testable' cannot be combined with 'todo'"; + } + if ( exists STATE->{not_testable} ) { + croak "'not_testable' can only be given once"; + } + STATE->{status} = [ 'not_testable', $_[0] ]; +} + +=head2 todo + + todo 'optional reason'; + +Mark the scenario as “to do”. + +Scenarios marked as to do are executed normally during testing, but are +expected to fail. Failing “to do” scenarios do not cause the parent test suite +to fail. + +It is semantically equivalent to L. + +This facility is useful for defining scenarios that are expected to fail +because of a known bug in the test case’s implementation that has not been +fixed yet. + +Packets related to the scenario are saved to the test’s C<.data> file when +C is set in the environment. This means that no rerecord is +necessary when the C keyword is removed or when trying to fix the +implementation. + +The optional reason, if supplied, is used in the test harness’s diagnostic +output. It is useful for documenting the exact reason why the test is expected +to fail, for example by referring to an item on an issue tracker. + +=cut + +sub todo (;$) { + if ( exists STATE->{not_testable} ) { + croak "'todo' cannot be combined with 'not_testable'"; + } + if ( exists STATE->{todo} ) { + croak "'todo' can only be given once"; + } + STATE->{status} = [ 'todo', $_[0] ]; +} + +1; diff --git a/t/TestUtil/DSL/Compiler.pm b/t/TestUtil/DSL/Compiler.pm index 4580c3ef6..2400bd71b 100644 --- a/t/TestUtil/DSL/Compiler.pm +++ b/t/TestUtil/DSL/Compiler.pm @@ -1,497 +1,483 @@ -package TestUtil::DSL::Compiler; - -use warnings; -use strict; -use v5.24; - -use Carp qw(croak confess); -use Test::More (); - -=encoding utf8 - -=head1 NAME - -TestUtil::DSL::Compiler - compiler for the language defined in TestUtil::DSL - -=cut - -=head1 FUNCTIONS - -=head2 compile - -Compiles the AST, obtained as a result of parsing an instance of the DSL, into -a coderef that executes the tests defined in that DSL. - -Set C<$TestUtil::DSL::Compiler::DEBUG> to a non-zero value in order to obtain -debugging output. If running the corresponding C<.t> file in a harness, you -may need to enable verbose output in order to see it (e.g. by passing C<-v> -to C). - -=cut - -our $DEBUG = 0; - - -sub compile { - my ($ast) = @_; - - confess unless exists $ast->{test_module}; - confess unless exists $ast->{test_case}; - - my $test_module = $ast->{test_module}; - my $test_case = $ast->{test_case}; - - my $test_method = sub { - my ( $zone_name ) = @_; - return Zonemaster::Engine->test_method( - $test_module, $test_case, Zonemaster::Engine->zone( $zone_name )); - }; - - my $func_preamble = _compile_preamble($ast); - my $func_select_subtests = _compile_select_subtests($ast); - my @compiled_ops = _compile_ops($ast->{ops}, $test_case, $test_method); - - my $datafile = 't/' . File::Basename::basename( $0, '.t' ) . '.data'; - - return sub { - my $context = {}; - - if ($DEBUG) { - Test::More::note("Dumping AST read after parsing DSL:"); - Test::More::note(Test::More::explain($ast)); - } - - $func_preamble->(); - - $context->{todo_tests} = []; - $context->{disabled_tests} = []; - $context->{selected_subtests} = $func_select_subtests->( - $ENV{ZONEMASTER_SELECTED_SCENARIOS}, - $ENV{ZONEMASTER_DISABLED_SCENARIOS}); - - if ( not $ENV{ZONEMASTER_RECORD} ) { - Test::More::note "Loading data file: $datafile"; - die q{Stored data file missing} if not -r $datafile; - Zonemaster::Engine::Nameserver->restore( $datafile ); - Test::More::note "Done loading data file."; - Zonemaster::Engine::Profile->effective->set( q{no_network} => 1 ); - } - - Zonemaster::Engine::Profile->effective->merge( - Zonemaster::Engine::Profile->from_json( qq({ "test_cases": ["$test_case"] }) )); - - foreach my $callback ( @compiled_ops ) { - $callback->($context); - } - - Test::More::done_testing(); - - if (scalar @{$context->{todo_tests}}) { - Test::More::diag("The following scenarios are marked as TODO:\n"); - Test::More::diag(" $_") foreach @{$context->{todo_tests}}; - } - if (scalar @{$context->{disabled_tests}}) { - Test::More::diag("The following scenarios were not run:\n"); - Test::More::diag(" $_") foreach @{$context->{disabled_tests}}; - } - - if ( $ENV{ZONEMASTER_RECORD} ) { - Test::More::note "Saving data file: $datafile"; - Zonemaster::Engine::Nameserver->save( $datafile ); - Test::More::note "Done saving data file."; - } - }; -} - -# Top-level compilation helper functions - -sub _compile_preamble { - my ($ast) = @_; - - confess unless exists $ast->{test_module}; - - my $testmod = q{Zonemaster::Engine::Test::} . $ast->{test_module}; - - return sub { - Test::More::use_ok( q{Zonemaster::Engine::Nameserver} ); - Test::More::use_ok( $testmod ); - }; -} - -sub _compile_root_hints { - my ( $root_hints ) = @_; - - return sub { - Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); - Zonemaster::Engine::Recursor->add_fake_addresses( '.', $root_hints ); - Zonemaster::Engine::Recursor::clear_cache(); - } -} - -sub _compile_clear_cache { - return sub { - Zonemaster::Engine::Recursor::clear_cache(); - } -} - -sub _compile_select_subtests { - my ($ast) = @_; - - return sub { - my ( $selected_scenarios, $disabled_scenarios ) = @_; - - # Make a copy so as not to clobber the AST - my %scenario_status = ( %{$ast->{scenario_status}} ); - - # Force the listed tests in $selected_scenarios to run as if their - # status was testable. - if ( defined $selected_scenarios ) { - %scenario_status = map { - $_ => [ 'skip', 'not selected by environment variable' ] - } ( keys %scenario_status ); - foreach my $name ( split(/, */, $selected_scenarios) ) { - croak "$name: no such scenario" unless exists $scenario_status{$name}; - $scenario_status{$name} = [ 'testable' ]; - } - } - - # Skip the tests explicitly listed in $disabled_scenarios - foreach my $to_disable ( split(/, */, $disabled_scenarios // "") ) { - croak "$to_disable: no such scenario" unless exists $scenario_status{$to_disable}; - $scenario_status{$to_disable} = - [ 'skip', 'disabled by environment variable' ]; - } - - return \%scenario_status; - }; -} - -sub _compile_ops { - my ( $ops, $test_case, $test_method ) = @_; - - return map { - my ( $type, @args ) = @$_; - if ( $type eq 'root_hints' ) { - _compile_root_hints( @args ); - } - elsif ( $type eq 'scenario' ) { - _compile_run_scenario_block( @args, $test_case, $test_method ); - } - elsif ( $type eq 'clear_cache' ) { - _compile_clear_cache(); - } - } @$ops; -} - -sub _compile_run_scenario_block { - my ( $scenario_block, $test_case, $test_method ) = @_; - - # Compiling a scenario block is a bit tricky because determining which - # scenarios to run is done at runtime. We can’t just compile the scenario - # block to a sub directly and be done with it; we need to wrap it into a - # bit of code that checks if the scenario was forcibly enabled or disabled - # in the environment before making the decision to run it or not. - my $compiled_scenarios = _compile_scenario_block( $scenario_block, $test_case, $test_method ); - - my ($file, $line) = @{$compiled_scenarios->{caller}}; - my $callback = $compiled_scenarios->{callback}; - - return sub { - my ( $context ) = @_; - - my $selected_subtests = $context->{selected_subtests}; - my $disabled_tests = $context->{disabled_tests}; - my $todo_tests = $context->{todo_tests}; - - foreach my $descriptor (@{$compiled_scenarios->{args}}) { - my $name = $descriptor->{scenario_name}; - my $zone_name = $descriptor->{zone_name}; - - my ( $status, $reason ) = @{$selected_subtests->{$name}}; - my $name_and_reason = "$name" . (defined $reason ? " ($reason)" : ""); - - if ( $status eq 'skip' ) { - Test::More->builder->skip( $name_and_reason ); - push @$disabled_tests, $name_and_reason; - next; - } - elsif ( $status eq 'not_testable' ) { - Test::More->builder->todo_skip( $name_and_reason ); - push @$disabled_tests, $name_and_reason; - next; - } - elsif ( $status eq 'todo' ) { - # Avoid passing undef to Test::Builder::todo_start(), otherwise - # older versions (e.g. the one shipped with Perl 5.26) will not - # enable the todo status properly for the subtest if no reason - # was provided for the todo keyword in the DSL. - Test::More->builder->todo_start( $reason // "" ); - push @$todo_tests, $name_and_reason; - } - - my $ret = Test::More::subtest($name, $callback, $zone_name); - # Test::More->builder->no_diag(1) was called inside the callback just before - # exiting in order to suppress the default diag() output in case of failure - # of the subtest. Be sure to re-enable it before continuing. - Test::More->builder->no_diag(0); - - if ( $status eq 'todo' ) { - Test::More->builder->todo_end(); - } - elsif ( $status eq 'testable' and not $ret ) { - Test::More::diag(<{names}}) { - my $zone = lc _expand_template( - $scenario_block->{body}{zone}, - SCENARIO => $name, TESTCASE => $test_case ); - - push @subtest_args, { scenario_name => $name, zone_name => $zone }; - } - - return { - caller => $scenario_block->{caller}, - callback => _compile_scenario_subtest( $scenario_block, $test_method ), - args => \@subtest_args - }; -} - -# Scenario compilation helper functions - -sub _compile_scenario_subtest { - my ( $scenario_declaration, $test_method ) = @_; - - my $func_add_fake_delegation = _compile_fake_ns( $scenario_declaration ); - my $func_add_fake_ds = _compile_fake_ds( $scenario_declaration ); - my @func_message_tests = _compile_message_tests( $scenario_declaration ); - - return sub { - my ( $zone_name ) = @_; - Test::More::plan(tests => scalar @func_message_tests + 1); - - Test::More::note("Zone: $zone_name"); - $func_add_fake_delegation->($zone_name) if defined $func_add_fake_delegation; - $func_add_fake_ds->($zone_name) if defined $func_add_fake_ds; - - my @messages = $test_method->( $zone_name ); - - if ( my ( $error ) = grep { $_->tag eq 'MODULE_ERROR' } @messages ) { - Test::More::fail("Test case executes without errors"); - Test::More::diag("Module died with the following error:\n " . $error->args->{"msg"}); - } - else { - Test::More::pass("Test case executes without errors"); - $_->( @messages ) foreach ( @func_message_tests ); - } - - # At the end of a subtest, if there is at least one failure, - # Test::More automatically generates a comment containing the location - # of the failing test. This location is wrong, so we squelch any - # diag() output. There is no other way than to call no_diag() here. - Test::More->builder->no_diag(1); - }; -} - -sub _compile_fake_ns { - my ( $scenario_declaration ) = @_; - - if ( exists $scenario_declaration->{body}{fake_ns} ) { - my $undel_ns = $scenario_declaration->{body}{fake_ns}; - return sub { - my ( $zone_name ) = @_; - if ( $zone_name eq '.' ) { - Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); - } - # Use default value of "fill_in_empty_oob_glue". - Zonemaster::Engine->add_fake_delegation( - $zone_name => $undel_ns, fill_in_empty_oob_glue => 1 ); - } - } - return undef; -} - -sub _compile_fake_ds { - my ( $scenario_declaration ) = @_; - - if ( exists $scenario_declaration->{body}{fake_ds} ) { - my @undel_ds = @{$scenario_declaration->{body}{fake_ds}}; - return sub { - my ( $zone_name ) = @_; - Zonemaster::Engine->add_fake_ds( $zone_name => $_ ) foreach @undel_ds; - } - } - return undef; -} - -sub _compile_message_tests { - my ( $scenario_declaration ) = @_; - - map { - my ( $type, $caller, $tag, %args ) = @$_; - - if ( $type eq 'expect' and exists $args{code} ) { - _compile_expect_with_code( $caller, $tag, $args{code} ); - } - elsif ( $type eq 'expect' and exists $args{args} ) { - _compile_expect_with_args( $caller, $tag, %{$args{args}} ); - } - elsif ( $type eq 'expect' ) { - _compile_expect_bare( $caller, $tag ); - } - elsif ( $type eq 'forbid' ) { - _compile_forbid( $caller, $tag ); - } - } ( @{$scenario_declaration->{body}{message_tests}} ); -} - -sub _compile_expect_bare { - my ( $caller, $tag ) = @_; - - return sub { - _ok( - scalar ( grep { $_->{tag} eq $tag } @_ ), - "Tag '$tag' is outputted", - $caller ) - or Test::More::diag("Tag '$tag' should have been outputted, but wasn't"); - }; -} - -sub _compile_expect_with_args { - my ( $caller, $tag, %args ) = @_; - - my %predicates; - my $explanation = "Looked for a message whose tag is '$tag'"; - my $where = "where"; - - foreach my $argument ( sort keys %args ) { - $explanation .= "\n $where '$argument' "; - $where = " and"; - - my $value = $args{$argument}; - my $comparison = do { - if ( ref $value eq '' ) { - $explanation .= "equals '$value'"; - sub { $_[0] eq $_[1] }; - } - elsif ( ref $value eq 'Regexp' ) { - $explanation .= "matches $value"; - sub { $_[0] =~ $_[1] }; - } - elsif ( ref $value eq 'CODE' ) { - $explanation .= "satisfies a custom predicate"; - sub { $_[1]->($_[0]) }; - } - else { - croak "Invalid argument value given to key '$argument'"; - } - }; - $predicates{$argument} = sub { - $comparison->($_->{args}{$argument}, $value) - }; - } - - $explanation .= "\n and contains no argument other than those listed above"; - - my $combined_predicate = sub { - foreach my $k ( keys %{$_->{args}} ) { - if ( exists $predicates{$k} ) { - return 0 unless $predicates{$k}->($_); - } - else { - # The message contains an argument that isn’t matched by anything - # from the 'expect' keyword, so we fail the test for this message. - return 0; - } - } - return 1; - }; - - return sub { - my @messages = grep { $_->{tag} eq $tag } @_; - _ok( - scalar ( grep { $combined_predicate->($_) } @messages ), - "Messages of tag '$tag' exist with specified arguments", - $caller ) - or do { - Test::More::diag($explanation); - Test::More::diag("Here are all messages that unsuccessfully matched:"); - Test::More::diag(" $_->{tag} " . $_->argstr) foreach ( @messages ); - } - }; -} - -sub _compile_expect_with_code { - my ( $caller, $tag, $code ) = @_; - - return sub { - my @messages_of_tag = grep { $_->{tag} eq $tag } @_; - _ok( - $code->( @messages_of_tag ), - "Messages of tag '$tag' satisfy custom callback", - $caller ); - }; -} - -sub _compile_forbid { - my ( $caller, $tag ) = @_; - - return sub { - _ok( - ! scalar ( grep { $_->{tag} eq $tag } @_ ), - "Tag '$tag' is not outputted", - $caller ) - or Test::More::diag("Tag '$tag' shouldn't have been outputted, but it was"); - }; -} - - -# Miscellaneous utilities - -sub _expand_template { - my ($template, %variables) = @_; - - confess unless defined $template; - - my $result = $template; - for my $k (keys %variables) { - $result =~ s/\{$k\}/$variables{$k}/g; - } - - return $result; -} - -# A version of Test::More::ok that prints the correct location when a test fails. - -sub _ok { - my ( $ok, $test_name, $caller ) = @_; - my ( $file, $line ) = @$caller; - - # This is the only way to squelch the automatic diagnostics that are printed - # on the TAP output when ok() fails. The TAP output erroneously points to - # a line in t/TestUtil/DSL/Compiler.pm when an error occurs. - Test::More->builder->no_diag(1); - my $ret = Test::More::ok( $ok, $test_name ); - Test::More->builder->no_diag(0); - - unless ( $ok ) { - Test::More::diag(< to a non-zero value in order to obtain +debugging output. If running the corresponding C<.t> file in a harness, you +may need to enable verbose output in order to see it (e.g. by passing C<-v> +to C). + +=cut + +our $DEBUG = 0; + +sub compile { + my ( $ast ) = @_; + + confess unless exists $ast->{test_module}; + confess unless exists $ast->{test_case}; + + my $test_module = $ast->{test_module}; + my $test_case = $ast->{test_case}; + + my $test_method = sub { + my ( $zone_name ) = @_; + return Zonemaster::Engine->test_method( $test_module, $test_case, Zonemaster::Engine->zone( $zone_name ) ); + }; + + my $func_preamble = _compile_preamble( $ast ); + my $func_select_subtests = _compile_select_subtests( $ast ); + my @compiled_ops = _compile_ops( $ast->{ops}, $test_case, $test_method ); + + my $datafile = 't/' . File::Basename::basename( $0, '.t' ) . '.data'; + + return sub { + my $context = {}; + + if ( $DEBUG ) { + Test::More::note( "Dumping AST read after parsing DSL:" ); + Test::More::note( Test::More::explain( $ast ) ); + } + + $func_preamble->(); + + $context->{todo_tests} = []; + $context->{disabled_tests} = []; + $context->{selected_subtests} = + $func_select_subtests->( $ENV{ZONEMASTER_SELECTED_SCENARIOS}, $ENV{ZONEMASTER_DISABLED_SCENARIOS} ); + + if ( not $ENV{ZONEMASTER_RECORD} ) { + Test::More::note "Loading data file: $datafile"; + die q{Stored data file missing} if not -r $datafile; + Zonemaster::Engine::Nameserver->restore( $datafile ); + Test::More::note "Done loading data file."; + Zonemaster::Engine::Profile->effective->set( q{no_network} => 1 ); + } + + Zonemaster::Engine::Profile->effective->merge( + Zonemaster::Engine::Profile->from_json( qq({ "test_cases": ["$test_case"] }) ) ); + + foreach my $callback ( @compiled_ops ) { + $callback->( $context ); + } + + Test::More::done_testing(); + + if ( scalar @{ $context->{todo_tests} } ) { + Test::More::diag( "The following scenarios are marked as TODO:\n" ); + Test::More::diag( " $_" ) foreach @{ $context->{todo_tests} }; + } + if ( scalar @{ $context->{disabled_tests} } ) { + Test::More::diag( "The following scenarios were not run:\n" ); + Test::More::diag( " $_" ) foreach @{ $context->{disabled_tests} }; + } + + if ( $ENV{ZONEMASTER_RECORD} ) { + Test::More::note "Saving data file: $datafile"; + Zonemaster::Engine::Nameserver->save( $datafile ); + Test::More::note "Done saving data file."; + } + }; +} ## end sub compile + +# Top-level compilation helper functions + +sub _compile_preamble { + my ( $ast ) = @_; + + confess unless exists $ast->{test_module}; + + my $testmod = q{Zonemaster::Engine::Test::} . $ast->{test_module}; + + return sub { + Test::More::use_ok( q{Zonemaster::Engine::Nameserver} ); + Test::More::use_ok( $testmod ); + }; +} + +sub _compile_root_hints { + my ( $root_hints ) = @_; + + return sub { + Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); + Zonemaster::Engine::Recursor->add_fake_addresses( '.', $root_hints ); + Zonemaster::Engine::Recursor::clear_cache(); + } +} + +sub _compile_clear_cache { + return sub { + Zonemaster::Engine::Recursor::clear_cache(); + } +} + +sub _compile_select_subtests { + my ( $ast ) = @_; + + return sub { + my ( $selected_scenarios, $disabled_scenarios ) = @_; + + # Make a copy so as not to clobber the AST + my %scenario_status = ( %{ $ast->{scenario_status} } ); + + # Force the listed tests in $selected_scenarios to run as if their + # status was testable. + if ( defined $selected_scenarios ) { + %scenario_status = + map { $_ => [ 'skip', 'not selected by environment variable' ] } ( keys %scenario_status ); + foreach my $name ( split( /, */, $selected_scenarios ) ) { + croak "$name: no such scenario" unless exists $scenario_status{$name}; + $scenario_status{$name} = ['testable']; + } + } + + # Skip the tests explicitly listed in $disabled_scenarios + foreach my $to_disable ( split( /, */, $disabled_scenarios // "" ) ) { + croak "$to_disable: no such scenario" unless exists $scenario_status{$to_disable}; + $scenario_status{$to_disable} = [ 'skip', 'disabled by environment variable' ]; + } + + return \%scenario_status; + }; +} ## end sub _compile_select_subtests + +sub _compile_ops { + my ( $ops, $test_case, $test_method ) = @_; + + return map { + my ( $type, @args ) = @$_; + if ( $type eq 'root_hints' ) { + _compile_root_hints( @args ); + } + elsif ( $type eq 'scenario' ) { + _compile_run_scenario_block( @args, $test_case, $test_method ); + } + elsif ( $type eq 'clear_cache' ) { + _compile_clear_cache(); + } + } @$ops; +} + +sub _compile_run_scenario_block { + my ( $scenario_block, $test_case, $test_method ) = @_; + + # Compiling a scenario block is a bit tricky because determining which + # scenarios to run is done at runtime. We can’t just compile the scenario + # block to a sub directly and be done with it; we need to wrap it into a + # bit of code that checks if the scenario was forcibly enabled or disabled + # in the environment before making the decision to run it or not. + my $compiled_scenarios = _compile_scenario_block( $scenario_block, $test_case, $test_method ); + + my ( $file, $line ) = @{ $compiled_scenarios->{caller} }; + my $callback = $compiled_scenarios->{callback}; + + return sub { + my ( $context ) = @_; + + my $selected_subtests = $context->{selected_subtests}; + my $disabled_tests = $context->{disabled_tests}; + my $todo_tests = $context->{todo_tests}; + + foreach my $descriptor ( @{ $compiled_scenarios->{args} } ) { + my $name = $descriptor->{scenario_name}; + my $zone_name = $descriptor->{zone_name}; + + my ( $status, $reason ) = @{ $selected_subtests->{$name} }; + my $name_and_reason = "$name" . ( defined $reason ? " ($reason)" : "" ); + + if ( $status eq 'skip' ) { + Test::More->builder->skip( $name_and_reason ); + push @$disabled_tests, $name_and_reason; + next; + } + elsif ( $status eq 'not_testable' ) { + Test::More->builder->todo_skip( $name_and_reason ); + push @$disabled_tests, $name_and_reason; + next; + } + elsif ( $status eq 'todo' ) { + # Avoid passing undef to Test::Builder::todo_start(), otherwise + # older versions (e.g. the one shipped with Perl 5.26) will not + # enable the todo status properly for the subtest if no reason + # was provided for the todo keyword in the DSL. + Test::More->builder->todo_start( $reason // "" ); + push @$todo_tests, $name_and_reason; + } + + my $ret = Test::More::subtest( $name, $callback, $zone_name ); + # Test::More->builder->no_diag(1) was called inside the callback just before + # exiting in order to suppress the default diag() output in case of failure + # of the subtest. Be sure to re-enable it before continuing. + Test::More->builder->no_diag( 0 ); + + if ( $status eq 'todo' ) { + Test::More->builder->todo_end(); + } + elsif ( $status eq 'testable' and not $ret ) { + Test::More::diag( <{names} } ) { + my $zone = lc _expand_template( + $scenario_block->{body}{zone}, + SCENARIO => $name, + TESTCASE => $test_case, + ); + + push @subtest_args, { scenario_name => $name, zone_name => $zone }; + } + + return { + caller => $scenario_block->{caller}, + callback => _compile_scenario_subtest( $scenario_block, $test_method ), + args => \@subtest_args, + }; +} ## end sub _compile_scenario_block + +# Scenario compilation helper functions + +sub _compile_scenario_subtest { + my ( $scenario_declaration, $test_method ) = @_; + + my $func_add_fake_delegation = _compile_fake_ns( $scenario_declaration ); + my $func_add_fake_ds = _compile_fake_ds( $scenario_declaration ); + my @func_message_tests = _compile_message_tests( $scenario_declaration ); + + return sub { + my ( $zone_name ) = @_; + Test::More::plan( tests => scalar @func_message_tests + 1 ); + + Test::More::note( "Zone: $zone_name" ); + $func_add_fake_delegation->( $zone_name ) if defined $func_add_fake_delegation; + $func_add_fake_ds->( $zone_name ) if defined $func_add_fake_ds; + + my @messages = $test_method->( $zone_name ); + + if ( my ( $error ) = grep { $_->tag eq 'MODULE_ERROR' } @messages ) { + Test::More::fail( "Test case executes without errors" ); + Test::More::diag( "Module died with the following error:\n " . $error->args->{"msg"} ); + } + else { + Test::More::pass( "Test case executes without errors" ); + $_->( @messages ) foreach ( @func_message_tests ); + } + + # At the end of a subtest, if there is at least one failure, + # Test::More automatically generates a comment containing the location + # of the failing test. This location is wrong, so we squelch any + # diag() output. There is no other way than to call no_diag() here. + Test::More->builder->no_diag( 1 ); + }; +} ## end sub _compile_scenario_subtest + +sub _compile_fake_ns { + my ( $scenario_declaration ) = @_; + + if ( exists $scenario_declaration->{body}{fake_ns} ) { + my $undel_ns = $scenario_declaration->{body}{fake_ns}; + return sub { + my ( $zone_name ) = @_; + if ( $zone_name eq '.' ) { + Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); + } + # Use default value of "fill_in_empty_oob_glue". + Zonemaster::Engine->add_fake_delegation( + $zone_name => $undel_ns, + fill_in_empty_oob_glue => 1, + ); + } + } + return undef; +} + +sub _compile_fake_ds { + my ( $scenario_declaration ) = @_; + + if ( exists $scenario_declaration->{body}{fake_ds} ) { + my @undel_ds = @{ $scenario_declaration->{body}{fake_ds} }; + return sub { + my ( $zone_name ) = @_; + Zonemaster::Engine->add_fake_ds( $zone_name => $_ ) foreach @undel_ds; + } + } + return undef; +} + +sub _compile_message_tests { + my ( $scenario_declaration ) = @_; + + map { + my ( $type, $caller, $tag, %args ) = @$_; + + if ( $type eq 'expect' and exists $args{code} ) { + _compile_expect_with_code( $caller, $tag, $args{code} ); + } + elsif ( $type eq 'expect' and exists $args{args} ) { + _compile_expect_with_args( $caller, $tag, %{ $args{args} } ); + } + elsif ( $type eq 'expect' ) { + _compile_expect_bare( $caller, $tag ); + } + elsif ( $type eq 'forbid' ) { + _compile_forbid( $caller, $tag ); + } + } ( @{ $scenario_declaration->{body}{message_tests} } ); +} ## end sub _compile_message_tests + +sub _compile_expect_bare { + my ( $caller, $tag ) = @_; + + return sub { + _ok( scalar( grep { $_->{tag} eq $tag } @_ ), "Tag '$tag' is outputted", $caller ) + or Test::More::diag( "Tag '$tag' should have been outputted, but wasn't" ); + }; +} + +sub _compile_expect_with_args { + my ( $caller, $tag, %args ) = @_; + + my %predicates; + my $explanation = "Looked for a message whose tag is '$tag'"; + my $where = "where"; + + foreach my $argument ( sort keys %args ) { + $explanation .= "\n $where '$argument' "; + $where = " and"; + + my $value = $args{$argument}; + my $comparison = do { + if ( ref $value eq '' ) { + $explanation .= "equals '$value'"; + sub { $_[0] eq $_[1] }; + } + elsif ( ref $value eq 'Regexp' ) { + $explanation .= "matches $value"; + sub { $_[0] =~ $_[1] }; + } + elsif ( ref $value eq 'CODE' ) { + $explanation .= "satisfies a custom predicate"; + sub { $_[1]->( $_[0] ) }; + } + else { + croak "Invalid argument value given to key '$argument'"; + } + }; + $predicates{$argument} = sub { + $comparison->( $_->{args}{$argument}, $value ); + }; + } ## end foreach my $argument ( sort...) + + $explanation .= "\n and contains no argument other than those listed above"; + + my $combined_predicate = sub { + foreach my $k ( keys %{ $_->{args} } ) { + if ( exists $predicates{$k} ) { + return 0 unless $predicates{$k}->( $_ ); + } + else { + # The message contains an argument that isn’t matched by anything + # from the 'expect' keyword, so we fail the test for this message. + return 0; + } + } + return 1; + }; + + return sub { + my @messages = grep { $_->{tag} eq $tag } @_; + _ok( scalar( grep { $combined_predicate->( $_ ) } @messages ), + "Messages of tag '$tag' exist with specified arguments", $caller, ) + or do { + Test::More::diag( $explanation ); + Test::More::diag( "Here are all messages that unsuccessfully matched:" ); + Test::More::diag( " $_->{tag} " . $_->argstr ) foreach ( @messages ); + } + }; +} ## end sub _compile_expect_with_args + +sub _compile_expect_with_code { + my ( $caller, $tag, $code ) = @_; + + return sub { + my @messages_of_tag = grep { $_->{tag} eq $tag } @_; + _ok( $code->( @messages_of_tag ), "Messages of tag '$tag' satisfy custom callback", $caller ); + }; +} + +sub _compile_forbid { + my ( $caller, $tag ) = @_; + + return sub { + _ok( !scalar( grep { $_->{tag} eq $tag } @_ ), "Tag '$tag' is not outputted", $caller ) + or Test::More::diag( "Tag '$tag' shouldn't have been outputted, but it was" ); + }; +} + +# Miscellaneous utilities + +sub _expand_template { + my ( $template, %variables ) = @_; + + confess unless defined $template; + + my $result = $template; + for my $k ( keys %variables ) { + $result =~ s/\{$k\}/$variables{$k}/g; + } + + return $result; +} + +# A version of Test::More::ok that prints the correct location when a test fails. + +sub _ok { + my ( $ok, $test_name, $caller ) = @_; + my ( $file, $line ) = @$caller; + + # This is the only way to squelch the automatic diagnostics that are printed + # on the TAP output when ok() fails. The TAP output erroneously points to + # a line in t/TestUtil/DSL/Compiler.pm when an error occurs. + Test::More->builder->no_diag( 1 ); + my $ret = Test::More::ok( $ok, $test_name ); + Test::More->builder->no_diag( 0 ); + + unless ( $ok ) { + Test::More::diag( <effective->set( q{no_network}, 1 ); } -Zonemaster::Engine::Profile->effective->set(q{asn_db.style}, "cymru" ); -Zonemaster::Engine::Profile->effective->set(q{asn_db.sources}, { cymru => [ "asnlookup.zonemaster.net", "asn.cymru.com" ] }); +Zonemaster::Engine::Profile->effective->set( q{asn_db.style}, "cymru" ); +Zonemaster::Engine::Profile->effective->set( q{asn_db.sources}, + { cymru => [ "asnlookup.zonemaster.net", "asn.cymru.com" ] }, +); my ( $asn1, $prefix1 ) = Zonemaster::Engine::ASNLookup->get_with_prefix( '8.8.8.8' ); -is $asn1->[0], 15169, '8.8.8.8 is in AS15169'; +is $asn1->[0], 15169, '8.8.8.8 is in AS15169'; is $prefix1->prefix, '8.8.8.0/24', '8.8.8.8 is in 8.8.8.0/24'; my ( $asn2, $prefix2 ) = Zonemaster::Engine::ASNLookup->get_with_prefix( '91.226.36.46' ); -is $asn2->[0], 197564, '91.226.36.46 is in AS197564'; +is $asn2->[0], 197564, '91.226.36.46 is in AS197564'; is $prefix2->prefix, '91.226.36.0/23', '91.226.36.46 is in 91.226.36.0/24'; my @asn3 = Zonemaster::Engine::ASNLookup->get( '2001:7fd::1' ); @@ -28,17 +30,21 @@ is $asn3[0], 25152, '2001:7fd::1 is in AS 25152'; my ( $asn4, $prefix4 ) = Zonemaster::Engine::ASNLookup->get_with_prefix( '192.168.0.1' ); ok( scalar @{$asn4} == 0, '192.168.0.1 (RFC1918 address) is in no AS' ); -Zonemaster::Engine::Profile->effective->set(q{asn_db.sources}, { cymru => [ "fake.asnlookup.zonemaster.net", "asnlookup.dufberg.se" ] }); +Zonemaster::Engine::Profile->effective->set( q{asn_db.sources}, + { cymru => [ "fake.asnlookup.zonemaster.net", "asnlookup.dufberg.se" ] }, +); my ( $asn5, $prefix5 ) = Zonemaster::Engine::ASNLookup->get_with_prefix( '3.124.111.178' ); -is $asn5->[0], 16509, '3.124.111.178 is in AS16509'; +is $asn5->[0], 16509, '3.124.111.178 is in AS16509'; is $prefix5->prefix, '3.124.0.0/14', '3.124.111.178 is in 3.124.0.0/14'; -Zonemaster::Engine::Profile->effective->set(q{asn_db.style}, "ripe" ); -Zonemaster::Engine::Profile->effective->set(q{asn_db.sources}, { ripe => [ "fake.riswhois.zonemaster.net", "riswhois.ripe.net" ] }); +Zonemaster::Engine::Profile->effective->set( q{asn_db.style}, "ripe" ); +Zonemaster::Engine::Profile->effective->set( q{asn_db.sources}, + { ripe => [ "fake.riswhois.zonemaster.net", "riswhois.ripe.net" ] }, +); my ( $asn6, $prefix6 ) = Zonemaster::Engine::ASNLookup->get_with_prefix( '1.1.1.1' ); -is $asn6->[0], 13335, '1.1.1.1 is in AS13335'; +is $asn6->[0], 13335, '1.1.1.1 is in AS13335'; is $prefix6->prefix, '1.1.1.0/24', '1.1.1.1 is in 1.1.1.0/24'; if ( $ENV{ZONEMASTER_RECORD} ) { diff --git a/t/dnsname.t b/t/dnsname.t index 9f831189d..733964f9f 100644 --- a/t/dnsname.t +++ b/t/dnsname.t @@ -9,7 +9,7 @@ my $name = Zonemaster::Engine::DNSName->new( 'www.iis.se' ); is_deeply( $name->labels, [ 'www', 'iis', 'se' ] ); my $root = Zonemaster::Engine::DNSName->new( '' ); -is_deeply( $root->labels, [] ); +is_deeply( $root->labels, [] ); is_deeply( Zonemaster::Engine::DNSName->new( '.' )->labels, [] ); is( $name->string, 'www.iis.se', 'Default, no final dot' ); @@ -21,7 +21,7 @@ is( $root->fqdn, '.', 'Root fqdn OK.' ); ok( '.' eq $root, 'Root equal with dot' ); ok( $root eq '.', 'Root equal with dot, other way around' ); -is( Zonemaster::Engine::DNSName->new({ labels => [qw(www nic se)] }), 'www.nic.se' ); +is( Zonemaster::Engine::DNSName->new( { labels => [qw(www nic se)] } ), 'www.nic.se' ); is_deeply( Zonemaster::Engine::DNSName->new( 'www.nic.se.' )->labels, [qw(www nic se)] ); is( $name->next_higher, 'iis.se' ); diff --git a/t/logger.t b/t/logger.t index 61f420ca1..25b17ad8c 100644 --- a/t/logger.t +++ b/t/logger.t @@ -57,17 +57,20 @@ $entry = info( 'TEST2', { an => 'argument', domain => Zonemaster::Engine::Util:: is( "$entry", 'System:Unspecified:TEST2 an=argument; domain="logger.test.example"', - 'stringification overload works with DNS names' ); + 'stringification overload works with DNS names', +); is_deeply( - (decode_json $log->json)->[-1]->{args}, + ( decode_json $log->json )->[-1]->{args}, { - an => 'argument', - domain => 'logger.test.example' + an => 'argument', + domain => 'logger.test.example', }, - 'entry arguments serialize to JSON' ); + 'entry arguments serialize to JSON', +); is( $entry->level, 'DEBUG', 'right level' ); -my $example = Zonemaster::Engine::Logger::Entry->new({ module => 'Basic', tag => 'B02_NS_BROKEN', testcase => 'Basic02' } ); +my $example = + Zonemaster::Engine::Logger::Entry->new( { module => 'Basic', tag => 'B02_NS_BROKEN', testcase => 'Basic02' } ); is( $example->level, 'ERROR', 'expected level' ); is( $example->numeric_level, 4, 'expected numeric level' ); @@ -101,8 +104,8 @@ is( "$err", 'canary' ); $log->callback( undef ); Zonemaster::Engine::Logger->reset_config(); -$json = read_file( "t/profiles/profile.json" ); -$profile_test = Zonemaster::Engine::Profile->from_json( $json ); +$json = read_file( "t/profiles/profile.json" ); +$profile_test = Zonemaster::Engine::Profile->from_json( $json ); ok( Zonemaster::Engine::Profile->effective->merge( $profile_test ), 'profile loaded' ); $log->add( FILTER_THIS => { when => 1, and => 'this' } ); my $filtered = $log->entries->[-1]; @@ -127,12 +130,13 @@ ok( length( $all_json ) > length( $some_json ), 'All longer than some' ); like( $some_json, qr[[{"args":{"exception":"in callback at t/logger.t line 47, line 1.\n"},"level":"ERROR","module":"SYSTEM","tag":"LOGGER_CALLBACK_ERROR","timestamp":0.\d+}]], - 'JSON looks OK' + 'JSON looks OK', ); Zonemaster::Engine::Logger->reset_config(); -Zonemaster::Engine::Profile->effective->set( q{test_levels}, {"BASIC" => {"B02_NS_BROKEN" => "GURKSALLAD" }}); -my $fail = Zonemaster::Engine::Logger::Entry->new( { module => 'Basic', tag => 'B02_NS_BROKEN', testcase => 'Basic02' } ); +Zonemaster::Engine::Profile->effective->set( q{test_levels}, { "BASIC" => { "B02_NS_BROKEN" => "GURKSALLAD" } } ); +my $fail = + Zonemaster::Engine::Logger::Entry->new( { module => 'Basic', tag => 'B02_NS_BROKEN', testcase => 'Basic02' } ); like( exception { $fail->level }, qr/Unknown level string: GURKSALLAD/, 'Dies on unknown level string' ); done_testing; diff --git a/t/manifest.t b/t/manifest.t index 6ef40011e..55fea7309 100644 --- a/t/manifest.t +++ b/t/manifest.t @@ -18,7 +18,7 @@ sub make { undef $ENV{MAKEFLAGS}; my $command = join( ' ', $makebin, '-s', @make_args ); - my $output = `$command 2>&1`; + my $output = `$command 2>&1`; if ( $? == -1 ) { BAIL_OUT( "failed to execute: $!" ); diff --git a/t/nameserver-axfr.t b/t/nameserver-axfr.t index 737d995ba..9232c30a1 100644 --- a/t/nameserver-axfr.t +++ b/t/nameserver-axfr.t @@ -16,14 +16,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { } # This should be a successful AXFR -my $ns = Zonemaster::Engine::Nameserver->new( { name => 'kennedy.faerywicca.se', address => '46.21.106.227' } ); +my $ns = Zonemaster::Engine::Nameserver->new( { name => 'kennedy.faerywicca.se', address => '46.21.106.227' } ); my $counter = 0; is( exception { $ns->axfr( 'cyberpomo.com', sub { $counter += 1; return 1; } ); }, undef, - 'No exception' + 'No exception', ); ok( ( $counter > 10 ), 'At least ten records seen' ); @@ -35,7 +35,7 @@ like( $ns2->axfr( 'iis.se', sub { $counter += 1; return 1; } ); }, qr/REFUSED/, - 'AXFR was refused' + 'AXFR was refused', ); is( $counter, 0, 'No records seen' ); diff --git a/t/nameserver.t b/t/nameserver.t index e18882e1c..6c6d49ccd 100644 --- a/t/nameserver.t +++ b/t/nameserver.t @@ -16,7 +16,8 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my $nsv6 = new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '2001:67c:124c:100a::45' } ] ); +my $nsv6 = + new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '2001:67c:124c:100a::45' } ] ); my $nsv4 = new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '91.226.36.45' } ] ); eval { Zonemaster::Engine::Nameserver->new( { name => 'dummy' } ); }; @@ -36,18 +37,18 @@ isa_ok( $p2, 'Zonemaster::Engine::Packet' ); my ( $soa ) = grep { $_->type eq 'SOA' } $p1->answer; is( scalar( $p1->answer ), 1, 'one answer RR present ' ); ok( $soa, 'it is a SOA RR' ); -is( lc( $soa->rname ), 'hostmaster.nic.se.', 'RNAME has expected format' ); +is( lc( $soa->rname ), 'hostmaster.nic.se.', 'RNAME has expected format' ); is( scalar( grep { $_->type eq 'SOA' or $_->type eq 'RRSIG' } $p2->answer ), 2, 'SOA and RRSIG RRs present' ); -ok( $p3 eq $p2, 'Same packet object returned' ); -ok( $p3 ne $p4, 'Same packet object not returned from other server' ); -ok( $p3 ne $p1, 'Same packet object not returned with other flag' ); +ok( $p3 eq $p2, 'Same packet object returned' ); +ok( $p3 ne $p4, 'Same packet object not returned from other server' ); +ok( $p3 ne $p1, 'Same packet object not returned with other flag' ); my $nscopy = Zonemaster::Engine->ns( 'ns.nic.se.', '2001:67c:124c:100a:0000::45' ); ok( $nsv6 eq $nscopy, 'Same nameserver object returned' ); my $nssame = Zonemaster::Engine->ns( 'foo.example.org', '2001:67c:124c:100a:0000::45' ); ok( ( $nssame ne $nsv6 and $nssame->cache eq $nsv6->cache ), - 'Different name, same IP are different but has same cache' + 'Different name, same IP are different but has same cache', ); SKIP: { @@ -58,27 +59,30 @@ SKIP: { undef %Zonemaster::Engine::Nameserver::object_cache; is( scalar( keys %Zonemaster::Engine::Nameserver::object_cache ), 0, 'Nameserver cache is empty after clear.' ); Zonemaster::Engine::Nameserver->restore( $name ); - is( scalar( keys %Zonemaster::Engine::Nameserver::object_cache ), - $count, 'Same number of top-level keys in cache after restore.' ); + is( + scalar( keys %Zonemaster::Engine::Nameserver::object_cache ), + $count, 'Same number of top-level keys in cache after restore.', + ); unlink $name; } my $broken = new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.not.existing', address => '192.0.2.17' } ] ); -my $p = $broken->query( 'www.iis.se' ); +my $p = $broken->query( 'www.iis.se' ); ok( !$p, 'no response from broken server' ); my $googlens = ns( 'ns1.google.com', '216.239.32.10' ); -my $save = Zonemaster::Engine::Profile->effective->get( q{no_network} ); +my $save = Zonemaster::Engine::Profile->effective->get( q{no_network} ); Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); delete( $googlens->cache->{'www.google.com'} ); eval { $googlens->query( 'www.google.com', 'TXT' ) }; -like( $@, - qr{External query for www.google.com, TXT attempted to ns1.google.com/216.239.32.10 while running with no_network} +like( + $@, + qr{External query for www.google.com, TXT attempted to ns1.google.com/216.239.32.10 while running with no_network}, ); Zonemaster::Engine::Profile->effective->set( q{no_network}, $save ); @{ $nsv6->times } = ( qw[2 4 4 4 5 5 7 9] ); -is( $nsv6->stddev_time, 2, 'known value check' ); +is( $nsv6->stddev_time, 2, 'known value check' ); is( $nsv6->average_time, 5 ); is( $nsv6->median_time, 4.5 ); is( $nsv6->max_time, 9 ); @@ -155,7 +159,11 @@ subtest 'dnssec, edns_size and edns_details{do, size} flags behavior for queries $p = $ns->_make_query_packet( 'f.fr', 'SOA', { "edns_details" => { "do" => 1 } } ); ok( $p->do(), 'DNSSEC flag is also set via edns_details{do}' ); - is( $p->edns_size(), $EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT, 'EDNS size uses default DNSSEC query value when set with edns_details{do}' ); + is( + $p->edns_size(), + $EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT, + 'EDNS size uses default DNSSEC query value when set with edns_details{do}', + ); $p = $ns->_make_query_packet( 'g.fr', 'SOA', { "edns_details" => { "size" => 900 } } ); ok( !$p->do(), 'DNSSEC flag is unset' ); @@ -167,24 +175,33 @@ subtest 'dnssec, edns_size and edns_details{do, size} flags behavior for queries $p = $ns->_make_query_packet( 'i.fr', 'SOA', { "dnssec" => 1, "edns_details" => { "do" => 0 } } ); ok( !$p->do(), 'edns_details{do} takes precedence over dnssec for (un)setting the DNSSEC flag' ); - is( $p->edns_size(), $EDNS_UDP_PAYLOAD_DEFAULT, 'EDNS size uses default EDNS query value when DNSSEC flag is unset by edns_details{do}' ); + is( $p->edns_size(), $EDNS_UDP_PAYLOAD_DEFAULT, + 'EDNS size uses default EDNS query value when DNSSEC flag is unset by edns_details{do}', + ); $p = $ns->_make_query_packet( 'j.fr', 'SOA', { "edns_size" => 1003, "edns_details" => { "size" => 901 } } ); ok( !$p->do(), 'DNSSEC flag is unset' ); is( $p->edns_size(), 901, 'edns_details{size} takes precedence over edns_size for setting the edns_size flag' ); - $p = $ns->_make_query_packet( 'k.fr', 'SOA', { "dnssec" => 1, "edns_size" => 1004, "edns_details" => { "size" => 0 } } ); + $p = + $ns->_make_query_packet( 'k.fr', 'SOA', { "dnssec" => 1, "edns_size" => 1004, "edns_details" => { "size" => 0 } }, + ); ok( $p->do(), 'DNSSEC flag is set' ); is( $p->edns_size(), 0, 'EDNS size is unset' ); - $p = $ns->_make_query_packet( 'l.fr', 'SOA', { "dnssec" => 0, "edns_size" => 1005, "edns_details" => { "do" => 1, "size" => 0 } } ); + $p = + $ns->_make_query_packet( 'l.fr', 'SOA', + { "dnssec" => 0, "edns_size" => 1005, "edns_details" => { "do" => 1, "size" => 0 } }, + ); ok( $p->do(), 'DNSSEC flag is set' ); is( $p->edns_size(), 0, 'EDNS size is unset' ); - dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_size" => 65536 } ); } "dies when edns_size exceeds 65535"; - dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_details" => { "size" => 65536 } } ); } "dies when edns_size (set with edns_details->size) exceeds 65535"; - dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_size" => -1 } ); } "dies when edns_size is lower than 0"; - dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_details" => { "size" => -1 } } ); } "dies when edns_size (set with edns_details->size) is lower than 0"; + dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_size" => 65536 } ); } "dies when edns_size exceeds 65535"; + dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_details" => { "size" => 65536 } } ); } + "dies when edns_size (set with edns_details->size) exceeds 65535"; + dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_size" => -1 } ); } "dies when edns_size is lower than 0"; + dies_ok { $p = $ns->query( 'fr', 'SOA', { "edns_details" => { "size" => -1 } } ); } + "dies when edns_size (set with edns_details->size) is lower than 0"; }; subtest 'comparisons' => sub { @@ -202,39 +219,40 @@ subtest 'sorting' => sub { my @unsorted = ( Zonemaster::Engine->ns( 'localhost.test', '::1' ), Zonemaster::Engine->ns( 'localhost.test', '127.0.0.1' ), - Zonemaster::Engine->ns( 'a.test', '192.0.2.150' ), - Zonemaster::Engine->ns( 'a.test', '192.0.2.1' ), + Zonemaster::Engine->ns( 'a.test', '192.0.2.150' ), + Zonemaster::Engine->ns( 'a.test', '192.0.2.1' ), Zonemaster::Engine::DNSName->new( 'b.test' ), Zonemaster::Engine->ns( 'a.test', '2001:db8::1000' ), Zonemaster::Engine->ns( 'a.test', '2001:db8::1' ), 'm.test', - Zonemaster::Engine->ns( 'b.test', '3ffe::b' ) + Zonemaster::Engine->ns( 'b.test', '3ffe::b' ), ); my @sorted = map { "$_" } sort @unsorted; my @expected = qw( - a.test/192.0.2.1 - a.test/192.0.2.150 - a.test/2001:db8::1 - a.test/2001:db8::1000 - b.test - b.test/3ffe::b - localhost.test/127.0.0.1 - localhost.test/::1 - m.test - ); - - is_deeply( \@sorted, \@expected ) or diag( "This is what we got:\n" . join( "\n", @sorted )); + a.test/192.0.2.1 + a.test/192.0.2.150 + a.test/2001:db8::1 + a.test/2001:db8::1000 + b.test + b.test/3ffe::b + localhost.test/127.0.0.1 + localhost.test/::1 + m.test + ); + + is_deeply( \@sorted, \@expected ) or diag( "This is what we got:\n" . join( "\n", @sorted ) ); }; Zonemaster::Engine::Profile->effective->set( q{resolver.source4}, q{127.0.0.1} ); my $ns_test = new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '212.247.7.228' } ] ); -is($ns_test->dns->source, '127.0.0.1', 'Source IPv4 address set.'); +is( $ns_test->dns->source, '127.0.0.1', 'Source IPv4 address set.' ); Zonemaster::Engine::Profile->effective->set( q{resolver.source6}, q{::1} ); -$ns_test = new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '2001:67c:124c:100a::45' } ] ); -is($ns_test->dns->source, '::1', 'Source IPv6 address set.'); +$ns_test = + new_ok( 'Zonemaster::Engine::Nameserver' => [ { name => 'ns.nic.se', address => '2001:67c:124c:100a::45' } ] ); +is( $ns_test->dns->source, '::1', 'Source IPv6 address set.' ); # We have to make a query to test the following message tags, so no_network must be false. Zonemaster::Engine::Profile->effective->set( q{no_network}, 0 ); @@ -244,7 +262,7 @@ Zonemaster::Engine->logger->clear_history(); # 192.0.2.17 is part of TEST-NET-1 IP address range (see RFC6890) and reserved # for documentation. my $fail_ns = Zonemaster::Engine::Nameserver->new( { name => 'fail', address => '192.0.2.17' } ); -my $fail_p = $fail_ns->query( 'example.org', 'SOA', {} ); +my $fail_p = $fail_ns->query( 'example.org', 'SOA', {} ); is( $fail_p, undef, 'No return from broken server' ); if ( $ENV{ZONEMASTER_RECORD} ) { @@ -264,15 +282,21 @@ if ( $ENV{ZONEMASTER_RECORD} ) { isa_ok( $e, 'Zonemaster::Engine::Logger::Entry' ); ( $e ) = grep { $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries }; - is( %{$e->args}{proto}, 'UDP', 'Name server is blacklisted for UDP on non-EDNS SOA UDP query' ); + is( %{ $e->args }{proto}, 'UDP', 'Name server is blacklisted for UDP on non-EDNS SOA UDP query' ); } else { - ok( ! grep({ $_->tag eq 'EXTERNAL_QUERY' } @{ Zonemaster::Engine->logger->entries }), - 'No network access was attempted' ) or diag(join("\n", @{ Zonemaster::Engine->logger->entries })); - ok( ! grep({ $_->tag eq 'LOOKUP_ERROR' } @{ Zonemaster::Engine->logger->entries }), - 'The lookup error came from cache, not network' ); - ok( ! grep({ $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries }), - 'No blacklisting is done when running offline' ); + ok( + !grep( { $_->tag eq 'EXTERNAL_QUERY' } @{ Zonemaster::Engine->logger->entries } ), + 'No network access was attempted', + ) or diag( join( "\n", @{ Zonemaster::Engine->logger->entries } ) ); + ok( + !grep( { $_->tag eq 'LOOKUP_ERROR' } @{ Zonemaster::Engine->logger->entries } ), + 'The lookup error came from cache, not network', + ); + ok( + !grep( { $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries } ), + 'No blacklisting is done when running offline', + ); } Zonemaster::Engine->logger->clear_history(); @@ -284,15 +308,21 @@ if ( $ENV{ZONEMASTER_RECORD} ) { # For the same reason as above, the test in this block will not work if # running offline (i.e. without ZONEMASTER_RECORD=1). my ( $e ) = grep { $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries }; - is( %{$e->args}{proto}, 'TCP', 'Name server is blacklisted for TCP on non-EDNS SOA TCP query' ); + is( %{ $e->args }{proto}, 'TCP', 'Name server is blacklisted for TCP on non-EDNS SOA TCP query' ); } else { - ok( ! grep({ $_->tag eq 'EXTERNAL_QUERY' } @{ Zonemaster::Engine->logger->entries }), - 'No network access was attempted' ) or diag(join("\n", @{ Zonemaster::Engine->logger->entries })); - ok( ! grep({ $_->tag eq 'LOOKUP_ERROR' } @{ Zonemaster::Engine->logger->entries }), - 'The lookup error came from cache, not network' ); - ok( ! grep({ $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries }), - 'No blacklisting is done when running offline' ); + ok( + !grep( { $_->tag eq 'EXTERNAL_QUERY' } @{ Zonemaster::Engine->logger->entries } ), + 'No network access was attempted', + ) or diag( join( "\n", @{ Zonemaster::Engine->logger->entries } ) ); + ok( + !grep( { $_->tag eq 'LOOKUP_ERROR' } @{ Zonemaster::Engine->logger->entries } ), + 'The lookup error came from cache, not network', + ); + ok( + !grep( { $_->tag eq 'BLACKLISTING' } @{ Zonemaster::Engine->logger->entries } ), + 'No blacklisting is done when running offline', + ); } if ( $ENV{ZONEMASTER_RECORD} ) { diff --git a/t/nameserverset.t b/t/nameserverset.t index c3d8c2a5e..a8b2de3b9 100644 --- a/t/nameserverset.t +++ b/t/nameserverset.t @@ -26,7 +26,7 @@ subtest 'is_empty() method' => sub { $set->push( 'not.empty.anymore.test' ); - ok( ! $set->is_empty(), 'is_empty() is false if set is nonempty' ); + ok( !$set->is_empty(), 'is_empty() is false if set is nonempty' ); }; subtest 'pushing nothing is a non-operation' => sub { @@ -40,7 +40,7 @@ subtest 'push() methods returns self' => sub { isa_ok( Zonemaster::Engine::NameserverSet->new()->push(), 'Zonemaster::Engine::NameserverSet', - 'push() method returns the object' + 'push() method returns the object', ); }; @@ -50,44 +50,46 @@ subtest 'pushing a DNS name onto an empty set' => sub { $set->push( Zonemaster::Engine::DNSName->new( 'one.test' ) ); - ok( ! $set->is_empty(), 'set is no longer empty' ); + ok( !$set->is_empty(), 'set is no longer empty' ); is( scalar $set->items, 1, 'set contains one item' ); - is( 'one.test', ($set->items)[0] ); + is( 'one.test', ( $set->items )[0] ); }; subtest 'pushing a nameserver onto an empty set' => sub { my $set = Zonemaster::Engine::NameserverSet->new(); $set->push( - Zonemaster::Engine::Nameserver->new( { - name => 'ns1.one.test', - address => '2001:db8::' - } ) + Zonemaster::Engine::Nameserver->new( + { + name => 'ns1.one.test', + address => '2001:db8::', + } + ) ); is( scalar $set->items, 1, 'set contains one item' ); - is( 'ns1.one.test/2001:db8::', ($set->items)[0] ); + is( 'ns1.one.test/2001:db8::', ( $set->items )[0] ); }; subtest 'pushing a plain string onto an empty set' => sub { my $set = Zonemaster::Engine::NameserverSet->new(); - $set->push('plain.string.test'); + $set->push( 'plain.string.test' ); is( scalar $set->items, 1, 'set contains one item' ); - is( 'plain.string.test', ($set->items)[0] ); - isa_ok( ($set->items)[0], 'Zonemaster::Engine::DNSName' ); + is( 'plain.string.test', ( $set->items )[0] ); + isa_ok( ( $set->items )[0], 'Zonemaster::Engine::DNSName' ); }; subtest 'pushing an empty string is a non-operation' => sub { my $set = Zonemaster::Engine::NameserverSet->new(); - is( scalar $set->push('')->items(), 0, 'set does not grow' ); + is( scalar $set->push( '' )->items(), 0, 'set does not grow' ); }; subtest 'pushing undef is a non-operation' => sub { my $set = Zonemaster::Engine::NameserverSet->new(); - is( scalar $set->push(undef)->items(), 0, 'set does not grow' ); + is( scalar $set->push( undef )->items(), 0, 'set does not grow' ); }; subtest 'pushing two equivalent DNS names' => sub { @@ -98,21 +100,19 @@ subtest 'pushing two equivalent DNS names' => sub { $set->push( Zonemaster::Engine::DNSName->new( 'ONE.TEST' ) ); is( scalar $set->items, $old_size, 'set still contains one item' ); - is( 'one.test', ($set->items)[0] ); + is( 'one.test', ( $set->items )[0] ); }; subtest 'pushing a mix of equivalent DNS names and strings' => sub { my $set = Zonemaster::Engine::NameserverSet->new(); $set->push( - 'HeLLo.TeST', - Zonemaster::Engine::DNSName->new('HELLO.TEST'), - Zonemaster::Engine::DNSName->new('HEllo.TEst'), - 'hello.test' + 'HeLLo.TeST', Zonemaster::Engine::DNSName->new( 'HELLO.TEST' ), + Zonemaster::Engine::DNSName->new( 'HEllo.TEst' ), 'hello.test', ); is( scalar $set->items, 1, 'set contains exactly one item' ); - is( 'hello.test', ($set->items)[0] ); + is( 'hello.test', ( $set->items )[0] ); }; subtest 'pushing two distinct DNS names' => sub { @@ -129,24 +129,26 @@ subtest 'pushing two distinct DNS names' => sub { }; subtest 'new() can also create non-empty sets from a list' => sub { - my $set = Zonemaster::Engine::NameserverSet->new( - map { Zonemaster::Engine::DNSName->new( $_ ) } - qw( one.test two.test three.test ) - ); + my $set = Zonemaster::Engine::NameserverSet->new( map { Zonemaster::Engine::DNSName->new( $_ ) } + qw( one.test two.test three.test ) ); is( scalar $set->items, 3, 'set contains three items' ); }; subtest 'pushing two names and a nameserver' => sub { my $set = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'one.test' ), - Zonemaster::Engine::DNSName->new( 'two.test' ) + Zonemaster::Engine::DNSName->new( 'two.test' ), ); my $old_size = scalar $set->items; - $set->push( Zonemaster::Engine::Nameserver->new({ - name => 'three.test', - address => '2001:db8::3:1' - } ) ); + $set->push( + Zonemaster::Engine::Nameserver->new( + { + name => 'three.test', + address => '2001:db8::3:1', + } + ) + ); is( scalar $set->items, $old_size + 1, 'set grows by one' ); }; @@ -155,17 +157,23 @@ subtest 'set only holds unique nameservers' => sub { my $set = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'one.test' ), Zonemaster::Engine::DNSName->new( 'two.test' ), - Zonemaster::Engine::Nameserver->new( { - name => 'three.test', - address => '2001:db8::3:1' - } ) + Zonemaster::Engine::Nameserver->new( + { + name => 'three.test', + address => '2001:db8::3:1', + } + ), ); my $old_size = scalar $set->items; - $set->push( Zonemaster::Engine::Nameserver->new({ - name => 'THREE.TEST.', - address => '2001:db8::3:1' - } ) ); + $set->push( + Zonemaster::Engine::Nameserver->new( + { + name => 'THREE.TEST.', + address => '2001:db8::3:1', + } + ) + ); is( scalar $set->items, $old_size, 'set does not grow' ); }; @@ -174,23 +182,29 @@ subtest 'overwriting a DNS name with a name server' => sub { my $set = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'one.test' ), Zonemaster::Engine::DNSName->new( 'two.test' ), - Zonemaster::Engine::Nameserver->new( { - name => 'three.test', - address => '2001:db8::3:1' - } ) + Zonemaster::Engine::Nameserver->new( + { + name => 'three.test', + address => '2001:db8::3:1', + } + ), ); my $old_size = scalar $set->items; ok( grep( { $_ eq 'one.test' } $set->items ), 'one.test is in the set' ); - $set->push( Zonemaster::Engine::Nameserver->new({ - name => 'OnE.TeSt', - address => '2001:db8::1:1' - } ) ); + $set->push( + Zonemaster::Engine::Nameserver->new( + { + name => 'OnE.TeSt', + address => '2001:db8::1:1', + } + ) + ); my @set_items = $set->items; is( scalar @set_items, $old_size, 'set size did not grow' ); - ok( !grep( { $_ eq 'one.test' } @set_items ), 'one.test is no longer in the set' ); + ok( !grep( { $_ eq 'one.test' } @set_items ), 'one.test is no longer in the set' ); ok( grep( { $_ eq 'one.test/2001:db8::1:1' } @set_items ), 'the new name server is in the set' ); }; @@ -198,44 +212,51 @@ subtest 'pushing a DNS name when a name server already exists' => sub { my $set = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'one.test' ), Zonemaster::Engine::DNSName->new( 'two.test' ), - Zonemaster::Engine::Nameserver->new( { - name => 'three.test', - address => '2001:db8::3:1' - } ) + Zonemaster::Engine::Nameserver->new( + { + name => 'three.test', + address => '2001:db8::3:1', + } + ), ); my $old_size = scalar $set->items; - $set->push( - Zonemaster::Engine::DNSName->new( 'THREE.TEST' ), - 'THREE.TEST' - ); + $set->push( Zonemaster::Engine::DNSName->new( 'THREE.TEST' ), 'THREE.TEST' ); my @set_items = $set->items; is( scalar $set->items, $old_size, 'set size did not grow' ); - ok( ! grep( { lc $_ eq 'three.test' } @set_items ), 'the name is not in the set' ) - or diag join(", ", @set_items); + ok( !grep( { lc $_ eq 'three.test' } @set_items ), 'the name is not in the set' ) + or diag join( ", ", @set_items ); ok( grep( { $_ eq 'three.test/2001:db8::3:1' } @set_items ), 'the nameserver is still there' ) - or diag join(", ", @set_items); + or diag join( ", ", @set_items ); }; subtest 'adding a name server with same name but different IP' => sub { my $set = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::Nameserver->new( { - name => 'one.test', - address => '2001:db8::1:1' - } ), + Zonemaster::Engine::Nameserver->new( + { + name => 'one.test', + address => '2001:db8::1:1', + } + ), Zonemaster::Engine::DNSName->new( 'two.test' ), - Zonemaster::Engine::Nameserver->new( { - name => 'three.test', - address => '2001:db8::3:1' - } ) + Zonemaster::Engine::Nameserver->new( + { + name => 'three.test', + address => '2001:db8::3:1', + } + ), ); my $old_size = scalar $set->items; - $set->push( Zonemaster::Engine::Nameserver->new({ - name => 'one.test', - address => '2001:db8::2:1' - } ) ); + $set->push( + Zonemaster::Engine::Nameserver->new( + { + name => 'one.test', + address => '2001:db8::2:1', + } + ) + ); my @set_items = $set->items; is( scalar @set_items, $old_size + 1, 'set size increased by one' ); @@ -245,165 +266,198 @@ subtest 'adding a name server with same name but different IP' => sub { subtest 'sorted_items() method' => sub { my $set = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('b.test'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bbbb::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '203.0.113.234' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '192.0.2.2' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '192.0.2.101' - }), + Zonemaster::Engine::DNSName->new( 'b.test' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bbbb::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '203.0.113.234', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '192.0.2.2', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '192.0.2.101', + } + ), ); my @ordered_items = map { "$_" } $set->sorted_items(); my @expected = qw( - a.test/127.0.0.1 - a.test/::1 - b.test - d.test/192.0.2.2 - d.test/192.0.2.101 - d.test/203.0.113.234 - d.test/2001:db8:bc:: - d.test/2001:db8:bbbb::1 - ); + a.test/127.0.0.1 + a.test/::1 + b.test + d.test/192.0.2.2 + d.test/192.0.2.101 + d.test/203.0.113.234 + d.test/2001:db8:bc:: + d.test/2001:db8:bbbb::1 + ); is_deeply( \@ordered_items, \@expected, 'ordering items works as it should' ) - or diag("Here’s how \$set->sorted_items() sorted the items:\n" - . join "\n", map { " * $_" } @ordered_items ); + or diag( "Here’s how \$set->sorted_items() sorted the items:\n" . join "\n", map { " * $_" } @ordered_items ); }; subtest 'names() method' => sub { my $set = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('B.TEST'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'A.TEST', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'D.TEST', - address => '2001:db8:bbbb::1' - }) + Zonemaster::Engine::DNSName->new( 'B.TEST' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'A.TEST', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'D.TEST', + address => '2001:db8:bbbb::1', + } + ), ); my @names = $set->names(); is( scalar @names, 3, 'correct list size' ); - ok( grep({ $_ eq 'a.test' } @names), 'a.test is in the list' ); - ok( grep({ $_ eq 'b.test' } @names), 'b.test is in the list' ); - ok( grep({ $_ eq 'd.test' } @names), 'd.test is in the list' ); - ok( List::Util::all(sub { $_->isa('Zonemaster::Engine::DNSName') }, @names), - 'names() returns DNSName objects' ); + ok( grep( { $_ eq 'a.test' } @names ), 'a.test is in the list' ); + ok( grep( { $_ eq 'b.test' } @names ), 'b.test is in the list' ); + ok( grep( { $_ eq 'd.test' } @names ), 'd.test is in the list' ); + ok( + List::Util::all( sub { $_->isa( 'Zonemaster::Engine::DNSName' ) }, @names ), + 'names() returns DNSName objects', + ); }; subtest 'get() method' => sub { my $set = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('B.TEST'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'A.TEST', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'D.TEST', - address => '2001:db8:bbbb::1' - }) + Zonemaster::Engine::DNSName->new( 'B.TEST' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'A.TEST', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'D.TEST', + address => '2001:db8:bbbb::1', + } + ), ); - my @a = $set->get('A.TeSt'); + my @a = $set->get( 'A.TeSt' ); is( scalar @a, 2, 'get a.test gives correct number of items' ); - ok( grep({ $_ eq 'a.test/::1' } @a) ); - ok( grep({ $_ eq 'a.test/127.0.0.1' } @a) ); + ok( grep( { $_ eq 'a.test/::1' } @a ) ); + ok( grep( { $_ eq 'a.test/127.0.0.1' } @a ) ); - my @b = $set->get('b.test'); + my @b = $set->get( 'b.test' ); is( scalar @b, 1, 'get b.test gives correct amount of items' ); ok( $b[0] eq 'b.test' ); - is( $set->get('b.test'), 'b.test' ); + is( $set->get( 'b.test' ), 'b.test' ); - is( scalar do { my @c = $set->get('c.test'); @c }, 0, - 'get c.test in list context return empty array'); - is( $set->get('c.test'), undef, - 'get c.test in scalar context returns undef'); + is( scalar do { my @c = $set->get( 'c.test' ); @c }, 0, 'get c.test in list context return empty array' ); + is( $set->get( 'c.test' ), undef, 'get c.test in scalar context returns undef' ); - my @d = $set->get( Zonemaster::Engine::DNSName->new('d.test') ); - is( scalar @d, 2, - 'passing a DNSName to get() instead of a string also works'); + my @d = $set->get( Zonemaster::Engine::DNSName->new( 'd.test' ) ); + is( scalar @d, 2, 'passing a DNSName to get() instead of a string also works' ); }; subtest 'get_ips() method' => sub { my $set = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('B.TEST'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'A.TEST', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'D.TEST', - address => '2001:db8:bbbb::1' - }) + Zonemaster::Engine::DNSName->new( 'B.TEST' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'A.TEST', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'D.TEST', + address => '2001:db8:bbbb::1', + } + ), ); - my @a = $set->get_ips('A.TeSt'); + my @a = $set->get_ips( 'A.TeSt' ); is( scalar @a, 2, 'get_ips a.test gives correct number of items' ); - ok( grep({ $_ eq 'a.test/::1' } @a) ); - ok( grep({ $_ eq 'a.test/127.0.0.1' } @a) ); + ok( grep( { $_ eq 'a.test/::1' } @a ) ); + ok( grep( { $_ eq 'a.test/127.0.0.1' } @a ) ); - my @b = $set->get_ips('b.test'); + my @b = $set->get_ips( 'b.test' ); is( scalar @b, 0, 'get_ips b.test gives correct amount of items' ); - is( scalar do { my @c = $set->get_ips('c.test'); @c }, 0, - 'get_ips c.test in list context return empty array'); - is( $set->get_ips('c.test'), undef, - 'get_ips c.test in scalar context returns undef'); + is( scalar do { my @c = $set->get_ips( 'c.test' ); @c }, 0, 'get_ips c.test in list context return empty array' ); + is( $set->get_ips( 'c.test' ), undef, 'get_ips c.test in scalar context returns undef' ); - my @d = $set->get_ips( Zonemaster::Engine::DNSName->new('d.test') ); - is( scalar @d, 2, - 'passing a DNSName to get_ips() instead of a string also works'); + my @d = $set->get_ips( Zonemaster::Engine::DNSName->new( 'd.test' ) ); + is( scalar @d, 2, 'passing a DNSName to get_ips() instead of a string also works' ); }; subtest 'difference() method on two empty sets' => sub { @@ -417,45 +471,61 @@ subtest 'difference() method on two empty sets' => sub { subtest 'difference() method on non-empty sets' => sub { my $set_a = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('B.TEST'), - Zonemaster::Engine::DNSName->new('e.TEST'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'A.TEST', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'D.TEST', - address => '2001:db8:bbbb::1' - }) + Zonemaster::Engine::DNSName->new( 'B.TEST' ), + Zonemaster::Engine::DNSName->new( 'e.TEST' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'A.TEST', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'D.TEST', + address => '2001:db8:bbbb::1', + } + ), ); my $set_b = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new('b.test'), - Zonemaster::Engine::DNSName->new('c.test'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bbbb::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '203.0.113.234' - }), + Zonemaster::Engine::DNSName->new( 'b.test' ), + Zonemaster::Engine::DNSName->new( 'c.test' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bbbb::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '203.0.113.234', + } + ), ); my ( $only_in_a, $only_in_b ) = $set_a->difference( $set_b ); @@ -463,14 +533,8 @@ subtest 'difference() method on non-empty sets' => sub { isa_ok( $only_in_a, 'Zonemaster::Engine::NameserverSet' ); isa_ok( $only_in_b, 'Zonemaster::Engine::NameserverSet' ); - is_deeply( - [ map { "$_" } $only_in_a->sorted_items() ], - [ qw( a.test/::1 e.TEST ) ] - ); - is_deeply( - [ map { "$_" } $only_in_b->sorted_items() ], - [ qw( c.test d.test/203.0.113.234 ) ] - ); + is_deeply( [ map { "$_" } $only_in_a->sorted_items() ], [qw( a.test/::1 e.TEST )] ); + is_deeply( [ map { "$_" } $only_in_b->sorted_items() ], [qw( c.test d.test/203.0.113.234 )] ); }; subtest 'equals() on two empty sets' => sub { @@ -482,68 +546,65 @@ subtest 'equals() on two empty sets' => sub { subtest 'equals() on two nonempty sets' => sub { my $set_a = Zonemaster::Engine::NameserverSet->new(); - my $set_b = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new( 'hello.test' ) - ); + my $set_b = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'hello.test' ) ); - ok( ! $set_a->equals( $set_b ), 'both sets are not equal' ); + ok( !$set_a->equals( $set_b ), 'both sets are not equal' ); }; subtest 'equals() on two different sets' => sub { - my $set_a = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new( 'hello.test' ) - ); + my $set_a = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'hello.test' ) ); - my $set_b = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new( 'hello2.test' ) - ); + my $set_b = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'hello2.test' ) ); - ok( ! $set_a->equals( $set_b ), 'equals() returns false on sets containing different items' ); + ok( !$set_a->equals( $set_b ), 'equals() returns false on sets containing different items' ); }; subtest 'equals() on sub- and supersets' => sub { - my $set_a = Zonemaster::Engine::NameserverSet->new( - Zonemaster::Engine::DNSName->new( 'hello.test' ) - ); + my $set_a = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'hello.test' ) ); my $set_b = Zonemaster::Engine::NameserverSet->new( Zonemaster::Engine::DNSName->new( 'hello.test' ), - Zonemaster::Engine::DNSName->new( 'hello2.test' ) + Zonemaster::Engine::DNSName->new( 'hello2.test' ), ); - ok( ! $set_a->equals( $set_b ), - 'one set is not equal to a strict superset of oneself' ); - ok( ! $set_b->equals( $set_a ), - 'one set is not equal to a strict subset of oneself' ); + ok( !$set_a->equals( $set_b ), 'one set is not equal to a strict superset of oneself' ); + ok( !$set_b->equals( $set_a ), 'one set is not equal to a strict subset of oneself' ); }; subtest 'equals() on equal sets' => sub { my @input = ( - Zonemaster::Engine::DNSName->new('b.test'), - Zonemaster::Engine::DNSName->new('c.test'), - Zonemaster::Engine::Nameserver->new({ - name => 'a.test', - address => '127.0.0.1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bc::' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '2001:db8:bbbb::1' - }), - Zonemaster::Engine::Nameserver->new({ - name => 'd.test', - address => '203.0.113.234' - }), + Zonemaster::Engine::DNSName->new( 'b.test' ), + Zonemaster::Engine::DNSName->new( 'c.test' ), + Zonemaster::Engine::Nameserver->new( + { + name => 'a.test', + address => '127.0.0.1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bc::', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '2001:db8:bbbb::1', + } + ), + Zonemaster::Engine::Nameserver->new( + { + name => 'd.test', + address => '203.0.113.234', + } + ), ); my $set_a = Zonemaster::Engine::NameserverSet->new( @input ); my $set_b = Zonemaster::Engine::NameserverSet->new( @input ); - ok( $set_a->equals( $set_b ), - 'two non-empty sets with same items test equal'); + ok( $set_a->equals( $set_b ), 'two non-empty sets with same items test equal' ); }; done_testing; diff --git a/t/normalization.t b/t/normalization.t index 6a66425f7..e610c1818 100644 --- a/t/normalization.t +++ b/t/normalization.t @@ -9,72 +9,74 @@ use Test::Exception; use Zonemaster::Engine::Normalization qw( normalize_name trim_space ); sub char_to_hex_esc { - my ($char) = @_; - my $ord = ord($char); - if ($ord >= 32 && $ord <= 127) { + my ( $char ) = @_; + my $ord = ord( $char ); + if ( $ord >= 32 && $ord <= 127 ) { return $char; - } elsif ($ord <= 255) { - return sprintf('\x%02X', $ord); - } else { - return sprintf('\x{%04X}', $ord); + } + elsif ( $ord <= 255 ) { + return sprintf( '\x%02X', $ord ); + } + else { + return sprintf( '\x{%04X}', $ord ); } } sub to_hex_esc { - my ($str) = @_; - return join('', map({ char_to_hex_esc($_) } (split //, $str))); + my ( $str ) = @_; + return join( '', map( { char_to_hex_esc( $_ ) } ( split //, $str ) ) ); } subtest 'Valid domains' => sub { my %input_domains = ( # Roots - '.' => '.', # Full stop - '.' => '.', # Fullwidth full stop - '。' => '.', # Ideographic full stop - '。' => '.', # Halfwidth ideographic full stop + '.' => '.', # Full stop + '.' => '.', # Fullwidth full stop + '。' => '.', # Ideographic full stop + '。' => '.', # Halfwidth ideographic full stop # Mixed dots with trailing dot - 'example。com.' => 'example.com', - 'example。com.' => 'example.com', + 'example。com.' => 'example.com', + 'example。com.' => 'example.com', 'sub.example.com。' => 'sub.example.com', 'sub.example.com。' => 'sub.example.com', # Mixed dots without trailing dot - 'example。com' => 'example.com', - 'example。com' => 'example.com', + 'example。com' => 'example.com', + 'example。com' => 'example.com', 'sub.example.com' => 'sub.example.com', 'sub.example.com' => 'sub.example.com', # Domains with U-Labels - 'café.example.com' => 'xn--caf-dma.example.com', + 'café.example.com' => 'xn--caf-dma.example.com', 'エグザンプル。example。com' => 'xn--ickqs6k2dyb.example.com', - 'αβγδε.example.com' => 'xn--mxacdef.example.com', + 'αβγδε.example.com' => 'xn--mxacdef.example.com', # Domains with uppercase unicode - 'CafÉ.example.com' => 'xn--caf-dma.example.com', + 'CafÉ.example.com' => 'xn--caf-dma.example.com', 'ΑβΓΔε.example.com' => 'xn--mxacdef.example.com', # All ascii domains (lowercase) - 'example.com' => 'example.com', + 'example.com' => 'example.com', '0/28.2.0.192.example.com' => '0/28.2.0.192.example.com', - '_http._tcp.example.com.' => '_http._tcp.example.com', - 'sub-domain.example.com' => 'sub-domain.example.com', + '_http._tcp.example.com.' => '_http._tcp.example.com', + 'sub-domain.example.com' => 'sub-domain.example.com', # All ascii domains with uppercase characters 'suB-doMaIN.ExamPlE.cOm' => 'sub-domain.example.com', # Single label domains 'test' => 'test', - 'テスト' => 'xn--zckzah', + 'テスト' => 'xn--zckzah', # Length limits "a" x 63 . ".example.com" => "a" x 63 . ".example.com", # this is 253 characters - ("a" x 15 . ".") x 15 . "b" . ".example.com" => ("a" x 15 . ".") x 15 . "b" . ".example.com", + ( "a" x 15 . "." ) x 15 . "b" . ".example.com" => ( "a" x 15 . "." ) x 15 . "b" . ".example.com", # NFC conversion (for each group first is non-NFC, second is equivalent NFC) "d\x{006F}\x{0308}d" => 'xn--dd-fka', - 'död' => 'xn--dd-fka', + 'död' => 'xn--dd-fka', "aq\x{0307}\x{0323}a" => 'xn--aqa-9dc3l', "aq\x{0323}\x{0307}a" => 'xn--aqa-9dc3l', @@ -85,12 +87,15 @@ subtest 'Valid domains' => sub { for my $domain ( sort keys %input_domains ) { my $expected_output = $input_domains{$domain}; - my $safe_domain = to_hex_esc($domain); + my $safe_domain = to_hex_esc( $domain ); subtest "Domain: '$safe_domain'" => sub { my ( $errors, $final_domain ); - lives_ok(sub { - ($errors, $final_domain) = normalize_name($domain); - }, 'correct domain should live'); + lives_ok( + sub { + ( $errors, $final_domain ) = normalize_name( $domain ); + }, + 'correct domain should live', + ); my $actual = { domain => $final_domain, errors => $errors }; my $expected = { domain => $expected_output, errors => [] }; @@ -133,25 +138,28 @@ subtest 'Bad domains' => sub { for my $domain ( sort keys %input_domains ) { my $expected_errors = $input_domains{$domain}; - my $safe_domain = to_hex_esc( $domain ); + my $safe_domain = to_hex_esc( $domain ); subtest "Domain: '$safe_domain'" => sub { my ( $errors, $final_domain ); - lives_ok(sub { - ($errors, $final_domain) = normalize_name($domain); - }, 'incorrect domain should live'); + lives_ok( + sub { + ( $errors, $final_domain ) = normalize_name( $domain ); + }, + 'incorrect domain should live', + ); my $actual = { domain => $final_domain, - errors => [ map { $_->tag } @$errors ] + errors => [ map { $_->tag } @$errors ], }; my $expected = { domain => undef, - errors => $expected_errors + errors => $expected_errors, }; eq_or_diff $actual, $expected; } - } + } ## end for my $domain ( sort keys...) }; subtest 'Trimming space' => sub { @@ -164,7 +172,7 @@ subtest 'Trimming space' => sub { for my $str ( sort keys %cases ) { my $expected = $cases{$str}; - my $safe_str = to_hex_esc($str); + my $safe_str = to_hex_esc( $str ); subtest "Domain: '$safe_str'" => sub { my $actual = trim_space( $str ); diff --git a/t/po-files.t b/t/po-files.t index 3b0a3ed2e..349f56d51 100644 --- a/t/po-files.t +++ b/t/po-files.t @@ -3,12 +3,12 @@ use v5.14.2; use strict; use warnings; use utf8; -use Test::More; # see done_testing() +use Test::More; # see done_testing() use File::Basename qw( dirname ); chdir dirname( dirname( __FILE__ ) ) or BAIL_OUT( "chdir: $!" ); -chdir 'share' or BAIL_OUT( "chdir: $!" ); +chdir 'share' or BAIL_OUT( "chdir: $!" ); my $makebin = 'make'; @@ -18,7 +18,7 @@ sub make { undef $ENV{MAKEFLAGS}; my $command = join( ' ', $makebin, '--silent', '--no-print-directory', @make_args ); - my $output = `$command`; + my $output = `$command`; if ( $? == -1 ) { BAIL_OUT( "failed to execute: $!" ); @@ -48,7 +48,7 @@ subtest "check msg args" => sub { }; subtest "tidy po files" => sub { - SKIP: { + SKIP: { my ( $output, $status ); $output = `git diff --numstat`; @@ -63,7 +63,7 @@ subtest "tidy po files" => sub { $output = `git diff --numstat`; is $output, "", 'all files are tidied (if not run "make tidy-po")' - or diag `git diff`; + or diag `git diff`; } }; diff --git a/t/pod-coverage.t b/t/pod-coverage.t index db774bc2b..6fa2cd6d7 100644 --- a/t/pod-coverage.t +++ b/t/pod-coverage.t @@ -24,12 +24,12 @@ find( push @modules, $name; } }, - 'lib' + 'lib', ); foreach my $name ( @modules ) { next if $name =~ q{Zonemaster::Engine::Constants}; - my $pc = Pod::Coverage->new( package => $name , private => [ qr/^_/ ] ); + my $pc = Pod::Coverage->new( package => $name, private => [qr/^_/] ); if ( defined $pc->coverage ) { my @uncovered = $pc->uncovered; if ( @uncovered == 1 and $uncovered[0] eq 'LC_MESSAGES' ) { @@ -46,6 +46,6 @@ foreach my $name ( @modules ) { else { diag $pc->why_unrated . ' for ' . $name; } -} +} ## end foreach my $name ( @modules) done_testing; diff --git a/t/recursor-A.t b/t/recursor-A.t index f817f9af9..c80360f65 100644 --- a/t/recursor-A.t +++ b/t/recursor-A.t @@ -12,7 +12,7 @@ BEGIN { use_ok( q{Zonemaster::Engine::Util}, qw( name ) ); } -my $datafile = 't/' . basename ($0, '.t') . '.data'; +my $datafile = 't/' . basename( $0, '.t' ) . '.data'; if ( not $ENV{ZONEMASTER_RECORD} ) { die "Stored data file missing" if not -r $datafile; @@ -22,10 +22,12 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { # Common hint file (test-zone-data/COMMON/hintfile) Zonemaster::Engine::Recursor->remove_fake_addresses( '.' ); -Zonemaster::Engine::Recursor->add_fake_addresses( '.', - { 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], - 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], - } +Zonemaster::Engine::Recursor->add_fake_addresses( + '.', + { + 'ns1' => [ '127.1.0.1', 'fda1:b2:c3::127:1:0:1' ], + 'ns2' => [ '127.1.0.2', 'fda1:b2:c3::127:1:0:2' ], + }, ); # Test zone scenarios @@ -35,16 +37,16 @@ subtest 'GOOD-CNAME-1' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 2, 'two records in answer section' ); - isa_ok( ($p->answer)[0], 'Zonemaster::LDNS::RR::CNAME' ); - is( name( ($p->answer)[0]->owner ), 'good-cname-1.cname.recursor.engine.xa', 'RR name ok' ); - is( name( ($p->answer)[0]->cname ), 'good-cname-1-target.cname.recursor.engine.xa', 'RR cname ok' ); + isa_ok( ( $p->answer )[0], 'Zonemaster::LDNS::RR::CNAME' ); + is( name( ( $p->answer )[0]->owner ), 'good-cname-1.cname.recursor.engine.xa', 'RR name ok' ); + is( name( ( $p->answer )[0]->cname ), 'good-cname-1-target.cname.recursor.engine.xa', 'RR cname ok' ); - isa_ok( ($p->answer)[1], 'Zonemaster::LDNS::RR::A' ); - is( name( ($p->answer)[1]->owner ), 'good-cname-1-target.cname.recursor.engine.xa', 'RR name ok' ); - is( ($p->answer)[1]->address, '127.0.0.1', 'RR address ok' ); + isa_ok( ( $p->answer )[1], 'Zonemaster::LDNS::RR::A' ); + is( name( ( $p->answer )[1]->owner ), 'good-cname-1-target.cname.recursor.engine.xa', 'RR name ok' ); + is( ( $p->answer )[1]->address, '127.0.0.1', 'RR address ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_IN_ZONE}, q{should emit CNAME_FOLLOWED_IN_ZONE} ); }; @@ -54,20 +56,20 @@ subtest 'GOOD-CNAME-2' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 3, 'three records in answer section' ); - isa_ok( ($p->answer)[0], 'Zonemaster::LDNS::RR::CNAME' ); - is( name( ($p->answer)[0]->owner ), 'good-cname-2.cname.recursor.engine.xa', 'RR name ok' ); - is( name( ($p->answer)[0]->cname ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR cname ok' ); + isa_ok( ( $p->answer )[0], 'Zonemaster::LDNS::RR::CNAME' ); + is( name( ( $p->answer )[0]->owner ), 'good-cname-2.cname.recursor.engine.xa', 'RR name ok' ); + is( name( ( $p->answer )[0]->cname ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR cname ok' ); - isa_ok( ($p->answer)[1], 'Zonemaster::LDNS::RR::A' ); - is( name( ($p->answer)[1]->owner ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR name ok' ); - is( ($p->answer)[1]->address, '127.0.0.1', 'RR address ok' ); + isa_ok( ( $p->answer )[1], 'Zonemaster::LDNS::RR::A' ); + is( name( ( $p->answer )[1]->owner ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR name ok' ); + is( ( $p->answer )[1]->address, '127.0.0.1', 'RR address ok' ); - isa_ok( ($p->answer)[2], 'Zonemaster::LDNS::RR::A' ); - is( name( ($p->answer)[2]->owner ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR name ok' ); - is( ($p->answer)[2]->address, '127.0.0.2', 'RR address ok' ); + isa_ok( ( $p->answer )[2], 'Zonemaster::LDNS::RR::A' ); + is( name( ( $p->answer )[2]->owner ), 'good-cname-2-target.cname.recursor.engine.xa', 'RR name ok' ); + is( ( $p->answer )[2]->address, '127.0.0.2', 'RR address ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_IN_ZONE}, q{should emit CNAME_FOLLOWED_IN_ZONE} ); }; @@ -77,24 +79,24 @@ subtest 'GOOD-CNAME-CHAIN' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 4, 'four records in answer section' ); - isa_ok( ($p->answer)[0], 'Zonemaster::LDNS::RR::CNAME' ); - is( name( ($p->answer)[0]->owner ), 'good-cname-chain.cname.recursor.engine.xa', 'RR name ok' ); - is( name( ($p->answer)[0]->cname ), 'good-cname-chain-two.cname.recursor.engine.xa', 'RR cname ok' ); + isa_ok( ( $p->answer )[0], 'Zonemaster::LDNS::RR::CNAME' ); + is( name( ( $p->answer )[0]->owner ), 'good-cname-chain.cname.recursor.engine.xa', 'RR name ok' ); + is( name( ( $p->answer )[0]->cname ), 'good-cname-chain-two.cname.recursor.engine.xa', 'RR cname ok' ); - isa_ok( ($p->answer)[1], 'Zonemaster::LDNS::RR::CNAME' ); - is( name( ($p->answer)[1]->owner ), 'good-cname-chain-two.cname.recursor.engine.xa', 'RR name ok' ); - is( name( ($p->answer)[1]->cname ), 'good-cname-chain-three.cname.recursor.engine.xa', 'RR cname ok' ); + isa_ok( ( $p->answer )[1], 'Zonemaster::LDNS::RR::CNAME' ); + is( name( ( $p->answer )[1]->owner ), 'good-cname-chain-two.cname.recursor.engine.xa', 'RR name ok' ); + is( name( ( $p->answer )[1]->cname ), 'good-cname-chain-three.cname.recursor.engine.xa', 'RR cname ok' ); - isa_ok( ($p->answer)[2], 'Zonemaster::LDNS::RR::CNAME' ); - is( name( ($p->answer)[2]->owner ), 'good-cname-chain-three.cname.recursor.engine.xa', 'RR name ok' ); - is( name( ($p->answer)[2]->cname ), 'good-cname-chain-target.cname.recursor.engine.xa', 'RR cname ok' ); + isa_ok( ( $p->answer )[2], 'Zonemaster::LDNS::RR::CNAME' ); + is( name( ( $p->answer )[2]->owner ), 'good-cname-chain-three.cname.recursor.engine.xa', 'RR name ok' ); + is( name( ( $p->answer )[2]->cname ), 'good-cname-chain-target.cname.recursor.engine.xa', 'RR cname ok' ); - isa_ok( ($p->answer)[3], 'Zonemaster::LDNS::RR::A' ); - is( name( ($p->answer)[3]->owner ), 'good-cname-chain-target.cname.recursor.engine.xa', 'RR name ok' ); - is( ($p->answer)[3]->address, '127.0.0.1', 'RR address ok' ); + isa_ok( ( $p->answer )[3], 'Zonemaster::LDNS::RR::A' ); + is( name( ( $p->answer )[3]->owner ), 'good-cname-chain-target.cname.recursor.engine.xa', 'RR name ok' ); + is( ( $p->answer )[3]->address, '127.0.0.1', 'RR address ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_IN_ZONE}, q{should emit CNAME_FOLLOWED_IN_ZONE} ); }; @@ -104,12 +106,12 @@ subtest 'GOOD-CNAME-OUT-OF-ZONE' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 1, 'one record in answer section' ); - isa_ok( ($p->answer)[0], 'Zonemaster::LDNS::RR::A' ); - is( name( ($p->answer)[0]->owner ), 'target.goodsub.cname.recursor.engine.xa', 'RR name ok' ); - is( ($p->answer)[0]->address, '127.0.0.1', 'RR address ok' ); + isa_ok( ( $p->answer )[0], 'Zonemaster::LDNS::RR::A' ); + is( name( ( $p->answer )[0]->owner ), 'target.goodsub.cname.recursor.engine.xa', 'RR name ok' ); + is( ( $p->answer )[0]->address, '127.0.0.1', 'RR address ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_OUT_OF_ZONE}, q{should emit CNAME_FOLLOWED_OUT_OF_ZONE} ); }; @@ -117,15 +119,15 @@ subtest 'NXDOMAIN-VIA-CNAME' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'nxdomain-via-cname.cname.recursor.engine.xa' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); - is( $p->rcode, 'NXDOMAIN', 'NXDOMAIN in response' ); - is( scalar( $p->answer ), 0, 'no records in answer section' ); - is( scalar( $p->authority ), 1, 'one record in authority section' ); + is( $p->rcode, 'NXDOMAIN', 'NXDOMAIN in response' ); + is( scalar( $p->answer ), 0, 'no records in answer section' ); + is( scalar( $p->authority ), 1, 'one record in authority section' ); - isa_ok( ($p->authority)[0], 'Zonemaster::LDNS::RR::SOA' ); - is( name( ($p->authority)[0]->owner ), 'cname.recursor.engine.xa', 'RR name ok' ); + isa_ok( ( $p->authority )[0], 'Zonemaster::LDNS::RR::SOA' ); + is( name( ( $p->authority )[0]->owner ), 'cname.recursor.engine.xa', 'RR name ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_OUT_OF_ZONE}, q{should emit CNAME_FOLLOWED_OUT_OF_ZONE} ); }; @@ -133,65 +135,65 @@ subtest 'NODATA-VIA-CNAME' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'nodata-via-cname.cname.recursor.engine.xa' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); - is( $p->rcode, 'NOERROR', 'NOERROR in response' ); - is( scalar( $p->answer ), 0, 'no records in answer section' ); - is( scalar( $p->authority ), 1, 'one record in authority section' ); + is( $p->rcode, 'NOERROR', 'NOERROR in response' ); + is( scalar( $p->answer ), 0, 'no records in answer section' ); + is( scalar( $p->authority ), 1, 'one record in authority section' ); - isa_ok( ($p->authority)[0], 'Zonemaster::LDNS::RR::SOA' ); - is( name( ($p->authority)[0]->owner ), 'cname.recursor.engine.xa', 'RR name ok' ); + isa_ok( ( $p->authority )[0], 'Zonemaster::LDNS::RR::SOA' ); + is( name( ( $p->authority )[0]->owner ), 'cname.recursor.engine.xa', 'RR name ok' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_FOLLOWED_OUT_OF_ZONE}, q{should emit CNAME_FOLLOWED_OUT_OF_ZONE} ); }; subtest 'MULT-CNAME' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'mult-cname.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_RECORDS_MULTIPLE_FOR_NAME}, q{should emit CNAME_RECORDS_MULTIPLE_FOR_NAME} ); }; subtest 'LOOPED-CNAME-IN-ZONE-1' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'looped-cname-in-zone-1.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_LOOP_INNER}, q{should emit CNAME_LOOP_INNER} ); }; subtest 'LOOPED-CNAME-IN-ZONE-2' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'looped-cname-in-zone-2.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_LOOP_INNER}, q{should emit CNAME_LOOP_INNER} ); }; subtest 'LOOPED-CNAME-IN-ZONE-3' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'looped-cname-in-zone-3.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_LOOP_INNER}, q{should emit CNAME_LOOP_INNER} ); }; subtest 'LOOPED-CNAME-OUT-OF-ZONE' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'looped-cname-out-of-zone.sub2.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_LOOP_OUTER}, q{should emit CNAME_LOOP_OUTER} ); }; @@ -199,20 +201,20 @@ subtest 'TOO-LONG-CNAME-CHAIN' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'too-long-cname-chain.sub2.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_CHAIN_TOO_LONG}, q{should emit CNAME_CHAIN_TOO_LONG} ); }; subtest 'TOO-MANY-CNAME' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'too-many-cname.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_RECORDS_TOO_MANY}, q{should emit CNAME_RECORDS_TOO_MANY} ); }; @@ -222,17 +224,17 @@ subtest 'TARGET-NO-MATCH-CNAME' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_NO_MATCH}, q{should emit CNAME_NO_MATCH} ); }; subtest 'BROKEN-CNAME-CHAIN' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'broken-cname-chain.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_RECORDS_CHAIN_BROKEN}, q{should emit CNAME_RECORDS_CHAIN_BROKEN} ); }; @@ -242,12 +244,21 @@ subtest 'WRONG-CNAME-OWNER-NAME' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 2, 'two records in answer section' ); - ok( name( ($p->question)[0]->owner )->string ne name( ($p->answer)[0]->owner )->string, 'expected different owner name as QNAME on first RR' ); - ok( name( ($p->question)[0]->owner )->string ne name( ($p->answer)[1]->owner )->string, 'expected different owner name as QNAME on second RR' ); + ok( + name( ( $p->question )[0]->owner )->string ne name( ( $p->answer )[0]->owner )->string, + 'expected different owner name as QNAME on first RR', + ); + ok( + name( ( $p->question )[0]->owner )->string ne name( ( $p->answer )[1]->owner )->string, + 'expected different owner name as QNAME on second RR', + ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; ok( !$res{CNAME_START}, q{should not emit CNAME_START} ); - ok( scalar ( grep { index($_->tag, 'CNAME') != -1 } @{ Zonemaster::Engine->logger->entries } ) == 0, 'empty CNAME message tags' ); + ok( + scalar( grep { index( $_->tag, 'CNAME' ) != -1 } @{ Zonemaster::Engine->logger->entries } ) == 0, + 'empty CNAME message tags', + ); }; subtest 'EXTRA-CNAME-IN-ANSWER' => sub { @@ -256,14 +267,23 @@ subtest 'EXTRA-CNAME-IN-ANSWER' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); is( scalar( $p->answer ), 2, 'two records in answer section' ); - isa_ok( ($p->answer)[0], 'Zonemaster::LDNS::RR::A' ); - ok( name( ($p->question)[0]->owner )->string eq name( ($p->answer)[0]->owner )->string, 'expected same owner name as QNAME on first RR' ); - isa_ok( ($p->answer)[1], 'Zonemaster::LDNS::RR::CNAME' ); - ok( name( ($p->question)[0]->owner )->string ne name( ($p->answer)[1]->owner )->string, 'expected different owner name as QNAME on second RR' ); + isa_ok( ( $p->answer )[0], 'Zonemaster::LDNS::RR::A' ); + ok( + name( ( $p->question )[0]->owner )->string eq name( ( $p->answer )[0]->owner )->string, + 'expected same owner name as QNAME on first RR', + ); + isa_ok( ( $p->answer )[1], 'Zonemaster::LDNS::RR::CNAME' ); + ok( + name( ( $p->question )[0]->owner )->string ne name( ( $p->answer )[1]->owner )->string, + 'expected different owner name as QNAME on second RR', + ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; ok( !$res{CNAME_START}, q{should not emit CNAME_START} ); - ok( scalar ( grep { index($_->tag, 'CNAME') != -1 } @{ Zonemaster::Engine->logger->entries } ) == 0, 'empty CNAME message tags' ); + ok( + scalar( grep { index( $_->tag, 'CNAME' ) != -1 } @{ Zonemaster::Engine->logger->entries } ) == 0, + 'empty CNAME message tags', + ); }; subtest 'CNAME-CHAIN-TO-NODATA' => sub { @@ -272,17 +292,17 @@ subtest 'CNAME-CHAIN-TO-NODATA' => sub { isa_ok( $p, 'Zonemaster::Engine::Packet' ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_TO_NODATA}, q{should emit CNAME_TO_NODATA} ); }; subtest 'CNAME-UNRESOLVABLE' => sub { Zonemaster::Engine->logger->clear_history; my $p = Zonemaster::Engine->recurse( 'unresolvable-cname.cname.recursor.engine.xa' ); - is( $p, undef, "undefined as expected"); + is( $p, undef, "undefined as expected" ); my %res = map { $_->tag => $_ } @{ Zonemaster::Engine->logger->entries }; - ok( $res{CNAME_START}, q{should emit CNAME_START} ); + ok( $res{CNAME_START}, q{should emit CNAME_START} ); ok( $res{CNAME_UNRESOLVABLE}, q{should emit CNAME_UNRESOLVABLE} ); }; diff --git a/t/recursor.t b/t/recursor.t index 9deed59d2..911cb66e3 100644 --- a/t/recursor.t +++ b/t/recursor.t @@ -20,7 +20,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { my $p = Zonemaster::Engine::Recursor->recurse( 'www.iis.se' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); ok( $p->answer > 0, 'answer records' ); -is( name( ($p->answer)[0]->name ), 'www.iis.se', 'RR name ok' ); +is( name( ( $p->answer )[0]->name ), 'www.iis.se', 'RR name ok' ); my $p2 = Zonemaster::Engine::Recursor->recurse( 'zonemaster.net' ); isa_ok( $p2, 'Zonemaster::Engine::Packet' ); @@ -33,10 +33,14 @@ isa_ok( $p2, 'Zonemaster::Engine::Packet' ); $count++; }; - Zonemaster::Engine::Recursor->recurse( 'zonemaster.net', 'A', 'IN', [ Zonemaster::Engine::Recursor->root_servers() ] ); + Zonemaster::Engine::Recursor->recurse( 'zonemaster.net', 'A', 'IN', + [ Zonemaster::Engine::Recursor->root_servers() ], + ); is( $count, 0, 'memoize normalizer for recurse() works' ); - Zonemaster::Engine::Recursor->recurse( 'zonemaster.net', 'A', 'IN', [ (Zonemaster::Engine->ns( 'a.root-servers.net.', '198.41.0.4' )) ] ); + Zonemaster::Engine::Recursor->recurse( 'zonemaster.net', 'A', 'IN', + [ ( Zonemaster::Engine->ns( 'a.root-servers.net.', '198.41.0.4' ) ) ], + ); is( $count, 1, 'memoize for recurse() works' ); Zonemaster::Engine::Recursor->clear_cache; diff --git a/t/translator.t b/t/translator.t index 8da403fbf..821776024 100644 --- a/t/translator.t +++ b/t/translator.t @@ -9,7 +9,7 @@ use Test::Fatal; use Zonemaster::Engine::Logger::Entry; use Zonemaster::Engine::Translator; -my ($json, $profile_tmp); +my ( $json, $profile_tmp ); $json = read_file( 't/profiles/Test-all.json' ); $profile_tmp = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_tmp ); @@ -21,8 +21,7 @@ Zonemaster::Engine::Translator->initialize( locale => 'C' ); subtest 'Everything but Test::NoWarnings' => sub { my $trans = Zonemaster::Engine::Translator->instance(); - isa_ok $trans, 'Zonemaster::Engine::Translator', - 'Zonemaster::Engine::Translator->instance()'; + isa_ok $trans, 'Zonemaster::Engine::Translator', 'Zonemaster::Engine::Translator->instance()'; ok( exists $trans->data->{Basic}{B01_PARENT_FOUND}, 'expected key from file exists' ); ok( exists $trans->data->{System}{NO_NETWORK}, 'expected key from module exists' ); @@ -39,7 +38,7 @@ subtest 'Everything but Test::NoWarnings' => sub { like( $trans->to_string( $entry ), qr' \d+.\d\d INFO The parent zone is "nothing.nowhere" as returned from name servers "ns1.nothing.nowhere/1.1.1.1".', - 'string to_stringd as expected' + 'string to_stringd as expected', ); my $untranslated = Zonemaster::Engine::Logger::Entry->new( @@ -57,8 +56,10 @@ qr' \d+.\d\d INFO The parent zone is "nothing.nowhere" as returned from n foreach my $module ( keys %methods ) { foreach my $testmethod ( @{ $methods{$module} } ) { - ok( $trans->_translate_tag( $module, uc( $testmethod ), {} ), - 'Test method ' . uc( $testmethod ) . ' has message tag with description' ); + ok( + $trans->_translate_tag( $module, uc( $testmethod ), {} ), + 'Test method ' . uc( $testmethod ) . ' has message tag with description', + ); } } }; diff --git a/t/undelegated.t b/t/undelegated.t index 64119782e..2d1a9b129 100644 --- a/t/undelegated.t +++ b/t/undelegated.t @@ -17,14 +17,14 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { my $plain_p = Zonemaster::Engine->recurse( 'www.lysator.liu.se', 'AAAA' ); isa_ok( $plain_p, 'Zonemaster::Engine::Packet' ); -ok( $plain_p, 'Got answer' ); +ok( $plain_p, 'Got answer' ); Zonemaster::Engine->add_fake_delegation( 'lysator.liu.se' => { - 'ns-slave.lysator.liu.se' => [ '130.236.254.4', '130.236.255.2' ], + 'ns-slave.lysator.liu.se' => [ '130.236.254.4', '130.236.255.2' ], 'ns-master.lysator.liu.se' => [ '130.236.254.2', '2001:6b0:17:f0a0::2' ], - 'ns-slave-1.ifm.liu.se' => [ '130.236.160.2', '2001:6b0:17:f180::1001' ], - 'ns-slave-2.ifm.liu.se' => [ '130.236.160.3', '2001:6b0:17:f180::1002' ] + 'ns-slave-1.ifm.liu.se' => [ '130.236.160.2', '2001:6b0:17:f180::1001' ], + 'ns-slave-2.ifm.liu.se' => [ '130.236.160.3', '2001:6b0:17:f180::1002' ], }, fill_in_empty_oob_glue => 0, ); @@ -44,10 +44,10 @@ if ( $fake_p ) { } Zonemaster::Engine->logger->callback( undef ); -Zonemaster::Engine->add_fake_ds( 'lysator.liu.se' => [ { keytag => 4711, algorithm => 17, type => 42, digest => 'FACEB00C' } ], -); +Zonemaster::Engine->add_fake_ds( + 'lysator.liu.se' => [ { keytag => 4711, algorithm => 17, type => 42, digest => 'FACEB00C' } ], ); -my $lys = Zonemaster::Engine->zone( 'lysator.liu.se' ); +my $lys = Zonemaster::Engine->zone( 'lysator.liu.se' ); my $ds_p = $lys->parent->query_one( 'lysator.liu.se', 'DS' ); isa_ok( $ds_p, 'Zonemaster::Engine::Packet' ); my ( $ds ) = $ds_p->answer; @@ -59,39 +59,45 @@ Zonemaster::Engine->add_fake_delegation( 'nic.se' => { 'ns.nic.se' => [ '212.247.7.228', '2a00:801:f0:53::53' ], 'i.ns.se' => [ '194.146.106.22', '2001:67c:1010:5::53' ], - 'ns3.nic.se' => [ '212.247.8.152', '2a00:801:f0:211::152' ] + 'ns3.nic.se' => [ '212.247.8.152', '2a00:801:f0:211::152' ], }, fill_in_empty_oob_glue => 0, ); -ok( !!( grep { $_->tag eq 'FAKE_DELEGATION_TO_SELF' } @{ Zonemaster::Engine->logger->entries } ), - 'Refused adding circular fake delegation.' ); +ok( + !!( grep { $_->tag eq 'FAKE_DELEGATION_TO_SELF' } @{ Zonemaster::Engine->logger->entries } ), + 'Refused adding circular fake delegation.', +); Zonemaster::Engine->logger->clear_history; Zonemaster::Engine->add_fake_delegation( 'lysator.liu.se' => { - 'frfr.sesefrfr' => [ ], - 'i.ns.se' => [ '194.146.106.22', '2001:67c:1010:5::53' ], - 'ns3.nic.se' => [ '212.247.8.152', '2a00:801:f0:211::152' ] + 'frfr.sesefrfr' => [], + 'i.ns.se' => [ '194.146.106.22', '2001:67c:1010:5::53' ], + 'ns3.nic.se' => [ '212.247.8.152', '2a00:801:f0:211::152' ], }, fill_in_empty_oob_glue => 0, ); -ok( !!( grep { $_->tag eq 'FAKE_DELEGATION_NO_IP' } @{ Zonemaster::Engine->logger->entries } ), - 'Refused fake delegation without IP address for bad ns.' ); +ok( + !!( grep { $_->tag eq 'FAKE_DELEGATION_NO_IP' } @{ Zonemaster::Engine->logger->entries } ), + 'Refused fake delegation without IP address for bad ns.', +); Zonemaster::Engine->logger->clear_history; Zonemaster::Engine->add_fake_delegation( 'nic.fr' => { - 'ns1.ext.nic.fr' => [ '193.51.208.13' ], + 'ns1.ext.nic.fr' => ['193.51.208.13'], 'ns4.nic.fr' => [ '192.134.4.19', '2001:67c:2218:2::4:19' ], 'ns6.ext.nic.fr' => [ '130.59.31.29', '2001:620:0:ff::2f' ], - 'ns7.ext.nic.fr' => [] + 'ns7.ext.nic.fr' => [], }, fill_in_empty_oob_glue => 0, ); -ok( !!( grep { $_->tag eq 'FAKE_DELEGATION_IN_ZONE_NO_IP' } @{ Zonemaster::Engine->logger->entries } ), - 'Refused in-zone fake delegation without IP address.' ); +ok( + !!( grep { $_->tag eq 'FAKE_DELEGATION_IN_ZONE_NO_IP' } @{ Zonemaster::Engine->logger->entries } ), + 'Refused in-zone fake delegation without IP address.', +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/util.t b/t/util.t index bdd27e3a8..b50708c1a 100644 --- a/t/util.t +++ b/t/util.t @@ -7,17 +7,17 @@ use utf8; BEGIN { use_ok( 'Zonemaster::Engine' ); - use_ok( 'Zonemaster::Engine::Util', qw( info name ns parse_hints ) ) + use_ok( 'Zonemaster::Engine::Util', qw( info name ns parse_hints ) ); } -isa_ok( ns( 'name', '::1' ), 'Zonemaster::Engine::Nameserver' ); -isa_ok( info( 'TAG', {} ), 'Zonemaster::Engine::Logger::Entry' ); +isa_ok( ns( 'name', '::1' ), 'Zonemaster::Engine::Nameserver' ); +isa_ok( info( 'TAG', {} ), 'Zonemaster::Engine::Logger::Entry' ); isa_ok( name( "foo.bar.com" ), 'Zonemaster::Engine::DNSName' ); subtest 'parse_hints()' => sub { my @cases = ( { - name => 'Cropped IANA hints', + name => 'Cropped IANA hints', hints => <{hints} ) - } $case->{error}, $case->{name}; + } + $case->{error}, $case->{name}; } } }; @@ -129,17 +130,17 @@ EOF subtest 'escape_unprintable' => sub { my @cases = ( { - input => 'hello world!', + input => 'hello world!', expected => 'hello world!', }, { - input => "escape this: \x1B\x7F\x80\xFF\x00\x0D\x0A\\", + input => "escape this: \x1B\x7F\x80\xFF\x00\x0D\x0A\\", expected => 'escape this: \027\127\128\255\000\013\010\\\\', }, { - input => encode('UTF-8', 'cassé'), - expected => 'cass\195\169' - } + input => encode( 'UTF-8', 'cassé' ), + expected => 'cass\195\169', + }, ); for my $case ( @cases ) { diff --git a/t/validation.t b/t/validation.t index 43e4e0e7e..18b54f900 100644 --- a/t/validation.t +++ b/t/validation.t @@ -4,8 +4,8 @@ use warnings; use Test::More; use Test::Differences; -BEGIN { - use_ok( 'Zonemaster::Engine::Validation' ), qw( validate_ipv4 validate_ipv6 ) +BEGIN { + use_ok( 'Zonemaster::Engine::Validation' ), qw( validate_ipv4 validate_ipv6 ); } subtest 'validate_ipv4()' => sub { @@ -21,7 +21,7 @@ subtest 'validate_ipv4()' => sub { subtest 'Invalid IPv4 addresses' => sub { foreach my $ip ( @inv_ipv4_addresses ) { my $ip_is_valid = validate_ipv4( $ip ); - $ip = 'undef' unless defined($ip); + $ip = 'undef' unless defined( $ip ); eq_or_diff $ip_is_valid, 0, "$ip is an invalid IPv4 address"; } }; @@ -40,7 +40,7 @@ subtest 'validate_ipv6()' => sub { subtest 'Invalid IPv6 addresses' => sub { foreach my $ip ( @inv_ipv6_addresses ) { my $ip_is_valid = validate_ipv6( $ip ); - $ip = 'undef' unless defined($ip); + $ip = 'undef' unless defined( $ip ); eq_or_diff $ip_is_valid, 0, "$ip is an invalid IPv6 address"; } }; diff --git a/t/zone.t b/t/zone.t index 6b5cfb520..eb4519274 100644 --- a/t/zone.t +++ b/t/zone.t @@ -39,66 +39,114 @@ ok( @{ $zone->ns } > 0, 'NS list not empty' ); isa_ok( $_, 'Zonemaster::Engine::Nameserver' ) for @{ $zone->ns }; isa_ok( $zone->glue_addresses, 'ARRAY' ); -isa_ok( $_, 'Zonemaster::LDNS::RR' ) for @{ $zone->glue_addresses }; +isa_ok( $_, 'Zonemaster::LDNS::RR' ) for @{ $zone->glue_addresses }; my $p = $zone->query_one( 'www.iis.se', 'A' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); my @rrs = $p->get_records( 'a', 'answer' ); -is( scalar( @rrs ), 1, 'one answer A RR' ); +is( scalar( @rrs ), 1, 'one answer A RR' ); is( $rrs[0]->address, '159.253.30.207', 'expected address' ); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); Zonemaster::Engine->logger->clear_history(); $p = $zone->query_one( 'www.iis.se', 'A' ); -ok( ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv6 disabled" ); -ok( ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv4 disabled" ); +ok( ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), "query_one: IPv6 disabled" ); +ok( ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), "query_one: IPv4 disabled" ); $p = $zone->query_auth( 'www.iis.se', 'A' ); -ok( ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv6 disabled" ); -ok( ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv4 disabled" ); +ok( + ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv6 disabled", +); +ok( + ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv4 disabled", +); $p = $zone->query_persistent( 'www.iis.se', 'A' ); -ok( ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv6 disabled" ); -ok( ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv4 disabled" ); +ok( + ( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv6 disabled", +); +ok( + ( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv4 disabled", +); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 1 ); Zonemaster::Engine->logger->clear_history(); $p = $zone->query_one( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv6 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_one: IPv6 not disabled", +); $p = $zone->query_auth( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv6 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv6 not disabled", +); $p = $zone->query_persistent( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv6 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv6 not disabled", +); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 1 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 0 ); Zonemaster::Engine->logger->clear_history(); $p = $zone->query_one( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_one: IPv4 not disabled", +); $p = $zone->query_auth( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv4 not disabled", +); $p = $zone->query_persistent( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv4 not disabled", +); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 1 ); Zonemaster::Engine::Profile->effective->set( q{net.ipv6}, 1 ); Zonemaster::Engine->logger->clear_history(); $p = $zone->query_one( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv6 not disabled" ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_one: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_one: IPv6 not disabled", +); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_one: IPv4 not disabled", +); $p = $zone->query_auth( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv6 not disabled" ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_auth: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv6 not disabled", +); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_auth: IPv4 not disabled", +); $p = $zone->query_persistent( 'www.iis.se', 'A' ); -ok( !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv6 not disabled" ); -ok( !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{Zonemaster::Engine->logger->entries} ), "query_persistent: IPv4 not disabled" ); +ok( + !( grep { $_->tag eq 'SKIP_IPV6_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv6 not disabled", +); +ok( + !( grep { $_->tag eq 'SKIP_IPV4_DISABLED' } @{ Zonemaster::Engine->logger->entries } ), + "query_persistent: IPv4 not disabled", +); $p = $zone->query_persistent( 'www.iis.se', 'A' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); @rrs = $p->get_records( 'a', 'answer' ); -is( scalar( @rrs ), 1, 'one answer A RR' ); +is( scalar( @rrs ), 1, 'one answer A RR' ); is( $rrs[0]->address, '159.253.30.207', 'expected address' ); $p = $zone->query_auth( 'www.iis.se', 'A' ); isa_ok( $p, 'Zonemaster::Engine::Packet' ); @rrs = $p->get_records( 'a', 'answer' ); -is( scalar( @rrs ), 1, 'one answer A RR' ); +is( scalar( @rrs ), 1, 'one answer A RR' ); is( $rrs[0]->address, '159.253.30.207', 'expected address' ); my $ary = $zone->query_all( 'www.iis.se', 'A' ); @@ -106,7 +154,7 @@ isa_ok( $ary, 'ARRAY' ); foreach my $p ( @$ary ) { isa_ok( $p, 'Zonemaster::Engine::Packet' ); my @rrs = $p->get_records( 'a', 'answer' ); - is( scalar( @rrs ), 1, 'one answer A RR' ); + is( scalar( @rrs ), 1, 'one answer A RR' ); is( $rrs[0]->address, '159.253.30.207', 'expected address' ); } @@ -125,8 +173,10 @@ ok( not $zone->is_in_zone( 'www.google.se', 'www.google.se is not in zone iis.se my $net = Zonemaster::Engine->zone( 'net' ); ok( not( $net->is_in_zone( 'k.gtld-servers.net.' ) ), 'k.gtld-servers.net is not in zone' ); -ok( Zonemaster::Engine->zone( 'gtld-servers.net' )->is_in_zone( 'k.gtld-servers.net.' ), - 'k.gtld-servers.net is in zone' ); +ok( + Zonemaster::Engine->zone( 'gtld-servers.net' )->is_in_zone( 'k.gtld-servers.net.' ), + 'k.gtld-servers.net is in zone', +); if ( $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Nameserver->save( $datafile ); diff --git a/t/zonemaster.t b/t/zonemaster.t index aff7d0614..bb5cc0d8b 100644 --- a/t/zonemaster.t +++ b/t/zonemaster.t @@ -10,7 +10,7 @@ BEGIN { use_ok( 'Zonemaster::Engine::Exception' ); } -is( exception { Zonemaster::Engine->reset(); }, undef, 'No crash on instant reset.'); +is( exception { Zonemaster::Engine->reset(); }, undef, 'No crash on instant reset.' ); my $datafile = q{t/zonemaster.data}; if ( not $ENV{ZONEMASTER_RECORD} ) { @@ -19,7 +19,7 @@ if ( not $ENV{ZONEMASTER_RECORD} ) { Zonemaster::Engine::Profile->effective->set( q{no_network}, 1 ); } -my ($json, $profile_tmp); +my ( $json, $profile_tmp ); $json = read_file( 't/profiles/Test-all.json' ); $profile_tmp = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_tmp ); @@ -27,7 +27,7 @@ $json = read_file( 't/profiles/Test-all-levels.json' ); $profile_tmp = Zonemaster::Engine::Profile->from_json( $json ); Zonemaster::Engine::Profile->effective->merge( $profile_tmp ); -isa_ok( Zonemaster::Engine->logger, 'Zonemaster::Engine::Logger' ); +isa_ok( Zonemaster::Engine->logger, 'Zonemaster::Engine::Logger' ); isa_ok( Zonemaster::Engine::Profile->effective, 'Zonemaster::Engine::Profile' ); my %module = map { $_ => 1 } Zonemaster::Engine::Test->modules; @@ -123,9 +123,12 @@ Zonemaster::Engine->logger->callback( die Zonemaster::Engine::Exception->new( { message => 'canary' } ); } ); -isa_ok( exception { Zonemaster::Engine->test_zone( 'nic.se' ) }, 'Zonemaster::Engine::Exception' ); +isa_ok( exception { Zonemaster::Engine->test_zone( 'nic.se' ) }, 'Zonemaster::Engine::Exception' ); isa_ok( exception { Zonemaster::Engine->test_module( 'SyNtAx', 'nic.se' ) }, 'Zonemaster::Engine::Exception' ); -isa_ok( exception { Zonemaster::Engine->test_method( 'Syntax', 'syntax01', 'nic.se' ) }, 'Zonemaster::Engine::Exception' ); +isa_ok( + exception { Zonemaster::Engine->test_method( 'Syntax', 'syntax01', 'nic.se' ) }, + 'Zonemaster::Engine::Exception', +); Zonemaster::Engine->logger->callback( undef ); Zonemaster::Engine::Profile->effective->set( q{net.ipv4}, 0 ); @@ -151,8 +154,8 @@ if ( $ENV{ZONEMASTER_RECORD} ) { ok( @{ Zonemaster::Engine->logger->entries } > 0, 'There are log entries' ); ok( scalar( keys( %Zonemaster::Engine::Nameserver::object_cache ) ) > 0, 'There are things in the object cache' ); Zonemaster::Engine->reset; -ok( @{ Zonemaster::Engine->logger->entries } == 0, 'There are no log entries' ); -ok( scalar( keys( %Zonemaster::Engine::Nameserver::object_cache ) ) == 0, 'The object cache is empty' ); +ok( @{ Zonemaster::Engine->logger->entries } == 0, 'There are no log entries' ); +ok( scalar( keys( %Zonemaster::Engine::Nameserver::object_cache ) ) == 0, 'The object cache is empty' ); ok( scalar( keys( %Zonemaster::Engine::Nameserver::Cache::object_cache ) ) == 0, 'The packet cache is empty' ); done_testing; diff --git a/util/convert_config_to_profile.pl b/util/convert_config_to_profile.pl index 054b95d99..acf73bb1a 100755 --- a/util/convert_config_to_profile.pl +++ b/util/convert_config_to_profile.pl @@ -4,7 +4,7 @@ use warnings; use strict; -use version; our $VERSION = version->declare("v1.0.1"); +use version; our $VERSION = version->declare( "v1.0.1" ); use Carp; @@ -18,13 +18,13 @@ use File::Basename; use Clone qw(clone); -my $DEBUG = 0; -my $DEST_DIR = q{}; +my $DEBUG = 0; +my $DEST_DIR = q{}; my $CONFIG_FILE = q{}; my $POLICY_FILE = q{}; -my $scriptName = basename($PROGRAM_NAME); -my $dest_dir = q{./}; +my $scriptName = basename( $PROGRAM_NAME ); +my $dest_dir = q{./}; my $config_file = q{}; my $policy_file = q{}; @@ -42,7 +42,7 @@ $policy_file = $POLICY_FILE; } -if ($DEBUG) { +if ( $DEBUG ) { print "Debug Mode set ON\n"; print "Destination directory : $dest_dir\n\n"; } @@ -50,7 +50,7 @@ #------------------------------------------------- # STEP 0: Check Directory existence and Directory/Files permissions #------------------------------------------------- -if ( ! -d $dest_dir ) { +if ( !-d $dest_dir ) { printf "(\"%s --help\" for help)\n", $scriptName; print "Directory $dest_dir does not exist.\n"; unless ( mkdir $dest_dir ) { @@ -58,58 +58,58 @@ } } -if ( ! -w $dest_dir ) { +if ( !-w $dest_dir ) { printf "(\"%s --help\" for help)\n", $scriptName; print "Directory $dest_dir mode must be changed.\n"; - unless ( chmod (oct(755), $dest_dir) ) { + unless ( chmod( oct( 755 ), $dest_dir ) ) { croak "Cannot change directory mode."; } } -if ( ! $config_file ) { +if ( !$config_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "A Config file must be provided."; } -if ( ! -e $config_file ) { +if ( !-e $config_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "Config file $config_file does not exists."; } -if ( ! -r $config_file ) { +if ( !-r $config_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "Config file $config_file is not readable."; } -if ( ! $policy_file ) { +if ( !$policy_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "A Policy file must be provided."; } -if ( ! -e $policy_file ) { +if ( !-e $policy_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "Policy file $policy_file does not exists."; } -if ( ! -r $policy_file ) { +if ( !-r $policy_file ) { printf "(\"%s --help\" for help)\n", $scriptName; croak "Policy file $policy_file is not readable."; } -my $policy_json = read_file( $policy_file ) ; -my $policy = decode_json( $policy_json ); -my $config_json = read_file( $config_file ); -my $config = decode_json( $config_json ); +my $policy_json = read_file( $policy_file ); +my $policy = decode_json( $policy_json ); +my $config_json = read_file( $config_file ); +my $config = decode_json( $config_json ); my $default = Zonemaster::Engine::Profile->default; my $profile = Zonemaster::Engine::Profile->new; my %paths; my %default_paths; -Zonemaster::Engine::Profile::_get_profile_paths(\%paths, $config); -Zonemaster::Engine::Profile::_get_profile_paths(\%default_paths, $default->{q{profile}}); -delete $default_paths{ q{test_cases} }; -delete $default_paths{ q{test_levels} }; +Zonemaster::Engine::Profile::_get_profile_paths( \%paths, $config ); +Zonemaster::Engine::Profile::_get_profile_paths( \%default_paths, $default->{q{profile}} ); +delete $default_paths{q{test_cases}}; +delete $default_paths{q{test_levels}}; # # General options part @@ -146,8 +146,8 @@ } $profile->set( q{test_levels}, \%tl ); -my $filename = $dest_dir.q{/profile.json}; -open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; +my $filename = $dest_dir . q{/profile.json}; +open( my $fh, '>', $filename ) or die "Could not open file '$filename' $!"; my $json = JSON::XS->new->canonical->pretty; print $fh $json->encode( $profile->{q{profile}} ); close $fh; @@ -156,12 +156,12 @@ sub process_options { my ( $opt_dest, $opt_config, $opt_policy, $opt_help, $opt_debug, $opt_version ); GetOptions( - q{dest-dir=s} => \$opt_dest, # Dest directory for generated profile file - q{config=s} => \$opt_config, # Config File - q{policy=s} => \$opt_policy, # Policy file - q{help} => \$opt_help, # Print Usage - q{debug} => \$opt_debug, # Set Debug MODE - q{version} => \$opt_version, # Print Version + q{dest-dir=s} => \$opt_dest, # Dest directory for generated profile file + q{config=s} => \$opt_config, # Config File + q{policy=s} => \$opt_policy, # Policy file + q{help} => \$opt_help, # Print Usage + q{debug} => \$opt_debug, # Set Debug MODE + q{version} => \$opt_version, # Print Version ); if ( $opt_debug ) { @@ -189,7 +189,7 @@ sub process_options { } return; -} +} ## end sub process_options sub Usage { my $_bold = "\e[1m"; @@ -231,7 +231,7 @@ sub Usage { exit 0; -} +} ## end sub Usage sub Version { printf "%s %s\n", $scriptName, $VERSION; diff --git a/util/get_iana_address_spaces_infos.pl b/util/get_iana_address_spaces_infos.pl index 7fdb19895..a845c3b3b 100755 --- a/util/get_iana_address_spaces_infos.pl +++ b/util/get_iana_address_spaces_infos.pl @@ -4,7 +4,7 @@ use warnings; use strict; -use version; our $VERSION = version->declare("v1.0.1"); +use version; our $VERSION = version->declare( "v1.0.1" ); use Carp; @@ -21,14 +21,22 @@ use Text::CSV; -my $DEBUG = 0; +my $DEBUG = 0; my $DEST_DIR = q{}; -my $iana_url = q{http://www.iana.org/assignments/}; -my $dest_dir = qq{$FindBin::Bin/../share}; +my $iana_url = q{http://www.iana.org/assignments/}; +my $dest_dir = qq{$FindBin::Bin/../share}; my @files_details = ( - { name => q{iana-ipv4-special-registry.csv}, url => $iana_url.q{/iana-ipv4-special-registry/iana-ipv4-special-registry-1.csv}, ip_version => 4 }, - { name => q{iana-ipv6-special-registry.csv}, url => $iana_url.q{/iana-ipv6-special-registry/iana-ipv6-special-registry-1.csv}, ip_version => 6 }, + { + name => q{iana-ipv4-special-registry.csv}, + url => $iana_url . q{/iana-ipv4-special-registry/iana-ipv4-special-registry-1.csv}, + ip_version => 4, + }, + { + name => q{iana-ipv6-special-registry.csv}, + url => $iana_url . q{/iana-ipv6-special-registry/iana-ipv6-special-registry-1.csv}, + ip_version => 6, + }, ); process_options(); @@ -37,7 +45,7 @@ $dest_dir = $DEST_DIR; } -if ($DEBUG) { +if ( $DEBUG ) { print "Debug Mode set ON\n"; print "Destination directory : $dest_dir\n\n"; } @@ -45,25 +53,25 @@ #------------------------------------------------- # STEP 0: Check Directory existence and Directory/Files permissions #------------------------------------------------- -if ( ! -d $dest_dir ) { +if ( !-d $dest_dir ) { print "Directory $dest_dir does not exist.\n"; unless ( mkdir $dest_dir ) { croak "Unable to create $dest_dir."; } } -if ( ! -w $dest_dir ) { +if ( !-w $dest_dir ) { print "Directory $dest_dir mode must be changed.\n"; - unless ( chmod (oct(755), $dest_dir) ) { + unless ( chmod( oct( 755 ), $dest_dir ) ) { croak "Cannot change directory mode."; } } foreach my $file_details ( @files_details ) { - my $fn = $dest_dir.q{/}.${$file_details}{name}; - if ( -e $fn and ! -w $fn ) { + my $fn = $dest_dir . q{/} . ${$file_details}{name}; + if ( -e $fn and !-w $fn ) { print "File $fn mode must be changed.\n"; - unless ( chmod (oct(664), $fn) ) { + unless ( chmod( oct( 664 ), $fn ) ) { croak "Cannot change file mode."; } } @@ -73,9 +81,9 @@ # STEP 1: If they exist, save original files #------------------------------------------------- foreach my $file_details ( @files_details ) { - my $fn = $dest_dir.q{/}.${$file_details}{name}; + my $fn = $dest_dir . q{/} . ${$file_details}{name}; if ( -e $fn ) { - my ($fh, $filename) = tempfile(); + my ( $fh, $filename ) = tempfile(); ${$file_details}{backup_filename} = $filename; unless ( copy $fn, $filename ) { croak "The Copy operation failed: $ERRNO"; @@ -87,17 +95,18 @@ # STEP 2: Retrieve remote files in temporary files #------------------------------------------------- foreach my $file_details ( @files_details ) { - my ($fh, $filename) = tempfile(); + my ( $fh, $filename ) = tempfile(); ${$file_details}{new_filename} = $filename; - my $rc = getstore(${$file_details}{url}, $filename); + my $rc = getstore( ${$file_details}{url}, $filename ); } #------------------------------------------------- # STEP 3: Check downloaded files integrity #------------------------------------------------- foreach my $file_details ( @files_details ) { - my $fn = ${$file_details}{new_filename}; - my $csv = Text::CSV->new({ binary => 1, auto_diag => 1, sep_char => q{,} }) or croak "Cannot use CSV: ".Text::CSV->error_diag (); + my $fn = ${$file_details}{new_filename}; + my $csv = Text::CSV->new( { binary => 1, auto_diag => 1, sep_char => q{,} } ) + or croak "Cannot use CSV: " . Text::CSV->error_diag(); open my $fh, "<:encoding(utf8)", $fn or croak "$fn: $ERRNO"; while ( my $row = $csv->getline( $fh ) ) { } @@ -110,7 +119,7 @@ # STEP 4: Copy Files on their final destination #------------------------------------------------- foreach my $file_details ( @files_details ) { - my $fn = $dest_dir.q{/}.${$file_details}{name}; + my $fn = $dest_dir . q{/} . ${$file_details}{name}; if ( -e ${$file_details}{new_filename} ) { unless ( copy ${$file_details}{new_filename}, $fn ) { croak "The Copy operation failed: $ERRNO"; @@ -125,12 +134,14 @@ sub clean_temporary_files { foreach my $file_details ( @files_details ) { - if ($DEBUG) { + if ( $DEBUG ) { print "${$file_details}{name} Details : \n"; print "Backup file : ${$file_details}{backup_filename}\n"; print "Downloaded file : ${$file_details}{new_filename}\n\n"; - } else { - unlink ${$file_details}{backup_filename} or carp "Could not unlink ${$file_details}{backup_filename}: $ERRNO"; + } + else { + unlink ${$file_details}{backup_filename} + or carp "Could not unlink ${$file_details}{backup_filename}: $ERRNO"; unlink ${$file_details}{new_filename} or carp "Could not unlink ${$file_details}{new_filename}: $ERRNO"; } } @@ -141,9 +152,9 @@ sub process_options { my ( $opt_dest, $opt_help, $opt_debug ); GetOptions( - q{dest-dir=s} => \$opt_dest, # Dest directory for downloaded files - q{help} => \$opt_help, # Print Usage - q{debug} => \$opt_debug, # Set Debug MODE + q{dest-dir=s} => \$opt_dest, # Dest directory for downloaded files + q{help} => \$opt_help, # Print Usage + q{debug} => \$opt_debug, # Set Debug MODE ); if ( $opt_debug ) { @@ -159,13 +170,13 @@ sub process_options { } return; -} +} ## end sub process_options sub Usage { my $_bold = "\e[1m"; my $_normal = "\e[0m"; my $_ul = "\e[4m"; - my $scriptName = basename($PROGRAM_NAME); + my $scriptName = basename( $PROGRAM_NAME ); my $scriptNameBlank = $scriptName; $scriptNameBlank =~ s/./ /smxg; @@ -199,5 +210,5 @@ sub Usage { exit 0; -} +} ## end sub Usage diff --git a/util/reformat_json.pl b/util/reformat_json.pl index 99b3ea9bc..c6e9e17e1 100755 --- a/util/reformat_json.pl +++ b/util/reformat_json.pl @@ -7,4 +7,4 @@ my $json = JSON::PP->new->canonical->pretty->utf8; -say $json->encode($json->decode(join('',<>))); +say $json->encode( $json->decode( join( '', <> ) ) );