tests: dnsexit2 Convert tests to table-driven
This makes the tests easier to read and extend.
This commit is contained in:
parent
6bb80cbdaa
commit
3b73350541
1 changed files with 151 additions and 131 deletions
|
@ -6,6 +6,9 @@ use ddclient::t::HTTPD;
|
|||
|
||||
httpd_required();
|
||||
|
||||
local $ddclient::globals{debug} = 1;
|
||||
local $ddclient::globals{verbose} = 1;
|
||||
|
||||
ddclient::load_json_support('dnsexit2');
|
||||
|
||||
httpd()->run(sub {
|
||||
|
@ -17,143 +20,160 @@ httpd()->run(sub {
|
|||
})]];
|
||||
});
|
||||
|
||||
local $ddclient::globals{verbose} = 1;
|
||||
|
||||
sub decode_and_sort_array {
|
||||
my ($data) = @_;
|
||||
if (!ref $data) {
|
||||
$data = decode_json($data);
|
||||
}
|
||||
@{$data->{update}} = sort { $a->{type} cmp $b->{type} } @{$data->{update}};
|
||||
return $data;
|
||||
sub cmp_update {
|
||||
my ($a, $b) = @_;
|
||||
return $a->{name} cmp $b->{name} || $a->{type} cmp $b->{type};
|
||||
}
|
||||
|
||||
subtest 'Testing nic_dnsexit2_update' => sub {
|
||||
httpd()->reset();
|
||||
local %ddclient::config = (
|
||||
'host.my.example.com' => {
|
||||
'usev4' => 'ipv4',
|
||||
'wantipv4' => '192.0.2.1',
|
||||
'usev6' => 'ipv6',
|
||||
'wantipv6' => '2001:db8::1',
|
||||
'protocol' => 'dnsexit2',
|
||||
'password' => 'mytestingpassword',
|
||||
'zone' => 'my.example.com',
|
||||
'server' => httpd()->endpoint(),
|
||||
'path' => '/update',
|
||||
'ttl' => 5
|
||||
});
|
||||
ddclient::nic_dnsexit2_update(undef, 'host.my.example.com');
|
||||
my @requests = httpd()->reset();
|
||||
is(scalar(@requests), 1, 'expected number of update requests');
|
||||
my $req = shift(@requests);
|
||||
is($req->method(), 'POST', 'Method is correct');
|
||||
is($req->uri()->as_string(), '/update', 'URI contains correct path');
|
||||
is($req->header('content-type'), 'application/json', 'Content-Type header is correct');
|
||||
is($req->header('accept'), 'application/json', 'Accept header is correct');
|
||||
my $got = decode_and_sort_array($req->content());
|
||||
my $want = decode_and_sort_array({
|
||||
'domain' => 'my.example.com',
|
||||
'apikey' => 'mytestingpassword',
|
||||
'update' => [
|
||||
sub sort_updates {
|
||||
my ($req) = @_;
|
||||
return {
|
||||
%$req,
|
||||
update => [sort({ cmp_update($a, $b); } @{$req->{update}})],
|
||||
};
|
||||
}
|
||||
|
||||
sub sort_reqs {
|
||||
my @reqs = map(sort_updates($_), @_);
|
||||
my @sorted = sort({
|
||||
my $ret = $a->{domain} cmp $b->{domain};
|
||||
$ret = @{$a->{update}} <=> @{$b->{update}} if !$ret;
|
||||
my $i = 0;
|
||||
while (!$ret && $i < @{$a->{update}} && $i < @{$b->{update}}) {
|
||||
$ret = cmp_update($a->{update}[$i], $b->{update}[$i]);
|
||||
}
|
||||
return $ret;
|
||||
} @reqs);
|
||||
return @sorted;
|
||||
}
|
||||
|
||||
my @test_cases = (
|
||||
{
|
||||
'type' => 'A',
|
||||
'name' => 'host',
|
||||
'content' => '192.0.2.1',
|
||||
'ttl' => 5,
|
||||
desc => 'both IPv4 and IPv6 are updated together',
|
||||
cfg => {
|
||||
'host.my.example.com' => {
|
||||
ttl => 5,
|
||||
wantipv4 => '192.0.2.1',
|
||||
wantipv6 => '2001:db8::1',
|
||||
zone => 'my.example.com',
|
||||
},
|
||||
},
|
||||
want => [{
|
||||
apikey => 'key',
|
||||
domain => 'my.example.com',
|
||||
update => [
|
||||
{
|
||||
content => '192.0.2.1',
|
||||
name => 'host',
|
||||
ttl => 5,
|
||||
type => 'A',
|
||||
},
|
||||
{
|
||||
'type' => 'AAAA',
|
||||
'name' => 'host',
|
||||
'content' => '2001:db8::1',
|
||||
'ttl' => 5,
|
||||
}
|
||||
]
|
||||
});
|
||||
is_deeply($got, $want, 'Data is correct');
|
||||
};
|
||||
|
||||
subtest 'Testing nic_dnsexit2_update without a zone set' => sub {
|
||||
httpd()->reset();
|
||||
local %ddclient::config = (
|
||||
'myhost.example.com' => {
|
||||
'usev4' => 'ipv4',
|
||||
'wantipv4' => '192.0.2.1',
|
||||
'protocol' => 'dnsexit2',
|
||||
'password' => 'anotherpassword',
|
||||
'server' => httpd()->endpoint(),
|
||||
'path' => '/update-alt',
|
||||
'ttl' => 10
|
||||
});
|
||||
ddclient::nic_dnsexit2_update(undef, 'myhost.example.com');
|
||||
my @requests = httpd()->reset();
|
||||
is(scalar(@requests), 1, 'expected number of update requests');
|
||||
my $req = shift(@requests);
|
||||
my $got = decode_and_sort_array($req->content());
|
||||
my $want = decode_and_sort_array({
|
||||
'domain' => 'myhost.example.com',
|
||||
'apikey' => 'anotherpassword',
|
||||
'update' => [
|
||||
content => '2001:db8::1',
|
||||
name => 'host',
|
||||
ttl => 5,
|
||||
type => 'AAAA',
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
'type' => 'A',
|
||||
'name' => '',
|
||||
'content' => '192.0.2.1',
|
||||
'ttl' => 10,
|
||||
}
|
||||
]
|
||||
});
|
||||
is_deeply($got, $want, 'Data is correct');
|
||||
};
|
||||
|
||||
subtest 'Testing nic_dnsexit2_update with two hostnames, one with a zone and one without' => sub {
|
||||
httpd()->reset();
|
||||
local %ddclient::config = (
|
||||
desc => 'zone defaults to host',
|
||||
cfg => {
|
||||
'host.my.example.com' => {
|
||||
ttl => 10,
|
||||
wantipv4 => '192.0.2.1',
|
||||
},
|
||||
},
|
||||
want => [{
|
||||
apikey => 'key',
|
||||
domain => 'host.my.example.com',
|
||||
update => [
|
||||
{
|
||||
content => '192.0.2.1',
|
||||
name => '',
|
||||
ttl => 10,
|
||||
type => 'A',
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
desc => 'two hosts, different zones',
|
||||
cfg => {
|
||||
'host1.example.com' => {
|
||||
'usev4' => 'ipv4',
|
||||
'wantipv4' => '192.0.2.1',
|
||||
'protocol' => 'dnsexit2',
|
||||
'password' => 'testingpassword',
|
||||
'server' => httpd()->endpoint(),
|
||||
'path' => '/update',
|
||||
'ttl' => 5
|
||||
ttl => 5,
|
||||
wantipv4 => '192.0.2.1',
|
||||
# 'zone' intentionally not set, so it will default to 'host1.example.com'.
|
||||
},
|
||||
'host2.example.com' => {
|
||||
'usev6' => 'ipv6',
|
||||
'wantipv6' => '2001:db8::1',
|
||||
'protocol' => 'dnsexit2',
|
||||
'password' => 'testingpassword',
|
||||
'server' => httpd()->endpoint(),
|
||||
'path' => '/update',
|
||||
'ttl' => 10,
|
||||
'zone' => 'example.com'
|
||||
}
|
||||
ttl => 10,
|
||||
wantipv6 => '2001:db8::1',
|
||||
zone => 'example.com',
|
||||
},
|
||||
},
|
||||
want => [
|
||||
{
|
||||
apikey => 'key',
|
||||
domain => 'host1.example.com',
|
||||
update => [
|
||||
{
|
||||
content => '192.0.2.1',
|
||||
name => '',
|
||||
ttl => 5,
|
||||
type => 'A',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
apikey => 'key',
|
||||
domain => 'example.com',
|
||||
update => [
|
||||
{
|
||||
content => '2001:db8::1',
|
||||
name => 'host2',
|
||||
ttl => 10,
|
||||
type => 'AAAA',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
ddclient::nic_dnsexit2_update(undef, 'host1.example.com', 'host2.example.com');
|
||||
my @requests = httpd()->reset();
|
||||
my @got = map(decode_and_sort_array($_->content()), @requests);
|
||||
my @want = (
|
||||
decode_and_sort_array({
|
||||
'domain' => 'host1.example.com',
|
||||
'apikey' => 'testingpassword',
|
||||
'update' => [{
|
||||
'type' => 'A',
|
||||
'name' => '',
|
||||
'content' => '192.0.2.1',
|
||||
'ttl' => 5,
|
||||
}],
|
||||
}),
|
||||
decode_and_sort_array({
|
||||
'domain' => 'example.com',
|
||||
'apikey' => 'testingpassword',
|
||||
'update' => [{
|
||||
'type' => 'AAAA',
|
||||
'name' => 'host2',
|
||||
'content' => '2001:db8::1',
|
||||
'ttl' => 10,
|
||||
}],
|
||||
}),
|
||||
);
|
||||
is_deeply(\@got, \@want, 'data is correct');
|
||||
|
||||
for my $tc (@test_cases) {
|
||||
subtest($tc->{desc} => sub {
|
||||
local $ddclient::_l = ddclient::pushlogctx($tc->{desc});
|
||||
local %ddclient::config = ();
|
||||
my @hosts = keys(%{$tc->{cfg}});
|
||||
for my $h (@hosts) {
|
||||
$ddclient::config{$h} = {
|
||||
password => 'key',
|
||||
path => '/update',
|
||||
server => httpd()->endpoint(),
|
||||
%{$tc->{cfg}{$h}},
|
||||
};
|
||||
}
|
||||
ddclient::nic_dnsexit2_update(undef, @hosts);
|
||||
my @requests = httpd()->reset();
|
||||
my @got;
|
||||
for (my $i = 0; $i < @requests; $i++) {
|
||||
subtest("request $i" => sub {
|
||||
my $req = $requests[$i];
|
||||
is($req->method(), 'POST', 'method is POST');
|
||||
is($req->uri()->as_string(), '/update', 'path is /update');
|
||||
is($req->header('content-type'), 'application/json', 'Content-Type is JSON');
|
||||
is($req->header('accept'), 'application/json', 'Accept is JSON');
|
||||
my $got = decode_json($req->content());
|
||||
is(ref($got), 'HASH', 'request content is a JSON object');
|
||||
is(ref($got->{update}), 'ARRAY', 'JSON object has array "update" property');
|
||||
push(@got, $got);
|
||||
});
|
||||
}
|
||||
@got = sort_reqs(@got);
|
||||
my @want = sort_reqs(@{$tc->{want}});
|
||||
is_deeply(\@got, \@want, 'request objects match');
|
||||
});
|
||||
}
|
||||
|
||||
done_testing();
|
||||
|
|
Loading…
Reference in a new issue