TestHostRecordQueue.cpp (3527B)
1 #include "gtest/gtest.h" 2 3 #include "HostRecordQueue.h" 4 #include "TRRQuery.h" 5 #include "TRR.h" 6 7 using namespace mozilla; 8 using namespace mozilla::net; 9 10 class MockHostRecord : public nsHostRecord { 11 public: 12 NS_DECL_ISUPPORTS_INHERITED 13 explicit MockHostRecord(const nsHostKey& aKey) : nsHostRecord(aKey) { 14 negative = true; 15 } 16 17 void ResolveComplete() override {} 18 19 bool HasUsableResultInternal( 20 const mozilla::TimeStamp& now, 21 nsIDNSService::DNSFlags queryFlags) const override { 22 return true; 23 } 24 25 private: 26 ~MockHostRecord() = default; 27 }; 28 29 NS_IMPL_ISUPPORTS_INHERITED(MockHostRecord, nsHostRecord, MockHostRecord) 30 31 class HostRecordQueueTest : public ::testing::Test { 32 protected: 33 void SetUp() override {} 34 35 HostRecordQueue queue; 36 Mutex mMutex{"HostRecordQueueTest"}; 37 nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord> mDB; 38 }; 39 40 static RefPtr<nsHostRecord> CreateAndInsertMockRecord( 41 nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord>& aDB, 42 const char* hostName) { 43 nsHostKey key(nsCString(hostName), ""_ns, 0, 44 nsIDNSService::RESOLVE_DEFAULT_FLAGS, 0, false, ""_ns); 45 return aDB.LookupOrInsertWith(key, [&] { return new MockHostRecord(key); }); 46 } 47 48 TEST_F(HostRecordQueueTest, AddToEvictionQ_BelowMax) { 49 RefPtr<nsHostRecord> rec = CreateAndInsertMockRecord(mDB, "A.com"); 50 51 MutexAutoLock lock(mMutex); 52 53 queue.AddToEvictionQ(rec.get(), 100, mDB, lock); 54 55 ASSERT_EQ(1u, queue.EvictionQSize()); 56 ASSERT_TRUE(rec->isInList()); 57 58 // Cleanup 59 rec->remove(); 60 } 61 62 // When the eviction queue is at capacity, adding a new entry evicts the 63 // oldest (head) entry. 64 TEST_F(HostRecordQueueTest, AddToEvictionQ_AtMax_EvictsOldest) { 65 const uint32_t MAX_ENTRIES = 3; 66 67 RefPtr<nsHostRecord> rec1 = CreateAndInsertMockRecord(mDB, "A.com"); 68 RefPtr<nsHostRecord> rec2 = CreateAndInsertMockRecord(mDB, "B.com"); 69 RefPtr<nsHostRecord> rec3 = CreateAndInsertMockRecord(mDB, "C.com"); 70 71 MutexAutoLock lock(mMutex); 72 queue.AddToEvictionQ(rec1, MAX_ENTRIES, mDB, lock); 73 queue.AddToEvictionQ(rec2, MAX_ENTRIES, mDB, lock); 74 queue.AddToEvictionQ(rec3, MAX_ENTRIES, mDB, lock); 75 76 ASSERT_EQ(MAX_ENTRIES, queue.EvictionQSize()); 77 78 RefPtr<nsHostRecord> rec4 = CreateAndInsertMockRecord(mDB, "New.com"); 79 queue.AddToEvictionQ(rec4, MAX_ENTRIES, mDB, lock); 80 81 ASSERT_TRUE(rec2->isInList()); 82 ASSERT_TRUE(rec3->isInList()); 83 ASSERT_TRUE(rec4->isInList()); 84 ASSERT_FALSE(rec1->isInList()); 85 86 rec2->remove(); 87 rec3->remove(); 88 rec4->remove(); 89 } 90 91 // After adding a new record, the touched entry 92 // remains, and the oldest untouched entry is evicted. 93 TEST_F(HostRecordQueueTest, MoveToEvictionQueueTail) { 94 const uint32_t MAX_ENTRIES = 3; 95 96 RefPtr<nsHostRecord> rec1 = CreateAndInsertMockRecord(mDB, "A.com"); 97 RefPtr<nsHostRecord> rec2 = CreateAndInsertMockRecord(mDB, "B.com"); 98 RefPtr<nsHostRecord> rec3 = CreateAndInsertMockRecord(mDB, "C.com"); 99 100 MutexAutoLock lock(mMutex); 101 queue.AddToEvictionQ(rec1, MAX_ENTRIES, mDB, lock); 102 queue.AddToEvictionQ(rec2, MAX_ENTRIES, mDB, lock); 103 queue.AddToEvictionQ(rec3, MAX_ENTRIES, mDB, lock); 104 105 ASSERT_EQ(MAX_ENTRIES, queue.EvictionQSize()); 106 107 queue.MoveToEvictionQueueTail(rec1, lock); 108 109 RefPtr<nsHostRecord> rec4 = CreateAndInsertMockRecord(mDB, "New.com"); 110 queue.AddToEvictionQ(rec4, MAX_ENTRIES, mDB, lock); 111 112 ASSERT_TRUE(rec1->isInList()); 113 ASSERT_TRUE(rec3->isInList()); 114 ASSERT_TRUE(rec4->isInList()); 115 ASSERT_FALSE(rec2->isInList()); 116 117 rec1->remove(); 118 rec3->remove(); 119 rec4->remove(); 120 }