benchmark_util.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (C) 2010 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. // $Id$
  15. #ifndef __BENCHMARK_UTIL_H
  16. #define __BENCHMARK_UTIL_H 1
  17. /// \file
  18. /// Utilities to help write benchmark cases.
  19. ///
  20. /// The initial version of this library only contains utilities for very
  21. /// specific benchmark cases, that is, building DNS query data.
  22. /// It's not clear if we have more utilities including scenario-independent
  23. /// ones in future, but we have them here for now.
  24. /// If we find we only need utilities specific to individual benchmark
  25. /// scenarios, we may move them to more specific places.
  26. /// For example, the query generator may go to benchmarks for DNS server
  27. /// implementations.
  28. #include <istream>
  29. #include <vector>
  30. #include <exceptions/exceptions.h>
  31. namespace isc {
  32. namespace dns {
  33. class RRClass;
  34. }
  35. namespace bench {
  36. /// \brief An exception that is thrown if an error occurs within the benchmark
  37. /// module.
  38. class BenchMarkError : public Exception {
  39. public:
  40. BenchMarkError(const char* file, size_t line, const char* what) :
  41. isc::Exception(file, line, what) {}
  42. };
  43. /// \brief A convenient shortcut type to represent a sequence of query %data
  44. /// in wire format.
  45. typedef std::vector<std::vector<unsigned char> > BenchQueries;
  46. /// \brief Load query %data from a file into a vector.
  47. ///
  48. /// The format of the %data file is a sequence of tuples of query name and
  49. /// query type. Each line specifies a single tuple. Empty lines and
  50. /// lines beginning with a pound sign (#) are considered comments and will
  51. /// be ignored. Example:
  52. /// \code
  53. /// # This is a comment line, will be ignored. same for the next line.
  54. ///
  55. /// www.example.com AAAA
  56. /// ftp.example.org NS
  57. /// text.dot.example TXT \endcode
  58. ///
  59. /// For those who are familiar with BIND 9's queryperf tool, this is the
  60. /// same as the simplest form of the input file for queryperf.
  61. ///
  62. /// For each tuple, this function builds a wire-format non recursive DNS
  63. /// query message, and appends it to the given vector in a form of
  64. /// a vector of <code>unsigned char</code>.
  65. ///
  66. /// The resulting vector can be used, e.g., for benchmarking query processing
  67. /// code without involving disk access or network I/O.
  68. /// It would be handier than existing tool such as queryperf and can help
  69. /// measure the "bare" (or the best possible) performance of the query
  70. /// processing itself.
  71. ///
  72. /// If this function fails to open the specified file to read the %data,
  73. /// an exception of class \c BenchMarkError will be thrown.
  74. /// If it fails to recognize an input line either as a comment or as
  75. /// a tuple of strings, an exception of class \c BenchMarkError will be
  76. /// thrown.
  77. ///
  78. /// By default, this function does not require the strings be a valid
  79. /// domain name or a valid textual representation of an RR type.
  80. /// This is because the input %data may be built from a packet dump of
  81. /// real query samples without validation, which may contain bogus values.
  82. /// It would make more sense to just ignore the bogus %data than filter
  83. /// the sample beforehand.
  84. /// This behavior can be changed by setting the \c strict argument to
  85. /// \c true, in which case if this function fails to parse the query name
  86. /// or the type, it will throw an exception of class \c BenchMarkError.
  87. ///
  88. /// If memory allocation fails during the processing, a corresponding standard
  89. /// exception will be thrown.
  90. ///
  91. /// This function only offers the basic exception guarantee. That is, if
  92. /// exception is thrown from this function, it is not guaranteed that
  93. /// \c queries keeps the content before this function is called.
  94. /// It is not so difficult to offer a stronger exception guarantee, but
  95. /// since this function is used in a limited usage, mainly for testing
  96. /// purposes, its benefit wouldn't outweigh the implementation complexity.
  97. ///
  98. /// \param input_file A character string specifying the %data file name.
  99. /// \param queries A vector wherein the query %data is to be stored.
  100. /// \param qclass The RR class of the resulting queries. The same RR class
  101. /// is used for all queries.
  102. /// \param strict If \c true, apply stricter validation on the query name and
  103. /// query RR types; otherwise invalid inputs will be ignored.
  104. void loadQueryData(const char* input_file, BenchQueries& queries,
  105. const isc::dns::RRClass& qclass, const bool strict = false);
  106. /// \brief Load query %data from an input stream into a vector.
  107. ///
  108. /// This version of function is same as
  109. /// loadQueryData(const char*, BenchQueries&, const isc::dns::RRClass&, const bool)
  110. /// except it reads the input query sequence from a specified input stream.
  111. ///
  112. /// This version will be used for a smaller scale test where query %data is
  113. /// hardcoded in the benchmark source code. For example, we could build
  114. /// a sequence of wire-format queries via the following code:
  115. /// \code
  116. /// vector<QueryParam> queries;
  117. /// stringstream qstream;
  118. /// qstream << "www.example.com AAAA" << endl
  119. /// << "ftp.example.org NS" << endl
  120. /// << "text.dot.example TXT" << endl;
  121. /// loadQueryData(qstream, queries, RRClass::IN()); \endcode
  122. /// This will result in the same sequence of queries as the example using
  123. /// a %data file shown in the other version of the function.
  124. ///
  125. /// \param input An input stream object that is to emit the query sequence.
  126. /// \param queries A vector wherein the query %data is to be stored.
  127. /// \param qclass The RR class of the resulting queries. The same RR class
  128. /// is used for all queries.
  129. /// \param strict If \c true, apply stricter validation on the query name and
  130. /// query RR types; otherwise invalid inputs will be ignored.
  131. void loadQueryData(std::istream& input, BenchQueries& queries,
  132. const isc::dns::RRClass& qclass, const bool strict = false);
  133. }
  134. }
  135. #endif // __BENCHMARK_UTIL_H
  136. // Local Variables:
  137. // mode: c++
  138. // End: