Browse Source

[trac859] Test for correct resolving start

Michal 'vorner' Vaner 14 years ago
parent
commit
ea46adf9f6
1 changed files with 75 additions and 3 deletions
  1. 75 3
      src/lib/resolve/tests/recursive_query_unittest.cc

+ 75 - 3
src/lib/resolve/tests/recursive_query_unittest.cc

@@ -31,7 +31,9 @@
 #include <dns/rcode.h>
 #include <dns/rcode.h>
 
 
 #include <util/buffer.h>
 #include <util/buffer.h>
+#include <util/unittests/resolver.h>
 #include <dns/message.h>
 #include <dns/message.h>
+#include <dns/rdataclass.h>
 
 
 #include <nsas/nameserver_address_store.h>
 #include <nsas/nameserver_address_store.h>
 #include <cache/resolver_cache.h>
 #include <cache/resolver_cache.h>
@@ -110,6 +112,9 @@ class RecursiveQueryTest : public ::testing::Test {
 protected:
 protected:
     RecursiveQueryTest();
     RecursiveQueryTest();
     ~RecursiveQueryTest() {
     ~RecursiveQueryTest() {
+        // It would delete itself, but after the io_service_, which could
+        // segfailt in case there were unhandled requests
+        resolver_.reset();
         if (res_ != NULL) {
         if (res_ != NULL) {
             freeaddrinfo(res_);
             freeaddrinfo(res_);
         }
         }
@@ -423,16 +428,17 @@ protected:
     vector<uint8_t> callback_data_;
     vector<uint8_t> callback_data_;
     int sock_;
     int sock_;
     struct addrinfo* res_;
     struct addrinfo* res_;
+    boost::shared_ptr<isc::util::unittests::TestResolver> resolver_;
 };
 };
 
 
 RecursiveQueryTest::RecursiveQueryTest() :
 RecursiveQueryTest::RecursiveQueryTest() :
     dns_service_(NULL), callback_(NULL), callback_protocol_(0),
     dns_service_(NULL), callback_(NULL), callback_protocol_(0),
-    callback_native_(-1), sock_(-1), res_(NULL)
+    callback_native_(-1), sock_(-1), res_(NULL),
+    resolver_(new isc::util::unittests::TestResolver())
 {
 {
     io_service_ = new IOService();
     io_service_ = new IOService();
     setDNSService(true, true);
     setDNSService(true, true);
-    boost::shared_ptr<MockResolver>mock_resolver(new MockResolver());
-    nsas_ = new isc::nsas::NameserverAddressStore(mock_resolver);
+    nsas_ = new isc::nsas::NameserverAddressStore(resolver_);
 }
 }
 
 
 TEST_F(RecursiveQueryTest, v6UDPSend) {
 TEST_F(RecursiveQueryTest, v6UDPSend) {
@@ -857,6 +863,72 @@ TEST_F(RecursiveQueryTest, DISABLED_recursiveSendNXDOMAIN) {
     EXPECT_EQ(0, answer->getRRCount(Message::SECTION_ANSWER));
     EXPECT_EQ(0, answer->getRRCount(Message::SECTION_ANSWER));
 }
 }
 
 
+// Test that we don't start at root when we have a lower NS cached.
+TEST_F(RecursiveQueryTest, CachedNS) {
+    setDNSService(true, true);
+
+    // Prefill the cache. There's a zone with a NS and IP address for one
+    // of them (to see that one is enough) and another deeper one, with NS,
+    // but without IP.
+    RRsetPtr nsUpper(new RRset(Name("example.org"), RRClass::IN(),
+                               RRType::NS(), RRTTL(300)));
+    nsUpper->addRdata(rdata::generic::NS(Name("ns.example.org")));
+    nsUpper->addRdata(rdata::generic::NS(Name("ns2.example.org")));
+
+    RRsetPtr nsLower(new RRset(Name("somewhere.deep.example.org"),
+                               RRClass::IN(), RRType::NS(), RRTTL(300)));
+    nsLower->addRdata(rdata::generic::NS(Name("ns.somewhere.deep.example.org"))
+                      );
+
+    RRsetPtr nsIp(new RRset(Name("ns2.example.org"), RRClass::IN(),
+                            RRType::A(), RRTTL(300)));
+    nsIp->addRdata(rdata::in::A("192.0.2.1"));
+
+    // Make sure the test runs in the correct environment (we don't test
+    // the cache, but we need it to unswer this way for the test, so we
+    // just make sure)
+    ASSERT_TRUE(cache_.update(nsUpper));
+    ASSERT_TRUE(cache_.update(nsLower));
+    ASSERT_TRUE(cache_.update(nsIp));
+    RRsetPtr deepest(cache_.lookupDeepestNS(Name(
+        "www.somewhere.deep.example.org"), RRClass::IN()));
+    ASSERT_NE(RRsetPtr(), deepest);
+    ASSERT_EQ(nsLower->getName(), deepest->getName());
+
+    // Prepare the recursive query
+    vector<pair<string, uint16_t> > roots;
+    roots.push_back(pair<string, uint16_t>("192.0.2.2", 53));
+
+    RecursiveQuery rq(*dns_service_, *nsas_, cache_,
+                      vector<pair<string, uint16_t> >(), roots);
+    // Ask a question at the bottom. It should not use the lower NS, because
+    // it would lead to a loop in NS. But it can use the nsUpper one, it has
+    // an IP address and we can avoid asking root.
+    Question q(Name("www.somewhere.deep.example.org"), RRClass::IN(),
+               RRType::A());
+    OutputBufferPtr buffer(new OutputBuffer(0));
+    MessagePtr answer(new Message(Message::RENDER));
+    bool done;
+    // The server is here so we have something to pass there
+    MockServer server(*io_service_);
+    rq.resolve(q, answer, buffer, &server);
+    // We don't need to run the service in this test. We are interested only
+    // in the place it starts resolving at
+
+    // Now, it should not start at the nsLower, because we don't have IP
+    // address for it and that could cause a loop. But it can be the nsUpper,
+    // we don't need to go to root.
+    //
+    // We use the trick that NSAS asks the resolver for the NS record, because
+    // it doesn't know it. This isn't the best way to write a unittest, but
+    // it isn't easy to replace the NSAS with something else, so this is the
+    // least painfull way.
+    EXPECT_NO_THROW(EXPECT_EQ(nsUpper->getName(),
+                              (*resolver_)[0]->getName()) <<
+                    "It starts resolving at the wrong place") <<
+        "It does not ask NSAS anything, how does it know where to send?";
+}
+
 // TODO: add tests that check whether the cache is updated on succesfull
 // TODO: add tests that check whether the cache is updated on succesfull
 // responses, and not updated on failures.
 // responses, and not updated on failures.