Browse Source

Tests for zones with injected nameserver

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac408@3758 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
c2a60ba2c2
1 changed files with 112 additions and 6 deletions
  1. 112 6
      src/lib/nsas/tests/zone_entry_unittest.cc

+ 112 - 6
src/lib/nsas/tests/zone_entry_unittest.cc

@@ -80,6 +80,15 @@ protected:
     };
     shared_ptr<Callback> callback_;
 
+    // Empty callback to pass to nameserver entry, to do injection of them
+    struct NseCallback : public NameserverEntry::Callback {
+        virtual void operator()(shared_ptr<NameserverEntry>) { }
+    };
+
+    shared_ptr<NseCallback> nseCallback() {
+        return (shared_ptr<NseCallback>(new NseCallback));
+    }
+
     /**
      * \short Function returning a new zone.
      *
@@ -90,6 +99,42 @@ protected:
             resolver_, EXAMPLE_CO_UK, RRClass::IN(), nameserver_table_,
             nameserver_lru_)));
     }
+
+    /// \short Creates and injects a nameserver entry
+    shared_ptr<NameserverEntry> injectEntry() {
+        shared_ptr<NameserverEntry> nse(new NameserverEntry(ns_name_.toText(),
+            RRClass::IN()));
+        nameserver_table_->add(nse, HashKey(ns_name_.toText(), RRClass::IN()));
+        EXPECT_EQ(Fetchable::NOT_ASKED, nse->getState());
+        return (nse);
+    }
+
+    void checkInjected(bool answer, size_t success_count = 1,
+        size_t failure_count = 0)
+    {
+        // Create the zone and check it acts correctly
+        shared_ptr<InheritedZoneEntry> zone(getZone());
+        resolver_->addPresetAnswer(Question(Name(EXAMPLE_CO_UK), RRClass::IN(),
+            RRType::NS()), rr_single_);
+        zone->addCallback(callback_, ANY_OK);
+        EXPECT_EQ(2, resolver_->requests.size());
+        EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
+        if (answer) {
+            EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
+                rdata::in::A("192.0.2.1")));
+            EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
+                rdata::in::AAAA("2001:db8::1")));
+        }
+        // Check the answers
+        EXPECT_EQ(Fetchable::READY, zone->getState());
+        EXPECT_EQ(failure_count, callback_->unreachable_count_);
+        EXPECT_EQ(success_count, callback_->successes_.size());
+        for (size_t i = 0; i < callback_->successes_.size(); ++ i) {
+            EXPECT_TRUE(IOAddress("192.0.2.1").equal(
+                callback_->successes_[i]) || IOAddress("2001:db8::1").equal(
+                    callback_->successes_[i]));
+        }
+    }
 };
 
 /// Tests of the default constructor
@@ -411,11 +456,72 @@ TEST_F(ZoneEntryTest, AddressTimeout) {
     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.
- * - Look what happens when the nameservers are already in some different
- *   states and not just newly created.
- */
+// Test how the zone reacts to a nameserver entry in ready state
+TEST_F(ZoneEntryTest, NameserverEntryReady) {
+    // Inject the entry
+    shared_ptr<NameserverEntry> nse(injectEntry());
+    // Fill it with data
+    nse->askIP(resolver_, nseCallback(), ANY_OK);
+    EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
+    EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
+        rdata::in::A("192.0.2.1")));
+    EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
+        rdata::in::AAAA("2001:db8::1")));
+    EXPECT_EQ(Fetchable::READY, nse->getState());
+
+    checkInjected(false);
+}
+
+// Test how the zone reacts to a nameserver in not asked state
+TEST_F(ZoneEntryTest, NameserverNotAsked) {
+    // Inject the entry
+    injectEntry();
+    // We do not need it, nothing to modify on it
+
+    checkInjected(true);
+}
+
+// What if the zone finds a nameserver in progress?
+TEST_F(ZoneEntryTest, NameserverInProgress) {
+    // Prepare the nameserver entry
+    shared_ptr<NameserverEntry> nse(injectEntry());
+    nse->askIP(resolver_, nseCallback(), ANY_OK);
+    EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
+
+    checkInjected(true);
+}
+
+// Check Zone's reaction to found expired nameserver
+TEST_F(ZoneEntryTest, NameserverExpired) {
+    shared_ptr<NameserverEntry> nse(injectEntry());
+    nse->askIP(resolver_, nseCallback(), ANY_OK);
+    EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
+    EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
+    EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
+        rdata::in::A("192.0.2.1"), 0));
+    EXPECT_NO_THROW(resolver_->answer(1, ns_name_, RRType::AAAA(),
+        rdata::in::AAAA("2001:db8::1"), 0));
+    EXPECT_EQ(Fetchable::READY, nse->getState());
+    NameserverEntry::AddressVector addresses;
+    EXPECT_EQ(Fetchable::EXPIRED, nse->getAddresses(addresses));
+    EXPECT_EQ(Fetchable::EXPIRED, nse->getState());
+    resolver_->requests.clear();
+
+    checkInjected(true);
+}
+
+// Check how it reacts to an unreachable zone already in the table
+TEST_F(ZoneEntryTest, NameserverUnreachable) {
+    shared_ptr<NameserverEntry> nse(injectEntry());
+    nse->askIP(resolver_, nseCallback(), ANY_OK);
+    ASSERT_EQ(2, resolver_->requests.size());
+    resolver_->requests[0].second->failure();
+    resolver_->requests[1].second->failure();
+    EXPECT_EQ(Fetchable::UNREACHABLE, nse->getState());
+
+    checkInjected(false, 0, 1);
+}
 
 }   // namespace