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