Browse Source

Interface update

* Uses RRClass instead of uint16_t
* NameserverEntry does not have constructor with rrsets, it will request
  them from resolver

It compiles but tests still do not pass

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac408@3678 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
96a97de26c

+ 1 - 1
src/lib/nsas/hash.cc

@@ -151,7 +151,7 @@ uint32_t Hash::operator()(const HashKey& key, bool ignorecase) const
         char        bytes[sizeof(uint16_t)];    // Byte equivalent
     } convert;
 
-    convert.class_code = key.class_code;
+    convert.class_code = key.class_code.getCode();
     for (int j = 0; j < sizeof(uint16_t); ++j, ++i) {
         partial_sum += convert.bytes[j] * randvec_[i];
     }

+ 13 - 5
src/lib/nsas/hash_key.h

@@ -17,6 +17,8 @@
 #ifndef __HASH_KEY_H
 #define __HASH_KEY_H
 
+#include <dns/rrclass.h>
+
 #include <stdint.h>
 #include <string>
 #include <config.h>
@@ -51,8 +53,11 @@ struct HashKey {
     /// \param the_key Array of bytes for which key is to be constructed
     /// \param the_keylen Length of the byte array
     /// \param the_class_code Class of this entry
-    HashKey(const char* the_key, uint32_t the_keylen, uint16_t the_class_code) :
-        key(the_key), keylen(the_keylen), class_code(the_class_code)
+    HashKey(const char* the_key, uint32_t the_keylen,
+        const isc::dns::RRClass& the_class_code) :
+        key(the_key),
+        keylen(the_keylen),
+        class_code(the_class_code)
     {}
 
     /// \brief String Constructor
@@ -61,8 +66,11 @@ struct HashKey {
     ///
     /// \param the_key Name to use as the key for the hash
     /// \param the_class_code Class of this entry
-    HashKey(const std::string& the_key, uint16_t the_class_code) :
-        key(the_key.c_str()), keylen(the_key.size()), class_code(the_class_code)
+    HashKey(const std::string& the_key,
+        const isc::dns::RRClass& the_class_code) :
+        key(the_key.c_str()),
+        keylen(the_key.size()),
+        class_code(the_class_code)
     {}
 
     /// \brief Equality
@@ -82,7 +90,7 @@ struct HashKey {
 
     const char* key;        ///< Pointer to the start of the key string
     uint32_t    keylen;     ///< Length of the key string
-    uint16_t    class_code; ///< Class associated with the key
+    isc::dns::RRClass class_code; ///< Class associated with the key
 };
 
 } // namespace nsas

+ 0 - 111
src/lib/nsas/nameserver_entry.cc

@@ -45,117 +45,6 @@ using namespace boost;
 namespace isc {
 namespace nsas {
 
-
-// Constructor, initialized with the list of addresses associated with this
-// nameserver.
-NameserverEntry::NameserverEntry(const AbstractRRset* v4Set,
-    const AbstractRRset* v6Set, time_t curtime) :
-    expiration_(0)
-
-{
-    // TODO: Use pseudo-random RTT
-    uint32_t rtt = 0;       // Round-trip time for an address
-    string v4name = "";     // Name from the V4 RRset
-    string v6name = "";     // Name from the v6 RRset
-    uint16_t v4class = 0;   // Class of V4 RRset
-    uint16_t v6class = 0;   // Class for V6 RRset
-
-    // Get the time for setting the expiration time.
-    if (curtime == 0) {
-        curtime = time(NULL);
-    }
-
-    // Add the v4 addresses to the list of addresses.  Each address is assigned
-    // a small RTT that ensures that each server is used at least once (in a
-    // random order).
-
-
-    has_address_[V4_ONLY] = has_address_[V6_ONLY] = false;
-    // Do the V4 addresses first
-    // XXX: Do we need to check that these are V4 addresses?
-    if (v4Set) {
-        bool has_address(false);
-        RdataIteratorPtr i = v4Set->getRdataIterator();
-        // TODO Remove at merge with #410
-        i->first();
-        while (! i->isLast()) {
-            has_address = true;
-            address_.push_back(AddressEntry(IOAddress(i->getCurrent().toText()),
-            ++rtt));
-            i->next();
-        }
-
-        // Set the expiration time and extract the owner name and class
-        expiration_ = curtime + v4Set->getTTL().getValue();
-        v4name = v4Set->getName().toText(false);    // Ensure trailing dot
-        v4class = v4Set->getClass().getCode();
-
-        // We have an address
-        has_address_[V4_ONLY] = has_address;
-    }
-
-    // Now the v6 addresses
-    // XXX: Do we need to check that these are V6 addresses?
-    if (v6Set) {
-        bool has_address(false);
-        RdataIteratorPtr i = v6Set->getRdataIterator();
-        // TODO Remove at merge with #410
-        i->first();
-        while (! i->isLast()) {
-            has_address = true;
-            address_.push_back(AddressEntry(IOAddress(i->getCurrent().toText()),
-            ++rtt));
-            i->next();
-        }
-
-        // Update the expiration time of the data
-        time_t v6expiration = curtime + v6Set->getTTL().getValue();
-        if (expiration_ == 0) {
-            expiration_ = v6expiration;
-        }
-        else {
-            expiration_ = min(expiration_, v6expiration);
-        }
-
-        // Extract the name of the v6 set and its class
-        v6name = v6Set->getName().toText(false);    // Ensure trailing dot
-        v6class = v6Set->getClass().getCode();
-
-        // We have an address
-        has_address_[V6_ONLY] = has_address;
-    }
-
-    // We got some addresses, so set we are ready & not expecting anything
-    if (has_address_[V4_ONLY] || has_address_[V6_ONLY]) {
-        has_address_[ANY_OK] = true;
-        expect_address_[ANY_OK] = expect_address_[V4_ONLY] =
-            expect_address_[V6_ONLY] = false;
-        setState(READY);
-    }
-
-    // TODO: Log a problem if both V4 and V6 address were null.
-
-    if (v4Set && v6Set) {
-
-        // If two owner names were specified and they were different, something
-        // has gone wrong with the logic that created this object.
-       if (strcasecmp(v4name.c_str(), v6name.c_str()) != 0) {
-           isc_throw(InconsistentOwnerNames,
-               "Owner names for NameserverEntry RRsets are different");
-       }
-
-       // Likewise with the class
-       if (v4class != v6class) {
-           isc_throw(InconsistentClass,
-               "Class codes for NameserverEntry RRsets are different");
-       }
-    }
-
-    // Otherwise set the owner name
-    name_ = v4Set ? v4name : v6name;
-    classCode_ = v4Set ? v4class : v6class;
-}
-
 namespace {
 
 /// Returns false if the address family of a given entry matches the address

+ 6 - 21
src/lib/nsas/nameserver_entry.h

@@ -94,27 +94,12 @@ public:
     ///
     /// \param name Name of the nameserver,
     /// \param class_code class of the nameserver
-    NameserverEntry(const std::string& name, uint16_t class_code) :
-        name_(name), classCode_(class_code)
+    NameserverEntry(const std::string& name,
+        const isc::dns::RRClass& class_code) :
+        name_(name),
+        classCode_(class_code)
     {}
 
-    /// Constructor where one or more RRsets of A/AAAA records are supplied.
-    /// The class is taken from class of address records and the name from
-    /// the owner of the records.  If both sets of information are supplied
-    /// and the owner names are different, the V4 set wins out; the V6 set of
-    /// information is ignored and an error message is logged.
-    ///
-    /// \param v4Set RRset of A records
-    /// \param v6Set RRset of AAAA records
-    /// \param curtime Current time.  Present for testing, but also as a
-    /// possible optimisation if the caller has the current time (it saves
-    /// the overhead of a call to time()).  The default value of 0 requests
-    /// the constructor to get its own copy of the current time.
-    /// \todo This is possibly unneeded, if NSAS uses the resolver for
-    /// everything
-    NameserverEntry(const isc::dns::AbstractRRset* v4Set,
-        const isc::dns::AbstractRRset* v6Set, time_t curtime = 0);
-
     /// \brief Return Address
     ///
     /// Returns a vector of addresses corresponding to this nameserver.
@@ -172,7 +157,7 @@ public:
     }
 
     /// \return Class of RRset
-    short getClass() const {
+    const isc::dns::RRClass& getClass() const {
         return classCode_;
     }
 
@@ -235,7 +220,7 @@ private:
     // TODO Read-write lock?
     mutable boost::mutex    mutex_;     ///< Mutex protecting this object
     std::string     name_;              ///< Canonical name of the nameserver
-    uint16_t        classCode_;         ///< Class of the nameserver
+    isc::dns::RRClass classCode_;       ///< Class of the nameserver
     std::vector<AddressEntry> address_; ///< Set of V4/V6 addresses
     time_t          expiration_;        ///< Summary expiration time
     time_t          last_access_;       ///< Last access time to the structure

+ 10 - 7
src/lib/nsas/tests/hash_deleter_unittest.cc

@@ -21,6 +21,8 @@
 #include <gtest/gtest.h>
 #include <boost/lexical_cast.hpp>
 
+#include <dns/rrclass.h>
+
 #include "../nsas_entry.h"
 #include "../hash_table.h"
 #include "../hash_key.h"
@@ -31,6 +33,7 @@
 #include "../nsas_entry_compare.h"
 
 using namespace std;
+using namespace isc::dns;
 
 namespace isc {
 namespace nsas {
@@ -40,13 +43,13 @@ namespace nsas {
 class HashDeleterTest : public ::testing::Test {
 protected:
     HashDeleterTest() :
-        entry1_(new TestEntry("alpha", 1)),
-        entry2_(new TestEntry("beta", 2)),
-        entry3_(new TestEntry("gamma", 3)),
-        entry4_(new TestEntry("delta", 4)),
-        entry5_(new TestEntry("epsilon", 5)),
-        entry6_(new TestEntry("zeta", 6)),
-        entry7_(new TestEntry("eta", 7)),
+        entry1_(new TestEntry("alpha", RRClass::IN())),
+        entry2_(new TestEntry("beta", RRClass::CH())),
+        entry3_(new TestEntry("gamma", RRClass::HS())),
+        entry4_(new TestEntry("delta", RRClass::IN())),
+        entry5_(new TestEntry("epsilon", RRClass::CH())),
+        entry6_(new TestEntry("zeta", RRClass::HS())),
+        entry7_(new TestEntry("eta", RRClass::IN())),
         hash_table_(new NsasEntryCompare<TestEntry>()),
         lru_list_(3, new HashDeleter<TestEntry>(hash_table_))
     {}

+ 25 - 15
src/lib/nsas/tests/hash_key_unittest.cc

@@ -22,8 +22,10 @@
 #include <boost/lexical_cast.hpp>
 
 #include "../hash_key.h"
+#include <dns/rrclass.h>
 
 using namespace std;
+using namespace isc::dns;
 
 namespace isc {
 namespace nsas {
@@ -38,17 +40,17 @@ TEST_F(HashKeyTest, Constructor) {
     
     // Basic constructor
     string  test1("ABCDEF");
-    HashKey key1(test1.c_str(), test1.size(), 1);
+    HashKey key1(test1.c_str(), test1.size(), RRClass::IN());
     EXPECT_EQ(key1.key, test1.c_str());
     EXPECT_EQ(key1.keylen, test1.size());
-    EXPECT_EQ(key1.class_code, 1);
+    EXPECT_EQ(key1.class_code, RRClass::IN());
 
     // String constructor
     string  test2("uvwxyz");
-    HashKey key2(test2, 2);
+    HashKey key2(test2, RRClass::CH());
     EXPECT_EQ(key2.key, test2.c_str());
     EXPECT_EQ(key2.keylen, test2.size());
-    EXPECT_EQ(key2.class_code, 2);
+    EXPECT_EQ(key2.class_code, RRClass::CH());
 }
 
 // Equality check
@@ -59,17 +61,25 @@ TEST_F(HashKeyTest, Equality) {
     string  test4("ABCDE123");     // Different key (almost same)
     string  test5("uvwxyz987");    // Different key
 
-    EXPECT_TRUE(HashKey(test1, 1) == HashKey(test1, 1));   // Same key and class
-    EXPECT_FALSE(HashKey(test1, 1) == HashKey(test1, 2));  // Different class
-
-    EXPECT_TRUE(HashKey(test1, 2) == HashKey(test2, 2));   // Same value key/class
-    EXPECT_FALSE(HashKey(test1, 2) == HashKey(test2, 3));
-
-    EXPECT_TRUE(HashKey(test1, 3) == HashKey(test3, 3));   // Same key
-    EXPECT_FALSE(HashKey(test1, 3) == HashKey(test3, 4));
-
-    EXPECT_FALSE(HashKey(test1, 1) == HashKey(test4, 1));
-    EXPECT_FALSE(HashKey(test1, 1) == HashKey(test5, 1));
+    EXPECT_TRUE(HashKey(test1, RRClass::IN()) == HashKey(test1,
+        RRClass::IN()));   // Same key and class
+    EXPECT_FALSE(HashKey(test1, RRClass::IN()) == HashKey(test1,
+        RRClass::CH()));  // Different class
+
+    EXPECT_TRUE(HashKey(test1, RRClass::CH()) == HashKey(test2,
+        RRClass::CH()));   // Same value key/class
+    EXPECT_FALSE(HashKey(test1, RRClass::CH()) == HashKey(test2,
+        RRClass::IN()));
+
+    EXPECT_TRUE(HashKey(test1, RRClass::HS()) == HashKey(test3,
+        RRClass::HS()));   // Same key
+    EXPECT_FALSE(HashKey(test1, RRClass::HS()) == HashKey(test3,
+        RRClass::IN()));
+
+    EXPECT_FALSE(HashKey(test1, RRClass::IN()) == HashKey(test4,
+        RRClass::IN()));
+    EXPECT_FALSE(HashKey(test1, RRClass::IN()) == HashKey(test5,
+        RRClass::IN()));
 }
 
 } // namespace nsas

+ 7 - 4
src/lib/nsas/tests/hash_table_unittest.cc

@@ -21,6 +21,8 @@
 #include <string.h>
 #include <iostream>
 
+#include <dns/rrclass.h>
+
 #include "../hash_table.h"
 #include "../hash_key.h"
 
@@ -29,6 +31,7 @@
 
 using namespace std;
 using boost::shared_ptr;
+using namespace isc::dns;
 
 namespace isc {
 namespace nsas {
@@ -46,10 +49,10 @@ protected:
     // Constructor - initialize the objects
     HashTableTest() :
         table_(new NsasEntryCompare<TestEntry>()),
-        dummy1_(new TestEntry("test", 1)),
-        dummy2_(new TestEntry("test", 1)),
-        dummy3_(new TestEntry("Something_Else", 1)),
-        dummy4_(new TestEntry("test", 3))
+        dummy1_(new TestEntry("test", RRClass::IN())),
+        dummy2_(new TestEntry("test", RRClass::IN())),
+        dummy3_(new TestEntry("Something_Else", RRClass::IN())),
+        dummy4_(new TestEntry("test", RRClass::CH()))
     {}
 
     // Members.

+ 18 - 10
src/lib/nsas/tests/hash_unittest.cc

@@ -82,7 +82,8 @@ TEST_F(HashTest, Algorithm) {
     // Generate hash values
     for (int i = 0; i < 50; ++i) {
         string name = base + boost::lexical_cast<string>(i);
-        uint32_t hashval = hash(HashKey(name.c_str(), name.size(), 0));
+        uint32_t hashval = hash(HashKey(name.c_str(), name.size(),
+            RRClass(0)));
         EXPECT_LT(hashval, size);
         values.push_back(hashval);
     }
@@ -122,18 +123,22 @@ TEST_F(HashTest, MixedCase) {
     Hash hash(HASHTABLE_DEFAULT_SIZE, 255, false);    // Disable randomisation for testing
 
     // Case not ignored, hashes should be different
-    uint32_t value1 = hash(HashKey(test1.c_str(), test1.size(), 0), false);
-    uint32_t value2 = hash(HashKey(test2.c_str(), test2.size(), 0), false);
+    uint32_t value1 = hash(HashKey(test1.c_str(), test1.size(), RRClass::IN()),
+        false);
+    uint32_t value2 = hash(HashKey(test2.c_str(), test2.size(), RRClass::IN()),
+        false);
     EXPECT_NE(value1, value2);
 
     // Case ignored, hashes should be the same
-    uint32_t value3 = hash(HashKey(test1.c_str(), test1.size(), 0), true);
-    uint32_t value4 = hash(HashKey(test2.c_str(), test2.size(), 0), true);
+    uint32_t value3 = hash(HashKey(test1.c_str(), test1.size(), RRClass::IN()),
+        true);
+    uint32_t value4 = hash(HashKey(test2.c_str(), test2.size(), RRClass::IN()),
+        true);
     EXPECT_EQ(value3, value4);
 
     // Check the default setting.
-    uint32_t value5 = hash(HashKey(test1.c_str(), test1.size(), 0));
-    uint32_t value6 = hash(HashKey(test2.c_str(), test2.size(), 0));
+    uint32_t value5 = hash(HashKey(test1.c_str(), test1.size(), RRClass::IN()));
+    uint32_t value6 = hash(HashKey(test2.c_str(), test2.size(), RRClass::IN()));
     EXPECT_EQ(value5, value6);
 
     // ... and just for good measure
@@ -151,7 +156,8 @@ TEST_F(HashTest, ClassCodes) {
     // codes.
     vector<uint32_t> values;
     for (uint32_t i = 0; i < 10; ++i) {
-        values.push_back(hash(HashKey(test1.c_str(), test1.size(), i)));
+        values.push_back(hash(HashKey(test1.c_str(), test1.size(),
+            RRClass(i))));
     }
 
     // find the number of unique values in the array.  Although there can
@@ -177,8 +183,10 @@ TEST_F(HashTest, Overlong) {
     Hash hash(HASHTABLE_DEFAULT_SIZE, string1.size());
 
     // Do two hashes
-    uint32_t value1 = hash(HashKey(string1.c_str(), string1.size(), 0));
-    uint32_t value2 = hash(HashKey(string2.c_str(), string2.size(), 0));
+    uint32_t value1 = hash(HashKey(string1.c_str(), string1.size(),
+        RRClass(0)));
+    uint32_t value2 = hash(HashKey(string2.c_str(), string2.size(),
+        RRClass(0)));
     EXPECT_EQ(value1, value2);
 }
 

+ 16 - 16
src/lib/nsas/tests/lru_list_unittest.cc

@@ -40,7 +40,7 @@ namespace nsas {
 class Dropped : public LruList<TestEntry>::Dropped {
 public:
     virtual void operator()(TestEntry* entry) const {
-        entry->setClass(entry->getClass() | 0x8000);
+        entry->setClass(RRClass(entry->getClass().getCode() | 0x8000));
     }
 };
 
@@ -49,13 +49,13 @@ public:
 class LruListTest : public ::testing::Test {
 protected:
     LruListTest() :
-        entry1_(new TestEntry("alpha", 1)),
-        entry2_(new TestEntry("beta", 2)),
-        entry3_(new TestEntry("gamma", 3)),
-        entry4_(new TestEntry("delta", 4)),
-        entry5_(new TestEntry("epsilon", 5)),
-        entry6_(new TestEntry("zeta", 6)),
-        entry7_(new TestEntry("eta", 7))
+        entry1_(new TestEntry("alpha", RRClass::IN())),
+        entry2_(new TestEntry("beta", RRClass::CH())),
+        entry3_(new TestEntry("gamma", RRClass::HS())),
+        entry4_(new TestEntry("delta", RRClass::IN())),
+        entry5_(new TestEntry("epsilon", RRClass::HS())),
+        entry6_(new TestEntry("zeta", RRClass::CH())),
+        entry7_(new TestEntry("eta", RRClass::IN()))
     {}
 
     virtual ~LruListTest() 
@@ -233,22 +233,22 @@ TEST_F(LruListTest, Dropped) {
     lru.add(entry2_);
     lru.add(entry3_);
 
-    EXPECT_EQ(1, entry1_->getClass());
-    EXPECT_EQ(2, entry2_->getClass());
+    EXPECT_EQ(RRClass::IN(), entry1_->getClass());
+    EXPECT_EQ(RRClass::CH(), entry2_->getClass());
 
     // Add another entry and check that the handler runs.
-    EXPECT_EQ(0, (entry1_->getClass() & 0x8000));
+    EXPECT_EQ(0, (entry1_->getClass().getCode() & 0x8000));
     lru.add(entry4_);
-    EXPECT_NE(0, (entry1_->getClass() & 0x8000));
+    EXPECT_NE(0, (entry1_->getClass().getCode() & 0x8000));
 
-    EXPECT_EQ(0, (entry2_->getClass() & 0x8000));
+    EXPECT_EQ(0, (entry2_->getClass().getCode() & 0x8000));
     lru.add(entry5_);
-    EXPECT_NE(0, (entry2_->getClass() & 0x8000));
+    EXPECT_NE(0, (entry2_->getClass().getCode() & 0x8000));
 
     // Delete an entry and check that the handler does not run. 
-    EXPECT_EQ(0, (entry3_->getClass() & 0x8000));
+    EXPECT_EQ(0, (entry3_->getClass().getCode() & 0x8000));
     lru.remove(entry3_);
-    EXPECT_EQ(0, (entry3_->getClass() & 0x8000));
+    EXPECT_EQ(0, (entry3_->getClass().getCode() & 0x8000));
 }
 
 // Miscellaneous tests - pathological conditions

+ 7 - 3
src/lib/nsas/tests/nameserver_address_unittest.cc

@@ -37,21 +37,24 @@ using namespace rdata;
 class NameserverEntrySample {
 public:
     NameserverEntrySample():
-        rrv4_(Name("example.org"), RRClass::IN(), RRType::A(), RRTTL(1200))
+        name_("example.org"),
+        rrv4_(name_, RRClass::IN(), RRType::A(), RRTTL(1200))
     {
         // Add some sample A records
         rrv4_.addRdata(ConstRdataPtr(new RdataTest<A>("1.2.3.4")));
         rrv4_.addRdata(ConstRdataPtr(new RdataTest<A>("5.6.7.8")));
         rrv4_.addRdata(ConstRdataPtr(new RdataTest<A>("9.10.11.12")));
 
-        ns_.reset(new NameserverEntry(&rrv4_, NULL));
+        ns_.reset(new NameserverEntry(name_.toText(), RRClass::IN()));
     }
 
     // Return the sample NameserverEntry
     boost::shared_ptr<NameserverEntry>& getNameserverEntry() { return ns_; }
 
     // Return the IOAddress corresponding to the index in rrv4_
-    asiolink::IOAddress getAddressAtIndex(uint32_t index) { return ns_.get()->getAddressAtIndex(index); }
+    asiolink::IOAddress getAddressAtIndex(uint32_t index) {
+        return ns_.get()->getAddressAtIndex(index);
+    }
 
     // Return the RTT of the address
     uint32_t getAddressRTTAtIndex(uint32_t index) { 
@@ -61,6 +64,7 @@ public:
     }
 
 private:
+    Name name_;                             ///< Name of the sample
     BasicRRset rrv4_;                       ///< Standard RRSet - IN, A, lowercase name
     boost::shared_ptr<NameserverEntry> ns_; ///< Shared_ptr that points to a NameserverEntry object
 };

+ 76 - 216
src/lib/nsas/tests/nameserver_entry_unittest.cc

@@ -57,91 +57,48 @@ protected:
         }
         Callback() : count(0) { }
     };
-};
-
-/// \brief Compare Vectors of String
-///
-/// Compares two vectors of strings.  A GoogleTest check is done on the results.
-///
-/// \param vec1 First vector.  This may be reordered in the comparison.
-/// \param vec2 Second vector.  This may be reordered in the comparison
-static void CompareStringVectors(vector<string>& vec1, vector<string>& vec2)
-{
-    // Check that the vectors are the same size.
-    EXPECT_EQ(vec1.size(), vec2.size());
-
-    // Get into canonical order
-    sort(vec1.begin(), vec1.end());
-    sort(vec2.begin(), vec2.end());
-
-    // ... and look for a mismatch.
-    EXPECT_TRUE(equal(vec1.begin(), vec1.end(), vec2.begin()));
-}
-
-/// \brief Compare Ranges of Addresses
-///
-/// Compares the addresses held in an address vector with those held in the
-/// RRset from which it was dervived and checks that there is a 1:1
-/// mapping between the two.
-///
-/// \param av AddressVector retrieved from NameserverEntry object
-/// \param rrs BasicRRSet from which the vector was created
-static void CompareAddresses(NameserverEntry::AddressVector& av,
-    BasicRRset& rrs)
-{
-
-    // Extract addresses from address vector into strings
-    vector<string> avs;
-    BOOST_FOREACH(AddressEntry addr, av) {
-        avs.push_back(addr.getAddress().toText());
-    }
-
-    // Do the same for the Basic RRset
-    vector<string> rrstr;
-    RdataIteratorPtr i = rrs.getRdataIterator();
-    // TODO Remove at merge with #410
-    i->first();
-    while (! i->isLast()) {
-        rrstr.push_back(i->getCurrent().toText());
-        i->next();
-    }
-
-    // ... and compare the results
-    CompareStringVectors(avs, rrstr);
-}
-
-
-/// \brief Compare Address Vectors
-///
-/// Compares two address vectors by converting the addresses to string form
-/// and comparing the strings.  Any mismatch will be reported.
-///
-/// \param vec1 First address vector
-/// \param vec2 Second address vector
-static void CompareAddressVectors(NameserverEntry::AddressVector& vec1,
-    NameserverEntry::AddressVector& vec2) {
-
-    // Extract addresses from address vectors into strings
-    vector<string> strvec1;
-    BOOST_FOREACH(AddressEntry addr, vec1) {
-        strvec1.push_back(addr.getAddress().toText());
+private:
+    void fillSet(shared_ptr<TestResolver> resolver, size_t index,
+        const BasicRRset *set)
+    {
+        if (set) {
+            shared_ptr<BasicRRset> new_set(new BasicRRset(set->getName(),
+                set->getClass(), set->getType(), set->getTTL()));
+            for(RdataIteratorPtr i(set->getRdataIterator()); !i->isLast();
+                i->next())
+            {
+                new_set->addRdata(i->getCurrent());
+            }
+            resolver->requests[index].second->success(new_set);
+        } else {
+            resolver->requests[index].second->failure();
+        }
     }
-
-    vector<string> strvec2;
-    BOOST_FOREACH(AddressEntry addr, vec2) {
-        strvec2.push_back(addr.getAddress().toText());
+protected:
+    /// Fills the nameserver entry with data trough ask IP
+    void fillNSEntry(shared_ptr<NameserverEntry> entry, const BasicRRset* rrv4,
+        const BasicRRset* rrv6)
+    {
+        // Prepare data to run askIP
+        shared_ptr<TestResolver> resolver(new TestResolver);
+        shared_ptr<Callback> callback(new Callback);
+        // Let it ask for data
+        entry->askIP(resolver, callback, ANY_OK, entry);
+        // Check it really asked and sort the queries
+        resolver->asksIPs(Name(entry->getName()), 0, 1);
+        // Respond with answers
+        fillSet(resolver, 0, rrv4);
+        fillSet(resolver, 1, rrv6);
     }
-
-    CompareStringVectors(strvec1, strvec2);
-}
+};
 
 /// Tests of the default constructor
 TEST_F(NameserverEntryTest, DefaultConstructor) {
 
     // Default constructor should not create any RRsets
-    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::IN().getCode());
+    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::IN());
     EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
-    EXPECT_EQ(RRClass::IN().getCode(), alpha.getClass());
+    EXPECT_EQ(RRClass::IN(), alpha.getClass());
 
     // Also check that no addresses have been created.
     NameserverEntry::AddressVector addresses;
@@ -149,99 +106,15 @@ TEST_F(NameserverEntryTest, DefaultConstructor) {
     EXPECT_TRUE(addresses.empty());
 }
 
-
-/// Tests of constructor passed a list of addresses.
-TEST_F(NameserverEntryTest, AddressListConstructor) {
-
-    // Initialize with no addresses and check that data returned has size of
-    // zero and knows it did not ask for the address yet
-    NameserverEntry alpha(NULL, NULL);
-    NameserverEntry::AddressVector av;
-    EXPECT_EQ(Fetchable::NOT_ASKED, alpha.getAddresses(av));
-    EXPECT_EQ(0, av.size());
-
-    NameserverEntry::AddressVector av4;
-    EXPECT_EQ(Fetchable::NOT_ASKED, alpha.getAddresses(av4, V4_ONLY));
-    EXPECT_EQ(0, av4.size());
-
-    NameserverEntry::AddressVector av6;
-    EXPECT_EQ(Fetchable::NOT_ASKED, alpha.getAddresses(av6, V6_ONLY));
-    EXPECT_EQ(0, av6.size());
-
-    // Initialize with V4 addresses only.
-    EXPECT_GT(rrv4_.getRdataCount(), 0);
-    NameserverEntry beta(&rrv4_, NULL);
-
-    NameserverEntry::AddressVector bv;
-    EXPECT_EQ(Fetchable::READY, beta.getAddresses(bv));
-    EXPECT_EQ(rrv4_.getRdataCount(), bv.size());
-
-    NameserverEntry::AddressVector bv4;
-    EXPECT_EQ(Fetchable::READY, beta.getAddresses(bv4, V4_ONLY));
-    EXPECT_EQ(rrv4_.getRdataCount(), bv4.size());
-
-    NameserverEntry::AddressVector bv6;
-    EXPECT_EQ(Fetchable::UNREACHABLE, beta.getAddresses(bv6, V6_ONLY));
-    EXPECT_EQ(0, bv6.size());
-
-    // Check that the addresses received are unique.
-    SCOPED_TRACE("Checking V4 addresses");
-    CompareAddresses(bv4, rrv4_);
-
-    // Initialize with V6 addresses only
-    EXPECT_TRUE(rrv6_.getRdataCount() > 0);
-    NameserverEntry gamma(NULL, &rrv6_);
-
-    NameserverEntry::AddressVector cv;
-    EXPECT_EQ(Fetchable::READY, gamma.getAddresses(cv));
-    EXPECT_EQ(rrv6_.getRdataCount(), cv.size());
-
-    NameserverEntry::AddressVector cv4;
-    EXPECT_EQ(Fetchable::UNREACHABLE, gamma.getAddresses(cv4, V4_ONLY));
-    EXPECT_EQ(0, cv4.size());
-
-    NameserverEntry::AddressVector cv6;
-    EXPECT_EQ(Fetchable::READY, gamma.getAddresses(cv6, V6_ONLY));
-    EXPECT_EQ(rrv6_.getRdataCount(), cv6.size());
-
-    SCOPED_TRACE("Checking V6 addresses");
-    CompareAddresses(cv6, rrv6_);
-
-    // Initialize with both sets of addresses
-    NameserverEntry delta(&rrv4_, &rrv6_);
-
-    NameserverEntry::AddressVector dv;
-    EXPECT_EQ(Fetchable::READY, delta.getAddresses(dv));
-    EXPECT_EQ((rrv4_.getRdataCount() + rrv6_.getRdataCount()), dv.size());
-
-    NameserverEntry::AddressVector dv4;
-    EXPECT_EQ(Fetchable::READY, delta.getAddresses(dv4, V4_ONLY));
-    EXPECT_EQ(rrv4_.getRdataCount(), dv4.size());
-    SCOPED_TRACE("Checking V4 addresses after dual-address family constructor");
-    CompareAddresses(dv4, rrv4_);
-
-    NameserverEntry::AddressVector dv6;
-    EXPECT_EQ(Fetchable::READY, delta.getAddresses(dv6, V6_ONLY));
-    EXPECT_EQ(rrv6_.getRdataCount(), dv6.size());
-    SCOPED_TRACE("Checking V6 addresses after dual-address family constructor");
-    CompareAddresses(dv6, rrv6_);
-
-    // ... and check that the composite of the v4 and v6 addresses is the same
-    // as that returned by the get without a filter.
-    NameserverEntry::AddressVector dvcomponent;
-    EXPECT_EQ(Fetchable::READY, delta.getAddresses(dvcomponent, V4_ONLY));
-    EXPECT_EQ(Fetchable::READY, delta.getAddresses(dvcomponent, V6_ONLY));
-    SCOPED_TRACE("Checking V4+V6 addresses same as composite return");
-    CompareAddressVectors(dv, dvcomponent);
-}
-
 // Test the the RTT on tthe created addresses is not 0 and is different
 TEST_F(NameserverEntryTest, InitialRTT) {
 
     // Get the RTT for the different addresses
-    NameserverEntry alpha(&rrv4_, &rrv6_);
+    shared_ptr<NameserverEntry> alpha(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(alpha, &rrv4_, &rrv6_);
     NameserverEntry::AddressVector vec;
-    alpha.getAddresses(vec);
+    alpha->getAddresses(vec);
 
     // Copy into a vector of time_t.
     vector<uint32_t> rtt;
@@ -267,9 +140,11 @@ TEST_F(NameserverEntryTest, InitialRTT) {
 TEST_F(NameserverEntryTest, SetRTT) {
 
     // Get the RTT for the different addresses
-    NameserverEntry alpha(&rrv4_, &rrv6_);
+    shared_ptr<NameserverEntry> alpha(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(alpha, &rrv4_, &rrv6_);
     NameserverEntry::AddressVector vec;
-    alpha.getAddresses(vec);
+    alpha->getAddresses(vec);
 
     ASSERT_TRUE(vec.size() > 0);
 
@@ -277,11 +152,11 @@ TEST_F(NameserverEntryTest, SetRTT) {
     IOAddress first_address = vec[0].getAddress();
     uint32_t first_rtt = vec[0].getRTT();
     uint32_t new_rtt = first_rtt + 42;
-    alpha.setAddressRTT(first_address, new_rtt);
+    alpha->setAddressRTT(first_address, new_rtt);
 
     // Now see if it has changed
     NameserverEntry::AddressVector newvec;
-    alpha.getAddresses(newvec);
+    alpha->getAddresses(newvec);
 
     int matchcount = 0;
     for (NameserverEntry::AddressVectorIterator i = newvec.begin();
@@ -300,9 +175,11 @@ TEST_F(NameserverEntryTest, SetRTT) {
 TEST_F(NameserverEntryTest, Unreachable) {
 
     // Get the RTT for the different addresses
-    NameserverEntry alpha(&rrv4_, &rrv6_);
+    shared_ptr<NameserverEntry> alpha(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(alpha, &rrv4_, &rrv6_);
     NameserverEntry::AddressVector vec;
-    alpha.getAddresses(vec);
+    alpha->getAddresses(vec);
 
     ASSERT_TRUE(vec.size() > 0);
 
@@ -310,11 +187,11 @@ TEST_F(NameserverEntryTest, Unreachable) {
     IOAddress first_address = vec[0].getAddress();
     EXPECT_FALSE(vec[0].isUnreachable());
 
-    alpha.setAddressUnreachable(first_address);
+    alpha->setAddressUnreachable(first_address);
 
     // Now see if it has changed
     NameserverEntry::AddressVector newvec;
-    alpha.getAddresses(newvec);
+    alpha->getAddresses(newvec);
 
     int matchcount = 0;
     for (NameserverEntry::AddressVectorIterator i = newvec.begin();
@@ -334,32 +211,42 @@ TEST_F(NameserverEntryTest, Unreachable) {
 // Note that for testing purposes we use the three-argument NameserverEntry
 // constructor (where we supply the time).  It eliminates intermittent errors
 // cause when this test is run just as the clock "ticks over" to another second.
+// TODO Return the way where we can pass time inside somehow
 TEST_F(NameserverEntryTest, ExpirationTime) {
 
     time_t curtime = time(NULL);
     time_t expiration = 0;
 
     // Test where there is a single TTL
-    NameserverEntry alpha(&rrv4_, NULL, curtime);
-    expiration = alpha.getExpiration();
+    shared_ptr<NameserverEntry> alpha(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(alpha, &rrv4_, NULL);
+    expiration = alpha->getExpiration();
     EXPECT_EQ(expiration, curtime + rrv4_.getTTL().getValue());
 
-    NameserverEntry beta(NULL, &rrv6_, curtime);
-    expiration = beta.getExpiration();
+    shared_ptr<NameserverEntry> beta(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(beta, NULL, &rrv6_);
+    expiration = beta->getExpiration();
     EXPECT_EQ(expiration, curtime + rrv6_.getTTL().getValue());
 
     // Test where there are two different TTLs
     EXPECT_NE(rrv4_.getTTL().getValue(), rrv6_.getTTL().getValue());
-    NameserverEntry gamma(&rrv4_, &rrv6_, curtime);
+    shared_ptr<NameserverEntry> gamma(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(gamma, &rrv4_, &rrv6_);
     uint32_t minttl = min(rrv4_.getTTL().getValue(), rrv6_.getTTL().getValue());
+    expiration = gamma->getExpiration();
     EXPECT_EQ(expiration, curtime + minttl);
 
     // Finally check where we don't specify a current time.  All we know is
     // that the expiration time should be greater than the TTL (as the current
     // time is greater than zero).
 
-    NameserverEntry delta(&rrv4_, NULL);
-    EXPECT_GT(delta.getExpiration(), rrv4_.getTTL().getValue());
+    shared_ptr<NameserverEntry> delta(new NameserverEntry(EXAMPLE_CO_UK,
+        RRClass::IN()));
+    fillNSEntry(gamma, &rrv4_, NULL);
+    EXPECT_GT(delta->getExpiration(), rrv4_.getTTL().getValue());
 }
 
 
@@ -367,50 +254,23 @@ TEST_F(NameserverEntryTest, ExpirationTime) {
 TEST_F(NameserverEntryTest, CheckName) {
 
     // Default constructor
-    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::IN().getCode());
+    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::IN());
     EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
-
-    // Address constructor
-    NameserverEntry beta(&rrv4_, NULL);
-    EXPECT_EQ(EXAMPLE_CO_UK, beta.getName());
-
-    NameserverEntry gamma(NULL, &rrv6_);
-    EXPECT_EQ(EXAMPLE_CO_UK, gamma.getName());
-
-    NameserverEntry delta(&rrv4_, &rrv6_);
-    EXPECT_EQ(EXAMPLE_CO_UK, delta.getName());
-
-    // Check that the name is not canonicalised
-    NameserverEntry epsilon(&rrcase_, NULL);
-    EXPECT_EQ(MIXED_EXAMPLE_CO_UK, epsilon.getName());
-
-    // Check that inconsistent names mean that an exception is generated.
-    EXPECT_THROW(NameserverEntry zeta(&rrnet_, &rrv6_),
-        isc::nsas::InconsistentOwnerNames);
 }
 
 // Check that it can cope with non-IN classes.
 TEST_F(NameserverEntryTest, CheckClass) {
 
     // Default constructor
-    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::CH().getCode());
-    EXPECT_EQ(RRClass::CH().getCode(), alpha.getClass());
-
-    // Address constructor
-    NameserverEntry beta(&rrch_, NULL);
-    EXPECT_EQ(RRClass::CH().getCode(), beta.getClass());
-
-    // Ensure that inconsistent class throws an exception
-    EXPECT_THROW(NameserverEntry gamma(&rrch_, &rrv6_),
-        isc::nsas::InconsistentClass);
-
+    NameserverEntry alpha(EXAMPLE_CO_UK, RRClass::CH());
+    EXPECT_EQ(RRClass::CH(), alpha.getClass());
 }
 
 // Tests if it asks the IP addresses and calls callbacks when it comes
 // including the right addresses are returned and that they expire
 TEST_F(NameserverEntryTest, IPCallbacks) {
     shared_ptr<NameserverEntry> entry(new NameserverEntry(EXAMPLE_CO_UK,
-        RRClass::IN().getCode()));
+        RRClass::IN()));
     shared_ptr<Callback> callback(new Callback);
     shared_ptr<TestResolver> resolver(new TestResolver);
 
@@ -418,8 +278,8 @@ TEST_F(NameserverEntryTest, IPCallbacks) {
     // Ensure it becomes IN_PROGRESS
     EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
     // Now, there should be two queries in the resolver
-    ASSERT_EQ(2, resolver->requests.size());
-    resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1);
+    EXPECT_EQ(2, resolver->requests.size());
+    ASSERT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
 
     // Another one might ask
     entry->askIP(resolver, callback, V4_ONLY, entry);
@@ -459,15 +319,15 @@ TEST_F(NameserverEntryTest, IPCallbacks) {
 // Test the callback is called even when the address is unreachable
 TEST_F(NameserverEntryTest, IPCallbacksUnreachable) {
     shared_ptr<NameserverEntry> entry(new NameserverEntry(EXAMPLE_CO_UK,
-        RRClass::IN().getCode()));
+        RRClass::IN()));
     shared_ptr<Callback> callback(new Callback);
     shared_ptr<TestResolver> resolver(new TestResolver);
 
     // Ask for its IP
     entry->askIP(resolver, callback, ANY_OK, entry);
     // Check it asks the resolver
-    ASSERT_EQ(2, resolver->requests.size());
-    resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1);
+    EXPECT_EQ(2, resolver->requests.size());
+    ASSERT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
     resolver->requests[0].second->failure();
     // It should still wait for the second one
     EXPECT_EQ(0, callback->count);

+ 3 - 3
src/lib/nsas/tests/nsas_entry_compare_unittest.cc

@@ -39,9 +39,9 @@ class NsasEntryCompareTest : public ::testing::Test {
 TEST_F(NsasEntryCompareTest, Compare) {
 
     // Construct a couple of different objects
-    TestEntry entry1("test1", 42);
-    TestEntry entry2("test1", 24);
-    TestEntry entry3("test2", 42);
+    TestEntry entry1("test1", RRClass(42));
+    TestEntry entry2("test1", RRClass(24));
+    TestEntry entry3("test2", RRClass(42));
 
     // Create corresponding hash key objects
     HashKey key1(entry1.getName(), entry1.getClass());

+ 14 - 9
src/lib/nsas/tests/nsas_test.h

@@ -158,7 +158,7 @@ public:
     /// \param name Name that will be used for the object.  This will form
     /// part of the key.
     /// \param class_code Class associated with the object.
-    TestEntry(std::string name, uint16_t class_code) :
+    TestEntry(std::string name, const isc::dns::RRClass& class_code) :
         name_(name), class_code_(class_code)
     {}
 
@@ -191,20 +191,20 @@ public:
     /// \brief Get the Class
     ///
     /// \return Class code assigned to this object
-    virtual uint16_t getClass() const {
+    virtual const isc::dns::RRClass& getClass() const {
         return class_code_;
     }
 
     /// \brief Set the Class
     ///
     /// \param class_code New class code of the object
-    virtual void setClass(uint16_t class_code) {
+    virtual void setClass(const isc::dns::RRClass& class_code) {
         class_code_ = class_code;
     }
 
 private:
     std::string name_;          ///< Name of the object
-    uint16_t    class_code_;    ///< Class of the object
+    isc::dns::RRClass    class_code_;    ///< Class of the object
 };
 
 /// \brief isc::nsas Constants
@@ -226,8 +226,8 @@ using namespace std;
  */
 class TestResolver : public isc::nsas::ResolverInterface {
     private:
-        void checkIndex(size_t index) {
-            ASSERT_GT(requests.size(), index);
+        bool checkIndex(size_t index) {
+            return (requests.size() > index);
         }
     public:
         typedef pair<QuestionPtr, CallbackPtr> Request;
@@ -236,16 +236,20 @@ class TestResolver : public isc::nsas::ResolverInterface {
             requests.push_back(Request(q, c));
         }
         QuestionPtr operator[](size_t index) {
-            checkIndex(index);
+            EXPECT_TRUE(checkIndex(index));
             return (requests[index].first);
         }
         /*
          * Looks if the two provided requests in resolver are A and AAAA.
          * Sorts them so index1 is A.
+         *
+         * Returns false if there aren't enough elements
          */
-        void asksIPs(const Name& name, size_t index1, size_t index2) {
+        bool asksIPs(const Name& name, size_t index1, size_t index2) {
             size_t max = (index1 < index2) ? index2 : index1;
-            checkIndex(max);
+            if (!checkIndex(max)) {
+                return false;
+            }
             EXPECT_EQ(name, (*this)[index1]->getName());
             EXPECT_EQ(name, (*this)[index2]->getName());
             EXPECT_EQ(RRClass::IN(), (*this)[index1]->getClass());
@@ -262,6 +266,7 @@ class TestResolver : public isc::nsas::ResolverInterface {
             // Check the correct addresses
             EXPECT_EQ(RRType::A(), (*this)[index1]->getType());
             EXPECT_EQ(RRType::AAAA(), (*this)[index2]->getType());
+            return (true);
         }
 
         /*

+ 2 - 2
src/lib/nsas/tests/zone_entry_unittest.cc

@@ -94,7 +94,7 @@ TEST_F(ZoneEntryTest, DefaultConstructor) {
     InheritedZoneEntry alpha(resolver_, EXAMPLE_CO_UK,
         RRClass::IN().getCode(), nameserver_table_, nameserver_lru_);
     EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
-    EXPECT_EQ(RRClass::IN().getCode(), alpha.getClass());
+    EXPECT_EQ(RRClass::IN(), alpha.getClass());
     EXPECT_TRUE(alpha.nameservers().empty());
 }
 
@@ -104,7 +104,7 @@ TEST_F(ZoneEntryTest, ReferralConstructor) {
         nameserver_lru_);
     // It should load the name and class from the referral info
     EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
-    EXPECT_EQ(RRClass::IN().getCode(), alpha.getClass());
+    EXPECT_EQ(RRClass::IN(), alpha.getClass());
     EXPECT_EQ(1, alpha.nameservers().size());
     EXPECT_EQ("ns.example.net.", alpha.nameservers()[0]->getName());
     // TODO Test with some additional data once NameserverEntry supports them?

+ 2 - 1
src/lib/nsas/zone_entry.cc

@@ -37,9 +37,10 @@ typedef shared_ptr<AddressRequestCallback> CallbackPtr;
 }
 
 ZoneEntry::ZoneEntry(shared_ptr<ResolverInterface> resolver,
-    const AbstractRRset&,
+    const AbstractRRset& set,
     shared_ptr<HashTable<NameserverEntry> > nameserver_table,
     shared_ptr<LruList<NameserverEntry> > nameserver_lru) :
+    classCode_(set.getClass()),
     resolver_(resolver),
     nameserver_table_(nameserver_table),
     nameserver_lru_(nameserver_lru)

+ 2 - 2
src/lib/nsas/zone_entry.h

@@ -95,7 +95,7 @@ public:
     }
 
     /// \return Class of zone
-    short getClass() const {
+    const isc::dns::RRClass& getClass() const {
         return classCode_;
     }
 
@@ -137,7 +137,7 @@ protected:
 private:
     mutable boost::mutex    mutex_;     ///< Mutex protecting this zone entry
     std::string     name_;      ///< Canonical zone name
-    uint16_t        classCode_; ///< Class code
+    isc::dns::RRClass        classCode_; ///< Class code
     // Internal function that adds a callback (if there's one) and processes
     // the nameservers (if there's chance there's some info) and calls
     // callbacks. If nameserver is given, it is considered new and valid