use Test::More; use Test::Differences; use Test::Exception; BEGIN { 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( name( "foo.bar.com" ), 'Zonemaster::Engine::DNSName' ); subtest 'parse_hints()' => sub { my @cases = ( { name => 'Cropped IANA hints', hints => < { 'A.ROOT-SERVERS.NET' => [ '198.41.0.4', '2001:503:ba3e:0:0:0:2:30' ], 'B.ROOT-SERVERS.NET' => [ '199.9.14.201', '2001:500:200:0:0:0:0:b' ], }, }, { name => 'Syntax error', hints => '(>_<)', error => qr/Unable to parse root hints/, }, { name => 'Forbidden $TTL', hints => "\n\$TTL 3600", error => qr/Forbidden directive \$TTL/, }, { name => 'Forbidden $INCLUDE', hints => "\n\$INCLUDE /etc/motd", error => qr/Forbidden directive \$INCLUDE/, }, { name => 'Forbidden $ORIGIN', hints => "\n\$ORIGIN NET.", error => qr/Forbidden directive \$ORIGIN/, }, { name => 'Forbidden $GENERATE', hints => "\n\$GENERATE 65-126 $ CNAME \$.64/26", error => qr/Forbidden directive \$GENERATE/, }, { name => 'Forbidden CH class', hints => '. CH 3600000 NS A.ROOT-SERVERS.NET.', error => qr/Forbidden RR class CH/, }, { name => 'Forbidden RR type SOA', hints => < qr/Forbidden RR type SOA/, }, { name => 'Forbidden RR type TXT', hints => '. 3600000 TXT "B.ROOT-SERVERS.NET"', error => qr/Forbidden RR type TXT/, }, { name => 'Wrong owner name', hints => 'NET. 3600000 NS A.ROOT-SERVERS.NET.', error => qr/Owner name for NS record must be "\."/, }, { name => 'Missing address record', hints => '. 3600000 NS A.ROOT-SERVERS.NET.', error => qr/No address record found for NS A\.ROOT-SERVERS\.NET/, }, { name => 'Orphan A record', hints => 'B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201', error => qr/Owner name of A record does not match any NS RDATA/, }, { name => 'Orphan AAAA record', hints => 'B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b', error => qr/Owner name of AAAA record does not match any NS RDATA/, }, { name => 'Missing NS', hints => '', error => qr/No NS record found/, }, ); for my $case ( @cases ) { if ( exists $case->{expected} ) { my $actual = parse_hints( $case->{hints} ); eq_or_diff $actual, $case->{expected}, $case->{name}; } else { throws_ok { parse_hints( $case->{hints} ) } $case->{error}, $case->{name}; } } }; done_testing;