diff options
Diffstat (limited to 'extensions/cookie/test/unit/test_eviction.js')
-rw-r--r-- | extensions/cookie/test/unit/test_eviction.js | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/extensions/cookie/test/unit/test_eviction.js b/extensions/cookie/test/unit/test_eviction.js new file mode 100644 index 000000000..7b1550208 --- /dev/null +++ b/extensions/cookie/test/unit/test_eviction.js @@ -0,0 +1,249 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var test_generator = do_run_test(); + +function run_test() +{ + do_test_pending(); + do_run_generator(test_generator); +} + +function continue_test() +{ + do_run_generator(test_generator); +} + +function repeat_test() +{ + // The test is probably going to fail because setting a batch of cookies took + // a significant fraction of 'gPurgeAge'. Compensate by rerunning the + // test with a larger purge age. + do_check_true(gPurgeAge < 64); + gPurgeAge *= 2; + gShortExpiry *= 2; + + do_execute_soon(function() { + test_generator.close(); + test_generator = do_run_test(); + do_run_generator(test_generator); + }); +} + +// Purge threshold, in seconds. +var gPurgeAge = 1; + +// Short expiry age, in seconds. +var gShortExpiry = 2; + +// Required delay to ensure a purge occurs, in milliseconds. This must be at +// least gPurgeAge + 10%, and includes a little fuzz to account for timer +// resolution and possible differences between PR_Now() and Date.now(). +function get_purge_delay() +{ + return gPurgeAge * 1100 + 100; +} + +// Required delay to ensure a cookie set with an expiry time 'gShortExpiry' into +// the future will have expired. +function get_expiry_delay() +{ + return gShortExpiry * 1000 + 100; +} + +function do_run_test() +{ + // Set up a profile. + let profile = do_get_profile(); + + // twiddle prefs to convenient values for this test + Services.prefs.setIntPref("network.cookie.purgeAge", gPurgeAge); + Services.prefs.setIntPref("network.cookie.maxNumber", 100); + + let expiry = Date.now() / 1000 + 1000; + + // eviction is performed based on two limits: when the total number of cookies + // exceeds maxNumber + 10% (110), and when cookies are older than purgeAge + // (1 second). purging is done when both conditions are satisfied, and only + // those cookies are purged. + + // we test the following cases of eviction: + // 1) excess and age are satisfied, but only some of the excess are old enough + // to be purged. + Services.cookiemgr.removeAll(); + if (!set_cookies(0, 5, expiry)) { + repeat_test(); + return; + } + // Sleep a while, to make sure the first batch of cookies is older than + // the second (timer resolution varies on different platforms). + do_timeout(get_purge_delay(), continue_test); + yield; + if (!set_cookies(5, 111, expiry)) { + repeat_test(); + return; + } + + // Fake a profile change, to ensure eviction affects the database correctly. + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(111, 5, 106)); + + // 2) excess and age are satisfied, and all of the excess are old enough + // to be purged. + Services.cookiemgr.removeAll(); + if (!set_cookies(0, 10, expiry)) { + repeat_test(); + return; + } + do_timeout(get_purge_delay(), continue_test); + yield; + if (!set_cookies(10, 111, expiry)) { + repeat_test(); + return; + } + + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(111, 10, 101)); + + // 3) excess and age are satisfied, and more than the excess are old enough + // to be purged. + Services.cookiemgr.removeAll(); + if (!set_cookies(0, 50, expiry)) { + repeat_test(); + return; + } + do_timeout(get_purge_delay(), continue_test); + yield; + if (!set_cookies(50, 111, expiry)) { + repeat_test(); + return; + } + + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(111, 50, 101)); + + // 4) excess but not age are satisfied. + Services.cookiemgr.removeAll(); + if (!set_cookies(0, 120, expiry)) { + repeat_test(); + return; + } + + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(120, 0, 120)); + + // 5) age but not excess are satisfied. + Services.cookiemgr.removeAll(); + if (!set_cookies(0, 20, expiry)) { + repeat_test(); + return; + } + do_timeout(get_purge_delay(), continue_test); + yield; + if (!set_cookies(20, 110, expiry)) { + repeat_test(); + return; + } + + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(110, 20, 110)); + + // 6) Excess and age are satisfied, but the cookie limit can be satisfied by + // purging expired cookies. + Services.cookiemgr.removeAll(); + let shortExpiry = Math.floor(Date.now() / 1000) + gShortExpiry; + if (!set_cookies(0, 20, shortExpiry)) { + repeat_test(); + return; + } + do_timeout(get_expiry_delay(), continue_test); + yield; + if (!set_cookies(20, 110, expiry)) { + repeat_test(); + return; + } + do_timeout(get_purge_delay(), continue_test); + yield; + if (!set_cookies(110, 111, expiry)) { + repeat_test(); + return; + } + + do_close_profile(test_generator); + yield; + do_load_profile(); + do_check_true(check_remaining_cookies(111, 20, 91)); + + do_finish_generator_test(test_generator); +} + +// Set 'end - begin' total cookies, with consecutively increasing hosts numbered +// 'begin' to 'end'. +function set_cookies(begin, end, expiry) +{ + do_check_true(begin != end); + + let beginTime; + for (let i = begin; i < end; ++i) { + let host = "eviction." + i + ".tests"; + Services.cookiemgr.add(host, "", "test", "eviction", false, false, false, + expiry, {}); + + if (i == begin) + beginTime = get_creationTime(i); + } + + let endTime = get_creationTime(end - 1); + do_check_true(begin == end - 1 || endTime > beginTime); + if (endTime - beginTime > gPurgeAge * 1000000) { + // Setting cookies took an amount of time very close to the purge threshold. + // Retry the test with a larger threshold. + return false; + } + + return true; +} + +function get_creationTime(i) +{ + let host = "eviction." + i + ".tests"; + let enumerator = Services.cookiemgr.getCookiesFromHost(host, {}); + do_check_true(enumerator.hasMoreElements()); + let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + return cookie.creationTime; +} + +// Test that 'aNumberToExpect' cookies remain after purging is complete, and +// that the cookies that remain consist of the set expected given the number of +// of older and newer cookies -- eviction should occur by order of lastAccessed +// time, if both the limit on total cookies (maxNumber + 10%) and the purge age +// + 10% are exceeded. +function check_remaining_cookies(aNumberTotal, aNumberOld, aNumberToExpect) { + var enumerator = Services.cookiemgr.enumerator; + + let i = 0; + while (enumerator.hasMoreElements()) { + var cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + ++i; + + if (aNumberTotal != aNumberToExpect) { + // make sure the cookie is one of the batch we expect was purged. + var hostNumber = new Number(cookie.rawHost.split(".")[1]); + if (hostNumber < (aNumberOld - aNumberToExpect)) break; + } + } + + return i == aNumberToExpect; +} |