Browse Source

added documentation for new test functions

JINMEI Tatuya 14 years ago
parent
commit
21e8607873
2 changed files with 109 additions and 16 deletions
  1. 1 1
      doc/Doxyfile
  2. 108 15
      src/lib/testutils/dnsmessage_test.h

+ 1 - 1
doc/Doxyfile

@@ -568,7 +568,7 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas
+INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas ../src/lib/testutils
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

+ 108 - 15
src/lib/testutils/dnsmessage_test.h

@@ -45,11 +45,38 @@ headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
             const unsigned int ancount, const unsigned int nscount,
             const unsigned int arcount);
 
+/// Set of unit tests to check equality of two RRsets
+///
+/// This function takes two RRset objects and performs detailed tests to
+/// check if these two are "equal", where equal means:
+/// - The owner name, RR class, RR type and TTL are all equal.  Names are
+///   compared in case-insensitive manner.
+/// - The number of RRs (more accurately RDATAs) is the same.
+/// - RDATAs are equal as a sequence.  That is, the first RDATA of
+///   \c expected_rrset is equal to the first RDATA of \c actual_rrset,
+///   the second RDATA of \c expected_rrset is equal to the second RDATA
+///   of \c actual_rrset, and so on.  Two RDATAs are equal iff they have
+///   the same DNSSEC sorting order as defined in RFC4034.
+///
+/// Some of the tests will fail if any of the above isn't met.
+///
+/// \note In future we may want to allow more flexible matching for RDATAs.
+/// For example, we may want to allow comparison as "sets", i.e., comparing
+/// RDATAs regardless of the ordering; we may also want to support suppressing
+/// duplicate RDATA.  For now, it's caller's responsibility to match the
+/// ordering (and any duplicates) between the expected and actual sets.
+/// Even if and when we support the flexible behavior, this "strict mode"
+/// will still be useful.
+///
+/// \param expected_rrset The expected RRset
+/// \param actual_rrset The RRset to be tested
 void rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
-                isc::dns::ConstRRsetPtr rrset);
+                isc::dns::ConstRRsetPtr actual_rrset);
 
+/// The definitions in this name space are not supposed to be used publicly,
+/// but are given here because they are used in templated functions.
 namespace detail {
-// Helper matching class
+// Helper matching class used in rrsetsCheck()
 struct RRsetMatch : public std::unary_function<isc::dns::ConstRRsetPtr, bool> {
     RRsetMatch(isc::dns::ConstRRsetPtr target) : target_(target) {}
     bool operator()(isc::dns::ConstRRsetPtr rrset) const {
@@ -60,6 +87,8 @@ struct RRsetMatch : public std::unary_function<isc::dns::ConstRRsetPtr, bool> {
     const isc::dns::ConstRRsetPtr target_;
 };
 
+// Helper callback functor for masterLoad() used in rrsetsCheck (stream
+// version)
 class RRsetInserter {
 public:
     RRsetInserter(std::vector<isc::dns::ConstRRsetPtr>& rrsets) :
@@ -73,6 +102,31 @@ private:
 };
 }
 
+/// Set of unit tests to check if two sets of RRsets are identical.
+///
+/// This templated function takes two sets of sequences, each defined by
+/// two input iterators pointing to \c ConstRRsetPtr (begin and end).
+/// This function compares these two sets of RRsets as "sets", and considers
+/// they are equal when:
+/// - The number of RRsets are the same.
+/// - For any RRset in one set, there is an equivalent RRset in the other set,
+///   and vice versa, where the equivalence of two RRsets is tested using
+///   \c rrsetCheck().
+///
+/// Note that the sets of RRsets are compared as "sets", i.e, they don't have
+/// to be listed in the same order.
+/// There is one known restriction: each set of RRsets must not have more
+/// then one RRsets for the same name, RR type and RR class.  If this
+/// condition isn't met, this function will be confused and produce
+/// meaningless results.
+///
+/// The entire tests will pass if the two sets are identical.  Otherwise
+/// some of the tests will indicate a failure.
+///
+/// \param expected_begin The beginning of the expected set of RRsets
+/// \param expected_end The end of the expected set of RRsets
+/// \param actual_begin The beginning of the set of RRsets to be tested
+/// \param actual_end The end of the set of RRsets to be tested
 template<typename EXPECTED_ITERATOR, typename ACTUAL_ITERATOR>
 void
 rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
@@ -82,7 +136,7 @@ rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
     unsigned int rrset_count = 0;
     ACTUAL_ITERATOR it;
     for (it = actual_begin; it != actual_end; ++it) {
-        std::vector<isc::dns::ConstRRsetPtr>::const_iterator found_rrset_it =
+        EXPECTED_ITERATOR found_rrset_it =
             find_if(expected_begin, expected_end, detail::RRsetMatch(*it));
         if (found_rrset_it != expected_end) {
             rrsetCheck(*found_rrset_it, *it);
@@ -91,21 +145,60 @@ rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
         ++rrset_count;
     }
 
-    // make sure all expected RRsets are in rrsets
-    EXPECT_EQ(distance(expected_begin, expected_end), rrset_matched);
+    // make sure all expected RRsets are in actual sets
+    EXPECT_EQ(std::distance(expected_begin, expected_end), rrset_matched);
     // make sure rrsets only contains expected RRsets
-    EXPECT_EQ(distance(expected_begin, expected_end), rrset_count);
-}
-
-template <typename EXPECTED_CONTAINER, typename ACTUAL_CONTAINER>
-void
-rrsetsCheck(EXPECTED_CONTAINER& expected_rrsets,
-            ACTUAL_CONTAINER& actual_rrsets)
-{
-    rrsetsCheck(expected_rrsets.begin(), expected_rrsets.end(),
-                actual_rrsets.begin(), actual_rrsets.end());
+    EXPECT_EQ(std::distance(expected_begin, expected_end), rrset_count);
 }
 
+/// Set of unit tests to check if two sets of RRsets are identical using
+/// streamed expected data.
+///
+/// This templated function takes a standard input stream that produces
+/// a sequence of textural RRs and compares the entire set of RRsets
+/// with the range of RRsets specified by two input iterators.
+///
+/// This function is actually a convenient wrapper for the other version
+/// of function; it internally builds a standard vector of RRsets
+/// from the input stream and uses iterators of the vector as the expected
+/// input iterators for the backend function.
+/// Expected data in the form of input stream would be useful for testing
+/// as it can be easily hardcoded in test cases using string streams or
+/// given from a data source file.
+///
+/// One common use case of this function is to test whether a particular
+/// section of a DNS message contains an expected set of RRsets.
+/// For example, when \c message is an \c dns::Message object, the following
+/// test code will check if the additional section of \c message contains
+/// the hardcoded two RRsets (2 A RRs and 1 AAAA RR) and only contains these
+/// RRsets:
+/// \code std::stringstream expected;
+/// expected << "foo.example.com. 3600 IN A 192.0.2.1\n"
+///          << "foo.example.com. 3600 IN A 192.0.2.2\n"
+///          << "foo.example.com. 7200 IN AAAA 2001:db8::1\n"
+/// rrsetsCheck(expected, message.beginSection(Message::SECTION_ADDITIONAL),
+///                       message.endSection(Message::SECTION_ADDITIONAL));
+/// \endcode
+///
+/// The input stream is parsed using the \c dns::masterLoad() function,
+/// and notes and restrictions of that function apply.
+/// This is also the reason why this function takes \c origin and \c rrclass
+/// parameters.  The default values of these parameters should just work
+/// in many cases for usual tests, but due to a validity check on the SOA RR
+/// in \c dns::masterLoad(), if the input stream contains an SOA RR, the
+/// \c origin parameter will have to be set to the owner name of the SOA
+/// explicitly.  Likewise, all RRsets must have the same RR class.
+/// (We may have to modify \c dns::masterLoad() so that it can
+/// have an option to be more generous about these points if it turns out
+/// to be too restrictive).
+///
+/// \param expected_stream An input stream object that is to emit expected set
+/// of RRsets
+/// \param actual_begin The beginning of the set of RRsets to be tested
+/// \param actual_end The end of the set of RRsets to be tested
+/// \param origin A domain name that is a super domain of the owner name
+/// of all RRsets contained in the stream.
+/// \param rrclass The RR class of the RRsets contained in the stream.
 template<typename ACTUAL_ITERATOR>
 void
 rrsetsCheck(std::istream& expected_stream,