BIND 10 trac1975, updated. 4ddcc3bd007c6d131b8fb6e0380550a1b8be85b4 [1975] TODO for the time we support caches

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jun 5 19:22:15 UTC 2012


The branch, trac1975 has been updated
       via  4ddcc3bd007c6d131b8fb6e0380550a1b8be85b4 (commit)
       via  9ede3992a795cecab1644795895f17391c22fe11 (commit)
       via  e654de7dea5adaa224dd56dc06201a9f902248d3 (commit)
       via  c6a9d7749573a23bfff82784b124f0602a29f786 (commit)
      from  739ce253a1702927a5991ff36672df92f9063e65 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4ddcc3bd007c6d131b8fb6e0380550a1b8be85b4
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Jun 5 21:20:33 2012 +0200

    [1975] TODO for the time we support caches
    
    The search semantics will be slightly different at places. The places
    are now marked and explained.

commit 9ede3992a795cecab1644795895f17391c22fe11
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Jun 5 21:15:30 2012 +0200

    [1975] Implement the search function
    
    Or, at last, the part without caches.

commit e654de7dea5adaa224dd56dc06201a9f902248d3
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Jun 5 21:14:31 2012 +0200

    [1975] Fix the fake data source
    
    It behaved wrongly in partial matches, since the lower_bound function
    went to the other side of the wanted iterator than I wanted.

commit c6a9d7749573a23bfff82784b124f0602a29f786
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Jun 5 20:37:07 2012 +0200

    [1975] Tests with multiple data sources

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/container.cc                |   61 +++++++++-
 src/lib/datasrc/tests/container_unittest.cc |  161 ++++++++++++++++++++++-----
 2 files changed, 193 insertions(+), 29 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/container.cc b/src/lib/datasrc/container.cc
index 71ec75b..bb3e12a 100644
--- a/src/lib/datasrc/container.cc
+++ b/src/lib/datasrc/container.cc
@@ -13,8 +13,13 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include "container.h"
+#include "client.h"
+
+#include <memory>
+#include <boost/foreach.hpp>
 
 using namespace isc::data;
+using namespace std;
 
 namespace isc {
 namespace datasrc {
@@ -26,9 +31,59 @@ ConfigurableContainer::ConfigurableContainer(const ConstElementPtr&, bool,
 }
 
 Container::SearchResult
-ConfigurableContainer::search(const dns::Name& , bool , bool ) const {
-    // TODO: Implement
-    isc_throw(NotImplemented, "A virtual unimplemented method, just to make it compile for now");
+ConfigurableContainer::search(const dns::Name& name, bool want_exact_match,
+                              bool ) const
+{
+    // Nothing found yet.
+    // Pointer is used as the SearchResult can't be assigned.
+    auto_ptr<SearchResult> candidate(new SearchResult());
+
+    BOOST_FOREACH(const DataSourceInfo& info, data_sources_) {
+        // TODO: Once we have support for the caches, consider them too here
+        // somehow. This would probably get replaced by a function, that
+        // checks if there's a cache available, if it is, checks the loaded
+        // zones and zones expected to be in the real data source. If it is
+        // the cached one, provide the cached one. If it is in the external
+        // data source, use the datasource and don't provide the finder yet.
+        DataSourceClient::FindResult result(info.data_src_->findZone(name));
+        switch (result.code) {
+            case result::SUCCESS: {
+                // If we found an exact match, we have no hope to getting
+                // a better one. Stop right here.
+
+                // TODO: In case we have only the datasource and not the finder
+                // and the need_updater parameter is true, get the zone there.
+                return (SearchResult(info.data_src_, result.zone_finder,
+                                     name.getLabelCount(), true));
+            }
+            case result::PARTIALMATCH: {
+                if (!want_exact_match) {
+                    // In case we have a partial match, check if it is better
+                    // than what we have. If so, replace it.
+                    uint8_t labels(
+                        result.zone_finder->getOrigin().getLabelCount());
+                    if (labels > candidate->matched_labels_) {
+                        // This one is strictly better. Replace it.
+                        candidate.reset(new SearchResult(info.data_src_,
+                                                         result.zone_finder,
+                                                         labels, false));
+                    }
+                }
+                break;
+            }
+            default: {
+                // Nothing found, nothing to do.
+                ;
+            }
+        }
+    }
+
+    // TODO: In case we have only the datasource and not the finder
+    // and the need_updater parameter is true, get the zone there.
+
+    // Return the partial match we have. In case we didn't want a partial
+    // match, this surely contains the original empty result.
+    return (*candidate);
 }
 
 }
diff --git a/src/lib/datasrc/tests/container_unittest.cc b/src/lib/datasrc/tests/container_unittest.cc
index 8a29b1b..491700e 100644
--- a/src/lib/datasrc/tests/container_unittest.cc
+++ b/src/lib/datasrc/tests/container_unittest.cc
@@ -79,20 +79,20 @@ public:
         }
     }
     virtual FindResult findZone(const Name& name) const {
-        set<Name>::const_iterator it(zones.lower_bound(name));
-        if (it == zones.end()) {
+        if (zones.empty()) {
             return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
-        } else {
-            NameComparisonResult compar(it->compare(name));
-            const ZoneFinderPtr finder(new Finder(*it));
-            switch (compar.getRelation()) {
-                case NameComparisonResult::EQUAL:
-                    return (FindResult(result::SUCCESS, finder));
-                case NameComparisonResult::SUPERDOMAIN:
-                    return (FindResult(result::PARTIALMATCH, finder));
-                default:
-                    return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
-            }
+        }
+        set<Name>::const_iterator it(zones.upper_bound(name));
+        -- it;
+        NameComparisonResult compar(it->compare(name));
+        const ZoneFinderPtr finder(new Finder(*it));
+        switch (compar.getRelation()) {
+            case NameComparisonResult::EQUAL:
+                return (FindResult(result::SUCCESS, finder));
+            case NameComparisonResult::SUPERDOMAIN:
+                return (FindResult(result::PARTIALMATCH, finder));
+            default:
+                return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
         }
     }
     // These methods are not used. They just need to be there to have
@@ -109,9 +109,25 @@ private:
     set<Name> zones;
 };
 
-const char* ds1_zones[] = {
-    "example.org.",
-    "example.com."
+const size_t ds_count = 4;
+
+const char* ds_zones[ds_count][3] = {
+    {
+        "example.org.",
+        "example.com.",
+        NULL
+    },
+    {
+        "sub.example.org.",
+        NULL, NULL
+    },
+    {
+        NULL, NULL, NULL
+    },
+    {
+        "sub.example.org.",
+        NULL, NULL
+    }
 };
 
 class ContainerTest : public ::testing::Test {
@@ -119,10 +135,15 @@ public:
     ContainerTest() :
         // The empty list corresponds to a container with no elements inside
         container_(new TestedContainer(ConstElementPtr(new ListElement()),
-                                       true)),
-        ds1_(new TestDS(ds1_zones))
+                                       true))
     {
-        ds1_info_.data_src_ = ds1_;
+        for (size_t i(0); i < ds_count; ++ i) {
+            shared_ptr<TestDS> ds(new TestDS(ds_zones[i]));
+            ConfigurableContainer::DataSourceInfo info;
+            info.data_src_ = ds;
+            ds_.push_back(ds);
+            ds_info_.push_back(info);
+        }
     }
     // Check the positive result is as we expect it.
     void positiveResult(const Container::SearchResult& result,
@@ -137,12 +158,51 @@ public:
         EXPECT_EQ(name.getLabelCount(), result.matched_labels_);
         EXPECT_EQ(exact, result.exact_match_);
     }
+    // Configure the container with multiple data sources, according to
+    // some configuration. It uses the index as parameter, to be able to
+    // loop through the configurations.
+    void multiConfiguration(size_t index) {
+        container_->dataSources().clear();
+        switch (index) {
+            case 2:
+                container_->dataSources().push_back(ds_info_[2]);
+                // The ds3 is empty. We just check that it doesn't confuse
+                // us. Fall through to the case 0.
+            case 0:
+                container_->dataSources().push_back(ds_info_[0]);
+                container_->dataSources().push_back(ds_info_[1]);
+                break;
+            case 1:
+                // The other order
+                container_->dataSources().push_back(ds_info_[1]);
+                container_->dataSources().push_back(ds_info_[0]);
+                break;
+            case 3:
+                container_->dataSources().push_back(ds_info_[1]);
+                container_->dataSources().push_back(ds_info_[0]);
+                // It is the same as 2, but we take from the first one.
+                // The first one to match is the correct one.
+                container_->dataSources().push_back(ds_info_[3]);
+                break;
+            default:
+                FAIL() << "Unknown configuration index " << index;
+        }
+    }
     shared_ptr<TestedContainer> container_;
     const Container::SearchResult negativeResult_;
-    shared_ptr<TestDS> ds1_;
-    ConfigurableContainer::DataSourceInfo ds1_info_;
+    vector<shared_ptr<TestDS> > ds_;
+    vector<ConfigurableContainer::DataSourceInfo> ds_info_;
 };
 
+// Test the test itself
+TEST_F(ContainerTest, selfTest) {
+    EXPECT_EQ(result::SUCCESS, ds_[0]->findZone(Name("example.org")).code);
+    EXPECT_EQ(result::PARTIALMATCH,
+              ds_[0]->findZone(Name("sub.example.org")).code);
+    EXPECT_EQ(result::NOTFOUND, ds_[0]->findZone(Name("org")).code);
+    EXPECT_EQ(result::NOTFOUND, ds_[1]->findZone(Name("example.org")).code);
+}
+
 // Test the container we create with empty configuration is, in fact, empty
 TEST_F(ContainerTest, emptyContainer) {
     EXPECT_TRUE(container_->dataSources().empty());
@@ -166,12 +226,12 @@ TEST_F(ContainerTest, emptySearch) {
 // Put a single data source inside the container and check it can find an
 // exact match if there's one.
 TEST_F(ContainerTest, singleDSExactMatch) {
-    container_->dataSources().push_back(ds1_info_);
+    container_->dataSources().push_back(ds_info_[0]);
     // This zone is not there
     EXPECT_EQ(negativeResult_, container_->search(Name("org."), true));
     // But this one is, so check it.
     positiveResult(container_->search(Name("example.org"), true),
-                   ds1_, Name("example.org"), true, "Exact match");
+                   ds_[0], Name("example.org"), true, "Exact match");
     // When asking for a sub zone of a zone there, we get nothing
     // (we want exact match, this would be partial one)
     EXPECT_EQ(negativeResult_, container_->search(Name("sub.example.org."),
@@ -180,16 +240,65 @@ TEST_F(ContainerTest, singleDSExactMatch) {
 
 // When asking for a partial match, we get all that the exact one, but more.
 TEST_F(ContainerTest, singleDSBestMatch) {
-    container_->dataSources().push_back(ds1_info_);
+    container_->dataSources().push_back(ds_info_[0]);
     // This zone is not there
     EXPECT_EQ(negativeResult_, container_->search(Name("org.")));
     // But this one is, so check it.
     positiveResult(container_->search(Name("example.org")),
-                   ds1_, Name("example.org"), true, "Exact match");
+                   ds_[0], Name("example.org"), true, "Exact match");
     // When asking for a sub zone of a zone there, we get nothing
     // (we want exact match, this would be partial one)
     positiveResult(container_->search(Name("sub.example.org.")),
-                   ds1_, Name("example.org"), false, "Subdomain match");
+                   ds_[0], Name("example.org"), false, "Subdomain match");
+}
+
+const char* test_names[] = {
+    "Sub second",
+    "Sub first",
+    "With empty",
+    "With a duplicity"
+};
+
+TEST_F(ContainerTest, multiExactMatch) {
+    // Run through all the multi-configurations
+    for (size_t i(0); i < 4; ++ i) {
+        SCOPED_TRACE(test_names[i]);
+        multiConfiguration(i);
+        // Something that is nowhere there
+        EXPECT_EQ(negativeResult_, container_->search(Name("org."), true));
+        // This one is there exactly.
+        positiveResult(container_->search(Name("example.org"), true),
+                       ds_[0], Name("example.org"), true, "Exact match");
+        // This one too, but in a different data source.
+        positiveResult(container_->search(Name("sub.example.org."), true),
+                       ds_[1], Name("sub.example.org"), true,
+                       "Subdomain match");
+        // But this one is in neither data source.
+        EXPECT_EQ(negativeResult_, container_->search(Name("sub.example.com."),
+                                                      true));
+    }
+}
+
+TEST_F(ContainerTest, multiBestMatch) {
+    // Run through all the multi-configurations
+    for (size_t i(0); i < 4; ++ i) {
+        SCOPED_TRACE(test_names[i]);
+        multiConfiguration(i);
+        // Something that is nowhere there
+        EXPECT_EQ(negativeResult_, container_->search(Name("org.")));
+        // This one is there exactly.
+        positiveResult(container_->search(Name("example.org")),
+                       ds_[0], Name("example.org"), true, "Exact match");
+        // This one too, but in a different data source.
+        positiveResult(container_->search(Name("sub.example.org.")),
+                       ds_[1], Name("sub.example.org"), true,
+                       "Subdomain match");
+        // But this one is in neither data source. But it is a subdomain
+        // of one of the zones in the first data source.
+        positiveResult(container_->search(Name("sub.example.com.")),
+                       ds_[0], Name("example.com."), false,
+                       "Subdomain in com");
+    }
 }
 
 }



More information about the bind10-changes mailing list