summaryrefslogtreecommitdiffstats
path: root/dom/quota/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:42 +0000
commitda4c7e7ed675c3bf405668739c3012d140856109 (patch)
treecdd868dba063fecba609a1d819de271f0d51b23e /dom/quota/test
parentAdding upstream version 125.0.3. (diff)
downloadfirefox-da4c7e7ed675c3bf405668739c3012d140856109.tar.xz
firefox-da4c7e7ed675c3bf405668739c3012d140856109.zip
Adding upstream version 126.0.upstream/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.py0
-rw-r--r--dom/quota/test/marionette/manifest.toml3
-rw-r--r--dom/quota/test/marionette/quota_test_case.py180
-rw-r--r--dom/quota/test/marionette/test_private_repository_cleanup.py94
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()