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>
This commit is contained in:
841
zonemaster-engine/t/profiles.t
Normal file
841
zonemaster-engine/t/profiles.t
Normal file
@@ -0,0 +1,841 @@
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use Test::More;
|
||||
use Log::Any::Test; # Must come before use Log::Any
|
||||
|
||||
use JSON::PP;
|
||||
use Readonly;
|
||||
use Test::Differences;
|
||||
use Test::Exception;
|
||||
use Log::Any qw( $log );
|
||||
|
||||
use Zonemaster::Engine::Profile;
|
||||
|
||||
# YAML representation of an example profile with all properties set
|
||||
Readonly my $EXAMPLE_PROFILE_1_YAML => q(
|
||||
---
|
||||
resolver:
|
||||
defaults:
|
||||
fallback: true
|
||||
igntc: false
|
||||
recurse: true
|
||||
retrans: 234
|
||||
retry: 123
|
||||
usevc: true
|
||||
source4: 192.0.2.53
|
||||
source6: 2001:db8::42
|
||||
net:
|
||||
ipv4: true
|
||||
ipv6: false
|
||||
no_network: true
|
||||
cache:
|
||||
redis:
|
||||
server: 127.0.0.1:6379
|
||||
expire: 3600
|
||||
asn_db:
|
||||
style: cymru
|
||||
sources:
|
||||
cymru:
|
||||
- asn1.example.com
|
||||
- asn2.example.com
|
||||
logfilter:
|
||||
Zone:
|
||||
TAG:
|
||||
- set: WARNING
|
||||
when:
|
||||
bananas: 0
|
||||
test_levels:
|
||||
Zone:
|
||||
TAG: INFO
|
||||
test_cases:
|
||||
- Zone01
|
||||
);
|
||||
|
||||
# JSON representation of an example profile with all properties set
|
||||
Readonly my $EXAMPLE_PROFILE_1 => q(
|
||||
{
|
||||
"resolver": {
|
||||
"defaults": {
|
||||
"usevc": true,
|
||||
"recurse": true,
|
||||
"igntc": false,
|
||||
"fallback": true,
|
||||
"retry": 123,
|
||||
"retrans": 234
|
||||
},
|
||||
"source4": "192.0.2.53",
|
||||
"source6": "2001:db8::42"
|
||||
},
|
||||
"net": {
|
||||
"ipv4": true,
|
||||
"ipv6": false
|
||||
},
|
||||
"no_network": true,
|
||||
"cache": {
|
||||
"redis": {
|
||||
"server": "127.0.0.1:6379",
|
||||
"expire": 3600
|
||||
}
|
||||
},
|
||||
"asn_db" : {
|
||||
"style" : "cymru",
|
||||
"sources" : {
|
||||
"cymru" : [ "asn1.example.com", "asn2.example.com" ]
|
||||
}
|
||||
},
|
||||
"logfilter": {
|
||||
"Zone": {
|
||||
"TAG": [
|
||||
{
|
||||
"when": {
|
||||
"bananas": 0
|
||||
},
|
||||
"set": "WARNING"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test_levels": {
|
||||
"Zone": {
|
||||
"TAG": "INFO"
|
||||
}
|
||||
},
|
||||
"test_cases": [
|
||||
"Zone01"
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
# JSON representation of an example profile with all properties set to values
|
||||
# that are different from those in $EXAMPLE_PROFILE_1
|
||||
Readonly my $EXAMPLE_PROFILE_2 => q(
|
||||
{
|
||||
"resolver": {
|
||||
"defaults": {
|
||||
"usevc": false,
|
||||
"recurse": false,
|
||||
"igntc": true,
|
||||
"fallback": false,
|
||||
"retry": 99,
|
||||
"retrans": 88
|
||||
},
|
||||
"source4": "198.51.100.53",
|
||||
"source6": "2001:db8::cafe"
|
||||
},
|
||||
"net": {
|
||||
"ipv4": false,
|
||||
"ipv6": true
|
||||
},
|
||||
"no_network": false,
|
||||
"cache": {
|
||||
"redis": {
|
||||
"server": "127.0.0.2:6379",
|
||||
"expire": 7200
|
||||
}
|
||||
},
|
||||
"asn_db" : {
|
||||
"style" : "ripe",
|
||||
"sources" : {
|
||||
"ripe" : [ "asn3.example.com", "asn4.example.com" ]
|
||||
}
|
||||
},
|
||||
"logfilter": {
|
||||
"Nameserver": {
|
||||
"OTHER_TAG": [
|
||||
{
|
||||
"when": {
|
||||
"apples": 1
|
||||
},
|
||||
"set": "INFO"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test_levels": {
|
||||
"Nameserver": {
|
||||
"OTHER_TAG": "ERROR"
|
||||
}
|
||||
},
|
||||
"test_cases": [
|
||||
"Zone02"
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
Readonly my $EXAMPLE_PROFILE_3 => qq(
|
||||
{
|
||||
"resolver": {
|
||||
"source4": "",
|
||||
"source6": ""
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
subtest 'new() returns a new profile every time' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->new;
|
||||
|
||||
my $profile2 = Zonemaster::Engine::Profile->new;
|
||||
$profile1->set( 'net.ipv4', 1 );
|
||||
|
||||
is $profile2->get( 'net.ipv4' ), undef, 'net.ipv4 is unaffected by update to another instance';
|
||||
};
|
||||
|
||||
subtest 'new() returns a profile with all properties unset' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
|
||||
for my $property ( Zonemaster::Engine::Profile->all_properties ) {
|
||||
is $profile->get( $property ), undef, "$property is unset";
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'default() returns a new profile every time' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->default;
|
||||
$profile1->set( 'net.ipv4', 1 );
|
||||
|
||||
my $profile2 = Zonemaster::Engine::Profile->default;
|
||||
$profile2->set( 'net.ipv4', 0 );
|
||||
|
||||
is $profile1->get( 'net.ipv4' ), 1, 'net.ipv4 is unaffected by update to another instance';
|
||||
};
|
||||
|
||||
subtest 'default() returns a profile with all properties set' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->default;
|
||||
|
||||
for my $property ( Zonemaster::Engine::Profile->all_properties ) {
|
||||
ok defined( $profile->get( $property ) ), "$property is set";
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'from_json() returns a new profile every time' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->from_json( "{}" );
|
||||
|
||||
my $profile2 = Zonemaster::Engine::Profile->from_json( "{}" );
|
||||
$profile1->set( 'net.ipv4', 1 );
|
||||
|
||||
is $profile2->get( 'net.ipv4' ), undef, 'net.ipv4 is unaffected by update to another instance';
|
||||
};
|
||||
|
||||
subtest 'from_json("{}") returns a profile with all properties unset' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json( "{}" );
|
||||
|
||||
for my $property ( Zonemaster::Engine::Profile->all_properties ) {
|
||||
is $profile->get( $property ), undef, "$property is unset";
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'from_json() parses values from a string' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
|
||||
is $profile->get( 'resolver.defaults.usevc' ), 1, 'resolver.defaults.usevc was parsed from JSON';
|
||||
is $profile->get( 'resolver.defaults.recurse' ), 1, 'resolver.defaults.recurse was parsed from JSON';
|
||||
is $profile->get( 'resolver.defaults.igntc' ), 0, 'resolver.defaults.igntc was parsed from JSON';
|
||||
is $profile->get( 'resolver.defaults.fallback' ), 1, 'resolver.defaults.fallback was parsed from JSON';
|
||||
is $profile->get( 'net.ipv4' ), 1, 'net.ipv4 was parsed from JSON';
|
||||
is $profile->get( 'net.ipv6' ), 0, 'net.ipv6 was parsed from JSON';
|
||||
is $profile->get( 'no_network' ), 1, 'no_network was parsed from JSON';
|
||||
is $profile->get( 'resolver.defaults.retry' ), 123, 'resolver.defaults.retry was parsed from JSON';
|
||||
is $profile->get( 'resolver.defaults.retrans' ), 234, 'resolver.defaults.retrans was parsed from JSON';
|
||||
is $profile->get( 'resolver.source4' ), '192.0.2.53', 'resolver.source4 was parsed from JSON';
|
||||
is $profile->get( 'resolver.source6' ), '2001:db8::42', 'resolver.source6 was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'asn_db.style' ), 'cymru', 'asn_db.style was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'asn_db.sources' ), { cymru => ["asn1.example.com", "asn2.example.com"] }, 'asn_db.sources was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'logfilter' ), { Zone => { TAG => [ { when => { bananas => 0 }, set => 'WARNING' } ] } },
|
||||
'logfilter was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'test_levels' ), { Zone => { TAG => 'INFO' } }, 'test_levels was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'test_cases' ), ['Zone01'], 'test_cases was parsed from JSON';
|
||||
eq_or_diff $profile->get( 'cache' ), { redis => { server => '127.0.0.1:6379', expire => 3600 } }, 'cache was parsed from JSON';
|
||||
};
|
||||
|
||||
subtest 'from_json() parses sentinel values from a string' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_3 );
|
||||
|
||||
is $profile->get( 'resolver.source4' ), '', 'resolver.source4 was parsed from JSON';
|
||||
is $profile->get( 'resolver.source6' ), '', 'resolver.source6 was parsed from JSON';
|
||||
};
|
||||
|
||||
subtest 'from_json() dies on illegal paths' => sub {
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"foobar":1}' ) } qr/^.*Unknown property .*/, 'foobar';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"net":1}' ) } qr/^.*Unknown property .*/, 'net';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"net":{"foobar":1}}' ) } qr/^.*Unknown property .*/, 'net.foobar';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":1}' ) } qr/^.*Unknown property .*/, 'resolver';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":1}}' ) } qr/^.*Unknown property .*/, 'resolver.defaults';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"foobar":1}}}' ) } qr/^.*Unknown property .*/, 'resolver.defaults.foobar';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"dnssec":1}}}' ); } qr/^.*Unknown property .*/, 'resolver.defaults.dnssec';
|
||||
throws_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"edns_size":1}}}' ); } qr/^.*Unknown property .*/, 'resolver.defaults.edns_size';
|
||||
};
|
||||
|
||||
subtest 'from_json() dies on illegal values' => sub {
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"usevc":0}}}' ); } "checks type of resolver.defaults.usevc";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"recurse":0}}}' ); } "checks type of resolver.defaults.recurse";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"igntc":1}}}' ); } "checks type of resolver.defaults.igntc";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"fallback":0}}}' ); } "checks type of resolver.defaults.fallback";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"net":{"ipv4":1}}' ); } "checks type of net.ipv4";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"net":{"ipv6":0}}' ); } "checks type of net.ipv6";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"no_network":1}' ); } "checks type of no_network";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retry":0}}}' ); } "checks lower bound of resolver.defaults.retry";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retry":256}}}' ); } "checks upper bound of resolver.defaults.retry";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retry":1.5}}}' ); } "checks type of resolver.defaults.retry";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retrans":0}}}' ); } "checks lower bound of resolver.defaults.retrans";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retrans":256}}}' ); } "checks upper bound of resolver.defaults.retrans";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"defaults":{"retrans":1.5}}}' ); } "checks type of resolver.defaults.retrans";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"asn_db":{"style":["noreply@example"]}' ); } "checks type of asndb.style";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"asn_db":{"sources":["noreply@example"]}' ); } "checks type of asndb.sources";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"logfilter":[]}' ); } "checks type of logfilter";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"test_levels":[]}' ); } "checks type of test_levels";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"test_cases":{}}' ); } "checks type of test_cases";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"cache":[]}' ); } "checks type of cache";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"source4":"example.com"}}' ); } "checks type of resolver.source4";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"source4":"2001:db8::42"}}' ); } "checks type of resolver.source4 (only IPv4)";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"source6":"example.com"}}' ); } "checks type of resolver.source6";
|
||||
dies_ok { Zonemaster::Engine::Profile->from_json( '{"resolver":{"source6":"192.0.2.53"}}' ); } "checks type of resolver.source6 (only IPv6)";
|
||||
};
|
||||
|
||||
subtest 'from_yaml() equals from_json() for a similar profile' => sub {
|
||||
my $profile_json = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
my $profile_yaml = Zonemaster::Engine::Profile->from_yaml( $EXAMPLE_PROFILE_1_YAML );
|
||||
is_deeply( $profile_yaml, $profile_json, 'same JSON and YAML profile' );
|
||||
};
|
||||
|
||||
subtest 'get() returns 1 for true' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json(
|
||||
'{
|
||||
"resolver": {
|
||||
"defaults": {
|
||||
"usevc": true,
|
||||
"recurse": true,
|
||||
"igntc": true,
|
||||
"fallback": true
|
||||
}
|
||||
},
|
||||
"net": {
|
||||
"ipv4": true,
|
||||
"ipv6": true
|
||||
},
|
||||
"no_network": true
|
||||
}'
|
||||
);
|
||||
|
||||
is $profile->get( 'resolver.defaults.usevc' ), 1, "returns 1 for true resolver.defaults.usevc";
|
||||
is $profile->get( 'resolver.defaults.recurse' ), 1, "returns 1 for true resolver.defaults.recurse";
|
||||
is $profile->get( 'resolver.defaults.igntc' ), 1, "returns 1 for true resolver.defaults.igntc";
|
||||
is $profile->get( 'resolver.defaults.fallback' ), 1, "returns 1 for true resolver.defaults.fallback";
|
||||
is $profile->get( 'net.ipv4' ), 1, "returns 1 for true net.ipv4";
|
||||
is $profile->get( 'net.ipv6' ), 1, "returns 1 for true net.ipv6";
|
||||
is $profile->get( 'no_network' ), 1, "returns 1 for true no_network";
|
||||
};
|
||||
|
||||
subtest 'get() returns 0 for false' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json(
|
||||
'{
|
||||
"resolver": {
|
||||
"defaults": {
|
||||
"usevc": false,
|
||||
"recurse": false,
|
||||
"igntc": false,
|
||||
"fallback": false
|
||||
}
|
||||
},
|
||||
"net": {
|
||||
"ipv4": false,
|
||||
"ipv6": false
|
||||
},
|
||||
"no_network": false
|
||||
}'
|
||||
);
|
||||
|
||||
is $profile->get( 'resolver.defaults.usevc' ), 0, "returns 0 for false resolver.defaults.usevc";
|
||||
is $profile->get( 'resolver.defaults.recurse' ), 0, "returns 0 for false resolver.defaults.recurse";
|
||||
is $profile->get( 'resolver.defaults.igntc' ), 0, "returns 0 for false resolver.defaults.igntc";
|
||||
is $profile->get( 'resolver.defaults.fallback' ), 0, "returns 0 for false resolver.defaults.fallback";
|
||||
is $profile->get( 'net.ipv4' ), 0, "returns 0 for false net.ipv4";
|
||||
is $profile->get( 'net.ipv6' ), 0, "returns 0 for false net.ipv6";
|
||||
is $profile->get( 'no_network' ), 0, "returns 0 for false no_network";
|
||||
};
|
||||
|
||||
subtest 'get() returns deep copies of properties with complex types' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'asn_db.sources', {} );
|
||||
$profile->set( 'logfilter', {} );
|
||||
$profile->set( 'test_levels', {} );
|
||||
$profile->set( 'test_cases', [] );
|
||||
$profile->set( 'cache', {} );
|
||||
|
||||
$profile->get( 'asn_db.sources' )->{cymru} = ['asn1.example.com', 'asn2.example.com'];
|
||||
push @{ $profile->get( 'test_cases' ) }, 'Zone01';
|
||||
$profile->get( 'logfilter' )->{Zone} = {};
|
||||
$profile->get( 'test_levels' )->{Zone}{TAG} = 'INFO';
|
||||
$profile->get( 'cache' )->{redis}{server} = '127.0.0.1:6379';
|
||||
|
||||
eq_or_diff $profile->get( 'asn_db.sources' ), {}, 'get(asn_db.sources) returns a deep copy';
|
||||
eq_or_diff $profile->get( 'logfilter' ), {}, 'get(logfilter) returns a deep copy';
|
||||
eq_or_diff $profile->get( 'test_levels' ), {}, 'get(test_levels) returns a deep copy';
|
||||
eq_or_diff $profile->get( 'test_cases' ), [], 'get(test_cases) returns a deep copy';
|
||||
eq_or_diff $profile->get( 'cache' ), {}, 'get(cache) returns a deep copy';
|
||||
};
|
||||
|
||||
subtest 'get() dies if the given property name is invalid' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'asn_db.style', 'cymru' );
|
||||
$profile->set( 'asn_db.sources', { cymru => ['asn1.example.com', 'asn2.example.com'] } );
|
||||
$profile->set( 'logfilter', { Zone => {} } );
|
||||
$profile->set( 'test_levels', { Zone => { TAG => 'INFO' } } );
|
||||
$profile->set( 'test_cases', ['Zone01'] );
|
||||
$profile->set( 'cache', { redis => { server => '127.0.0.1:6379' } } );
|
||||
|
||||
throws_ok { $profile->get( 'net' ) } qr/^.*Unknown property .*/, 'net';
|
||||
throws_ok { $profile->get( 'net.foobar' ) } qr/^.*Unknown property .*/, 'net.foobar';
|
||||
throws_ok { $profile->get( 'resolver.defaults' ) } qr/^.*Unknown property .*/, 'resolver.defaults';
|
||||
throws_ok { $profile->get( 'resolver' ) } qr/^.*Unknown property .*/, 'resolver';
|
||||
throws_ok { $profile->get( 'asn_db.fake' ) } qr/^.*Unknown property .*/, 'asn_db.fake';
|
||||
throws_ok { $profile->get( 'logfilter.Zone' ) } qr/^.*Unknown property .*/, 'logfilter.Zone';
|
||||
throws_ok { $profile->get( 'test_levels.Zone' ) } qr/^.*Unknown property .*/, 'test_levels.Zone';
|
||||
throws_ok { $profile->get( 'test_cases.Zone01' ) } qr/^.*Unknown property .*/, 'test_cases.Zone01';
|
||||
throws_ok { $profile->get( 'cache.redis' ) } qr/^.*Unknown property .*/, 'cache.redis';
|
||||
throws_ok { $profile->get( 'resolver.defaults.dnssec' ) } qr/^.*Unknown property .*/, 'resolver.defaults.dnssec';
|
||||
throws_ok { $profile->get( 'resolver.defaults.edns_size' ) } qr/^.*Unknown property .*/, 'resolver.defaults.edns_size';
|
||||
};
|
||||
|
||||
subtest 'set() inserts values for unset properties' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
|
||||
$profile->set( 'resolver.defaults.usevc', 1 );
|
||||
$profile->set( 'resolver.defaults.recurse', 1 );
|
||||
$profile->set( 'resolver.defaults.igntc', 0 );
|
||||
$profile->set( 'resolver.defaults.fallback', 1 );
|
||||
$profile->set( 'net.ipv4', 0 );
|
||||
$profile->set( 'net.ipv6', 1 );
|
||||
$profile->set( 'no_network', 0 );
|
||||
$profile->set( 'resolver.defaults.retry', 123 );
|
||||
$profile->set( 'resolver.defaults.retrans', 234 );
|
||||
$profile->set( 'resolver.source4', '192.0.2.53' );
|
||||
$profile->set( 'resolver.source6', '2001:db8::42' );
|
||||
$profile->set( 'asn_db.style', 'cymru' );
|
||||
$profile->set( 'asn_db.sources', { cymru => ['asn1.example.com', 'asn2.example.com'] } );
|
||||
$profile->set( 'logfilter', { Zone => { TAG => [ { when => { bananas => 0 }, set => 'WARNING' } ] } } );
|
||||
$profile->set( 'test_levels', { Zone => { TAG => 'INFO' } } );
|
||||
$profile->set( 'test_cases', ['Zone01'] );
|
||||
$profile->set( 'cache', { redis => { server => '127.0.0.1:6379', expire => 3600 } } );
|
||||
|
||||
is $profile->get( 'resolver.defaults.usevc' ), 1, 'resolver.defaults.usevc can be given a value when unset';
|
||||
is $profile->get( 'resolver.defaults.recurse' ), 1, 'resolver.defaults.recurse can be given a value when unset';
|
||||
is $profile->get( 'resolver.defaults.igntc' ), 0, 'resolver.defaults.igntc can be given a value when unset';
|
||||
is $profile->get( 'resolver.defaults.fallback' ), 1, 'resolver.defaults.fallback can be given a value when unset';
|
||||
is $profile->get( 'net.ipv4' ), 0, 'net.ipv4 can be given a value when unset';
|
||||
is $profile->get( 'net.ipv6' ), 1, 'net.ipv6 can be given a value when unset';
|
||||
is $profile->get( 'no_network' ), 0, 'no_network can be given a value when unset';
|
||||
is $profile->get( 'resolver.defaults.retry' ), 123, 'resolver.defaults.retry can be given a value when unset';
|
||||
is $profile->get( 'resolver.defaults.retrans' ), 234, 'resolver.defaults.retrans can be given a value when unset';
|
||||
is $profile->get( 'resolver.source4' ), '192.0.2.53', 'resolver.source4 can be given a value when unset';
|
||||
is $profile->get( 'resolver.source6' ), '2001:db8::42', 'resolver.source6 can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'asn_db.style' ), 'cymru', 'asn_db.style can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'asn_db.sources' ), { cymru => ['asn1.example.com', 'asn2.example.com'] }, 'asn_db.sources can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'logfilter' ), { Zone => { TAG => [ { when => { bananas => 0 }, set => 'WARNING' } ] } },
|
||||
'logfilter can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'test_levels' ), { Zone => { TAG => 'INFO' } },
|
||||
'test_levels can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'test_cases' ), ['Zone01'], 'test_cases can be given a value when unset';
|
||||
eq_or_diff $profile->get( 'cache' ), { redis => { server => '127.0.0.1:6379', expire => 3600 } },
|
||||
'cache can be given a value when unset';
|
||||
};
|
||||
|
||||
subtest 'set() updates values for set properties' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
|
||||
$profile->set( 'resolver.defaults.usevc', 0 );
|
||||
$profile->set( 'resolver.defaults.recurse', 0 );
|
||||
$profile->set( 'resolver.defaults.igntc', 1 );
|
||||
$profile->set( 'resolver.defaults.fallback', 0 );
|
||||
$profile->set( 'net.ipv4', 0 );
|
||||
$profile->set( 'net.ipv6', 1 );
|
||||
$profile->set( 'no_network', 0 );
|
||||
$profile->set( 'resolver.defaults.retry', 99 );
|
||||
$profile->set( 'resolver.defaults.retrans', 88 );
|
||||
$profile->set( 'resolver.source4', '198.51.100.53' );
|
||||
$profile->set( 'resolver.source6', '2001:db8::cafe' );
|
||||
$profile->set( 'asn_db.style', 'ripe' );
|
||||
$profile->set( 'asn_db.sources', { ripe => ['asn3.example.com', 'asn4.example.com'] } );
|
||||
$profile->set( 'logfilter', { Nameserver => { OTHER_TAG => [ { when => { apples => 1 }, set => 'INFO' } ] } } );
|
||||
$profile->set( 'test_levels', { Nameserver => { OTHER_TAG => 'ERROR' } } );
|
||||
$profile->set( 'test_cases', ['Zone02'] );
|
||||
$profile->set( 'cache', { redis => { server => '127.0.0.2:6379', expire => 7200 } } );
|
||||
|
||||
is $profile->get( 'resolver.defaults.usevc' ), 0, 'resolver.defaults.usevc was updated';
|
||||
is $profile->get( 'resolver.defaults.recurse' ), 0, 'resolver.defaults.recurse was updated';
|
||||
is $profile->get( 'resolver.defaults.igntc' ), 1, 'resolver.defaults.igntc was updated';
|
||||
is $profile->get( 'net.ipv4' ), 0, 'net.ipv4 was updated';
|
||||
is $profile->get( 'net.ipv6' ), 1, 'net.ipv6 was updated';
|
||||
is $profile->get( 'no_network' ), 0, 'no_network was updated';
|
||||
is $profile->get( 'resolver.defaults.retry' ), 99, 'resolver.defaults.retry was updated';
|
||||
is $profile->get( 'resolver.defaults.retrans' ), 88, 'resolver.defaults.retrans was updated';
|
||||
is $profile->get( 'resolver.source4' ), '198.51.100.53', 'resolver.source4 was updated';
|
||||
is $profile->get( 'resolver.source6' ), '2001:db8::cafe', 'resolver.source6 was updated';
|
||||
eq_or_diff $profile->get( 'asn_db.style' ), 'ripe', 'asn_db.style was updated';
|
||||
eq_or_diff $profile->get( 'asn_db.sources' ), { ripe => ['asn3.example.com', 'asn4.example.com'] }, 'asn_db.sources was updated';
|
||||
eq_or_diff $profile->get( 'logfilter' ),
|
||||
{ Nameserver => { OTHER_TAG => [ { when => { apples => 1 }, set => 'INFO' } ] } }, 'logfilter was updated';
|
||||
eq_or_diff $profile->get( 'test_levels' ), { Nameserver => { OTHER_TAG => 'ERROR' } }, 'test_levels was updated';
|
||||
eq_or_diff $profile->get( 'test_cases' ), ['Zone02'], 'test_cases was updated';
|
||||
eq_or_diff $profile->get( 'cache' ), { redis => { server => '127.0.0.2:6379', expire => 7200 } },
|
||||
'cache was updated';
|
||||
};
|
||||
|
||||
subtest 'set() dies on attempts to unset properties' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
|
||||
for my $property ( Zonemaster::Engine::Profile->all_properties ) {
|
||||
throws_ok { $profile->set( $property, undef ); } qr/^.* can not be undef/, "dies on attempt to unset $property";
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'set() dies if the given property name is invalid' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'asn_db.style', 'cymru' );
|
||||
$profile->set( 'asn_db.sources', { cymru => ['asn1.example.com', 'asn2.example.com'] } );
|
||||
$profile->set( 'logfilter', { Zone => {} } );
|
||||
$profile->set( 'test_levels', { Zone => {} } );
|
||||
$profile->set( 'test_cases', ['Zone01'] );
|
||||
$profile->set( 'cache', { redis => { server => '127.0.0.1:6379' } } );
|
||||
|
||||
throws_ok { $profile->set( 'net', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for net';
|
||||
throws_ok { $profile->set( 'net.foobar', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for net.foobar';
|
||||
throws_ok { $profile->set( 'resolver', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for resolver';
|
||||
throws_ok { $profile->set( 'resolver.defaults', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for resolver.defaults';
|
||||
throws_ok { $profile->set( 'asn_db', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for asn_db';
|
||||
throws_ok { $profile->set( 'asn_db.fake', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for asn_db.fake';
|
||||
throws_ok { $profile->set( 'logfilter.Zone', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for logfilter.Zone';
|
||||
throws_ok { $profile->set( 'test_levels.Zone', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for test_levels.Zone';
|
||||
throws_ok { $profile->set( 'test_cases.Zone01', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for test_cases.Zone01';
|
||||
throws_ok { $profile->set( 'cache.redis', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for cache.redis';
|
||||
throws_ok { $profile->set( 'resolver.defaults.dnssec', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for resolver.defaults.dnssec';
|
||||
throws_ok { $profile->set( 'resolver.defaults.edns_size', 1 ) } qr/^.*Unknown property .*/, 'dies on attempt to set a value for resolver.defaults.edns_size';
|
||||
};
|
||||
|
||||
subtest 'set() dies on illegal value' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
|
||||
dies_ok { $profile->set( 'resolver.defaults.retry', 0 ); } 'checks lower bound of resolver.defaults.retry';
|
||||
dies_ok { $profile->set( 'resolver.defaults.retry', 256 ); } 'checks upper bound of resolver.defaults.retry';
|
||||
dies_ok { $profile->set( 'resolver.defaults.retry', 1.5 ); } 'checks type of resolver.defaults.retry';
|
||||
dies_ok { $profile->set( 'resolver.defaults.retrans', 0 ); } 'checks lower bound of resolver.defaults.retrans';
|
||||
dies_ok { $profile->set( 'resolver.defaults.retrans', 256 ); } 'checks upper bound of resolver.defaults.retrans';
|
||||
dies_ok { $profile->set( 'resolver.defaults.retrans', 1.5 ); } 'checks type of resolver.defaults.retrans';
|
||||
dies_ok { $profile->set( 'resolver.source4', 'example.com' ); } 'resolver.source4 rejects domain name string';
|
||||
dies_ok { $profile->set( 'resolver.source4', ['192.0.2.53'] ); } 'resolver.source4 rejects arrayref';
|
||||
dies_ok { $profile->set( 'resolver.source6', 'example.com' ); } 'resolver.source6 rejects domain name string';
|
||||
dies_ok { $profile->set( 'resolver.source6', ['2001:db8::42'] ); } 'resolver.source6 rejects arrayref';
|
||||
dies_ok { $profile->set( 'asn_db.style', ['noreply@example.com'] ); } 'checks type of asn_db.style';
|
||||
dies_ok { $profile->set( 'asn_db.sources', ['noreply@example.com'] ); } 'checks type of asn_db.sources';
|
||||
dies_ok { $profile->set( 'logfilter', [] ); } 'checks type of logfilter';
|
||||
dies_ok { $profile->set( 'test_levels', [] ); } 'checks type of test_levels';
|
||||
dies_ok { $profile->set( 'test_cases', {} ); } 'checks type of test_cases';
|
||||
dies_ok { $profile->set( 'cache', [] ); } 'checks type of cache';
|
||||
};
|
||||
|
||||
subtest 'set() accepts sentinel values' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
|
||||
$profile->set( 'resolver.source4', '' );
|
||||
is $profile->get( 'resolver.source4' ), '', 'resolver.source4 was updated';
|
||||
|
||||
$profile->set( 'resolver.source6', '' );
|
||||
is $profile->get( 'resolver.source6' ), '', 'resolver.source6 was updated';
|
||||
};
|
||||
|
||||
subtest 'set() uses standard truthiness rules for boolean properties' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
|
||||
subtest 'values considered false' => sub {
|
||||
$profile->set( 'no_network', 0 );
|
||||
ok !$profile->get( 'no_network' ), 'the number 0';
|
||||
|
||||
$profile->set( 'no_network', "" );
|
||||
ok !$profile->get( 'no_network' ), 'the empty string';
|
||||
|
||||
$profile->set( 'no_network', "0" );
|
||||
ok !$profile->get( 'no_network' ), 'the string that contains a single 0 digit';
|
||||
};
|
||||
|
||||
subtest 'values considered true' => sub {
|
||||
$profile->set( 'no_network', 1 );
|
||||
ok $profile->get( 'no_network' ), 'any non-0 number';
|
||||
|
||||
$profile->set( 'no_network', " " );
|
||||
ok $profile->get( 'no_network' ), 'the string with a space in it';
|
||||
|
||||
$profile->set( 'no_network', "00" );
|
||||
ok $profile->get( 'no_network' ), 'two or more 0 characters in a string';
|
||||
|
||||
$profile->set( 'no_network', "0\n" );
|
||||
ok $profile->get( 'no_network' ), 'a 0 followed by a newline';
|
||||
|
||||
$profile->set( 'no_network', "true" );
|
||||
ok $profile->get( 'no_network' ), 'the string "true"';
|
||||
|
||||
$profile->set( 'no_network', "false" );
|
||||
ok $profile->get( 'no_network' ), 'yes, even the string "false"';
|
||||
};
|
||||
};
|
||||
|
||||
subtest 'merge() with a profile with all properties unset' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
my $profile2 = Zonemaster::Engine::Profile->new;
|
||||
|
||||
$profile1->merge( $profile2 );
|
||||
|
||||
is $profile1->get( 'resolver.defaults.usevc' ), 1, 'keeps value of resolver.defaults.usevc';
|
||||
is $profile1->get( 'resolver.defaults.recurse' ), 1, 'keeps value of resolver.defaults.recurse';
|
||||
is $profile1->get( 'resolver.defaults.igntc' ), 0, 'keeps value of resolver.defaults.igntc';
|
||||
is $profile1->get( 'resolver.defaults.fallback' ), 1, 'keeps value of resolver.defaults.fallback';
|
||||
is $profile1->get( 'net.ipv4' ), 1, 'keeps value of net.ipv4';
|
||||
is $profile1->get( 'net.ipv6' ), 0, 'keeps value of net.ipv6';
|
||||
is $profile1->get( 'no_network' ), 1, 'keeps value of no_network';
|
||||
is $profile1->get( 'resolver.defaults.retry' ), 123, 'keeps value of resolver.defaults.retry';
|
||||
is $profile1->get( 'resolver.defaults.retrans' ), 234, 'keeps value of resolver.defaults.retrans';
|
||||
is $profile1->get( 'resolver.source4' ), '192.0.2.53', 'keeps value of resolver.source4';
|
||||
is $profile1->get( 'resolver.source6' ), '2001:db8::42', 'keeps value of resolver.source6';
|
||||
eq_or_diff $profile1->get( 'asn_db.style' ), 'cymru', 'keeps value of asn_db.style';
|
||||
eq_or_diff $profile1->get( 'asn_db.sources' ), { cymru => ['asn1.example.com', 'asn2.example.com'] }, 'keeps value of asn_db.sources';
|
||||
eq_or_diff $profile1->get( 'logfilter' ), { Zone => { TAG => [ { when => { bananas => 0 }, set => 'WARNING' } ] } },
|
||||
'keeps value of logfilter';
|
||||
eq_or_diff $profile1->get( 'test_levels' ), { Zone => { TAG => 'INFO' } }, 'keeps value of test_levels';
|
||||
eq_or_diff $profile1->get( 'test_cases' ), ['Zone01'], 'keeps value of test_cases';
|
||||
eq_or_diff $profile1->get( 'cache' ), { redis => { server => '127.0.0.1:6379', expire => 3600 } }, 'keeps value of cache';
|
||||
};
|
||||
|
||||
subtest 'merge() with a profile with all properties set' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
my $profile2 = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_2 );
|
||||
|
||||
$profile1->merge( $profile2 );
|
||||
|
||||
is $profile1->get( 'resolver.defaults.usevc' ), 0, 'updates resolver.defaults.usevc';
|
||||
is $profile1->get( 'resolver.defaults.recurse' ), 0, 'updates resolver.defaults.recurse';
|
||||
is $profile1->get( 'resolver.defaults.igntc' ), 1, 'updates resolver.defaults.igntc';
|
||||
is $profile1->get( 'resolver.defaults.fallback' ), 0, 'updates resolver.defaults.fallback';
|
||||
is $profile1->get( 'net.ipv4' ), 0, 'updates net.ipv4';
|
||||
is $profile1->get( 'net.ipv6' ), 1, 'updates net.ipv6';
|
||||
is $profile1->get( 'no_network' ), 0, 'updates no_network';
|
||||
is $profile1->get( 'resolver.defaults.retry' ), 99, 'updates resolver.defaults.retry';
|
||||
is $profile1->get( 'resolver.defaults.retrans' ), 88, 'updates resolver.defaults.retrans';
|
||||
is $profile1->get( 'resolver.source4' ), '198.51.100.53', 'updates resolver.source4';
|
||||
is $profile1->get( 'resolver.source6' ), '2001:db8::cafe', 'updates resolver.source6';
|
||||
eq_or_diff $profile1->get( 'asn_db.style' ), 'ripe', 'updates asn_db.style';
|
||||
eq_or_diff $profile1->get( 'asn_db.sources' ), { ripe => ['asn3.example.com', 'asn4.example.com'] }, 'updates asn_db.sources';
|
||||
eq_or_diff $profile1->get( 'logfilter' ),
|
||||
{ Nameserver => { OTHER_TAG => [ { when => { apples => 1 }, set => 'INFO' } ] } }, 'updates logfilter';
|
||||
eq_or_diff $profile1->get( 'test_levels' ), { Nameserver => { OTHER_TAG => 'ERROR' } }, 'updates test_levels';
|
||||
eq_or_diff $profile1->get( 'test_cases' ), ['Zone02'], 'updates test_cases';
|
||||
eq_or_diff $profile1->get( 'cache' ), { redis => { server => '127.0.0.2:6379', expire => 7200 } }, 'updates cache';
|
||||
};
|
||||
|
||||
subtest 'merge() does not update the other profile' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->from_json( $EXAMPLE_PROFILE_1 );
|
||||
my $profile2 = Zonemaster::Engine::Profile->new;
|
||||
|
||||
$profile1->merge( $profile2 );
|
||||
|
||||
is $profile2->get( 'resolver.defaults.usevc' ), undef, 'resolver.defaults.usevc was untouched in other';
|
||||
is $profile2->get( 'resolver.defaults.retrans' ), undef, 'resolver.defaults.retrans was untouched in other';
|
||||
is $profile2->get( 'resolver.defaults.recurse' ), undef, 'resolver.defaults.recurse was untouched in other';
|
||||
is $profile2->get( 'resolver.defaults.retry' ), undef, 'resolver.defaults.retry was untouched in other';
|
||||
is $profile2->get( 'resolver.defaults.igntc' ), undef, 'resolver.defaults.igntc was untouched in other';
|
||||
is $profile2->get( 'resolver.defaults.fallback' ), undef, 'resolver.defaults.fallback was untouched in other';
|
||||
is $profile2->get( 'resolver.source4' ), undef, 'resolver.source4 was untouched in other';
|
||||
is $profile2->get( 'resolver.source6' ), undef, 'resolver.source6 was untouched in other';
|
||||
is $profile2->get( 'net.ipv4' ), undef, 'net.ipv4 was untouched in other';
|
||||
is $profile2->get( 'net.ipv6' ), undef, 'net.ipv6 was untouched in other';
|
||||
is $profile2->get( 'no_network' ), undef, 'no_network was untouched in other';
|
||||
is $profile2->get( 'asn_db.style' ), undef, 'asn_db.style was untouched in other';
|
||||
is $profile2->get( 'asn_db.sources' ), undef, 'asn_db.sources was untouched in other';
|
||||
is $profile2->get( 'logfilter' ), undef, 'logfilter was untouched in other';
|
||||
is $profile2->get( 'test_levels' ), undef, 'test_levels was untouched in other';
|
||||
is $profile2->get( 'test_cases' ), undef, 'test_cases was untouched in other';
|
||||
is $profile2->get( 'cache' ), undef, 'cache was untouched in other';
|
||||
};
|
||||
|
||||
subtest 'to_json() serializes each property' => sub {
|
||||
subtest 'resolver.defaults.usevc' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.usevc', 1 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"usevc":true}}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.defaults.recurse' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.recurse', 1 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"recurse":true}}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.defaults.igntc' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.igntc', 0 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"igntc":false}}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.defaults.fallback' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.fallback', 0 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"fallback":false}}}' );
|
||||
};
|
||||
|
||||
subtest 'net.ipv4' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'net.ipv4', 1 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"net":{"ipv4":true}}' );
|
||||
};
|
||||
|
||||
subtest 'net.ipv6' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'net.ipv6', 0 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"net":{"ipv6":false}}' );
|
||||
};
|
||||
|
||||
subtest 'no_network' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'no_network', 1 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"no_network":true}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.defaults.retry' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.retry', 123 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"retry":123}}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.defaults.retrans' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.defaults.retrans', 234 );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"defaults":{"retrans":234}}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.source4' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.source4', '192.0.2.53' );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"source4":"192.0.2.53"}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.source6' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.source6', '2001:db8::42' );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"resolver":{"source6":"2001:db8::42"}}' );
|
||||
};
|
||||
|
||||
subtest 'resolver.source6 sentinel value' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'resolver.source6', '' );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( qq({"resolver":{"source6":""}}) );
|
||||
};
|
||||
|
||||
subtest 'asn_db.style' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'asn_db.style', 'cymru' );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"asn_db":{"style": "cymru"}}' );
|
||||
};
|
||||
|
||||
subtest 'asn_db.sources' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'asn_db.sources', { cymru => ['asn1.example.com','asn2.example.com'] } );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"asn_db":{"sources": {"cymru": ["asn1.example.com","asn2.example.com"]}}} ' );
|
||||
};
|
||||
|
||||
subtest 'test_cases' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'test_cases', ['Zone01'] );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"test_cases":["Zone01"]}' );
|
||||
};
|
||||
|
||||
subtest 'test_levels' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'test_levels', { Zone => { TAG => 'INFO' } } );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ), decode_json( '{"test_levels":{"Zone":{"TAG":"INFO"}}}' );
|
||||
};
|
||||
|
||||
subtest 'logfilter' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'logfilter', { Zone => { TAG => [ { when => { bananas => 0 }, set => 'WARNING' } ] } } );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ),
|
||||
decode_json( '{"logfilter":{"Zone":{"TAG":[{"when":{"bananas":0},"set":"WARNING"}]}}}' );
|
||||
};
|
||||
|
||||
subtest 'cache' => sub {
|
||||
my $profile = Zonemaster::Engine::Profile->new;
|
||||
$profile->set( 'cache', { redis => { server => '127.0.0.1:6379', expire => 3600 } } );
|
||||
|
||||
my $json = $profile->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json ),
|
||||
decode_json( '{"cache":{"redis":{"server":"127.0.0.1:6379","expire":3600}}}' );
|
||||
};
|
||||
};
|
||||
|
||||
subtest 'effective() is initially equivalent to default()' => sub {
|
||||
my $json0 = Zonemaster::Engine::Profile->default->to_json;
|
||||
|
||||
my $json1 = Zonemaster::Engine::Profile->effective->to_json;
|
||||
|
||||
eq_or_diff decode_json( $json1 ), decode_json( $json0 );
|
||||
};
|
||||
|
||||
subtest 'effective() returns the same profile every time' => sub {
|
||||
my $profile1 = Zonemaster::Engine::Profile->effective;
|
||||
$profile1->set( 'resolver.defaults.retry', 111 );
|
||||
|
||||
my $profile2 = Zonemaster::Engine::Profile->effective;
|
||||
$profile2->set( 'resolver.defaults.retry', 222 );
|
||||
|
||||
is $profile1->get( 'resolver.defaults.retry' ), 222;
|
||||
};
|
||||
|
||||
done_testing;
|
||||
Reference in New Issue
Block a user