1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 var test_generator = do_run_test();
10 do_run_generator(test_generator);
13 function continue_test() {
14 do_run_generator(test_generator);
17 function repeat_test() {
18 // The test is probably going to fail because setting a batch of cookies took
19 // a significant fraction of 'gPurgeAge'. Compensate by rerunning the
20 // test with a larger purge age.
21 Assert.ok(gPurgeAge < 64);
25 executeSoon(function () {
26 test_generator.return();
27 test_generator = do_run_test();
28 do_run_generator(test_generator);
32 // Purge threshold, in seconds.
35 // Short expiry age, in seconds.
38 // Required delay to ensure a purge occurs, in milliseconds. This must be at
39 // least gPurgeAge + 10%, and includes a little fuzz to account for timer
40 // resolution and possible differences between PR_Now() and Date.now().
41 function get_purge_delay() {
42 return gPurgeAge * 1100 + 100;
45 // Required delay to ensure a cookie set with an expiry time 'gShortExpiry' into
46 // the future will have expired.
47 function get_expiry_delay() {
48 return gShortExpiry * 1000 + 100;
51 function* do_run_test() {
55 // twiddle prefs to convenient values for this test
56 Services.prefs.setIntPref("network.cookie.purgeAge", gPurgeAge);
57 Services.prefs.setIntPref("network.cookie.maxNumber", 100);
59 let expiry = Date.now() / 1000 + 1000;
61 // eviction is performed based on two limits: when the total number of cookies
62 // exceeds maxNumber + 10% (110), and when cookies are older than purgeAge
63 // (1 second). purging is done when both conditions are satisfied, and only
64 // those cookies are purged.
66 // we test the following cases of eviction:
67 // 1) excess and age are satisfied, but only some of the excess are old enough
69 Services.cookies.removeAll();
70 if (!set_cookies(0, 5, expiry)) {
74 // Sleep a while, to make sure the first batch of cookies is older than
75 // the second (timer resolution varies on different platforms).
76 do_timeout(get_purge_delay(), continue_test);
78 if (!set_cookies(5, 111, expiry)) {
83 // Fake a profile change, to ensure eviction affects the database correctly.
84 do_close_profile(test_generator);
87 Assert.ok(check_remaining_cookies(111, 5, 106));
89 // 2) excess and age are satisfied, and all of the excess are old enough
91 Services.cookies.removeAll();
92 if (!set_cookies(0, 10, expiry)) {
96 do_timeout(get_purge_delay(), continue_test);
98 if (!set_cookies(10, 111, expiry)) {
103 do_close_profile(test_generator);
106 Assert.ok(check_remaining_cookies(111, 10, 101));
108 // 3) excess and age are satisfied, and more than the excess are old enough
110 Services.cookies.removeAll();
111 if (!set_cookies(0, 50, expiry)) {
115 do_timeout(get_purge_delay(), continue_test);
117 if (!set_cookies(50, 111, expiry)) {
122 do_close_profile(test_generator);
125 Assert.ok(check_remaining_cookies(111, 50, 101));
127 // 4) excess but not age are satisfied.
128 Services.cookies.removeAll();
129 if (!set_cookies(0, 120, expiry)) {
134 do_close_profile(test_generator);
137 Assert.ok(check_remaining_cookies(120, 0, 120));
139 // 5) age but not excess are satisfied.
140 Services.cookies.removeAll();
141 if (!set_cookies(0, 20, expiry)) {
145 do_timeout(get_purge_delay(), continue_test);
147 if (!set_cookies(20, 110, expiry)) {
152 do_close_profile(test_generator);
155 Assert.ok(check_remaining_cookies(110, 20, 110));
157 // 6) Excess and age are satisfied, but the cookie limit can be satisfied by
158 // purging expired cookies.
159 Services.cookies.removeAll();
160 let shortExpiry = Math.floor(Date.now() / 1000) + gShortExpiry;
161 if (!set_cookies(0, 20, shortExpiry)) {
165 do_timeout(get_expiry_delay(), continue_test);
167 if (!set_cookies(20, 110, expiry)) {
171 do_timeout(get_purge_delay(), continue_test);
173 if (!set_cookies(110, 111, expiry)) {
178 do_close_profile(test_generator);
181 Assert.ok(check_remaining_cookies(111, 20, 91));
183 do_finish_generator_test(test_generator);
186 // Set 'end - begin' total cookies, with consecutively increasing hosts numbered
188 function set_cookies(begin, end, expiry) {
189 Assert.ok(begin != end);
192 for (let i = begin; i < end; ++i) {
193 let host = "eviction." + i + ".tests";
194 Services.cookies.add(
204 Ci.nsICookie.SAMESITE_NONE,
205 Ci.nsICookie.SCHEME_HTTPS
209 beginTime = get_creationTime(i);
213 let endTime = get_creationTime(end - 1);
214 Assert.ok(begin == end - 1 || endTime > beginTime);
215 if (endTime - beginTime > gPurgeAge * 1000000) {
216 // Setting cookies took an amount of time very close to the purge threshold.
217 // Retry the test with a larger threshold.
224 function get_creationTime(i) {
225 let host = "eviction." + i + ".tests";
226 let cookies = Services.cookies.getCookiesFromHost(host, {});
227 Assert.ok(cookies.length);
228 let cookie = cookies[0];
229 return cookie.creationTime;
232 // Test that 'aNumberToExpect' cookies remain after purging is complete, and
233 // that the cookies that remain consist of the set expected given the number of
234 // of older and newer cookies -- eviction should occur by order of lastAccessed
235 // time, if both the limit on total cookies (maxNumber + 10%) and the purge age
236 // + 10% are exceeded.
237 function check_remaining_cookies(aNumberTotal, aNumberOld, aNumberToExpect) {
239 for (let cookie of Services.cookies.cookies) {
242 if (aNumberTotal != aNumberToExpect) {
243 // make sure the cookie is one of the batch we expect was purged.
244 var hostNumber = Number(cookie.rawHost.split(".")[1]);
245 if (hostNumber < aNumberOld - aNumberToExpect) {
251 return i == aNumberToExpect;