Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/url-classifier/tests/gtest/TestCaching.cpp
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "Common.h"
6
7
0
#define EXPIRED_TIME_SEC     (PR_Now() / PR_USEC_PER_SEC - 3600)
8
0
#define NOTEXPIRED_TIME_SEC  (PR_Now() / PR_USEC_PER_SEC + 3600)
9
10
static void
11
SetupCacheEntry(LookupCacheV2* aLookupCache,
12
                const nsCString& aCompletion,
13
                bool aNegExpired = false,
14
                bool aPosExpired = false)
15
0
{
16
0
  AddCompleteArray completes;
17
0
  AddCompleteArray emptyCompletes;
18
0
  MissPrefixArray misses;
19
0
  MissPrefixArray emptyMisses;
20
0
21
0
  AddComplete* add = completes.AppendElement(fallible);
22
0
  add->complete.FromPlaintext(aCompletion);
23
0
24
0
  Prefix* prefix = misses.AppendElement(fallible);
25
0
  prefix->FromPlaintext(aCompletion);
26
0
27
0
  // Setup positive cache first otherwise negative cache expiry will be
28
0
  // overwritten.
29
0
  int64_t posExpirySec = aPosExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
30
0
  aLookupCache->AddGethashResultToCache(completes, emptyMisses, posExpirySec);
31
0
32
0
  int64_t negExpirySec = aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
33
0
  aLookupCache->AddGethashResultToCache(emptyCompletes, misses, negExpirySec);
34
0
}
35
36
static void
37
SetupCacheEntry(LookupCacheV4* aLookupCache,
38
                const nsCString& aCompletion,
39
                bool aNegExpired = false,
40
                bool aPosExpired = false)
41
0
{
42
0
  FullHashResponseMap map;
43
0
44
0
  Prefix prefix;
45
0
  prefix.FromPlaintext(aCompletion);
46
0
47
0
  CachedFullHashResponse* response = map.LookupOrAdd(prefix.ToUint32());
48
0
49
0
  response->negativeCacheExpirySec =
50
0
    aNegExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC;
51
0
  response->fullHashes.Put(GeneratePrefix(aCompletion, COMPLETE_SIZE),
52
0
                           aPosExpired ? EXPIRED_TIME_SEC : NOTEXPIRED_TIME_SEC);
53
0
54
0
  aLookupCache->AddFullHashResponseToCache(map);
55
0
}
56
57
template<typename T>
58
void
59
TestCache(const Completion aCompletion,
60
          bool aExpectedHas,
61
          bool aExpectedConfirmed,
62
          bool aExpectedInCache,
63
          T* aCache = nullptr)
64
0
{
65
0
  bool has, inCache, confirmed;
66
0
  uint32_t matchLength;
67
0
68
0
  if (aCache) {
69
0
    aCache->Has(aCompletion, &has, &matchLength, &confirmed);
70
0
    inCache = aCache->IsInCache(aCompletion.ToUint32());
71
0
  } else {
72
0
    _PrefixArray array = { GeneratePrefix(_Fragment("cache.notexpired.com/"), 10),
73
0
                           GeneratePrefix(_Fragment("cache.expired.com/"), 8),
74
0
                           GeneratePrefix(_Fragment("gound.com/"), 5),
75
0
                           GeneratePrefix(_Fragment("small.com/"), 4)
76
0
                         };
77
0
78
0
    RefPtr<T> cache = SetupLookupCache<T>(array);
79
0
80
0
    // Create an expired entry and a non-expired entry
81
0
    SetupCacheEntry(cache, _Fragment("cache.notexpired.com/"));
82
0
    SetupCacheEntry(cache, _Fragment("cache.expired.com/"), true, true);
83
0
84
0
    cache->Has(aCompletion, &has, &matchLength, &confirmed);
85
0
    inCache = cache->IsInCache(aCompletion.ToUint32());
86
0
  }
87
0
88
0
  EXPECT_EQ(has, aExpectedHas);
89
0
  EXPECT_EQ(confirmed, aExpectedConfirmed);
90
0
  EXPECT_EQ(inCache, aExpectedInCache);
91
0
}
Unexecuted instantiation: void TestCache<mozilla::safebrowsing::LookupCacheV2>(mozilla::safebrowsing::SafebrowsingHash<32u, mozilla::safebrowsing::CompletionComparator>, bool, bool, bool, mozilla::safebrowsing::LookupCacheV2*)
Unexecuted instantiation: void TestCache<mozilla::safebrowsing::LookupCacheV4>(mozilla::safebrowsing::SafebrowsingHash<32u, mozilla::safebrowsing::CompletionComparator>, bool, bool, bool, mozilla::safebrowsing::LookupCacheV4*)
92
93
template<typename T>
94
void
95
TestCache(const _Fragment& aFragment,
96
          bool aExpectedHas,
97
          bool aExpectedConfirmed,
98
          bool aExpectedInCache,
99
          T* aCache = nullptr)
100
0
{
101
0
  Completion lookupHash;
102
0
  lookupHash.FromPlaintext(aFragment);
103
0
104
0
  TestCache<T>(lookupHash, aExpectedHas, aExpectedConfirmed, aExpectedInCache, aCache);
105
0
}
Unexecuted instantiation: void TestCache<mozilla::safebrowsing::LookupCacheV2>(nsTString<char> const&, bool, bool, bool, mozilla::safebrowsing::LookupCacheV2*)
Unexecuted instantiation: void TestCache<mozilla::safebrowsing::LookupCacheV4>(nsTString<char> const&, bool, bool, bool, mozilla::safebrowsing::LookupCacheV4*)
106
107
// This testcase check the returned result of |Has| API if fullhash cannot match
108
// any prefix in the local database.
109
TEST(UrlClassifierCaching, NotFound)
110
0
{
111
0
  TestCache<LookupCacheV2>(_Fragment("nomatch.com/"), false, false, false);
112
0
  TestCache<LookupCacheV4>(_Fragment("nomatch.com/"), false, false, false);
113
0
}
114
115
// This testcase check the returned result of |Has| API if fullhash find a match
116
// in the local database but not in the cache.
117
TEST(UrlClassifierCaching, NotInCache)
118
0
{
119
0
  TestCache<LookupCacheV2>(_Fragment("gound.com/"), true, false, false);
120
0
  TestCache<LookupCacheV4>(_Fragment("gound.com/"), true, false, false);
121
0
}
122
123
// This testcase check the returned result of |Has| API if fullhash matches
124
// a cache entry in positive cache.
125
TEST(UrlClassifierCaching, InPositiveCacheNotExpired)
126
0
{
127
0
  TestCache<LookupCacheV2>(_Fragment("cache.notexpired.com/"), true, true, true);
128
0
  TestCache<LookupCacheV4>(_Fragment("cache.notexpired.com/"), true, true, true);
129
0
}
130
131
// This testcase check the returned result of |Has| API if fullhash matches
132
// a cache entry in positive cache but that it is expired.
133
TEST(UrlClassifierCaching, InPositiveCacheExpired)
134
0
{
135
0
  TestCache<LookupCacheV2>(_Fragment("cache.expired.com/"), true, false, true);
136
0
  TestCache<LookupCacheV4>(_Fragment("cache.expired.com/"), true, false, true);
137
0
}
138
139
// This testcase check the returned result of |Has| API if fullhash matches
140
// a cache entry in negative cache.
141
TEST(UrlClassifierCaching, InNegativeCacheNotExpired)
142
0
{
143
0
  // Create a fullhash whose prefix matches the prefix in negative cache
144
0
  // but completion doesn't match any fullhash in positive cache.
145
0
146
0
  Completion prefix;
147
0
  prefix.FromPlaintext(_Fragment("cache.notexpired.com/"));
148
0
149
0
  Completion fullhash;
150
0
  fullhash.FromPlaintext(_Fragment("firefox.com/"));
151
0
152
0
  // Overwrite the 4-byte prefix of `fullhash` so that it conflicts with `prefix`.
153
0
  // Since "cache.notexpired.com" is added to database in TestCache as a
154
0
  // 10-byte prefix, we should copy more than 10 bytes to fullhash to ensure
155
0
  // it can match the prefix in database.
156
0
  memcpy(fullhash.buf, prefix.buf, 10);
157
0
158
0
  TestCache<LookupCacheV2>(fullhash, false, false, true);
159
0
  TestCache<LookupCacheV4>(fullhash, false, false, true);
160
0
}
161
162
// This testcase check the returned result of |Has| API if fullhash matches
163
// a cache entry in negative cache but that entry is expired.
164
TEST(UrlClassifierCaching, InNegativeCacheExpired)
165
0
{
166
0
  // Create a fullhash whose prefix is in the cache.
167
0
168
0
  Completion prefix;
169
0
  prefix.FromPlaintext(_Fragment("cache.expired.com/"));
170
0
171
0
  Completion fullhash;
172
0
  fullhash.FromPlaintext(_Fragment("firefox.com/"));
173
0
174
0
  memcpy(fullhash.buf, prefix.buf, 10);
175
0
176
0
  TestCache<LookupCacheV2>(fullhash, true, false, true);
177
0
  TestCache<LookupCacheV4>(fullhash, true, false, true);
178
0
}
179
180
0
#define CACHED_URL              _Fragment("cache.com/")
181
0
#define NEG_CACHE_EXPIRED_URL   _Fragment("cache.negExpired.com/")
182
0
#define POS_CACHE_EXPIRED_URL   _Fragment("cache.posExpired.com/")
183
0
#define BOTH_CACHE_EXPIRED_URL  _Fragment("cache.negAndposExpired.com/")
184
185
// This testcase create 4 cache entries.
186
// 1. unexpired entry.
187
// 2. an entry whose negative cache time is expired but whose positive cache
188
//    is not expired.
189
// 3. an entry whose positive cache time is expired
190
// 4. an entry whose negative cache time and positive cache time are expired
191
// After calling |InvalidateExpiredCacheEntry| API, entries with expired
192
// negative time should be removed from cache(2 & 4)
193
template<typename T>
194
void TestInvalidateExpiredCacheEntry()
195
0
{
196
0
  _PrefixArray array = { GeneratePrefix(CACHED_URL, 10),
197
0
                         GeneratePrefix(NEG_CACHE_EXPIRED_URL, 8),
198
0
                         GeneratePrefix(POS_CACHE_EXPIRED_URL, 5),
199
0
                         GeneratePrefix(BOTH_CACHE_EXPIRED_URL, 4)
200
0
                       };
201
0
  RefPtr<T> cache = SetupLookupCache<T>(array);
202
0
203
0
  SetupCacheEntry(cache, CACHED_URL, false, false);
204
0
  SetupCacheEntry(cache, NEG_CACHE_EXPIRED_URL, true, false);
205
0
  SetupCacheEntry(cache, POS_CACHE_EXPIRED_URL, false, true);
206
0
  SetupCacheEntry(cache, BOTH_CACHE_EXPIRED_URL, true, true);
207
0
208
0
  // Before invalidate
209
0
  TestCache<T>(CACHED_URL, true, true, true, cache.get());
210
0
  TestCache<T>(NEG_CACHE_EXPIRED_URL, true, true, true, cache.get());
211
0
  TestCache<T>(POS_CACHE_EXPIRED_URL, true, false, true, cache.get());
212
0
  TestCache<T>(BOTH_CACHE_EXPIRED_URL, true, false, true, cache.get());
213
0
214
0
  // Call InvalidateExpiredCacheEntry to remove cache entries whose negative cache
215
0
  // time is expired
216
0
  cache->InvalidateExpiredCacheEntries();
217
0
218
0
  // After invalidate, NEG_CACHE_EXPIRED_URL & BOTH_CACHE_EXPIRED_URL should
219
0
  // not be found in cache.
220
0
  TestCache<T>(NEG_CACHE_EXPIRED_URL, true, false, false, cache.get());
221
0
  TestCache<T>(BOTH_CACHE_EXPIRED_URL, true, false, false, cache.get());
222
0
223
0
  // Other entries should remain the same result.
224
0
  TestCache<T>(CACHED_URL, true, true, true, cache.get());
225
0
  TestCache<T>(POS_CACHE_EXPIRED_URL, true, false, true, cache.get());
226
0
}
Unexecuted instantiation: void TestInvalidateExpiredCacheEntry<mozilla::safebrowsing::LookupCacheV2>()
Unexecuted instantiation: void TestInvalidateExpiredCacheEntry<mozilla::safebrowsing::LookupCacheV4>()
227
228
TEST(UrlClassifierCaching, InvalidateExpiredCacheEntryV2)
229
0
{
230
0
  TestInvalidateExpiredCacheEntry<LookupCacheV2>();
231
0
}
232
233
TEST(UrlClassifierCaching, InvalidateExpiredCacheEntryV4)
234
0
{
235
0
  TestInvalidateExpiredCacheEntry<LookupCacheV4>();
236
0
}
237
238
// This testcase check if an cache entry whose negative cache time is expired
239
// and it doesn't have any postive cache entries in it, it should be removed
240
// from cache after calling |Has|.
241
TEST(UrlClassifierCaching, NegativeCacheExpireV2)
242
0
{
243
0
  _PrefixArray array = { GeneratePrefix(NEG_CACHE_EXPIRED_URL, 8) };
244
0
  RefPtr<LookupCacheV2> cache = SetupLookupCache<LookupCacheV2>(array);
245
0
246
0
  nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
247
0
248
0
  MissPrefixArray misses;
249
0
  Prefix* prefix = misses.AppendElement(fallible);
250
0
  prefix->FromPlaintext(NEG_CACHE_EXPIRED_URL);
251
0
252
0
  AddCompleteArray dummy;
253
0
  cache->AddGethashResultToCache(dummy, misses, EXPIRED_TIME_SEC);
254
0
255
0
  // Ensure it is in cache in the first place.
256
0
  EXPECT_EQ(cache->IsInCache(prefix->ToUint32()), true);
257
0
258
0
  // It should be removed after calling Has API.
259
0
  TestCache<LookupCacheV2>(NEG_CACHE_EXPIRED_URL, true, false, false, cache.get());
260
0
}
261
262
TEST(UrlClassifierCaching, NegativeCacheExpireV4)
263
0
{
264
0
  _PrefixArray array = { GeneratePrefix(NEG_CACHE_EXPIRED_URL, 8) };
265
0
  RefPtr<LookupCacheV4> cache = SetupLookupCache<LookupCacheV4>(array);
266
0
267
0
  FullHashResponseMap map;
268
0
  Prefix prefix;
269
0
  nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
270
0
  prefix.FromPlaintext(NEG_CACHE_EXPIRED_URL);
271
0
  CachedFullHashResponse* response = map.LookupOrAdd(prefix.ToUint32());
272
0
273
0
  response->negativeCacheExpirySec = EXPIRED_TIME_SEC;
274
0
275
0
  cache->AddFullHashResponseToCache(map);
276
0
277
0
  // Ensure it is in cache in the first place.
278
0
  EXPECT_EQ(cache->IsInCache(prefix.ToUint32()), true);
279
0
280
0
  // It should be removed after calling Has API.
281
0
  TestCache<LookupCacheV4>(NEG_CACHE_EXPIRED_URL, true, false, false, cache.get());
282
0
}