aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/test/test-packet_cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/test/test-packet_cache.cc')
-rw-r--r--hicn-light/src/hicn/test/test-packet_cache.cc524
1 files changed, 524 insertions, 0 deletions
diff --git a/hicn-light/src/hicn/test/test-packet_cache.cc b/hicn-light/src/hicn/test/test-packet_cache.cc
new file mode 100644
index 000000000..bb24daeb8
--- /dev/null
+++ b/hicn-light/src/hicn/test/test-packet_cache.cc
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <thread>
+#include <optional>
+
+extern "C" {
+#define WITH_TESTS
+#include <hicn/core/packet_cache.h>
+}
+
+const unsigned CS_SIZE = 100;
+const unsigned CONN_ID = 0;
+const unsigned CONN_ID_2 = 1;
+const unsigned MSGBUF_ID = 0;
+const unsigned MSGBUF_ID_2 = 1;
+const unsigned MSGBUF_ID_3 = 2;
+const unsigned FIVE_SECONDS = 5000;
+const unsigned IPV4_LEN = 32;
+const unsigned IPV6_LEN = 128;
+
+class PacketCacheTest : public ::testing::Test {
+ protected:
+ PacketCacheTest() {
+ pkt_cache = pkt_cache_create(CS_SIZE);
+ name = (Name *)malloc(sizeof(Name));
+ name_CreateFromAddress(name, AF_INET, IPV4_ANY, IPV4_LEN);
+ msgbuf_pool = msgbuf_pool_create();
+ }
+ virtual ~PacketCacheTest() {
+ pkt_cache_free(pkt_cache);
+ msgbuf_pool_free(msgbuf_pool);
+ }
+
+ pkt_cache_t *pkt_cache;
+ pkt_cache_entry_t *entry = nullptr;
+ msgbuf_pool_t *msgbuf_pool;
+ Name *name;
+};
+
+msgbuf_t *msgbuf_factory(msgbuf_pool_t *msgbuf_pool, unsigned conn_id,
+ Name *name,
+ std::optional<Ticks> lifetime = FIVE_SECONDS) {
+ msgbuf_t *msgbuf;
+ msgbuf_pool_get(msgbuf_pool, &msgbuf);
+
+ msgbuf->connection_id = conn_id;
+ name_Copy(name, msgbuf_get_name(msgbuf));
+ hicn_packet_init_header(HF_INET6_TCP,
+ (hicn_header_t *)msgbuf_get_packet(msgbuf));
+ // Same as 'msgbuf_set_data_expiry_time',
+ // it would write in the same field
+ msgbuf_set_interest_lifetime(msgbuf, *lifetime);
+
+ return msgbuf;
+}
+
+TEST_F(PacketCacheTest, CreatePacketCache) {
+ // Check packet cache allocation
+ EXPECT_NE(pkt_cache, nullptr);
+ pit_t *pit = pkt_cache_get_pit(pkt_cache);
+ ASSERT_NE(pit, nullptr);
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ ASSERT_NE(cs, nullptr);
+
+ // Check sizes
+ ASSERT_EQ(pkt_cache_get_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+}
+
+TEST_F(PacketCacheTest, AddPacketCacheEntry) {
+ // Add entry to the packet cache
+ entry = pkt_cache_allocate(pkt_cache, name);
+ EXPECT_NE(entry, nullptr);
+ ASSERT_EQ(pkt_cache_get_size(pkt_cache), 1u);
+
+ // // Get entry by name
+ Name name_key = name_key_factory(name);
+ khiter_t k = kh_get_pkt_cache_name(pkt_cache->index_by_name, &name_key);
+ EXPECT_NE(k, kh_end(pkt_cache->index_by_name));
+}
+
+TEST_F(PacketCacheTest, GetCS) {
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ ASSERT_NE(cs, nullptr);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ EXPECT_EQ(cs->type, CS_TYPE_LRU);
+ EXPECT_EQ(cs->num_entries, 0);
+ EXPECT_EQ(cs->lru.head, (off_t)INVALID_ENTRY_ID);
+ EXPECT_EQ(cs->lru.tail, (off_t)INVALID_ENTRY_ID);
+}
+
+TEST_F(PacketCacheTest, GetPIT) {
+ pit_t *pit = pkt_cache_get_pit(pkt_cache);
+ ASSERT_NE(pit, nullptr);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+}
+
+TEST_F(PacketCacheTest, LookupEmpty) {
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *entry = pkt_cache_lookup(pkt_cache, name, msgbuf_pool,
+ &lookup_result, &entry_id, true);
+
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
+ EXPECT_EQ(entry, nullptr);
+}
+
+TEST_F(PacketCacheTest, AddEntryAndLookup) {
+ // Add entry to the packet cache
+ entry = pkt_cache_allocate(pkt_cache, name);
+ entry->entry_type = PKT_CACHE_PIT_TYPE;
+ ASSERT_NE(entry, nullptr);
+
+ // Perform lookup
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+
+ EXPECT_TRUE(lookup_result == PKT_CACHE_LU_INTEREST_NOT_EXPIRED ||
+ lookup_result == PKT_CACHE_LU_INTEREST_EXPIRED);
+ EXPECT_NE(lu_entry, nullptr);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, AddToPIT) {
+ // Prepare msgbuf
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+
+ // Check if entry properly created
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
+ EXPECT_EQ(pit_entry_ingress_contains(&entry->u.pit_entry, CONN_ID), true);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, AddToCS) {
+ // Prepare msgbuf
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+
+ // Check if entry properly created
+ pkt_cache_entry_t *entry =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ cs_entry_t *cs_entry = &entry->u.cs_entry;
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_CS_TYPE);
+ EXPECT_EQ(cs_entry->msgbuf_id, MSGBUF_ID);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 1u);
+
+ // Check if CS properly updated
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+ EXPECT_EQ(cs->num_entries, 1);
+ EXPECT_EQ(cs->lru.head, entry_id);
+ EXPECT_EQ(cs->lru.tail, entry_id);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, PitToCS) {
+ // Prepare msgbuf and PIT entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if entry properly updated
+ pkt_cache_pit_to_cs(pkt_cache, entry, msgbuf_pool, msgbuf, MSGBUF_ID,
+ entry_id);
+ cs_entry_t *cs_entry = &entry->u.cs_entry;
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_CS_TYPE);
+ EXPECT_EQ(cs_entry->msgbuf_id, MSGBUF_ID);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 1u);
+
+ // Check if CS properly updated
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+ EXPECT_EQ(cs->num_entries, 1);
+ EXPECT_EQ(cs->lru.head, entry_id);
+ EXPECT_EQ(cs->lru.tail, entry_id);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, CsToPIT) {
+ // Prepare msgbuf and CS entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 1u);
+
+ // Check if entry properly updated
+ pkt_cache_cs_to_pit(pkt_cache, entry, msgbuf_pool, msgbuf, MSGBUF_ID,
+ entry_id);
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
+ EXPECT_EQ(pit_entry_ingress_contains(&entry->u.pit_entry, CONN_ID), true);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, UpdateInPIT) {
+ // Prepare msgbuf and PIT entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+
+ Name new_name;
+ name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *new_msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID_2, &new_name);
+
+ // Check if entry properly updated
+ pkt_cache_update_pit(pkt_cache, entry, new_msgbuf);
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
+ EXPECT_EQ(pit_entry_ingress_contains(&entry->u.pit_entry, CONN_ID_2), true);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, UpdateInCS) {
+ // Prepare msgbuf and CS entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
+
+ Name new_name;
+ name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *new_msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID_2, &new_name);
+
+ // Check if entry properly updated
+ pkt_cache_update_cs(pkt_cache, msgbuf_pool, entry, new_msgbuf, MSGBUF_ID_2);
+ cs_entry_t *cs_entry = &entry->u.cs_entry;
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_CS_TYPE);
+ EXPECT_EQ(cs_entry->msgbuf_id, MSGBUF_ID_2);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 1u);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, RemoveFromPIT) {
+ // Prepare msgbuf and PIT entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ pkt_cache_pit_remove_entry(pkt_cache, entry, name);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
+ EXPECT_EQ(lu_entry, nullptr);
+}
+
+TEST_F(PacketCacheTest, RemoveFromCS) {
+ // Prepare msgbuf and CS entry
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ pkt_cache_entry_t *entry =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 1u);
+
+ pkt_cache_cs_remove_entry(pkt_cache, entry, msgbuf_pool, false);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
+
+ // Check if CS properly updated
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ EXPECT_EQ(cs->num_entries, 0);
+ EXPECT_EQ(cs->lru.head, (off_t)INVALID_ENTRY_ID);
+ EXPECT_EQ(cs->lru.tail, (off_t)INVALID_ENTRY_ID);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
+ EXPECT_EQ(lu_entry, nullptr);
+}
+
+TEST_F(PacketCacheTest, AddTwoEntriesToCS) {
+ // Prepare msgbufs
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ Name new_name;
+ name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *new_msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID_2, &new_name);
+
+ pkt_cache_entry_t *entry_1 =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ pkt_cache_entry_t *entry_2 =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, new_msgbuf, MSGBUF_ID_2);
+ off_t entry_id_1 = pkt_cache_get_entry_id(pkt_cache, entry_1);
+ off_t entry_id_2 = pkt_cache_get_entry_id(pkt_cache, entry_2);
+
+ // Check if the CS and LRU cache are properly updated
+ cs_t *cs = pkt_cache_get_cs(pkt_cache);
+ EXPECT_EQ(cs->num_entries, 2);
+ EXPECT_EQ(cs->lru.head, entry_id_2);
+ EXPECT_EQ(cs->lru.tail, entry_id_1);
+ ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
+ ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 2u);
+}
+
+TEST_F(PacketCacheTest, AggregateInPIT) {
+ // Prepare msgbufs
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ Name new_name;
+ name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *new_msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID_2, &new_name);
+
+ // Check if entry properly created (use sleep to get an updated ts)
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ Ticks old_lifetime = entry->expire_ts;
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ bool is_aggregated =
+ pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf);
+ Ticks new_lifetime = entry->expire_ts;
+
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
+ EXPECT_GT(new_lifetime, old_lifetime);
+ ASSERT_EQ(is_aggregated, true);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, RetransmissionInPIT) {
+ // Prepare msgbufs (using same connection ID)
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name);
+ Name new_name;
+ name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *new_msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, &new_name);
+
+ // Check if entry properly created (use sleep to get an updated ts)
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ Ticks old_lifetime = entry->expire_ts;
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ bool is_aggregated =
+ pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf);
+ Ticks new_lifetime = entry->expire_ts;
+
+ ASSERT_NE(entry, nullptr);
+ EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
+ EXPECT_GT(new_lifetime, old_lifetime);
+ ASSERT_EQ(is_aggregated, false);
+
+ // Check if hashtable correctly updated
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
+ pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
+ EXPECT_EQ(lu_entry, entry);
+}
+
+TEST_F(PacketCacheTest, LookupExpiredInterest) {
+ // Prepare msgbuf with 0 as interest lifetime
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name, 0);
+
+ // Add to PIT
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf);
+ ASSERT_NE(entry, nullptr);
+
+ // Wait to make the interest expire
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_lookup(pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id,
+ true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_EXPIRED);
+}
+
+TEST_F(PacketCacheTest, LookupExpiredData) {
+ // Prepare msgbuf with 0 as data expiry time
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name, 0);
+
+ // Add to CS
+ pkt_cache_entry_t *entry =
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+ ASSERT_NE(entry, nullptr);
+
+ // Wait to make the interest expire
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ pkt_cache_lookup_t lookup_result;
+ off_t entry_id;
+ pkt_cache_lookup(pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id,
+ true);
+ EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_EXPIRED);
+}
+
+TEST_F(PacketCacheTest, GetStaleEntries) {
+ // Add to CS a msgbuf with immediate expiration (i.e. stale)
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, CONN_ID, name, 0);
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
+
+ // Add to CS another msgbuf with immediate expiration (i.e. stale)
+ Name name_2;
+ name_CreateFromAddress(&name_2, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ msgbuf_t *msgbuf_2 = msgbuf_factory(msgbuf_pool, CONN_ID, &name_2, 0);
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf_2, MSGBUF_ID_2);
+
+ // Add to CS a msgbuf with 5-seconds expiration (i.e. not stale)
+ Name name_3;
+ name_CreateFromAddress(&name_3, AF_INET6, IPV6_LOOPBACK, IPV6_LEN);
+ msgbuf_t *msgbuf_3 =
+ msgbuf_factory(msgbuf_pool, CONN_ID, &name_3, FIVE_SECONDS);
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf_3, MSGBUF_ID_3);
+
+ size_t num_stale_entries = pkt_cache_get_num_cs_stale_entries(pkt_cache);
+ EXPECT_EQ(num_stale_entries, 2u);
+}
+
+TEST_F(PacketCacheTest, GetMultipleStaleEntries) {
+ ip_address_t addr;
+ char name[30];
+ const int NUM_STALES = 10;
+
+ // Add to CS multiple msgbufs with immediate expiration (i.e. 0 seconds),
+ // resulting in stale entries
+ for (int i = 0; i < NUM_STALES; i++) {
+ snprintf(name, 30, "b001::%d", i);
+ inet_pton(AF_INET6, name, (struct in6_addr *)&addr);
+ Name name;
+ name_CreateFromAddress(&name, AF_INET6, addr, IPV6_LEN);
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, i, &name, 0);
+
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, i);
+ }
+
+ // Add to CS multiple msgbufs with 5-seconds expiration,
+ // resulting in non-stale entries
+ for (int i = NUM_STALES; i < 15; i++) {
+ snprintf(name, 30, "b001::%d", i);
+ inet_pton(AF_INET6, name, (struct in6_addr *)&addr);
+ Name name;
+ name_CreateFromAddress(&name, AF_INET6, addr, IPV6_LEN);
+ msgbuf_t *msgbuf = msgbuf_factory(msgbuf_pool, i, &name, FIVE_SECONDS);
+
+ pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, i);
+ }
+
+ size_t num_stale_entries = pkt_cache_get_num_cs_stale_entries(pkt_cache);
+ EXPECT_EQ(num_stale_entries, (size_t)NUM_STALES);
+}