Browse Source

[1305] refactoring the test: extended the MockAccessor to generalize findPreviousName().

JINMEI Tatuya 13 years ago
parent
commit
14909927e0
1 changed files with 30 additions and 17 deletions
  1. 30 17
      src/lib/datasrc/tests/database_unittest.cc

+ 30 - 17
src/lib/datasrc/tests/database_unittest.cc

@@ -259,9 +259,16 @@ private:
  * implementation of the optional functionality.
  */
 class MockAccessor : public NopAccessor {
-    // Type of mock database "row"s
-    typedef std::map<std::string, std::vector< std::vector<std::string> > >
-        Domains;
+    // Type of mock database "row"s.  This is a map whose keys are the
+    // own names.  We internally sort them by the name comparison order.
+    struct NameCompare : public binary_function<string, string, bool> {
+        bool operator()(const string& n1, const string n2) const {
+            return (Name(n1).compare(Name(n2)).getOrder() < 0);
+        }
+    };
+    typedef std::map<std::string,
+                     std::vector< std::vector<std::string> >,
+                     NameCompare > Domains;
 
 public:
     MockAccessor() : rollbacked_(false) {
@@ -555,30 +562,36 @@ public:
     virtual std::string findPreviousName(int id, const std::string& rname)
         const
     {
-        // Hardcoded for now, but we could compute it from the data
-        // Maybe do it when it is needed some time in future?
         if (id == -1) {
             isc_throw(isc::NotImplemented, "Test not implemented behaviour");
-        } else if (id == 42) {
-            if (rname == "org.example.nonterminal.") {
-                return ("l.example.org.");
-            } else if (rname == "org.example.aa.") {
-                return ("example.org.");
-            } else if (rname == "org.example.www2." ||
-                       rname == "org.example.www1.") {
-                return ("www.example.org.");
-            } else if (rname == "org.example.badnsec2.") {
+        } else if (id == READONLY_ZONE_ID) {
+            // For some specific names we intentionally return broken or
+            // unexpected result.
+            if (rname == "org.example.badnsec2.") {
                 return ("badnsec1.example.org.");
             } else if (rname == "org.example.brokenname.") {
                 return ("brokenname...example.org.");
-            } else if (rname == "org.example.bar.*.") {
-                return ("bao.example.org.");
             } else if (rname == "org.example.notimplnsec." ||
                        rname == "org.example.wild.here.") {
                 isc_throw(isc::NotImplemented, "Not implemented in this test");
-            } else {
+            }
+
+            // For the general case, we search for the first name N in the
+            // domains that meets N >= reverse(rname) using lower_bound.
+            // The "previous name" is the name of the previous entry of N.
+            // Note that Domains are internally sorted by the Name comparison
+            // order.  Due to the API requirement we are given a reversed
+            // name (rname), so we need to reverse it again to convert it
+            // to the original name.
+            Domains::const_iterator it(readonly_records_->lower_bound(
+                                           Name(rname).reverse().toText()));
+            if (it == readonly_records_->begin()) {
                 isc_throw(isc::Unexpected, "Unexpected name");
             }
+            if (it == readonly_records_->end()) {
+                return ((*readonly_records_->rbegin()).first);
+            }
+            return ((*(--it)).first);
         } else {
             isc_throw(isc::Unexpected, "Unknown zone ID");
         }