LCOV - code coverage report
Current view: top level - testutils - dnsmessage_test.h (source / functions) Hit Total Coverage
Test: report.info Lines: 47 48 97.9 %
Date: 2012-05-15 Functions: 9 10 90.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 175 380 46.1 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #ifndef __ISC_TESTUTILS_DNSMESSAGETEST_H
      16                 :            : #define __ISC_TESTUTILS_DNSMESSAGETEST_H 1
      17                 :            : 
      18                 :            : #include <algorithm>
      19                 :            : #include <functional>
      20                 :            : #include <iosfwd>
      21                 :            : #include <string>
      22                 :            : #include <vector>
      23                 :            : 
      24                 :            : #include <dns/message.h>
      25                 :            : #include <dns/name.h>
      26                 :            : #include <dns/masterload.h>
      27                 :            : #include <dns/rdataclass.h>
      28                 :            : #include <dns/rrclass.h>
      29                 :            : #include <dns/rrset.h>
      30                 :            : 
      31                 :            : #include <gtest/gtest.h>
      32                 :            : 
      33                 :            : namespace isc {
      34                 :            : namespace testutils {
      35                 :            : ///
      36                 :            : /// \name Header flags
      37                 :            : ///
      38                 :            : /// These are flags to indicate whether the corresponding flag bit of the
      39                 :            : /// DNS header is to be set in the test cases using \c headerCheck().
      40                 :            : /// (The flag values is irrelevant to their wire-format values).
      41                 :            : /// The meaning of the flags should be obvious from the variable names.
      42                 :            : //@{
      43                 :            : extern const unsigned int QR_FLAG;
      44                 :            : extern const unsigned int AA_FLAG;
      45                 :            : extern const unsigned int TC_FLAG;
      46                 :            : extern const unsigned int RD_FLAG;
      47                 :            : extern const unsigned int RA_FLAG;
      48                 :            : extern const unsigned int AD_FLAG;
      49                 :            : extern const unsigned int CD_FLAG;
      50                 :            : //@}
      51                 :            : 
      52                 :            : /// Set of unit tests to examine a DNS message header.
      53                 :            : ///
      54                 :            : /// This function takes a dns::Message object and performs various tests
      55                 :            : /// to confirm if the header fields of the message have the given specified
      56                 :            : /// value.  The \c message parameter is the Message object to be tested,
      57                 :            : /// and the remaining parameters specify the expected values of the fields.
      58                 :            : ///
      59                 :            : /// If all fields have the expected values the test will be considered
      60                 :            : /// successful.  Otherwise, some of the tests will indicate a failure, which
      61                 :            : /// will make the test case that calls this function fail.
      62                 :            : ///
      63                 :            : /// The meaning of the parameters should be obvious, but here are some notes
      64                 :            : /// that may not be so trivial:
      65                 :            : /// - \c opcode is an integer, not an \c dns::Opcode object.  This is because
      66                 :            : ///   we can easily iterate over all possible OPCODEs in a test.
      67                 :            : /// - \c flags is a bitmask so that we can specify a set of header flags
      68                 :            : ///   via a single parameter.  For example, when we expect the message has
      69                 :            : ///   QR and AA flags are on and others are off, we'd set this parameter to
      70                 :            : ///   <code>(QR_FLAG | AA_FLAG)</code>.
      71                 :            : ///
      72                 :            : /// \param message The DNS message to be tested.
      73                 :            : /// \param qid The expected QID
      74                 :            : /// \param rcode The expected RCODE
      75                 :            : /// \param opcodeval The code value of the expected OPCODE
      76                 :            : /// \param flags Bit flags specifying header flags that are expected to be set
      77                 :            : /// \param qdcount The expected value of QDCOUNT
      78                 :            : /// \param ancount The expected value of ANCOUNT
      79                 :            : /// \param nscount The expected value of NSCOUNT
      80                 :            : /// \param arcount The expected value of ARCOUNT
      81                 :            : void
      82                 :            : headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
      83                 :            :             const isc::dns::Rcode& rcode,
      84                 :            :             const uint16_t opcodeval, const unsigned int flags,
      85                 :            :             const unsigned int qdcount,
      86                 :            :             const unsigned int ancount, const unsigned int nscount,
      87                 :            :             const unsigned int arcount);
      88                 :            : 
      89                 :            : /// Set of unit tests to check equality of two RRsets
      90                 :            : ///
      91                 :            : /// This function takes two RRset objects and performs detailed tests to
      92                 :            : /// check if these two are "equal", where equal means:
      93                 :            : /// - The owner name, RR class, RR type and TTL are all equal.  Names are
      94                 :            : ///   compared in case-insensitive manner.
      95                 :            : /// - The number of RRs (more accurately RDATAs) is the same.
      96                 :            : /// - RDATAs are equal as a sequence.  That is, the first RDATA of
      97                 :            : ///   \c expected_rrset is equal to the first RDATA of \c actual_rrset,
      98                 :            : ///   the second RDATA of \c expected_rrset is equal to the second RDATA
      99                 :            : ///   of \c actual_rrset, and so on.  Two RDATAs are equal iff they have
     100                 :            : ///   the same DNSSEC sorting order as defined in RFC4034.
     101                 :            : ///
     102                 :            : /// Some of the tests will fail if any of the above isn't met.
     103                 :            : ///
     104                 :            : /// \note In future we may want to allow more flexible matching for RDATAs.
     105                 :            : /// For example, we may want to allow comparison as "sets", i.e., comparing
     106                 :            : /// RDATAs regardless of the ordering; we may also want to support suppressing
     107                 :            : /// duplicate RDATA.  For now, it's caller's responsibility to match the
     108                 :            : /// ordering (and any duplicates) between the expected and actual sets.
     109                 :            : /// Even if and when we support the flexible behavior, this "strict mode"
     110                 :            : /// will still be useful.
     111                 :            : ///
     112                 :            : /// \param expected_rrset The expected RRset
     113                 :            : /// \param actual_rrset The RRset to be tested
     114                 :            : void rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
     115                 :            :                 isc::dns::ConstRRsetPtr actual_rrset);
     116                 :            : 
     117                 :            : /// The definitions in this name space are not supposed to be used publicly,
     118                 :            : /// but are given here because they are used in templated functions.
     119                 :            : namespace detail {
     120                 :            : // Helper matching class used in rrsetsCheck().  Basically we only have to
     121                 :            : // check the equality of name, RR type and RR class, but for RRSIGs we need
     122                 :            : // special additional checks because they are essentially different if their
     123                 :            : // 'type covered' are different.  For simplicity, we only compare the types
     124                 :            : // of the first RRSIG RDATAs (and only check when they exist); if there's
     125                 :            : // further difference in the RDATA, the main comparison checks will detect it.
     126                 :       2556 : struct RRsetMatch : public std::unary_function<isc::dns::ConstRRsetPtr, bool> {
     127                 :        852 :     RRsetMatch(isc::dns::ConstRRsetPtr target) : target_(target) {}
     128                 :       1326 :     bool operator()(isc::dns::ConstRRsetPtr rrset) const {
     129   [ +  +  +  -  :       2670 :         if (rrset->getType() != target_->getType() ||
           +  + ][ +  + ]
     130                 :        672 :             rrset->getClass() != target_->getClass() ||
     131                 :        672 :             rrset->getName() != target_->getName()) {
     132                 :            :             return (false);
     133                 :            :         }
     134         [ +  + ]:        444 :         if (rrset->getType() != isc::dns::RRType::RRSIG()) {
     135                 :            :             return (true);
     136                 :            :         }
     137 [ +  - ][ -  + ]:        107 :         if (rrset->getRdataCount() == 0 || target_->getRdataCount() == 0) {
                 [ +  - ]
     138                 :            :             return (true);
     139                 :            :         }
     140                 :        107 :         isc::dns::RdataIteratorPtr rdit = rrset->getRdataIterator();
     141         [ +  - ]:        107 :         isc::dns::RdataIteratorPtr targetit = target_->getRdataIterator();
     142                 :            :         return (dynamic_cast<const isc::dns::rdata::generic::RRSIG&>(
     143 [ +  - ][ +  - ]:        107 :                     rdit->getCurrent()).typeCovered() ==
                 [ +  - ]
     144                 :            :                 dynamic_cast<const isc::dns::rdata::generic::RRSIG&>(
     145 [ +  - ][ +  - ]:        107 :                     targetit->getCurrent()).typeCovered());
                 [ +  - ]
     146                 :            :     }
     147                 :            :     const isc::dns::ConstRRsetPtr target_;
     148                 :            : };
     149                 :            : 
     150                 :            : // Helper callback functor for masterLoad() used in rrsetsCheck (stream
     151                 :            : // version)
     152                 :          0 : class RRsetInserter {
     153                 :            : public:
     154                 :            :     RRsetInserter(std::vector<isc::dns::ConstRRsetPtr>& rrsets) :
     155                 :        189 :         rrsets_(rrsets)
     156                 :            :     {}
     157                 :            :     void operator()(isc::dns::ConstRRsetPtr rrset) const {
     158         [ +  - ]:        408 :         rrsets_.push_back(rrset);
     159                 :            :     }
     160                 :            : private:
     161                 :            :     std::vector<isc::dns::ConstRRsetPtr>& rrsets_;
     162                 :            : };
     163                 :            : 
     164                 :            : class RRsetDumper {
     165                 :            : public:
     166                 :            :     RRsetDumper(std::string& output) :
     167                 :        281 :         output_(output)
     168                 :            :     {}
     169                 :        852 :     void operator()(isc::dns::ConstRRsetPtr rrset) {
     170         [ +  - ]:       1704 :         output_ += "  " + rrset->toText();
     171                 :        852 :     }
     172                 :            : private:
     173                 :            :     std::string& output_;
     174                 :            : };
     175                 :            : }
     176                 :            : 
     177                 :            : /// \brief A converter from a string to RRset.
     178                 :            : ///
     179                 :            : /// This is a convenient shortcut for tests that need to create an RRset
     180                 :            : /// from textual representation with a single call to a function.
     181                 :            : ///
     182                 :            : /// An RRset consisting of multiple RRs can be constructed, but only one
     183                 :            : /// RRset is allowed.  If the given string contains mixed types of RRs
     184                 :            : /// it throws an \c isc::Unexpected exception.
     185                 :            : ///
     186                 :            : /// \param text_rrset A complete textual representation of an RRset.
     187                 :            : ///  It must meets the assumption of the \c dns::masterLoad() function.
     188                 :            : /// \param rrclass The RR class of the RRset.  Note that \c text_rrset should
     189                 :            : /// contain the RR class, but it's needed for \c dns::masterLoad().
     190                 :            : /// \param origin The zone origin where the RR is expected to belong.  This
     191                 :            : /// parameter normally doesn't have to be specified, but for an SOA RR it
     192                 :            : /// must be set to its owner name, due to the internal check of
     193                 :            : /// \c dns::masterLoad().
     194                 :            : isc::dns::RRsetPtr textToRRset(const std::string& text_rrset,
     195                 :            :                                const isc::dns::RRClass& rrclass =
     196                 :         93 :                                isc::dns::RRClass::IN(),
     197                 :            :                                const isc::dns::Name& origin =
     198   [ +  -  +  -  :         94 :                                isc::dns::Name::ROOT_NAME());
           +  - ][ +  -  
             +  -  +  - ]
         [ +  - ][ +  -  
          +  -  +  -  +  
              - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  -  
             +  -  +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
           [ +  -  +  - ]
         [ +  - ][ +  -  
          +  -  +  -  +  
                -  +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ +  -  +  - ]
                 [ +  - ]
     199                 :            : 
     200                 :            : /// Set of unit tests to check if two sets of RRsets are identical.
     201                 :            : ///
     202                 :            : /// This templated function takes two sets of sequences, each defined by
     203                 :            : /// two input iterators pointing to \c ConstRRsetPtr (begin and end).
     204                 :            : /// This function compares these two sets of RRsets as "sets", and considers
     205                 :            : /// they are equal when:
     206                 :            : /// - The number of RRsets are the same.
     207                 :            : /// - For any RRset in one set, there is an equivalent RRset in the other set,
     208                 :            : ///   and vice versa, where the equivalence of two RRsets is tested using
     209                 :            : ///   \c rrsetCheck().
     210                 :            : ///
     211                 :            : /// Note that the sets of RRsets are compared as "sets", i.e, they don't have
     212                 :            : /// to be listed in the same order.
     213                 :            : ///
     214                 :            : /// The entire tests will pass if the two sets are identical.  Otherwise
     215                 :            : /// some of the tests will indicate a failure.
     216                 :            : ///
     217                 :            : /// \note
     218                 :            : /// - There is one known restriction: each set of RRsets must not have more
     219                 :            : ///   than one RRsets for the same name, RR type and RR class.  If this
     220                 :            : ///   condition isn't met, some of the tests will fail either against an
     221                 :            : ///   explicit duplication check or as a result of counter mismatch.
     222                 :            : /// - This function uses linear searches on the expected and actual sequences,
     223                 :            : ///   and won't be scalable for large input.  For the purpose of testing it
     224                 :            : ///   should be acceptable, but be aware of the size of test data.
     225                 :            : ///
     226                 :            : /// \param expected_begin The beginning of the expected set of RRsets
     227                 :            : /// \param expected_end The end of the expected set of RRsets
     228                 :            : /// \param actual_begin The beginning of the set of RRsets to be tested
     229                 :            : /// \param actual_end The end of the set of RRsets to be tested
     230                 :            : template<typename EXPECTED_ITERATOR, typename ACTUAL_ITERATOR>
     231                 :            : void
     232                 :        214 : rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
     233                 :            :             ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end)
     234                 :            : {
     235                 :        214 :     std::vector<isc::dns::ConstRRsetPtr> checked_rrsets; // for duplicate check
     236                 :        214 :     std::string expected_text, actual_text;
     237 [ +  - ][ +  - ]:        179 :     std::for_each(expected_begin, expected_end,
     238                 :            :                   detail::RRsetDumper(expected_text));
     239 [ +  - ][ +  - ]:        305 :     std::for_each(actual_begin, actual_end, detail::RRsetDumper(actual_text));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     240                 :        214 :     unsigned int rrset_matched = 0;
     241         [ +  - ]:        115 :     ACTUAL_ITERATOR it;
     242 [ +  + ][ +  + ]:        640 :     for (it = actual_begin; it != actual_end; ++it) {
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
            [ + ][ +  - ]
         [ +  - ][ +  + ]
     243                 :            :         // Make sure there's no duplicate RRset in actual (using a naive
     244                 :            :         // search).  Since the actual set is guaranteed to be unique, we can
     245                 :            :         // detect it if the expected data has a duplicate by the match/size
     246                 :            :         // checks at the end of the function.
     247                 :            :         // Note: we cannot use EXPECT_EQ for iterators
     248 [ +  + ][ +  + ]:       1125 :         EXPECT_TRUE(checked_rrsets.end() ==
         [ #  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
            [ # ][ +  - ]
         [ +  - ][ +  + ]
         [ #  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
            [ + ][ #  # ]
            [ +  - ][ + ]
         [ #  # ][ +  - ]
     249                 :            :                     std::find_if(checked_rrsets.begin(), checked_rrsets.end(),
     250                 :            :                                  detail::RRsetMatch(*it)));
     251 [ +  - ][ +  - ]:        714 :         checked_rrsets.push_back(*it);
                 [ +  - ]
     252                 :            : 
     253                 :            :         EXPECTED_ITERATOR found_rrset_it =
     254                 :            :             std::find_if(expected_begin, expected_end,
     255 [ +  - ][ +  - ]:        729 :                          detail::RRsetMatch(*it));
                 [ +  - ]
     256 [ +  - ][ +  - ]:        426 :         if (found_rrset_it != expected_end) {
     257 [ +  - ][ +  - ]:        714 :             rrsetCheck(*found_rrset_it, *it);
                 [ +  - ]
     258                 :        426 :             ++rrset_matched;
     259                 :            :         }
     260                 :            :     }
     261                 :            : 
     262                 :            :     {
     263 [ +  - ][ +  - ]:        764 :         SCOPED_TRACE(std::string("Comparing two RRsets:\n") +
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     264                 :            :                      "Actual:\n" + actual_text +
     265                 :            :                      "Expected:\n" + expected_text);
     266                 :            :         // make sure all expected RRsets are in actual sets
     267 [ -  + ][ #  # ]:        214 :         EXPECT_EQ(std::distance(expected_begin, expected_end), rrset_matched);
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
     268                 :            :         // make sure rrsets only contains expected RRsets
     269 [ +  + ][ #  + ]:        329 :         EXPECT_EQ(std::distance(expected_begin, expected_end),
         [ #  + ][ #  + ]
         [ #  - ][ +  - ]
         [ +  + ][ #  + ]
         [ #  + ][ #  + ]
         [ #  - ][ +  - ]
          [ - ][ - ][ - ]
            [ + ][ #  # ]
         [ #  # ][ #  # ]
         [ +  -  - ][ - ]
               [ - ][ + ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
     270                 :            :                   std::distance(actual_begin, actual_end));
     271                 :            :     }
     272                 :        214 : }
     273                 :            : 
     274                 :            : /// Set of unit tests to check if two sets of RRsets are identical using
     275                 :            : /// streamed expected data.
     276                 :            : ///
     277                 :            : /// This templated function takes a standard input stream that produces
     278                 :            : /// a sequence of textural RRs and compares the entire set of RRsets
     279                 :            : /// with the range of RRsets specified by two input iterators.
     280                 :            : ///
     281                 :            : /// This function is actually a convenient wrapper for the other version
     282                 :            : /// of function; it internally builds a standard vector of RRsets
     283                 :            : /// from the input stream and uses iterators of the vector as the expected
     284                 :            : /// input iterators for the backend function.
     285                 :            : /// Expected data in the form of input stream would be useful for testing
     286                 :            : /// as it can be easily hardcoded in test cases using string streams or
     287                 :            : /// given from a data source file.
     288                 :            : ///
     289                 :            : /// One common use case of this function is to test whether a particular
     290                 :            : /// section of a DNS message contains an expected set of RRsets.
     291                 :            : /// For example, when \c message is an \c dns::Message object, the following
     292                 :            : /// test code will check if the additional section of \c message contains
     293                 :            : /// the hardcoded two RRsets (2 A RRs and 1 AAAA RR) and only contains these
     294                 :            : /// RRsets:
     295                 :            : /// \code std::stringstream expected;
     296                 :            : /// expected << "foo.example.com. 3600 IN A 192.0.2.1\n"
     297                 :            : ///          << "foo.example.com. 3600 IN A 192.0.2.2\n"
     298                 :            : ///          << "foo.example.com. 7200 IN AAAA 2001:db8::1\n"
     299                 :            : /// rrsetsCheck(expected, message.beginSection(Message::SECTION_ADDITIONAL),
     300                 :            : ///                       message.endSection(Message::SECTION_ADDITIONAL));
     301                 :            : /// \endcode
     302                 :            : ///
     303                 :            : /// The input stream is parsed using the \c dns::masterLoad() function,
     304                 :            : /// and notes and restrictions of that function apply.
     305                 :            : /// This is also the reason why this function takes \c origin and \c rrclass
     306                 :            : /// parameters.  The default values of these parameters should just work
     307                 :            : /// in many cases for usual tests, but due to a validity check on the SOA RR
     308                 :            : /// in \c dns::masterLoad(), if the input stream contains an SOA RR, the
     309                 :            : /// \c origin parameter will have to be set to the owner name of the SOA
     310                 :            : /// explicitly.  Likewise, all RRsets must have the same RR class.
     311                 :            : /// (We may have to modify \c dns::masterLoad() so that it can
     312                 :            : /// have an option to be more generous about these points if it turns out
     313                 :            : /// to be too restrictive).
     314                 :            : ///
     315                 :            : /// \param expected_stream An input stream object that is to emit expected set
     316                 :            : /// of RRsets
     317                 :            : /// \param actual_begin The beginning of the set of RRsets to be tested
     318                 :            : /// \param actual_end The end of the set of RRsets to be tested
     319                 :            : /// \param origin A domain name that is a super domain of the owner name
     320                 :            : /// of all RRsets contained in the stream.
     321                 :            : /// \param rrclass The RR class of the RRsets contained in the stream.
     322                 :            : template<typename ACTUAL_ITERATOR>
     323                 :            : void
     324                 :        182 : rrsetsCheck(std::istream& expected_stream,
     325                 :            :             ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end,
     326                 :            :             const isc::dns::Name& origin = isc::dns::Name::ROOT_NAME(),
     327                 :            :             const isc::dns::RRClass& rrclass = isc::dns::RRClass::IN())
     328                 :            : {
     329         [ +  - ]:        189 :     std::vector<isc::dns::ConstRRsetPtr> expected;
     330 [ +  + ][ +  + ]:        189 :     isc::dns::masterLoad(expected_stream, origin, rrclass,
               [ - ][ - ]
         [ +  - ][ +  - ]
     331                 :            :                          detail::RRsetInserter(expected));
     332 [ +  - ][ +  - ]:        189 :     rrsetsCheck(expected.begin(), expected.end(), actual_begin, actual_end);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     333                 :        182 : }
     334                 :            : 
     335                 :            : /// Set of unit tests to check if two sets of RRsets are identical using
     336                 :            : /// expected data as string.
     337                 :            : ///
     338                 :            : /// This function is a wrapper for the input stream version:
     339                 :            : /// \c rrsetsCheck(std::istream&, ACTUAL_ITERATOR, ACTUAL_ITERATOR, const isc::dns::Name&, const isc::dns::RRClass&)(),
     340                 :            : /// and takes a string object instead of a stream.
     341                 :            : /// While the stream version is more generic, this version would be more
     342                 :            : /// convenient for tests using hardcoded expected data.  Using this version,
     343                 :            : /// the example test case shown for the stream version would look as follows:
     344                 :            : /// \code
     345                 :            : /// rrsetsCheck("foo.example.com. 3600 IN A 192.0.2.1\n"
     346                 :            : ///             "foo.example.com. 3600 IN A 192.0.2.2\n"
     347                 :            : ///             "foo.example.com. 7200 IN AAAA 2001:db8::1\n",
     348                 :            : ///             message.beginSection(Message::SECTION_ADDITIONAL),
     349                 :            : ///             message.endSection(Message::SECTION_ADDITIONAL));
     350                 :            : /// \endcode
     351                 :            : ///
     352                 :            : /// The semantics of parameters is the same as that of the stream version
     353                 :            : /// except that \c expected is a string of expected sets of RRsets.
     354                 :            : template<typename ACTUAL_ITERATOR>
     355                 :            : void
     356                 :        189 : rrsetsCheck(const std::string& expected,
     357                 :            :             ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end,
     358                 :            :             const isc::dns::Name& origin = isc::dns::Name::ROOT_NAME(),
     359                 :            :             const isc::dns::RRClass& rrclass = isc::dns::RRClass::IN())
     360                 :            : {
     361                 :        378 :     std::stringstream expected_stream(expected);
     362 [ +  - ][ +  - ]:        182 :     rrsetsCheck(expected_stream, actual_begin, actual_end, origin,
         [ +  - ][ +  - ]
                 [ +  - ]
     363                 :            :                 rrclass);
     364                 :        189 : }
     365                 :            : 
     366                 :            : } // end of namespace testutils
     367                 :            : } // end of namespace isc
     368                 :            : #endif  // __ISC_TESTUTILS_DNSMESSAGETEST_H
     369                 :            : 
     370                 :            : // Local Variables:
     371                 :            : // mode: c++
     372                 :            : // End:

Generated by: LCOV version 1.9