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