diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
commit | d8bbc7858622b6d9c278469aab701ca0b609cddf (patch) | |
tree | eff41dc61d9f714852212739e6b3738b82a2af87 /dom/quota/test | |
parent | Releasing progress-linux version 125.0.3-1~progress7.99u1. (diff) | |
download | firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/quota/test')
-rw-r--r-- | dom/quota/test/marionette/dummy.py | 0 | ||||
-rw-r--r-- | dom/quota/test/marionette/manifest.toml | 3 | ||||
-rw-r--r-- | dom/quota/test/marionette/quota_test_case.py | 180 | ||||
-rw-r--r-- | dom/quota/test/marionette/test_private_repository_cleanup.py | 94 |
4 files changed, 231 insertions, 46 deletions
diff --git a/dom/quota/test/marionette/dummy.py b/dom/quota/test/marionette/dummy.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/dom/quota/test/marionette/dummy.py +++ /dev/null diff --git a/dom/quota/test/marionette/manifest.toml b/dom/quota/test/marionette/manifest.toml index de02cdd541..f80095c590 100644 --- a/dom/quota/test/marionette/manifest.toml +++ b/dom/quota/test/marionette/manifest.toml @@ -1,5 +1,4 @@ [DEFAULT] support-files = ["quota_test_case.py"] -["dummy.py"] -skip-if = ["true"] +["test_private_repository_cleanup.py"] diff --git a/dom/quota/test/marionette/quota_test_case.py b/dom/quota/test/marionette/quota_test_case.py index c31edcaaf7..7d161cf4ff 100644 --- a/dom/quota/test/marionette/quota_test_case.py +++ b/dom/quota/test/marionette/quota_test_case.py @@ -10,6 +10,51 @@ from marionette_harness import MarionetteTestCase class QuotaTestCase(MarionetteTestCase): + def executeAsyncScript(self, script, script_args): + res = self.marionette.execute_async_script( + """ + const resolve = arguments[arguments.length - 1]; + + class RequestError extends Error { + constructor(resultCode, resultName) { + super(`Request failed (code: ${resultCode}, name: ${resultName})`); + this.name = "RequestError"; + this.resultCode = resultCode; + this.resultName = resultName; + } + } + + async function requestFinished(request) { + await new Promise(function (resolve) { + request.callback = function () { + resolve(); + }; + }); + + if (request.resultCode !== Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; + } + """ + + script + + """ + main() + .then(function(result) { + resolve(result); + }) + .catch(function() { + resolve(null); + });; + """, + script_args=script_args, + new_sandbox=False, + ) + + assert res is not None + return res + def ensureInvariantHolds(self, op): maxWaitTime = 60 Wait(self.marionette, timeout=maxWaitTime).until( @@ -24,27 +69,23 @@ class QuotaTestCase(MarionetteTestCase): return None def getFullOriginMetadata(self, persistenceType, origin): - with self.marionette.using_context("chrome"): - res = self.marionette.execute_async_script( + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + res = self.executeAsyncScript( """ - const [persistenceType, origin, resolve] = arguments; + const [persistenceType, origin] = arguments; - const principal = Services.scriptSecurityManager. - createContentPrincipalFromOrigin(origin); - - const request = Services.qms.getFullOriginMetadata( - persistenceType, principal); - - request.callback = function() { - if (request.resultCode != Cr.NS_OK) { - resolve(null); - } else { - resolve(request.result); - } - } + async function main() { + const principal = Services.scriptSecurityManager. + createContentPrincipalFromOrigin(origin); + + const request = Services.qms.getFullOriginMetadata( + persistenceType, principal); + const metadata = await requestFinished(request); + + return metadata; + } """, script_args=(persistenceType, origin), - new_sandbox=False, ) assert res is not None @@ -57,41 +98,91 @@ class QuotaTestCase(MarionetteTestCase): sanitizedStorageOrigin = storageOrigin.replace(":", "+").replace("/", "+") return os.path.join( - profilePath, "storage", persistenceType, sanitizedStorageOrigin, client + self.getRepositoryPath(persistenceType), sanitizedStorageOrigin, client ) + def getRepositoryPath(self, persistenceType): + profilePath = self.marionette.instance.profile.profile + assert profilePath is not None + + return os.path.join(profilePath, "storage", persistenceType) + + def initStorage(self): + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + return self.executeAsyncScript( + """ + async function main() { + let req = Services.qms.init(); + await requestFinished(req); + + return true; + } + """, + script_args=(), + ) + + def initTemporaryOrigin(self, persistenceType, origin): + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + return self.executeAsyncScript( + """ + const [persistenceType, origin] = arguments; + async function main() { + const principal = Services.scriptSecurityManager. + createContentPrincipalFromOrigin(origin); + + let req = Services.qms.initializeTemporaryOrigin(persistenceType, principal); + await requestFinished(req) + + return true; + } + """, + script_args=( + persistenceType, + origin, + ), + ) + + def initTemporaryStorage(self): + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + return self.executeAsyncScript( + """ + async function main() { + const req = Services.qms.initTemporaryStorage(); + await requestFinished(req); + + return true; + } + """, + script_args=(), + ) + def resetStoragesForPrincipal(self, origin, persistenceType, client): # This method is used to force sqlite to write journal file contents to # main sqlite database file - script = """ - const [resolve] = arguments - - let origin = '%s'; - let persistenceType = '%s'; - let client = '%s'; - let principal = Services.scriptSecurityManager. - createContentPrincipalFromOrigin(origin); - - let req = Services.qms.resetStoragesForPrincipal(principal, persistenceType, client); - req.callback = () => { - if (req.resultCode == Cr.NS_OK) { - resolve(true); - } else { - resolve(false); + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + res = self.executeAsyncScript( + """ + const [origin, persistenceType, client] = arguments; + + async function main() { + const principal = Services.scriptSecurityManager. + createContentPrincipalFromOrigin(origin); + + const request = Services.qms.resetStoragesForPrincipal(principal, persistenceType, client); + await requestFinished(request); + + return true; } - } - """ % ( - origin, - persistenceType, - client, - ) + """, + script_args=(origin, persistenceType, client), + ) - with self.marionette.using_context(self.marionette.CONTEXT_CHROME): - return self.marionette.execute_async_script(script) + assert res is not None + return res @contextmanager - def using_new_window(self, path, private=False): + def using_new_window(self, path, private=False, skipCleanup=False): """ This helper method is created to ensure that a temporary window required inside the test scope is lifetime'd properly @@ -109,5 +200,6 @@ class QuotaTestCase(MarionetteTestCase): yield (origin, "private" if private else "default") finally: - self.marionette.close() - self.marionette.switch_to_window(oldWindow) + if not skipCleanup: + self.marionette.close() + self.marionette.switch_to_window(oldWindow) diff --git a/dom/quota/test/marionette/test_private_repository_cleanup.py b/dom/quota/test/marionette/test_private_repository_cleanup.py new file mode 100644 index 0000000000..0d4c488757 --- /dev/null +++ b/dom/quota/test/marionette/test_private_repository_cleanup.py @@ -0,0 +1,94 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import sys +from pathlib import Path + +sys.path.append(os.fspath(Path(__file__).parents[0])) +from quota_test_case import QuotaTestCase + +QM_TESTING_PREF = "dom.quotaManager.testing" +AUTOSTART_PBM_PREF = "browser.privatebrowsing.autostart" + +""" + This test ensures that private repository gets properly purged in all below scenarios: + 1. at PBM session end + 2. on firefox start when last session was abnormally terminated (crash) + 3. on firefox shutdown (when PBM autostart is enabled i.e. browser.privatebrowsing.autostart set to true) +""" + + +class PrivateRepositoryCleanup(QuotaTestCase): + def setUp(self, autostartPBM=False): + super(PrivateRepositoryCleanup, self).setUp() + + self.marionette.set_pref(AUTOSTART_PBM_PREF, autostartPBM) + self.marionette.set_pref(QM_TESTING_PREF, True) + + self.marionette.restart(in_app=True) + + assert self.initStorage() + assert self.initTemporaryStorage() + + def tearDown(self): + self.marionette.clear_pref(AUTOSTART_PBM_PREF) + self.marionette.clear_pref(QM_TESTING_PREF) + + self.marionette.restart(in_app=True) + super(PrivateRepositoryCleanup, self).tearDown() + + def doStorageWork(self): + origin = self.marionette.absolute_url("")[:-1] + "^privateBrowsingId=1" + assert self.initTemporaryOrigin("private", origin) + + self.ensureInvariantHolds(lambda _: os.path.exists(self.getPrivateRepository())) + + def verifyCleanup(self): + self.ensureInvariantHolds( + lambda _: not os.path.exists(self.getPrivateRepository()) + ) + + def getPrivateRepository(self): + return self.getRepositoryPath("private") + + +class PBM(PrivateRepositoryCleanup): + def test_ensure_cleanup(self): + with self.using_new_window("", private=True): + self.doStorageWork() + + # private window must have been close by now + self.verifyCleanup() + + def test_ensure_cleanup_after_crash(self): + with self.using_new_window("", private=True, skipCleanup=True): + self.doStorageWork() + + # verify cleanup was performed after crashing and restarting + # firefox with in_app=False + self.marionette.restart(in_app=False) + self.verifyCleanup() + + +class PBMAutoStart(PrivateRepositoryCleanup): + def setUp(self): + super(PBMAutoStart, self).setUp(True) + + def test_ensure_cleanup(self): + self.doStorageWork() + + # verify cleanup was performed at the shutdown + self.marionette.quit(in_app=True) + self.verifyCleanup() + + self.marionette.start_session() + + def test_ensure_cleanup_after_crash(self): + self.doStorageWork() + + # verify cleanup was performed after crashing and restarting + # firefox with in_app=False + self.marionette.restart(in_app=False) + self.verifyCleanup() |