unittest_util.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright (C) 2009 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. #include <config.h>
  15. #include <iostream>
  16. #include <fstream>
  17. #include <sstream>
  18. #include <stdexcept>
  19. #include <vector>
  20. #include <string>
  21. #include <gtest/gtest.h>
  22. #include <dns/rcode.h>
  23. #include <dns/name.h>
  24. #include <dns/message.h>
  25. #include <dns/tests/unittest_util.h>
  26. using namespace std;
  27. using namespace isc::dns;
  28. using isc::UnitTestUtil;
  29. namespace {
  30. class UnitTestUtilConfig {
  31. private:
  32. // This is a singleton object and cannot be constructed explicitly.
  33. UnitTestUtilConfig() {}
  34. UnitTestUtilConfig(const UnitTestUtilConfig& source);
  35. ~UnitTestUtilConfig() {}
  36. public:
  37. /// Return a singleton unit test configuration object. On first invocation
  38. /// one will be constructed.
  39. static UnitTestUtilConfig& getConfig();
  40. /// A list of paths to wire data files.
  41. /// \c UnitTestUtil::readWireData() (first version)
  42. /// will search the directories in this list for the specified data file.
  43. std::vector<string> data_paths_;
  44. };
  45. UnitTestUtilConfig&
  46. UnitTestUtilConfig::getConfig() {
  47. static UnitTestUtilConfig config;
  48. return (config);
  49. }
  50. }
  51. void
  52. UnitTestUtil::readWireData(const char* datafile, vector<unsigned char>& data) {
  53. ifstream ifs;
  54. const UnitTestUtilConfig& config = UnitTestUtilConfig::getConfig();
  55. vector<string>::const_iterator it = config.data_paths_.begin();
  56. for (; it != config.data_paths_.end(); ++it) {
  57. string data_path = *it;
  58. if (data_path.empty() || *data_path.rbegin() != '/') {
  59. data_path.push_back('/');
  60. }
  61. ifs.open((data_path + datafile).c_str(), ios_base::in);
  62. if ((ifs.rdstate() & istream::failbit) == 0) {
  63. break;
  64. }
  65. }
  66. if (it == config.data_paths_.end()) {
  67. throw runtime_error("failed to open data file in data paths: " +
  68. string(datafile));
  69. }
  70. data.clear();
  71. string s;
  72. while (getline(ifs, s), !ifs.eof()) {
  73. if (ifs.bad() || ifs.fail()) {
  74. throw runtime_error("unexpected data line");
  75. }
  76. if (s.empty() || s[0] == '#') {
  77. continue;
  78. }
  79. readWireData(s, data);
  80. }
  81. }
  82. void
  83. UnitTestUtil::addDataPath(const string& directory) {
  84. UnitTestUtilConfig::getConfig().data_paths_.push_back(directory);
  85. }
  86. void
  87. UnitTestUtil::readWireData(const string& datastr,
  88. vector<unsigned char>& data)
  89. {
  90. istringstream iss(datastr);
  91. do {
  92. string bytes;
  93. iss >> bytes;
  94. if (iss.bad() || iss.fail() || (bytes.size() % 2) != 0) {
  95. ostringstream err_oss;
  96. err_oss << "unexpected input or I/O error in reading " <<
  97. datastr;
  98. throw runtime_error(err_oss.str());
  99. }
  100. for (string::size_type pos = 0; pos < bytes.size(); pos += 2) {
  101. istringstream iss_byte(bytes.substr(pos, 2));
  102. unsigned int ch;
  103. iss_byte >> hex >> ch;
  104. if (iss_byte.rdstate() != istream::eofbit) {
  105. ostringstream err_oss;
  106. err_oss << "invalid byte representation: " << iss_byte.str();
  107. throw runtime_error(err_oss.str());
  108. }
  109. data.push_back(static_cast<unsigned char>(ch));
  110. }
  111. } while (!iss.eof());
  112. }
  113. ::testing::AssertionResult
  114. UnitTestUtil::matchName(const char*, const char*,
  115. const isc::dns::Name& name1,
  116. const isc::dns::Name& name2)
  117. {
  118. ::testing::Message msg;
  119. NameComparisonResult cmpresult = name1.compare(name2);
  120. if (cmpresult.getOrder() != 0 ||
  121. cmpresult.getRelation() != NameComparisonResult::EQUAL) {
  122. msg << "Two names are expected to be equal but not:\n"
  123. << " One: " << name1 << "\n"
  124. << "Other: " << name2 << "\n";
  125. return (::testing::AssertionFailure(msg));
  126. }
  127. return (::testing::AssertionSuccess());
  128. }
  129. void
  130. UnitTestUtil::createRequestMessage(Message& message,
  131. const Opcode& opcode,
  132. const uint16_t qid,
  133. const Name& name,
  134. const RRClass& rrclass,
  135. const RRType& rrtype)
  136. {
  137. message.clear(Message::RENDER);
  138. message.setOpcode(opcode);
  139. message.setRcode(Rcode::NOERROR());
  140. message.setQid(qid);
  141. message.addQuestion(Question(name, rrclass, rrtype));
  142. }
  143. void
  144. UnitTestUtil::createDNSSECRequestMessage(Message& message,
  145. const Opcode& opcode,
  146. const uint16_t qid,
  147. const Name& name,
  148. const RRClass& rrclass,
  149. const RRType& rrtype)
  150. {
  151. message.clear(Message::RENDER);
  152. message.setOpcode(opcode);
  153. message.setRcode(Rcode::NOERROR());
  154. message.setQid(qid);
  155. message.addQuestion(Question(name, rrclass, rrtype));
  156. EDNSPtr edns(new EDNS());
  157. edns->setUDPSize(4096);
  158. edns->setDNSSECAwareness(true);
  159. message.setEDNS(edns);
  160. }