author | Tim Huang <tihuang@mozilla.com> |
Thu, 07 Jul 2016 23:15:00 +0200 | |
changeset 304210 | b86836730296625d338375be5c736a036e1857c5 |
parent 304209 | dfbbd0e32a5ffe840365333b4d5266c123ae539d |
child 304211 | d23fa9b954300e8f5ed9fb6726ef5d5802ef3003 |
push id | 30417 |
push user | kwierso@gmail.com |
push date | Fri, 08 Jul 2016 21:56:02 +0000 |
treeherder | mozilla-central@fd8ff97bc294 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jimm |
bugs | 1238183 |
milestone | 50.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/components/contextualidentity/test/browser/browser.ini +++ b/browser/components/contextualidentity/test/browser/browser.ini @@ -1,19 +1,21 @@ [DEFAULT] skip-if = buildapp == "mulet" support-files = empty_file.html file_reflect_cookie_into_title.html favicon-normal32.png + file_set_storages.html serviceworker.html worker.js [browser_aboutURLs.js] [browser_favicon.js] +[browser_forgetaboutsite.js] [browser_usercontext.js] [browser_usercontextid_tabdrop.js] skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276 [browser_windowName.js] tags = openwindow [browser_windowOpen.js] tags = openwindow [browser_serviceworkers.js]
new file mode 100644 --- /dev/null +++ b/browser/components/contextualidentity/test/browser/browser_forgetaboutsite.js @@ -0,0 +1,351 @@ +/* + * Bug 1238183 - Test cases for forgetAboutSite with userContextId. + */ + +const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/ForgetAboutSite.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {}); +let LoadContextInfo = Cc["@mozilla.org/load-context-info-factory;1"] + .getService(Ci.nsILoadContextInfoFactory); +let css = Cc["@mozilla.org/netwerk/cache-storage-service;1"] + .getService(Ci.nsICacheStorageService); + +const USER_CONTEXTS = [ + "default", + "personal", + "work", +]; +const TEST_HOST = "example.com"; +const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/"; +const COOKIE_NAME = "userContextId"; + +// Counter for image load hits. +let gHits = 0; + +let gHttpServer = null; + +function imageHandler(metadata, response) { + // A 1x1 PNG image. + // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain) + const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" + + "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII="); + gHits++; + response.setHeader("Cache-Control", "max-age=10000", false); + response.setStatusLine(metadata.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "image/png", false); + response.write(IMAGE); +} + +function loadImagePageHandler(metadata, response) { + response.setHeader("Cache-Control", "max-age=10000", false); + response.setStatusLine(metadata.httpVersion, 200, "Ok"); + response.setHeader("Content-Type", "text/html", false); + let body = "<!DOCTYPE HTML>\ + <html>\ + <head>\ + <meta charset='utf-8'>\ + <title>Load Image</title>\ + </head>\ + <body>\ + <img src='image.png'>\ + </body>\ + </html>"; + response.bodyOutputStream.write(body, body.length); +} + +function* openTabInUserContext(uri, userContextId) { + // Open the tab in the correct userContextId. + let tab = gBrowser.addTab(uri, {userContextId}); + + // Select tab and make sure its browser is focused. + gBrowser.selectedTab = tab; + tab.ownerDocument.defaultView.focus(); + + let browser = gBrowser.getBrowserForTab(tab); + yield BrowserTestUtils.browserLoaded(browser); + return {tab, browser}; +} + +function getCookiesForOA(host, userContextId) { + return Services.cookies.getCookiesFromHost(host, {userContextId}); +} + +function createURI(uri) +{ + let ioServ = Cc["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + return ioServ.newURI(uri, null, null); +} + +function getCacheStorage(where, lci, appcache) +{ + if (!lci) lci = LoadContextInfo.default; + switch (where) { + case "disk": return css.diskCacheStorage(lci, false); + case "memory": return css.memoryCacheStorage(lci); + case "appcache": return css.appCacheStorage(lci, appcache); + case "pin": return css.pinningCacheStorage(lci); + } + return null; +} + +function OpenCacheEntry(key, where, flags, lci) +{ + return new Promise(resolve => { + key = createURI(key); + function CacheListener() { } + CacheListener.prototype = { + _appCache: null, + + QueryInterface: function (iid) { + if (iid.equals(Components.interfaces.nsICacheEntryOpenCallback) || + iid.equals(Components.interfaces.nsISupports)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + onCacheEntryCheck: function(entry, appCache) { + return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; + }, + + onCacheEntryAvailable: function (entry, isnew, appCache, status) { + resolve(); + }, + + run: function () { + let storage = getCacheStorage(where, lci, this._appCache); + storage.asyncOpenURI(key, "", flags, this); + } + }; + + (new CacheListener()).run(); + }); +} + +// +// Test functions. +// + +// Cookies +function* test_cookie_cleared() { + let tabs = []; + + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Load the page in 3 different contexts and set a cookie + // which should only be visible in that context. + let value = USER_CONTEXTS[userContextId]; + + // Open our tab in the given user context. + tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "file_reflect_cookie_into_title.html?" + value, userContextId); + + // Close this tab. + yield BrowserTestUtils.removeTab(tabs[userContextId].tab); + } + // Check that cookies have been set properly. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + let enumerator = getCookiesForOA(TEST_HOST, userContextId); + ok(enumerator.hasMoreElements(), "Cookies available"); + + let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + Assert.equal(foundCookie["name"], COOKIE_NAME, "Check cookie name"); + Assert.equal(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value"); + } + + // Forget the site. + ForgetAboutSite.removeDataFromDomain(TEST_HOST); + + // Check that whether cookies has been cleared or not. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + let enumerator = getCookiesForOA(TEST_HOST, userContextId); + ok(!enumerator.hasMoreElements(), "No Cookie should be here"); + } +} + +// Cache +function* test_cache_cleared() { + // First, add some caches. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + yield OpenCacheEntry("http://" + TEST_HOST + "/", + "disk", + Ci.nsICacheStorage.OPEN_NORMALLY, + LoadContextInfo.custom(false, false, {userContextId})); + + yield OpenCacheEntry("http://" + TEST_HOST + "/", + "memory", + Ci.nsICacheStorage.OPEN_NORMALLY, + LoadContextInfo.custom(false, false, {userContextId})); + } + + + // Check that caches have been set correctly. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + let mem = getCacheStorage("memory"); + let disk = getCacheStorage("disk"); + + Assert.ok(mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache has been set correctly"); + Assert.ok(disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache has been set correctly"); + } + + // Forget the site. + ForgetAboutSite.removeDataFromDomain(TEST_HOST); + + // Check that do caches be removed or not? + for (let userContextId of Object.keys(USER_CONTEXTS)) { + let mem = getCacheStorage("memory"); + let disk = getCacheStorage("disk"); + + Assert.ok(!mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache is cleared"); + Assert.ok(!disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache is cleared"); + } +} + +// Image Cache +function* test_image_cache_cleared() { + let tabs = []; + + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Open our tab in the given user context to cache image. + tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html', + userContextId); + yield BrowserTestUtils.removeTab(tabs[userContextId].tab); + } + + // Check that image cache works with the userContextId. + todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed"); + + // Reset the cache count. + gHits = 0; + + // Forget the site. + ForgetAboutSite.removeDataFromDomain("localhost:" + gHttpServer.identity.primaryPort + "/"); + + // Load again. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Open our tab in the given user context to cache image. + tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html', + userContextId); + yield BrowserTestUtils.removeTab(tabs[userContextId].tab); + } + + // Check that image cache was cleared and the server gets another three hits. + todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed"); +} + +// Offline Storage +function* test_storage_cleared() { + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Load the page in 3 different contexts and set the local storage + // which should only be visible in that context. + let value = USER_CONTEXTS[userContextId]; + + // Open our tab in the given user context. + let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html?" + value, userContextId); + + // Check that the local storage has been set correctly. + let win = tabInfo.browser.contentWindow; + Assert.equal(win.localStorage.getItem("userContext"), USER_CONTEXTS[userContextId], "Check the local storage value"); + + // Check that the session storage has been set correctly. + Assert.equal(win.sessionStorage.getItem("userContext"), USER_CONTEXTS[userContextId], "Check the session storage value"); + + // Check that the indexedDB has been set correctly. + yield ContentTask.spawn(tabInfo.browser, { userContext: USER_CONTEXTS[userContextId] }, function* (arg) { + let request = content.indexedDB.open("idb", 1); + + let db = yield new Promise(done => { + request.onsuccess = event => { + done(event.target.result); + }; + }); + + let transaction = db.transaction(["obj"], "readonly"); + let store = transaction.objectStore("obj"); + let storeRequest = store.get(1); + + yield new Promise(done => { + storeRequest.onsuccess = event => { + let res = storeRequest.result; + Assert.equal(res.userContext, arg.userContext, "Check the indexedDB value"); + done(); + }; + }); + }); + + // Close this tab. + yield BrowserTestUtils.removeTab(tabInfo.tab); + } + + // Forget the site. + ForgetAboutSite.removeDataFromDomain(TEST_HOST); + + // Open the tab again without setting the localStorage and check that the + // local storage has been cleared or not. + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // Open our tab in the given user context without setting local storage. + let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html", userContextId); + let win = tabInfo.browser.contentWindow; + + // Check that does the local storage be cleared or not. + Assert.ok(!win.localStorage.getItem("userContext"), "The local storage has been cleared"); + + // Check that does the session storage be cleared or not. + Assert.ok(!win.sessionStorage.getItem("userContext"), "The session storage has been cleared"); + + // Check that does the indexedDB be cleared or not. + yield ContentTask.spawn(tabInfo.browser, null, function* () { + let request = content.indexedDB.open("idb", 1); + + let db = yield new Promise(done => { + request.onsuccess = event => { + done(event.target.result); + }; + }); + try { + let transaction = db.transaction(["obj"], "readonly"); + Assert.ok(false, "The indexedDB should not exist"); + } catch (e) { + Assert.equal(e.name, "NotFoundError", "The indexedDB does not exist as expected"); + } + }); + + // Close the tab. + yield BrowserTestUtils.removeTab(tabInfo.tab); + } +} + +add_task(function* setup() { + // Make sure userContext is enabled. + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [ + ["privacy.userContext.enabled", true] + ]}, resolve); + }); + + // Create a http server for the image cache test. + if (!gHttpServer) { + gHttpServer = new HttpServer(); + gHttpServer.registerPathHandler('/image.png', imageHandler); + gHttpServer.registerPathHandler('/loadImage.html', loadImagePageHandler); + gHttpServer.start(-1); + } +}); + +let tests = [ + test_cookie_cleared, + test_cache_cleared, + test_image_cache_cleared, + test_storage_cleared, +]; + +add_task(function* test() { + for (let i = 0; i < tests.length; i++) + add_task(tests[i]); +}); + +registerCleanupFunction(() => { + gHttpServer.stop(() => { + gHttpServer = null; + }); +});
new file mode 100644 --- /dev/null +++ b/browser/components/contextualidentity/test/browser/file_set_storages.html @@ -0,0 +1,41 @@ +<html> + <head> + <meta charset="UTF-8"> + <title>Bug 1238183</title> + </head> + <body> + <script type="application/javascript;version=1.7"> + "use strict"; + + // if we have a query string, use it to set storages + if (window.location.search.length > 0) { + let context_name = window.location.search.substr(1); + localStorage.setItem("userContext", context_name); + sessionStorage.setItem("userContext", context_name); + + let request = indexedDB.open("idb", 1); + + request.onerror = function() { + throw new Error("error opening db connection"); + }; + + request.onupgradeneeded = event => { + let db = event.target.result; + let store = db.createObjectStore("obj", { keyPath: "id" }); + store.createIndex("userContext", "userContext", { unique: false }); + }; + + request.onsuccess = event => { + let db = request.result; + let transaction = db.transaction(["obj"], "readwrite"); + let store = transaction.objectStore("obj"); + store.add({id: 1, userContext: context_name}); + + transaction.oncomplete = () => { + db.close(); + }; + }; + } + </script> + </body> +</html>
--- a/dom/push/test/xpcshell/xpcshell.ini +++ b/dom/push/test/xpcshell/xpcshell.ini @@ -1,11 +1,12 @@ [DEFAULT] head = head.js head-http2.js tail = +firefox-appdir = browser # Push notifications and alarms are currently disabled on Android. skip-if = toolkit == 'android' [test_clear_forgetAboutSite.js] [test_clear_origin_data.js] [test_crypto.js] [test_drop_expired.js] [test_handler_service.js]
--- a/toolkit/forgetaboutsite/test/unit/xpcshell.ini +++ b/toolkit/forgetaboutsite/test/unit/xpcshell.ini @@ -1,8 +1,9 @@ [DEFAULT] head = head_forgetaboutsite.js ../../../../dom/push/test/xpcshell/head.js tail = +firefox-appdir = browser skip-if = toolkit == 'android' || toolkit == 'gonk' support-files = !/dom/push/test/xpcshell/head.js [test_removeDataFromDomain.js]