|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 let test_generator = do_run_test(); |
|
5 |
|
6 function run_test() |
|
7 { |
|
8 do_test_pending(); |
|
9 do_run_generator(test_generator); |
|
10 } |
|
11 |
|
12 function continue_test() |
|
13 { |
|
14 do_run_generator(test_generator); |
|
15 } |
|
16 |
|
17 function repeat_test() |
|
18 { |
|
19 // The test is probably going to fail because setting a batch of cookies took |
|
20 // a significant fraction of 'gPurgeAge'. Compensate by rerunning the |
|
21 // test with a larger purge age. |
|
22 do_check_true(gPurgeAge < 64); |
|
23 gPurgeAge *= 2; |
|
24 gShortExpiry *= 2; |
|
25 |
|
26 do_execute_soon(function() { |
|
27 test_generator.close(); |
|
28 test_generator = do_run_test(); |
|
29 do_run_generator(test_generator); |
|
30 }); |
|
31 } |
|
32 |
|
33 // Purge threshold, in seconds. |
|
34 let gPurgeAge = 1; |
|
35 |
|
36 // Short expiry age, in seconds. |
|
37 let gShortExpiry = 2; |
|
38 |
|
39 // Required delay to ensure a purge occurs, in milliseconds. This must be at |
|
40 // least gPurgeAge + 10%, and includes a little fuzz to account for timer |
|
41 // resolution and possible differences between PR_Now() and Date.now(). |
|
42 function get_purge_delay() |
|
43 { |
|
44 return gPurgeAge * 1100 + 100; |
|
45 } |
|
46 |
|
47 // Required delay to ensure a cookie set with an expiry time 'gShortExpiry' into |
|
48 // the future will have expired. |
|
49 function get_expiry_delay() |
|
50 { |
|
51 return gShortExpiry * 1000 + 100; |
|
52 } |
|
53 |
|
54 function do_run_test() |
|
55 { |
|
56 // Set up a profile. |
|
57 let profile = do_get_profile(); |
|
58 |
|
59 // twiddle prefs to convenient values for this test |
|
60 Services.prefs.setIntPref("network.cookie.purgeAge", gPurgeAge); |
|
61 Services.prefs.setIntPref("network.cookie.maxNumber", 100); |
|
62 |
|
63 let expiry = Date.now() / 1000 + 1000; |
|
64 |
|
65 // eviction is performed based on two limits: when the total number of cookies |
|
66 // exceeds maxNumber + 10% (110), and when cookies are older than purgeAge |
|
67 // (1 second). purging is done when both conditions are satisfied, and only |
|
68 // those cookies are purged. |
|
69 |
|
70 // we test the following cases of eviction: |
|
71 // 1) excess and age are satisfied, but only some of the excess are old enough |
|
72 // to be purged. |
|
73 Services.cookiemgr.removeAll(); |
|
74 if (!set_cookies(0, 5, expiry)) { |
|
75 repeat_test(); |
|
76 return; |
|
77 } |
|
78 // Sleep a while, to make sure the first batch of cookies is older than |
|
79 // the second (timer resolution varies on different platforms). |
|
80 do_timeout(get_purge_delay(), continue_test); |
|
81 yield; |
|
82 if (!set_cookies(5, 111, expiry)) { |
|
83 repeat_test(); |
|
84 return; |
|
85 } |
|
86 |
|
87 // Fake a profile change, to ensure eviction affects the database correctly. |
|
88 do_close_profile(test_generator); |
|
89 yield; |
|
90 do_load_profile(); |
|
91 do_check_true(check_remaining_cookies(111, 5, 106)); |
|
92 |
|
93 // 2) excess and age are satisfied, and all of the excess are old enough |
|
94 // to be purged. |
|
95 Services.cookiemgr.removeAll(); |
|
96 if (!set_cookies(0, 10, expiry)) { |
|
97 repeat_test(); |
|
98 return; |
|
99 } |
|
100 do_timeout(get_purge_delay(), continue_test); |
|
101 yield; |
|
102 if (!set_cookies(10, 111, expiry)) { |
|
103 repeat_test(); |
|
104 return; |
|
105 } |
|
106 |
|
107 do_close_profile(test_generator); |
|
108 yield; |
|
109 do_load_profile(); |
|
110 do_check_true(check_remaining_cookies(111, 10, 101)); |
|
111 |
|
112 // 3) excess and age are satisfied, and more than the excess are old enough |
|
113 // to be purged. |
|
114 Services.cookiemgr.removeAll(); |
|
115 if (!set_cookies(0, 50, expiry)) { |
|
116 repeat_test(); |
|
117 return; |
|
118 } |
|
119 do_timeout(get_purge_delay(), continue_test); |
|
120 yield; |
|
121 if (!set_cookies(50, 111, expiry)) { |
|
122 repeat_test(); |
|
123 return; |
|
124 } |
|
125 |
|
126 do_close_profile(test_generator); |
|
127 yield; |
|
128 do_load_profile(); |
|
129 do_check_true(check_remaining_cookies(111, 50, 101)); |
|
130 |
|
131 // 4) excess but not age are satisfied. |
|
132 Services.cookiemgr.removeAll(); |
|
133 if (!set_cookies(0, 120, expiry)) { |
|
134 repeat_test(); |
|
135 return; |
|
136 } |
|
137 |
|
138 do_close_profile(test_generator); |
|
139 yield; |
|
140 do_load_profile(); |
|
141 do_check_true(check_remaining_cookies(120, 0, 120)); |
|
142 |
|
143 // 5) age but not excess are satisfied. |
|
144 Services.cookiemgr.removeAll(); |
|
145 if (!set_cookies(0, 20, expiry)) { |
|
146 repeat_test(); |
|
147 return; |
|
148 } |
|
149 do_timeout(get_purge_delay(), continue_test); |
|
150 yield; |
|
151 if (!set_cookies(20, 110, expiry)) { |
|
152 repeat_test(); |
|
153 return; |
|
154 } |
|
155 |
|
156 do_close_profile(test_generator); |
|
157 yield; |
|
158 do_load_profile(); |
|
159 do_check_true(check_remaining_cookies(110, 20, 110)); |
|
160 |
|
161 // 6) Excess and age are satisfied, but the cookie limit can be satisfied by |
|
162 // purging expired cookies. |
|
163 Services.cookiemgr.removeAll(); |
|
164 let shortExpiry = Math.floor(Date.now() / 1000) + gShortExpiry; |
|
165 if (!set_cookies(0, 20, shortExpiry)) { |
|
166 repeat_test(); |
|
167 return; |
|
168 } |
|
169 do_timeout(get_expiry_delay(), continue_test); |
|
170 yield; |
|
171 if (!set_cookies(20, 110, expiry)) { |
|
172 repeat_test(); |
|
173 return; |
|
174 } |
|
175 do_timeout(get_purge_delay(), continue_test); |
|
176 yield; |
|
177 if (!set_cookies(110, 111, expiry)) { |
|
178 repeat_test(); |
|
179 return; |
|
180 } |
|
181 |
|
182 do_close_profile(test_generator); |
|
183 yield; |
|
184 do_load_profile(); |
|
185 do_check_true(check_remaining_cookies(111, 20, 91)); |
|
186 |
|
187 do_finish_generator_test(test_generator); |
|
188 } |
|
189 |
|
190 // Set 'end - begin' total cookies, with consecutively increasing hosts numbered |
|
191 // 'begin' to 'end'. |
|
192 function set_cookies(begin, end, expiry) |
|
193 { |
|
194 do_check_true(begin != end); |
|
195 |
|
196 let beginTime; |
|
197 for (let i = begin; i < end; ++i) { |
|
198 let host = "eviction." + i + ".tests"; |
|
199 Services.cookiemgr.add(host, "", "test", "eviction", false, false, false, |
|
200 expiry); |
|
201 |
|
202 if (i == begin) |
|
203 beginTime = get_creationTime(i); |
|
204 } |
|
205 |
|
206 let endTime = get_creationTime(end - 1); |
|
207 do_check_true(begin == end - 1 || endTime > beginTime); |
|
208 if (endTime - beginTime > gPurgeAge * 1000000) { |
|
209 // Setting cookies took an amount of time very close to the purge threshold. |
|
210 // Retry the test with a larger threshold. |
|
211 return false; |
|
212 } |
|
213 |
|
214 return true; |
|
215 } |
|
216 |
|
217 function get_creationTime(i) |
|
218 { |
|
219 let host = "eviction." + i + ".tests"; |
|
220 let enumerator = Services.cookiemgr.getCookiesFromHost(host); |
|
221 do_check_true(enumerator.hasMoreElements()); |
|
222 let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); |
|
223 return cookie.creationTime; |
|
224 } |
|
225 |
|
226 // Test that 'aNumberToExpect' cookies remain after purging is complete, and |
|
227 // that the cookies that remain consist of the set expected given the number of |
|
228 // of older and newer cookies -- eviction should occur by order of lastAccessed |
|
229 // time, if both the limit on total cookies (maxNumber + 10%) and the purge age |
|
230 // + 10% are exceeded. |
|
231 function check_remaining_cookies(aNumberTotal, aNumberOld, aNumberToExpect) { |
|
232 var enumerator = Services.cookiemgr.enumerator; |
|
233 |
|
234 i = 0; |
|
235 while (enumerator.hasMoreElements()) { |
|
236 var cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); |
|
237 ++i; |
|
238 |
|
239 if (aNumberTotal != aNumberToExpect) { |
|
240 // make sure the cookie is one of the batch we expect was purged. |
|
241 var hostNumber = new Number(cookie.rawHost.split(".")[1]); |
|
242 if (hostNumber < (aNumberOld - aNumberToExpect)) break; |
|
243 } |
|
244 } |
|
245 |
|
246 return i == aNumberToExpect; |
|
247 } |