NAME
   Test::DNS - Test DNS queries and zone configuration

VERSION
   version 0.13

SYNOPSIS
   This module helps you write tests for DNS queries. You could test your
   domain configuration in the world or on a specific DNS server, for
   example.

       use Test::DNS;
       use Test::More tests => 4;

       my $dns = Test::DNS->new();

       $dns->is_ptr( '1.2.3.4' => 'single.ptr.record.com' );
       $dns->is_ptr( '1.2.3.4' => [ 'one.ptr.record.com', 'two.ptr.record.com' ] );
       $dns->is_ns( 'google.com' => [ map { "ns$_.google.com" } 1 .. 4 ] );
       $dns->is_a( 'ns1.google.com' => '216.239.32.10' );

       ...

DESCRIPTION
   Test::DNS allows you to run tests which translate as DNS queries. It's
   simple to use and abstracts all the difficult query checks from you. It
   has a built-in tests naming scheme so you don't really have to name your
   tests (as shown in all the examples) even though it supports the option.

       use Test::DNS;
       use Test::More tests => 1;

       my $dns = Test::DNS->new( nameservers => [ 'my.dns.server' ] );
       $dns->is_ptr( '1.1.1.1' => 'my_new.mail.server' );

   That was a complete test script that will fetch the PTR (if there is
   one), warns if it's missing one (an option you can remove via the
   *warnings* attribute) and checks against the domain you gave. You could
   also give for each test an arrayref of expected values. That's useful if
   you want to check multiple values. For example:

       use Test::DNS;
       use Test::More tests => 1;

       my $dns = Test::DNS->new();
       $dns->is_ns( 'my.domain' => [ 'ns1.my.domain', 'ns2.my.domain' ] );
       # or
       $dns->is_ns( 'my.domain' => [ map { "ns$_.my.domain" } 1 .. 5 ] );

   You can set the *follow_cname* option if your PTR returns a CNAME
   instead of an A record and you want to test the A record instead of the
   CNAME. This happened to me at least twice and fumbled my tests. I was
   expecting an A record, but got a CNAME to an A record. This is obviously
   legal DNS practices, so using the *follow_cname* attribute listed below,
   the test went with flying colors. This is a recursive CNAME to A record
   function so you could handle multiple CNAME chaining if one has such an
   odd case.

   New in version 0.04 is the option to give a hashref as the testing
   values (not including a test name as well), which makes things much
   easier to test if you want to run multiple tests and don't want to write
   multiple lines. This helps connect Test::DNS with freshly-parsed data
   (YAML/JSON/XML/etc.).

       use Test::DNS;
       use YAML 'LoadFile';
       use Test::More tests => 2;

       my $dns = Test::DNS->new();
       # running two DNS tests in one command!
       $dns->is_ns( {
           'first.domain'  => [ map { "ns$_.first.domain"  } 1 .. 4 ],
           'second.domain' => [ map { "ns$_.second.domain" } 5, 6   ],
       } );

       my $tests = LoadFile('tests.yaml');
       $dns->is_a( $tests, delete $tests->{'name'} ); # $tests is a hashref

EXPORT
   This module is completely Object Oriented, nothing is exported.

ATTRIBUTES
 nameservers($arrayref)
   Same as in Net::DNS. Sets the nameservers, accepts an arrayref.

       $dns->nameservers( [ 'IP1', 'DOMAIN' ] );

 warnings($boolean)
   Do you want to output warnings from the module (in valid TAP), such as
   when a record doesn't a query result or incorrect types?

   This helps avoid common misconfigurations. You should probably keep it,
   but if it bugs you, you can stop it using:

       $dns->warnings(0);

   Default: 1 (on).

 follow_cname($boolean)
   When fetching an A record of a domain, it may resolve to a CNAME instead
   of an A record. That would result in a false-negative of sorts, in which
   you say "well, yes, I meant the A record the CNAME record points to" but
   Test::DNS doesn't know that.

   If you want want Test::DNS to follow every CNAME recursively till it
   reaches the actual A record and compare that A record, use this option.

       $dns->follow_cname(1);

   Default: 0 (off).

SUBROUTINES/METHODS
 is_a( $domain, $ips, [$test_name] )
   Check the A record resolving of domain or subdomain.

   $ip can be an arrayref.

   $test_name is not mandatory.

       $dns->is_a( 'domain' => 'IP' );

       $dns->is_a( 'domain', [ 'IP1', 'IP2' ] );

 is_ns( $domain, $ips, [$test_name] )
   Check the NS record resolving of a domain or subdomain.

   $ip can be an arrayref.

   $test_name is not mandatory.

       $dns->is_ns( 'domain' => 'IP' );

       $dns->is_ns( 'domain', [ 'IP1', 'IP2' ] );

 is_ptr( $ip, $domains, [$test_name] )
   Check the PTR records of an IP.

   $domains can be an arrayref.

   $test_name is not mandatory.

       $dns->is_ptr( 'IP' => 'ptr.records.domain' );

       $dns->is_ptr( 'IP', [ 'first.ptr.domain', 'second.ptr.domain' ] );

 is_mx( $domain, $domains, [$test_name] )
   Check the MX records of a domain.

   $domains can be an arrayref.

   $test_name is not mandatory.

       $dns->is_mx( 'domain' => 'mailer.domain' );

       $dns->is_ptr( 'domain', [ 'mailer1.domain', 'mailer2.domain' ] );

 is_cname( $domain, $domains, [$test_name] )
   Check the CNAME records of a domain.

   $domains can be an arrayref.

   $test_name is not mandatory.

       $dns->is_cname( 'domain' => 'sub.domain' );

       $dns->is_cname( 'domain', [ 'sub1.domain', 'sub2.domain' ] );

 is_txt( $domain, $txt, [$test_name] )
   Check the TXT records of a domain.

   $txt can be an arrayref.

   $test_name is not mandatory.

       $dns->is_txt( 'domain' => 'v=spf1 -all' );

       $dns->is_txt( 'domain', [ 'sub1.domain', 'sub2.domain' ] );

 is_record( $type, $input, $expected, [$test_name] )
   The general function all the other is_* functions run.

   $type is the record type (CNAME, A, NS, PTR, MX, etc.).

   $input is the domain or IP you're testing.

   $expected can be an arrayref.

   $test_name is not mandatory.

       $dns->is_record( 'CNAME', 'domain', 'sub.domain', 'test_name' );

 BUILD
   Moose builder method. Do not call it or override it. :)

HASH FORMAT
   The hash format option (since version 0.04) allows you to run the tests
   using a single hashref with an optional parameter for the test_name. The
   count is no longer 1 (as it is with single tests), but each key/value
   pair represents a test case.

       # these are 2 tests
       $dns->is_ns( {
           'first.domain'  => [ map { "ns$_.first.domain"  } 1 .. 4 ],
           'second.domain' => [ map { "ns$_.second.domain" } 5, 6   ],
       } );

       # number of tests: keys %{$tests}, test name: $tests->{'name'}
       $dns->is_a( $tests, delete $tests->{'name'} ); # $tests is a hashref

DEPENDENCIES
   Moose

   Net::DNS

   Test::Deep

   Set::Object

AUTHOR
   Sawyer X, "<xsawyerx at cpan.org>"

BUGS
   Please report any bugs or feature requests to "bug-test-dns at
   rt.cpan.org", or through the web interface at
   <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-DNS>. I will be
   notified, and then you'll automatically be notified of progress on your
   bug as I make changes.

SUPPORT
   You can find documentation for this module with the perldoc command.

       perldoc Test::DNS

   You can also look for information at:

   *   Github

       <http://github.com/xsawyerx/test-dns>

   *   RT: CPAN's request tracker

       <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-DNS>

   *   AnnoCPAN: Annotated CPAN documentation

       <http://annocpan.org/dist/Test-DNS>

   *   CPAN Ratings

       <http://cpanratings.perl.org/d/Test-DNS>

   *   Search CPAN

       <http://search.cpan.org/dist/Test-DNS/>

ACKNOWLEDGEMENTS
LICENSE AND COPYRIGHT
   Copyright 2010 Sawyer X.

   This program is free software; you can redistribute it and/or modify it
   under the terms of either: the GNU General Public License as published
   by the Free Software Foundation; or the Artistic License.

   See http://dev.perl.org/licenses/ for more information.

AUTHOR
     Sawyer X <[email protected]>

COPYRIGHT AND LICENSE
   This software is copyright (c) 2011 by Sawyer X.

   This is free software; you can redistribute it and/or modify it under
   the same terms as the Perl 5 programming language system itself.