Browse Source

[trac638] Fix the assert error by adding the check for empty pointer, also add test case for it.

zhanglikun 14 years ago
parent
commit
fa83bb9951

+ 3 - 0
src/lib/cache/message_cache.h

@@ -41,6 +41,9 @@ public:
     MessageCache(boost::shared_ptr<RRsetCache> rrset_cache_,
                  uint32_t cache_size, uint16_t message_class);
 
+    /// \brief Destructor function
+    virtual ~MessageCache() {}
+
     /// \brief Look up message in cache.
     /// \param message generated response message if the message entry
     ///        can be found.

+ 1 - 1
src/lib/cache/message_entry.cc

@@ -48,7 +48,7 @@ MessageEntry::getRRsetEntries(vector<RRsetEntryPtr>& rrset_entry_vec,
     for (int index = 0; index < entry_count; ++index) {
         RRsetEntryPtr rrset_entry = rrset_cache_->lookup(rrsets_[index].name_,
                                                         rrsets_[index].type_);
-        if (time_now < rrset_entry->getExpireTime()) {
+        if (rrset_entry && time_now < rrset_entry->getExpireTime()) {
             rrset_entry_vec.push_back(rrset_entry);
         } else {
             return (false);

+ 3 - 2
src/lib/cache/rrset_cache.h

@@ -45,7 +45,7 @@ public:
     /// \param cache_size the size of rrset cache.
     /// \param rrset_class the class of rrset cache.
     RRsetCache(uint32_t cache_size, uint16_t rrset_class);
-    ~RRsetCache() {}
+    virtual ~RRsetCache() {}
     //@}
 
     /// \brief Look up rrset in cache.
@@ -92,7 +92,8 @@ public:
     bool resize(uint32_t size);
 #endif
 
-private:
+    /// \short Protected memebers, so they can be accessed by tests.
+protected:
     uint16_t class_; // The class of the rrset cache.
     isc::nsas::HashTable<RRsetEntry> rrset_table_;
     isc::nsas::LruList<RRsetEntry> rrset_lru_;

+ 28 - 3
src/lib/cache/tests/message_cache_unittest.cc

@@ -43,20 +43,40 @@ public:
     }
 };
 
+/// \brief Derived from base class to make it easy to test
+/// its internals.
+class DerivedRRsetCache: public RRsetCache {
+public:
+    DerivedRRsetCache(uint32_t cache_size, uint16_t rrset_class):
+        RRsetCache(cache_size, rrset_class)
+    {}
+
+    /// \brief Remove one rrset entry from rrset cache.
+    void removeRRsetEntry(Name& name, const RRType& type) {
+        const string entry_name = genCacheEntryName(name, type);
+        HashKey entry_key = HashKey(entry_name, RRClass(class_));
+        RRsetEntryPtr rrset_entry = rrset_table_.get(entry_key);
+        if (rrset_entry) {
+            rrset_lru_.remove(rrset_entry);
+            rrset_table_.remove(entry_key);
+        }
+    }
+};
+
 class MessageCacheTest: public testing::Test {
 public:
     MessageCacheTest(): message_parse(Message::PARSE),
                         message_render(Message::RENDER)
     {
         uint16_t class_ = RRClass::IN().getCode();
-        rrset_cache_.reset(new RRsetCache(RRSET_CACHE_DEFAULT_SIZE, class_));
-        message_cache_.reset(new DerivedMessageCache(rrset_cache_, 
+        rrset_cache_.reset(new DerivedRRsetCache(RRSET_CACHE_DEFAULT_SIZE, class_));
+        message_cache_.reset(new DerivedMessageCache(rrset_cache_,
                                           MESSAGE_CACHE_DEFAULT_SIZE, class_ ));
     }
 
 protected:
     boost::shared_ptr<DerivedMessageCache> message_cache_;
-    RRsetCachePtr rrset_cache_;
+    boost::shared_ptr<DerivedRRsetCache> rrset_cache_;
     Message message_parse;
     Message message_render;
 };
@@ -75,6 +95,11 @@ TEST_F(MessageCacheTest, testLookup) {
 
     Name qname1("test.example.net.");
     EXPECT_TRUE(message_cache_->lookup(qname1, RRType::A(), message_render));
+
+    // Test looking up message which has expired rrsets.
+    // Remove one
+    rrset_cache_->removeRRsetEntry(qname1, RRType::A());
+    EXPECT_FALSE(message_cache_->lookup(qname1, RRType::A(), message_render));
 }
 
 TEST_F(MessageCacheTest, testUpdate) {