nameserver_address_store_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  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. /// \brief Nameserver Address Store Tests
  15. ///
  16. /// This file contains tests for the nameserver address store as a whole.
  17. #include <config.h>
  18. #include <algorithm>
  19. #include <cassert>
  20. #include <string.h>
  21. #include <vector>
  22. #include <boost/foreach.hpp>
  23. #include <boost/lexical_cast.hpp>
  24. #include <boost/shared_ptr.hpp>
  25. #include <gtest/gtest.h>
  26. #include <dns/rdataclass.h>
  27. #include <dns/rrclass.h>
  28. #include <dns/rrset.h>
  29. #include <dns/rrttl.h>
  30. #include "../address_request_callback.h"
  31. #include "../nameserver_address_store.h"
  32. #include "../nameserver_entry.h"
  33. #include "../nsas_entry_compare.h"
  34. #include "../zone_entry.h"
  35. #include "nsas_test.h"
  36. using namespace isc::dns;
  37. using namespace isc::util;
  38. using namespace std;
  39. namespace isc {
  40. namespace nsas {
  41. /// \brief NSAS Store
  42. ///
  43. /// This is a subclass of the NameserverAddressStore class, with methods to
  44. /// access the internal members to check that the deleter objects are working.
  45. class DerivedNsas : public NameserverAddressStore {
  46. public:
  47. /// \brief Constructor
  48. ///
  49. /// \param hashsize Size of the zone hash table
  50. /// \param lrusize Size of the zone hash table
  51. DerivedNsas(boost::shared_ptr<TestResolver> resolver, uint32_t hashsize,
  52. uint32_t lrusize) :
  53. NameserverAddressStore(resolver, hashsize, lrusize),
  54. resolver_(resolver)
  55. {}
  56. /// \brief Virtual Destructor
  57. virtual ~DerivedNsas()
  58. {}
  59. /// \brief Add Nameserver Entry to hash and LRU tables
  60. ///
  61. /// \param entry Nameserver Entry to add.
  62. void AddNameserverEntry(boost::shared_ptr<NameserverEntry>& entry) {
  63. HashKey h = entry->hashKey();
  64. nameserver_hash_->add(entry, h);
  65. nameserver_lru_->add(entry);
  66. }
  67. /// \brief Add Zone Entry to hash and LRU tables
  68. ///
  69. /// \param entry Zone Entry to add.
  70. void AddZoneEntry(boost::shared_ptr<ZoneEntry>& entry) {
  71. HashKey h = entry->hashKey();
  72. zone_hash_->add(entry, h);
  73. zone_lru_->add(entry);
  74. }
  75. /// \brief Wrap the common lookup
  76. ///
  77. /// Calls the lookup and provides the authority section if it is asked
  78. /// for by the resolver.
  79. ///
  80. /// \param name Name of zone for which an address is required
  81. /// \param class_code Class of the zone
  82. /// \param authority Pointer to authority section RRset to which NS
  83. /// records will be added.
  84. /// \param callback Callback object used to pass result back to caller
  85. void lookupAndAnswer(const string& name, const RRClass& class_code,
  86. RRsetPtr authority,
  87. boost::shared_ptr<AddressRequestCallback> callback)
  88. {
  89. // Note how many requests are in the resolver's queue
  90. size_t size(resolver_->requests.size());
  91. // Lookup the name. This should generate a request for NS records.
  92. NameserverAddressStore::lookup(name, class_code, callback, ANY_OK);
  93. if (size < resolver_->requests.size()) {
  94. // It asked something, the only thing it can ask is the NS list.
  95. // Once answered, drop the request so no-one else sees it
  96. resolver_->provideNS(size, authority);
  97. resolver_->requests.erase(resolver_->requests.begin() + size);
  98. } else {
  99. // The test resolver's requests queue has not increased in size,
  100. // so the lookup did not generate a request.
  101. ADD_FAILURE() << "Lookup did not generate a request for NS records";
  102. }
  103. }
  104. private:
  105. boost::shared_ptr<TestResolver> resolver_;
  106. ///< Resolver used to answer generated requests
  107. };
  108. /// \brief Text Fixture Class
  109. class NameserverAddressStoreTest : public TestWithRdata {
  110. protected:
  111. /// \brief Constructor
  112. NameserverAddressStoreTest() :
  113. authority_(new RRset(Name("example.net."), RRClass::IN(), RRType::NS(),
  114. RRTTL(128))),
  115. empty_authority_(new RRset(Name("example.net."), RRClass::IN(),
  116. RRType::NS(), RRTTL(128))),
  117. resolver_(new TestResolver)
  118. {
  119. // Initialize a set of nameserver and zone objects. For convenience,
  120. // these are stored in vectors.
  121. for (int i = 1; i <= 9; ++i) {
  122. std::string name = "nameserver" + boost::lexical_cast<std::string>(
  123. i);
  124. nameservers_.push_back(boost::shared_ptr<NameserverEntry>(
  125. new NameserverEntry(name, RRClass(40 + i))));
  126. }
  127. // Some zones. They will not use the tables in this test, so it can be
  128. // empty
  129. for (int i = 1; i <= 9; ++i) {
  130. std::string name = "zone" + boost::lexical_cast<std::string>(i);
  131. zones_.push_back(boost::shared_ptr<ZoneEntry>(new ZoneEntry(
  132. resolver_.get(), name, RRClass(40 + i),
  133. boost::shared_ptr<HashTable<NameserverEntry> >(),
  134. boost::shared_ptr<LruList<NameserverEntry> >())));
  135. }
  136. // A nameserver serving data
  137. authority_->addRdata(ConstRdataPtr(new rdata::generic::NS(Name(
  138. "ns.example.com."))));
  139. // This is reused because of convenience, clear it just in case
  140. NSASCallback::results.clear();
  141. }
  142. /// \brief Internal callback object
  143. ///
  144. /// Callback object. It just records whether the success() or
  145. /// unreachable() methods were called and if success, a copy of the
  146. /// Nameserver object. (The data is held in a static object that will
  147. /// outlive the lifetime of the callback object.)
  148. struct NSASCallback : public AddressRequestCallback {
  149. typedef pair<bool, NameserverAddress> Result;
  150. static vector<Result> results;
  151. virtual void success(const NameserverAddress& address) {
  152. results.push_back(Result(true, address));
  153. }
  154. virtual void unreachable() {
  155. results.push_back(Result(false, NameserverAddress()));
  156. }
  157. };
  158. /// \brief Return pointer to callback object
  159. boost::shared_ptr<AddressRequestCallback> getCallback() {
  160. return (boost::shared_ptr<AddressRequestCallback>(new NSASCallback));
  161. }
  162. // Member variables
  163. // Vector of pointers to nameserver and zone entries.
  164. std::vector<boost::shared_ptr<NameserverEntry> > nameservers_;
  165. std::vector<boost::shared_ptr<ZoneEntry> > zones_;
  166. // Authority sections used in the tests
  167. RRsetPtr authority_;
  168. RRsetPtr empty_authority_;
  169. // ... and the resolver
  170. boost::shared_ptr<TestResolver> resolver_;
  171. };
  172. /// Definition of the static results object
  173. vector<NameserverAddressStoreTest::NSASCallback::Result>
  174. NameserverAddressStoreTest::NSASCallback::results;
  175. /// \brief Remove Zone Entry from Hash Table
  176. ///
  177. /// Check that when an entry reaches the top of the zone LRU list, it is removed
  178. /// from the hash table as well.
  179. TEST_F(NameserverAddressStoreTest, ZoneDeletionCheck) {
  180. // Create a NSAS with a hash size of three and a LRU size of 9 (both zone
  181. // and nameserver tables).
  182. DerivedNsas nsas(resolver_, 2, 2);
  183. // Add six entries to the tables. After addition the reference count of
  184. // each element should be 3 - one for the entry in the zones_ vector, and
  185. // one each for the entries in the LRU list and hash table.
  186. for (int i = 1; i <= 6; ++i) {
  187. EXPECT_EQ(1, zones_[i].use_count());
  188. nsas.AddZoneEntry(zones_[i]);
  189. EXPECT_EQ(3, zones_[i].use_count());
  190. }
  191. // Adding another entry should cause the first one to drop off the LRU list,
  192. // which should also trigger the deletion of the entry from the hash table.
  193. // This should reduce its use count to 1.
  194. EXPECT_EQ(1, zones_[7].use_count());
  195. nsas.AddZoneEntry(zones_[7]);
  196. EXPECT_EQ(3, zones_[7].use_count());
  197. EXPECT_EQ(1, zones_[1].use_count());
  198. }
  199. /// \brief Remove Entry from Hash Table
  200. ///
  201. /// Check that when an entry reaches the top of the LRU list, it is removed from
  202. /// the hash table as well.
  203. TEST_F(NameserverAddressStoreTest, NameserverDeletionCheck) {
  204. // Create a NSAS with a hash size of three and a LRU size of 9 (both zone
  205. // and nameserver tables).
  206. DerivedNsas nsas(resolver_, 2, 2);
  207. // Add six entries to the tables. After addition the reference count of
  208. // each element should be 3 - one for the entry in the nameservers_ vector,
  209. // and one each for the entries in the LRU list and hash table.
  210. for (int i = 1; i <= 6; ++i) {
  211. EXPECT_EQ(1, nameservers_[i].use_count());
  212. nsas.AddNameserverEntry(nameservers_[i]);
  213. EXPECT_EQ(3, nameservers_[i].use_count());
  214. }
  215. // Adding another entry should cause the first one to drop off the LRU list,
  216. // which should also trigger the deletion of the entry from the hash table.
  217. // This should reduce its use count to 1.
  218. EXPECT_EQ(1, nameservers_[7].use_count());
  219. nsas.AddNameserverEntry(nameservers_[7]);
  220. EXPECT_EQ(3, nameservers_[7].use_count());
  221. EXPECT_EQ(1, nameservers_[1].use_count());
  222. }
  223. /// \brief Try lookup on empty store.
  224. ///
  225. /// Check if it asks correct questions and it keeps correct internal state.
  226. TEST_F(NameserverAddressStoreTest, emptyLookup) {
  227. DerivedNsas nsas(resolver_, 10, 10);
  228. // Ask it a question
  229. nsas.lookupAndAnswer("example.net.", RRClass::IN(), authority_,
  230. getCallback());
  231. // It should ask for IP addresses for ns.example.com.
  232. EXPECT_NO_THROW(resolver_->asksIPs(Name("ns.example.com."), 0, 1));
  233. // Ask another question for the same zone
  234. nsas.lookup("example.net.", RRClass::IN(), getCallback());
  235. // It should ask no more questions now
  236. EXPECT_EQ(2, resolver_->requests.size());
  237. // Ask another question with different zone but the same nameserver
  238. authority_->setName(Name("example.com."));
  239. nsas.lookupAndAnswer("example.com.", RRClass::IN(), authority_,
  240. getCallback());
  241. // It still should ask nothing
  242. EXPECT_EQ(2, resolver_->requests.size());
  243. // We provide IP address of one nameserver, it should generate all the
  244. // results
  245. EXPECT_NO_THROW(resolver_->answer(0, Name("ns.example.com."), RRType::A(),
  246. rdata::in::A("192.0.2.1")));
  247. EXPECT_EQ(3, NSASCallback::results.size());
  248. BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
  249. EXPECT_TRUE(result.first);
  250. EXPECT_EQ("192.0.2.1", result.second.getAddress().toText());
  251. }
  252. }
  253. /// \brief Try looking up a zone that does not have any nameservers.
  254. ///
  255. /// It should not ask anything and say it is unreachable right away.
  256. TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
  257. DerivedNsas nsas(resolver_, 10, 10);
  258. // Ask it a question
  259. nsas.lookupAndAnswer("example.net.", RRClass::IN(), empty_authority_,
  260. getCallback());
  261. // There should be no questions, because there's nothing to ask
  262. EXPECT_EQ(0, resolver_->requests.size());
  263. // And there should be one "unreachable" answer for the query
  264. ASSERT_EQ(1, NSASCallback::results.size());
  265. EXPECT_FALSE(NSASCallback::results[0].first);
  266. }
  267. /// \brief Try looking up a zone that has only an unreachable nameserver.
  268. ///
  269. /// It should be unreachable. Furthermore, subsequent questions for that zone
  270. /// or other zone with the same nameserver should be unreachable right away,
  271. /// without further asking.
  272. TEST_F(NameserverAddressStoreTest, unreachableNS) {
  273. DerivedNsas nsas(resolver_, 10, 10);
  274. // Ask it a question
  275. nsas.lookupAndAnswer("example.net.", RRClass::IN(), authority_,
  276. getCallback());
  277. // It should ask for IP addresses for example.com.
  278. EXPECT_NO_THROW(resolver_->asksIPs(Name("ns.example.com."), 0, 1));
  279. // Ask another question with different zone but the same nameserver
  280. authority_->setName(Name("example.com."));
  281. nsas.lookupAndAnswer("example.com.", RRClass::IN(), authority_,
  282. getCallback());
  283. // It should ask nothing more now
  284. EXPECT_EQ(2, resolver_->requests.size());
  285. // We say there are no addresses
  286. resolver_->requests[0].second->failure();
  287. resolver_->requests[1].second->failure();
  288. // We should have 2 answers now
  289. EXPECT_EQ(2, NSASCallback::results.size());
  290. // When we ask one same and one other zone with the same nameserver,
  291. // it should generate no questions and answer right away
  292. nsas.lookup("example.net.", RRClass::IN(), getCallback());
  293. authority_->setName(Name("example.org."));
  294. nsas.lookupAndAnswer("example.org.", RRClass::IN(), authority_,
  295. getCallback());
  296. // There should be 4 negative answers now
  297. EXPECT_EQ(4, NSASCallback::results.size());
  298. BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
  299. EXPECT_FALSE(result.first);
  300. }
  301. }
  302. /// \short Try to stress it little bit by having multiple zones and nameservers.
  303. ///
  304. /// Does some asking, on a set of zones that share some nameservers, with
  305. /// slower answering, evicting data, etc.
  306. TEST_F(NameserverAddressStoreTest, CombinedTest) {
  307. // Create small caches, so we get some evictions
  308. DerivedNsas nsas(resolver_, 1, 1);
  309. // Ask for example.net. It has single nameserver out of the zone
  310. nsas.lookupAndAnswer("example.net.", RRClass::IN(), authority_,
  311. getCallback());
  312. // It should ask for the nameserver IP addresses
  313. EXPECT_NO_THROW(resolver_->asksIPs(Name("ns.example.com."), 0, 1));
  314. EXPECT_EQ(0, NSASCallback::results.size());
  315. // But we do not answer it right away. We create a new zone and
  316. // let this nameserver entry get out.
  317. rrns_->addRdata(rdata::generic::NS("example.cz"));
  318. nsas.lookupAndAnswer(EXAMPLE_CO_UK, RRClass::IN(), rrns_, getCallback());
  319. // It really should ask something, one of the nameservers
  320. // (or both)
  321. ASSERT_GT(resolver_->requests.size(), 2);
  322. Name name(resolver_->requests[2].first->getName());
  323. EXPECT_TRUE(name == Name("example.fr") || name == Name("example.de") ||
  324. name == Name("example.cz"));
  325. EXPECT_NO_THROW(resolver_->asksIPs(name, 2, 3));
  326. EXPECT_EQ(0, NSASCallback::results.size());
  327. // This should still be in the hash table, so try it asks no more questions
  328. size_t request_count(resolver_->requests.size());
  329. nsas.lookup("example.net.", RRClass::IN(), getCallback());
  330. EXPECT_EQ(request_count, resolver_->requests.size());
  331. EXPECT_EQ(0, NSASCallback::results.size());
  332. // We respond to one of the 3 nameservers
  333. EXPECT_NO_THROW(resolver_->answer(2, name, RRType::A(),
  334. rdata::in::A("192.0.2.1")));
  335. // That should trigger one answer
  336. EXPECT_EQ(1, NSASCallback::results.size());
  337. EXPECT_TRUE(NSASCallback::results[0].first);
  338. EXPECT_EQ("192.0.2.1",
  339. NSASCallback::results[0].second.getAddress().toText());
  340. EXPECT_NO_THROW(resolver_->answer(3, name, RRType::AAAA(),
  341. rdata::in::AAAA("2001:bd8::1")));
  342. // And there should be yet another query
  343. ASSERT_GT(resolver_->requests.size(), 4);
  344. EXPECT_NE(name, resolver_->requests[4].first->getName());
  345. Name another_name = resolver_->requests[4].first->getName();
  346. EXPECT_TRUE(another_name == Name("example.fr") ||
  347. another_name == Name("example.de") ||
  348. another_name == Name("example.cz"));
  349. request_count = resolver_->requests.size();
  350. // But when ask for a different zone with the first nameserver, it should
  351. // ask again, as it is evicted already
  352. authority_->setName(Name("example.com."));
  353. nsas.lookupAndAnswer("example.com.", RRClass::IN(), authority_,
  354. getCallback());
  355. EXPECT_EQ(request_count + 2, resolver_->requests.size());
  356. EXPECT_NO_THROW(resolver_->asksIPs(Name("ns.example.com."), request_count,
  357. request_count + 1));
  358. // Now, we answer both queries for the same address and three (one for the
  359. // original, one for this one) more answers should arrive
  360. NSASCallback::results.clear();
  361. EXPECT_NO_THROW(resolver_->answer(0, Name("ns.example.com."), RRType::A(),
  362. rdata::in::A("192.0.2.2")));
  363. EXPECT_NO_THROW(resolver_->answer(request_count, Name("ns.example.com."),
  364. RRType::A(), rdata::in::A("192.0.2.2")));
  365. EXPECT_EQ(3, NSASCallback::results.size());
  366. BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
  367. EXPECT_TRUE(result.first);
  368. EXPECT_EQ("192.0.2.2", result.second.getAddress().toText());
  369. }
  370. }
  371. // Check that we can update the RTT associated with nameservers successfully.
  372. // Also checks that we can't set the RTT to zero (which would cause problems
  373. // with selection algorithm).
  374. TEST_F(NameserverAddressStoreTest, updateRTT) {
  375. // Initialization.
  376. string zone_name = "example.net.";
  377. string ns_name = "ns.example.com.";
  378. vector<string> address;
  379. address.push_back("192.0.2.1");
  380. address.push_back("192.0.2.2");
  381. uint32_t HIGH_RTT = 10000; // 1E4; When squared, the result fits in 32 bits
  382. DerivedNsas nsas(resolver_, 103, 107); // Arbitrary cache sizes
  383. // Ensure that location holding the addresses returned is empty. We'll
  384. // be using this throughout the tests. As the full name is a bit of a
  385. // mouthful, set up an alias.
  386. vector<NameserverAddressStoreTest::NSASCallback::Result>& results =
  387. NameserverAddressStoreTest::NSASCallback::results;
  388. results.clear();
  389. // Initialize the test resolver with the answer for the A record query
  390. // for ns.example.com (the nameserver set for example.net in the class
  391. // initialization). We'll set two addresses.
  392. Name ns_example_com(ns_name);
  393. RRsetPtr ns_address = boost::shared_ptr<RRset>(new RRset(
  394. ns_example_com, RRClass::IN(), RRType::A(), RRTTL(300)));
  395. BOOST_FOREACH(string addr, address) {
  396. ns_address->addRdata(rdata::in::A(addr));
  397. }
  398. // All set. Ask for example.net.
  399. boost::shared_ptr<AddressRequestCallback> callback = getCallback();
  400. nsas.lookupAndAnswer(zone_name, RRClass::IN(), authority_, getCallback());
  401. // This should generate two requests - one for A and one for AAAA.
  402. EXPECT_EQ(2, resolver_->requests.size());
  403. // Provide an answer that has two A records. This should generate one
  404. // result.
  405. EXPECT_NO_THROW(resolver_->answer(0, ns_address));
  406. EXPECT_EQ(1, results.size());
  407. // We expect the lookup to be successful. Check that the address is one of
  408. // the two we've set and that the RTT associated with this nameserver is
  409. // non-zero.
  410. EXPECT_EQ(true, results[0].first);
  411. vector<string>::iterator addr1 = find(address.begin(), address.end(),
  412. results[0].second.getAddress().toText());
  413. EXPECT_TRUE(addr1 != address.end());
  414. // The RTT we got should be non-zero and less than the high value we are
  415. // using for the test.
  416. uint32_t rtt1 = results[0].second.getAddressEntry().getRTT();
  417. EXPECT_NE(0, rtt1);
  418. EXPECT_LT(rtt1, HIGH_RTT);
  419. // Update the address with a very high RTT. Owning to the way the NSAS is
  420. // written, we can update the RTT but cannot read the new value back from
  421. // the new object.
  422. results[0].second.updateRTT(HIGH_RTT);
  423. // Get another nameserver. As the probability of returning a particular
  424. // address is proporational to 1/t^2, we should get the second address
  425. // since the first now has a larger RTT. However, this is not guaranteed
  426. // - this is a probability (albeit small) of getting the first again. We'll
  427. // allow three chances of getting the "wrong" address before we declare
  428. // an error.
  429. int attempt = 0;
  430. vector<string>::iterator addr2 = addr1;
  431. for (attempt = 0; (attempt < 3) && (*addr1 == *addr2); ++attempt) {
  432. results.clear();
  433. nsas.lookup(zone_name, RRClass::IN(),
  434. getCallback(), ANY_OK);
  435. addr2 = find(address.begin(), address.end(),
  436. results[0].second.getAddress().toText());
  437. }
  438. EXPECT_LT(attempt, 3);
  439. // Ensure that the RTT is non-zero.
  440. // obtained earlier.
  441. uint32_t rtt2 = results[0].second.getAddressEntry().getRTT();
  442. EXPECT_NE(0, rtt2);
  443. // The test has shown that the code can return the two nameservers. Now
  444. // try to set the RTT for the last one returned to zero. As there is a
  445. // smoothing effect in the calculations which damps out an abrupt change
  446. // in the RTT, the underlying RTT will not be set to zero immediately. So
  447. // loop a large number of times, each time setting it to zero.
  448. //
  449. // Between each setting of the RTT, we have to retrieve the nameserver from
  450. // the NSAS again. This means that we _could_ occasionally get the address
  451. // of the one whose RTT we have raised to HIGH_RTT. We overcome this by
  452. // looping a _very_ large number of times. Ultimately the RTT of both
  453. // addresses should decay to a small value.
  454. for (int i = 0; i < 2000; ++i) { // 1000 times for each nameserver
  455. results.clear();
  456. nsas.lookup(zone_name, RRClass::IN(), getCallback(), ANY_OK);
  457. EXPECT_EQ(1, results.size());
  458. uint32_t rtt3 = results[0].second.getAddressEntry().getRTT();
  459. EXPECT_NE(0, rtt3);
  460. results[0].second.updateRTT(0);
  461. }
  462. }
  463. } // namespace nsas
  464. } // namespace isc