Files
Malin 8d4eaa1489 feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI)
- Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend
- Dockerfile.gui: Astro static build served via nginx
- docker-compose.yml: backend (internal) + frontend (port 5353)
- nginx.conf: root redirects to /es/, /api/ proxied to backend
- zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 08:19:24 +02:00

124 lines
4.3 KiB
Perl

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 => <<EOF,
; This file holds the information on root name servers needed to
; -------- 8< --------
. 3600000 NS A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
. 3600000 NS B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201
B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b
; -------- 8< --------
; End of file
EOF
expected => {
'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 => <<EOF,
. 86400 SOA a.root-servers.net. nstld.verisign-grs.com. (
2022093000 ; serial
1800 ; refresh (30 minutes)
900 ; retry (15 minutes)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
EOF
error => 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;