Parcourir la source

Test it works with timeouting nameserver address

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac408@3756 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner il y a 14 ans
Parent
commit
5c655d323b

+ 1 - 1
src/lib/nsas/tests/nameserver_entry_unittest.cc

@@ -78,7 +78,7 @@ protected:
         // Let it ask for data
         entry->askIP(resolver, callback, ANY_OK);
         // Check it really asked and sort the queries
-        resolver->asksIPs(Name(entry->getName()), 0, 1);
+        EXPECT_TRUE(resolver->asksIPs(Name(entry->getName()), 0, 1));
         // Respond with answers
         fillSet(resolver, 0, rrv4);
         fillSet(resolver, 1, rrv6);

+ 48 - 9
src/lib/nsas/tests/zone_entry_unittest.cc

@@ -135,12 +135,13 @@ TEST_F(ZoneEntryTest, ChangedNS) {
     // It should not be answered yet, it should ask for the IP addresses
     EXPECT_TRUE(callback_->successes_.empty());
     EXPECT_EQ(0, callback_->unreachable_count_);
-    resolver_->asksIPs(ns_name_, 1, 2);
-    resolver_->answer(1, ns_name_, RRType::A(), rdata::in::A("192.0.2.1"));
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
+    EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
+        rdata::in::A("192.0.2.1")));
     ASSERT_EQ(1, callback_->successes_.size());
     EXPECT_TRUE(IOAddress("192.0.2.1").equal(callback_->successes_[0]));
-    resolver_->answer(2, ns_name_, RRType::AAAA(),
-        rdata::in::AAAA("2001:db8::1"));
+    EXPECT_NO_THROW(resolver_->answer(2, ns_name_, RRType::AAAA(),
+        rdata::in::AAAA("2001:db8::1")));
     EXPECT_EQ(1, callback_->successes_.size());
     // It should request the NSs again, as TTL is 0
     zone->addCallback(callback_, ANY_OK);
@@ -156,9 +157,9 @@ TEST_F(ZoneEntryTest, ChangedNS) {
     // It should become ready and ask for the new name
     EXPECT_EQ(Fetchable::READY, zone->getState());
     // Answer one of the IP addresses, we should get an address now
-    resolver_->asksIPs(different_name, 4, 5);
-    resolver_->answer(4, different_name, RRType::A(),
-        rdata::in::A("192.0.2.2"));
+    EXPECT_TRUE(resolver_->asksIPs(different_name, 4, 5));
+    EXPECT_NO_THROW(resolver_->answer(4, different_name, RRType::A(),
+        rdata::in::A("192.0.2.2")));
     ASSERT_EQ(2, callback_->successes_.size());
     EXPECT_TRUE(IOAddress("192.0.2.2").equal(callback_->successes_[1]));
 
@@ -187,7 +188,7 @@ TEST_F(ZoneEntryTest, CallbacksAnswered) {
     // It should not be answered yet, it should ask for the IP addresses
     EXPECT_TRUE(callback_->successes_.empty());
     EXPECT_EQ(0, callback_->unreachable_count_);
-    resolver_->asksIPs(ns_name_, 1, 2);
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
     // We should be READY, as it marks we have nameservers
     // (not that they are ready)
     EXPECT_EQ(Fetchable::READY, zone->getState());
@@ -232,7 +233,7 @@ TEST_F(ZoneEntryTest, CallbacksAOnly) {
     // It should not be answered yet, it should ask for the IP addresses
     EXPECT_TRUE(callback_->successes_.empty());
     EXPECT_EQ(0, callback_->unreachable_count_);
-    resolver_->asksIPs(ns_name_, 1, 2);
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
     EXPECT_EQ(Fetchable::READY, zone->getState());
     // Give two more callbacks, with different address families
     zone->addCallback(callback_, V4_ONLY);
@@ -372,6 +373,44 @@ TEST_F(ZoneEntryTest, DirectAnswer) {
     EXPECT_EQ(Fetchable::READY, zone->getState());
 }
 
+// Checks it asks only for addresses when the addresses time out, not NSs
+TEST_F(ZoneEntryTest, AddressTimeout) {
+    shared_ptr<InheritedZoneEntry> zone(getZone());
+    // It should be in NOT_ASKED state
+    EXPECT_EQ(Fetchable::NOT_ASKED, zone->getState());
+    // It should accept the callback
+    zone->addCallback(callback_, ANY_OK);
+    EXPECT_EQ(Fetchable::IN_PROGRESS, zone->getState());
+    EXPECT_NO_THROW(resolver_->provideNS(0, rr_single_));
+    // It should not be answered yet, it should ask for the IP addresses
+    EXPECT_TRUE(callback_->successes_.empty());
+    EXPECT_EQ(0, callback_->unreachable_count_);
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 1, 2));
+    // We should be READY, as it marks we have nameservers
+    // (not that they are ready)
+    EXPECT_EQ(Fetchable::READY, zone->getState());
+    EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::A(),
+         rdata::in::A("192.0.2.1"), 0));
+    ASSERT_EQ(1, callback_->successes_.size());
+    EXPECT_TRUE(IOAddress("192.0.2.1").equal(callback_->successes_[0]));
+    // None are rejected
+    EXPECT_EQ(0, callback_->unreachable_count_);
+    EXPECT_NO_THROW(resolver_->answer(2, ns_name_, RRType::AAAA(),
+        rdata::in::AAAA("2001:db8::1"), 0));
+    EXPECT_EQ(1, callback_->successes_.size());
+    EXPECT_EQ(Fetchable::READY, zone->getState());
+    // When we ask for another one, it should ask for the addresses again
+    zone->addCallback(callback_, ANY_OK);
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 3, 4));
+    EXPECT_EQ(0, callback_->unreachable_count_);
+    EXPECT_EQ(1, callback_->successes_.size());
+    EXPECT_NO_THROW(resolver_->answer(3, ns_name_, RRType::A(),
+         rdata::in::A("192.0.2.1"), 0));
+    EXPECT_EQ(0, callback_->unreachable_count_);
+    ASSERT_EQ(2, callback_->successes_.size());
+    EXPECT_TRUE(IOAddress("192.0.2.1").equal(callback_->successes_[1]));
+}
+
 /*
  * TODO: There should be more tests for sure. Some ideas:
  * - Combine this direct answering.

+ 5 - 5
src/lib/nsas/zone_entry.cc

@@ -167,7 +167,7 @@ class ZoneEntry::ResolverCallback : public ResolverInterface::Callback {
 
 void
 ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
-    Lock lock(mutex_);
+    shared_ptr<Lock> lock(new Lock(mutex_));
 
     bool ask(false);
 
@@ -186,15 +186,14 @@ ZoneEntry::addCallback(CallbackPtr callback, AddressFamily family) {
         callbacks_[family].push_back(callback);
     } else {
         // Try to process it right away, store if not possible to handle
-        lock.unlock();
-        process(callback, family, NameserverPtr());
+        process(callback, family, NameserverPtr(), lock);
         return;
     }
 
     if (ask) {
         setState(IN_PROGRESS);
         // Our callback might be directly called from resolve, unlock now
-        lock.unlock();
+        lock->unlock();
         QuestionPtr question(new Question(Name(name_), class_code_,
             RRType::NS()));
         shared_ptr<ResolverCallback> resolver_callback(
@@ -396,7 +395,8 @@ ZoneEntry::process(CallbackPtr callback, AddressFamily family,
                     }
                     // Retry with all the data that might have arrived
                     in_process_[family] = false;
-                    process(callback, family, nameserver);
+                    // We do not provide the callback again
+                    process(CallbackPtr(), family, nameserver);
                     // And be done
                     return;
                 // We have some addresses to answer