Bug 1624802 - Refactor tests in dom/quota/test; r=dom-workers-and-storage-reviewers,ttung

The refactoring consists of:
- moving tests into dedicated directories for given test type
  (browser, mochitest, xpcshell)
- replacing add_test with addTest in browser tests to share common setup code
- adding a way to synchronously load scripts in all test types by providing a
  path relative to the top level directory
- adding a way to explicitely run a mochitest inside a worker context
  (loadWorkerScript)
- removing the need to declare testGenerator in tests
- removing the need to set some common preferences in individual tests
- sharing common functions for:
  - system context (system.js)
  - content context (content.js)
  - browser tests (browser.js)
  - mochitest tests (mochitest.js)
  - xpcshell tests (xpcshell.js)
  - nested content test inside a browser test (nestedtest.js)
  - buffer/view/blob/file (file.js)

Differential Revision: https://phabricator.services.mozilla.com/D73149
This commit is contained in:
Jan Varga 2020-05-08 09:49:52 +00:00
Родитель d94331c3ca
Коммит 6caab074de
137 изменённых файлов: 531 добавлений и 454 удалений

Просмотреть файл

@ -7,25 +7,7 @@
with Files("**"):
BUG_COMPONENT = ("Core", "Storage: Quota Manager")
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
XPCSHELL_TESTS_MANIFESTS += [
'test/unit/telemetry/xpcshell.ini',
'test/unit/upgrades/xpcshell.ini',
'test/unit/xpcshell.ini'
]
TEST_HARNESS_FILES.xpcshell.dom.quota.test += [
'test/head-shared.js',
]
TEST_HARNESS_FILES.xpcshell.dom.quota.test.unit += [
'test/unit/head-shared.js',
]
TEST_DIRS += ['test/gtest']
DIRS += ['test']
XPIDL_SOURCES += [
'nsIQuotaCallbacks.idl',

Просмотреть файл

@ -1,5 +0,0 @@
"use strict";
module.exports = {
extends: ["plugin:mozilla/mochitest-test", "plugin:mozilla/browser-test"],
};

Просмотреть файл

@ -1,11 +1,10 @@
[DEFAULT]
skip-if = (buildapp != "browser")
support-files =
browserHelpers.js
browser_permissionsPrompt.html
head-shared.js
head.js
helpers.js
empty.html
permissionsPrompt.html
[browser_permissionsCrossOrigin.js]
[browser_permissionsPromptAllow.js]

Просмотреть файл

@ -3,9 +3,10 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const emptyURL = "https://example.com/browser/dom/quota/test/empty.html";
const emptyURL =
"https://example.com/browser/dom/quota/test/browser/empty.html";
add_task(async function testNoPermissionPrompt() {
addTest(async function testNoPermissionPrompt() {
registerPopupEventHandler("popupshowing", function() {
ok(false, "Shouldn't show a popup this time");
});

Просмотреть файл

@ -4,9 +4,9 @@
*/
const testPageURL =
"https://example.com/browser/dom/quota/test/browser_permissionsPrompt.html";
"https://example.com/browser/dom/quota/test/browser/permissionsPrompt.html";
add_task(async function testPermissionAllow() {
addTest(async function testPermissionAllow() {
removePermission(testPageURL, "persistent-storage");
registerPopupEventHandler("popupshowing", function() {
@ -37,7 +37,7 @@ add_task(async function testPermissionAllow() {
// Keep persistent-storage permission for the next test.
});
add_task(async function testNoPermissionPrompt() {
addTest(async function testNoPermissionPrompt() {
registerPopupEventHandler("popupshowing", function() {
ok(false, "Shouldn't show a popup this time");
});

Просмотреть файл

@ -4,9 +4,9 @@
*/
const testPageURL =
"https://example.com/browser/dom/quota/test/browser_permissionsPrompt.html";
"https://example.com/browser/dom/quota/test/browser/permissionsPrompt.html";
add_task(async function testPermissionTemporaryDenied() {
addTest(async function testPermissionTemporaryDenied() {
registerPopupEventHandler("popupshowing", function() {
ok(true, "prompt showing");
});
@ -46,7 +46,7 @@ add_task(async function testPermissionTemporaryDenied() {
removePermission(testPageURL, "persistent-storage");
});
add_task(async function testPermissionDenied() {
addTest(async function testPermissionDenied() {
removePermission(testPageURL, "persistent-storage");
registerPopupEventHandler("popupshowing", function() {
@ -77,7 +77,7 @@ add_task(async function testPermissionDenied() {
// Keep persistent-storage permission for the next test.
});
add_task(async function testNoPermissionPrompt() {
addTest(async function testNoPermissionPrompt() {
registerPopupEventHandler("popupshowing", function() {
ok(false, "Shouldn't show a popup this time");
});
@ -105,7 +105,7 @@ add_task(async function testNoPermissionPrompt() {
removePermission(testPageURL, "persistent-storage");
});
add_task(async function testPermissionDeniedDismiss() {
addTest(async function testPermissionDeniedDismiss() {
registerPopupEventHandler("popupshowing", function() {
ok(true, "prompt showing");
});

Просмотреть файл

@ -4,9 +4,9 @@
*/
const testPageURL =
"https://example.com/browser/dom/quota/test/browser_permissionsPrompt.html";
"https://example.com/browser/dom/quota/test/browser/permissionsPrompt.html";
add_task(async function testPermissionUnknownInPrivateWindow() {
addTest(async function testPermissionUnknownInPrivateWindow() {
removePermission(testPageURL, "persistent-storage");
info("Creating private window");
let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });

Просмотреть файл

@ -3,12 +3,13 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
add_task(async function testSimpleDB() {
// getRandomBuffer, compareBuffers
loadScript("dom/quota/test/common/file.js");
addTest(async function testSimpleDB() {
const name = "data";
const bufferSize = 100;
await SpecialPowers.pushPrefEnv({ set: [["dom.simpleDB.enabled", true]] });
let database = getSimpleDatabase();
let request = database.open("data");

Просмотреть файл

Просмотреть файл

@ -3,10 +3,18 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const NS_ERROR_STORAGE_BUSY = Cr.NS_ERROR_STORAGE_BUSY;
// The path to the top level directory.
const depth = "../../../../";
var gActiveListeners = {};
loadScript("dom/quota/test/common/browser.js");
function loadScript(path) {
const url = new URL(depth + path, gTestPath);
Services.scriptloader.loadSubScript(url.href, this);
}
// These event (un)registration handlers only work for one window, DONOT use
// them with multiple windows.
@ -157,38 +165,3 @@ function getPermission(url, permission) {
.getService(Ci.nsIPermissionManager)
.testPermissionFromPrincipal(principal, permission);
}
function getCurrentPrincipal() {
return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
}
function getSimpleDatabase(principal) {
let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance(
Ci.nsISDBConnection
);
if (!principal) {
principal = getCurrentPrincipal();
}
connection.init(principal);
return connection;
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = function(req) {
if (req.resultCode == Cr.NS_OK) {
resolve(req.result);
} else {
reject(req.resultCode);
}
};
});
}
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/dom/quota/test/head-shared.js",
this
);

Просмотреть файл

@ -3,20 +3,22 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
// The path to the top level directory.
const depth = "../../../../";
var testGenerator;
var testResult;
function clearAllDatabases(callback) {
let qms = SpecialPowers.Services.qms;
let principal = SpecialPowers.wrap(document).nodePrincipal;
let request = qms.clearStoragesForPrincipal(principal);
let cb = SpecialPowers.wrapCallback(callback);
request.callback = cb;
loadScript("dom/quota/test/common/nestedtest.js");
function loadScript(path) {
const url = new URL(depth + path, window.location.href);
SpecialPowers.Services.scriptloader.loadSubScript(url.href, this);
}
function runTest() {
clearAllDatabases(() => {
testGenerator = testSteps();
testGenerator.next();
});
}

Просмотреть файл

@ -7,12 +7,13 @@
<meta charset=UTF-8>
<title>Persistent-Storage Permission Prompt Test</title>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript">
function* testSteps()
{
SpecialPowers.pushPrefEnv({
"set": [["dom.storageManager.enabled", true],
["dom.storageManager.prompt.testing", false],
"set": [["dom.storageManager.prompt.testing", false],
["dom.storageManager.prompt.testing.allow", false]]
}, continueToNextStep);
yield undefined;
@ -26,8 +27,6 @@
}
</script>
<script type="text/javascript" src="browserHelpers.js"></script>
</head>
<body onload="runTest();" onunload="finishTestNow();"></body>

Просмотреть файл

@ -0,0 +1,34 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
loadScript("dom/quota/test/common/system.js");
function addTest(testFunction) {
const taskFunction = async function() {
await enableStorageTesting();
await testFunction();
};
Object.defineProperty(taskFunction, "name", {
value: testFunction.name,
writable: false,
});
add_task(taskFunction);
}
async function enableStorageTesting() {
const prefsToSet = [
["dom.quotaManager.testing", true],
["dom.storageManager.enabled", true],
["dom.simpleDB.enabled", true],
];
if (Services.appinfo.OS === "WINNT") {
prefsToSet.push(["dom.quotaManager.useDOSDevicePathSyntax", true]);
}
await SpecialPowers.pushPrefEnv({ set: prefsToSet });
}

Просмотреть файл

@ -0,0 +1,71 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const NS_ERROR_STORAGE_BUSY = SpecialPowers.Cr.NS_ERROR_STORAGE_BUSY;
function clearAllDatabases(callback) {
let qms = SpecialPowers.Services.qms;
let principal = SpecialPowers.wrap(document).nodePrincipal;
let request = qms.clearStoragesForPrincipal(principal);
let cb = SpecialPowers.wrapCallback(callback);
request.callback = cb;
return request;
}
// SimpleDB connections and SpecialPowers wrapping:
//
// SpecialPowers provides a SpecialPowersHandler Proxy mechanism that lets our
// content-privileged code borrow its chrome-privileged principal to access
// things we shouldn't be able to access. The proxies wrap their returned
// values, so once we have something wrapped we can rely on returned objects
// being wrapped as well. The proxy will also automatically unwrap wrapped
// arguments we pass in. However, we need to invoke wrapCallback on callback
// functions so that the arguments they receive will be wrapped because the
// proxy does not automatically wrap content-privileged functions.
//
// Our use of (wrapped) SpecialPowers.Cc results in getSimpleDatabase()
// producing a wrapped nsISDBConnection instance. The nsISDBResult instances
// exposed on the (wrapped) nsISDBRequest are also wrapped, so our
// requestFinished helper wraps the results in helper objects that behave the
// same as the result, automatically unwrapping the wrapped array/arraybuffer
// results.
function getSimpleDatabase() {
let connection = SpecialPowers.Cc[
"@mozilla.org/dom/sdb-connection;1"
].createInstance(SpecialPowers.Ci.nsISDBConnection);
let principal = SpecialPowers.wrap(document).nodePrincipal;
connection.init(principal);
return connection;
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = SpecialPowers.wrapCallback(function(req) {
if (req.resultCode === SpecialPowers.Cr.NS_OK) {
let result = req.result;
if (
SpecialPowers.call_Instanceof(result, SpecialPowers.Ci.nsISDBResult)
) {
let wrapper = {};
for (let i in result) {
if (typeof result[i] == "function") {
wrapper[i] = SpecialPowers.unwrap(result[i]);
} else {
wrapper[i] = result[i];
}
}
result = wrapper;
}
resolve(result);
} else {
reject(req.resultCode);
}
});
});
}

Просмотреть файл

Просмотреть файл

@ -0,0 +1,19 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
loadScript("dom/quota/test/common/content.js");
async function enableStorageTesting() {
let prefsToSet = [
["dom.quotaManager.testing", true],
["dom.storageManager.enabled", true],
["dom.simpleDB.enabled", true],
];
if (SpecialPowers.Services.appinfo.OS === "WINNT") {
prefsToSet.push(["dom.quotaManager.useDOSDevicePathSyntax", true]);
}
await SpecialPowers.pushPrefEnv({ set: prefsToSet });
}

Просмотреть файл

@ -0,0 +1,6 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
loadScript("dom/quota/test/common/content.js");

Просмотреть файл

@ -0,0 +1,68 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const NS_ERROR_STORAGE_BUSY = Cr.NS_ERROR_STORAGE_BUSY;
function getProfileDir() {
return Services.dirsvc.get("ProfD", Ci.nsIFile);
}
// Given a "/"-delimited path relative to a base file (or the profile
// directory if a base file is not provided) return an nsIFile representing the
// path. This does not test for the existence of the file or parent
// directories. It is safe even on Windows where the directory separator is
// not "/", but make sure you're not passing in a "\"-delimited path.
function getRelativeFile(relativePath, baseFile) {
if (!baseFile) {
baseFile = getProfileDir();
}
let file = baseFile.clone();
if (Services.appinfo.OS === "WINNT") {
let winFile = file.QueryInterface(Ci.nsILocalFileWin);
winFile.useDOSDevicePathSyntax = true;
}
relativePath.split("/").forEach(function(component) {
if (component == "..") {
file = file.parent;
} else {
file.append(component);
}
});
return file;
}
function getCurrentPrincipal() {
return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
}
function getSimpleDatabase(principal, persistence) {
let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance(
Ci.nsISDBConnection
);
if (!principal) {
principal = getCurrentPrincipal();
}
connection.init(principal, persistence);
return connection;
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = function(req) {
if (req.resultCode == Cr.NS_OK) {
resolve(req.result);
} else {
reject(req.resultCode);
}
};
});
}

Просмотреть файл

@ -3,7 +3,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var disableWorkerTest = "SimpleDB doesn't work in workers yet";
loadScript("dom/quota/test/common/file.js");
async function testSteps() {
const name = "data";

Просмотреть файл

@ -1,5 +1,7 @@
var disableWorkerTest = "Persist doesn't work in workers";
var testGenerator = testSteps();
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function* testSteps() {
SpecialPowers.pushPrefEnv(

Просмотреть файл

@ -1,5 +1,7 @@
var disableWorkerTest = "Persist doesn't work in workers";
var testGenerator = testSteps();
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function* testSteps() {
SpecialPowers.pushPrefEnv(

Просмотреть файл

@ -1,4 +1,7 @@
var testGenerator = testSteps();
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function* testSteps() {
navigator.storage.persisted().then(grabArgAndContinueHandler);

Просмотреть файл

@ -0,0 +1,91 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
loadScript("dom/quota/test/common/system.js");
function enableStorageTesting() {
Services.prefs.setBoolPref("dom.quotaManager.testing", true);
Services.prefs.setBoolPref("dom.storageManager.enabled", true);
Services.prefs.setBoolPref("dom.simpleDB.enabled", true);
if (Services.appinfo.OS === "WINNT") {
Services.prefs.setBoolPref("dom.quotaManager.useDOSDevicePathSyntax", true);
}
}
function resetStorageTesting() {
Services.prefs.clearUserPref("dom.quotaManager.testing");
Services.prefs.clearUserPref("dom.storageManager.enabled");
Services.prefs.clearUserPref("dom.simpleDB.enabled");
if (Services.appinfo.OS === "WINNT") {
Services.prefs.clearUserPref("dom.quotaManager.useDOSDevicePathSyntax");
}
}
function clear(callback) {
let request = Services.qms.clear();
request.callback = callback;
return request;
}
function reset(callback) {
let request = Services.qms.reset();
request.callback = callback;
return request;
}
function installPackage(packageRelativePath, allowFileOverwrites) {
let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
let packageFile = getRelativeFile(packageRelativePath + ".zip", currentDir);
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(
Ci.nsIZipReader
);
zipReader.open(packageFile);
let entryNames = Array.from(zipReader.findEntries(null));
entryNames.sort();
for (let entryName of entryNames) {
if (entryName.match(/^create_db\.(html|js)/)) {
continue;
}
let zipentry = zipReader.getEntry(entryName);
let file = getRelativeFile(entryName);
if (zipentry.isDirectory) {
if (!file.exists()) {
file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
}
} else {
if (!allowFileOverwrites && file.exists()) {
throw new Error("File already exists!");
}
let istream = zipReader.getInputStream(entryName);
var ostream = Cc[
"@mozilla.org/network/file-output-stream;1"
].createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, parseInt("0644", 8), 0);
let bostream = Cc[
"@mozilla.org/network/buffered-output-stream;1"
].createInstance(Ci.nsIBufferedOutputStream);
bostream.init(ostream, 32768);
bostream.writeFrom(istream, istream.available());
istream.close();
bostream.close();
}
}
zipReader.close();
}

Просмотреть файл

@ -3,63 +3,40 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const NS_ERROR_STORAGE_BUSY = SpecialPowers.Cr.NS_ERROR_STORAGE_BUSY;
// The path to the top level directory.
const depth = "../../../../";
var testGenerator;
if (testSteps.constructor.name === "GeneratorFunction") {
testGenerator = testSteps();
var testHarnessGenerator;
var workerScriptPaths = [];
loadScript("dom/quota/test/common/mochitest.js");
function loadScript(path) {
const url = new URL(depth + path, window.location.href);
SpecialPowers.Services.scriptloader.loadSubScript(url.href, this);
}
function clearAllDatabases(callback) {
let qms = SpecialPowers.Services.qms;
let principal = SpecialPowers.wrap(document).nodePrincipal;
let request = qms.clearStoragesForPrincipal(principal);
let cb = SpecialPowers.wrapCallback(callback);
request.callback = cb;
return request;
function loadWorkerScript(path) {
const url = new URL(depth + path, window.location.href);
workerScriptPaths.push(url.href);
}
var testHarnessGenerator = testHarnessSteps();
testHarnessGenerator.next();
function* testHarnessSteps() {
function nextTestHarnessStep(val) {
testHarnessGenerator.next(val);
}
function* loadScript(src) {
let script = document.createElement("script");
script.src = src;
script.onload = nextTestHarnessStep;
document.head.appendChild(script);
yield undefined;
}
let testScriptPath;
let testScriptFilename;
let scripts = document.getElementsByTagName("script");
for (let i = 0; i < scripts.length; i++) {
let src = scripts[i].src;
let match = src.match(/quota\/test\/unit\/(test_[^\/]+\.js)$/);
if (match && match.length == 2) {
testScriptPath = src;
testScriptFilename = match[1];
break;
}
}
info("Enabling storage testing");
enableStorageTesting().then(nextTestHarnessStep);
yield undefined;
info("Pushing preferences");
SpecialPowers.pushPrefEnv(
{
set: [
["dom.storageManager.enabled", true],
["dom.storageManager.prompt.testing", true],
["dom.simpleDB.enabled", true],
],
set: [["dom.storageManager.prompt.testing", true]],
},
nextTestHarnessStep
);
@ -70,9 +47,9 @@ function* testHarnessSteps() {
clearAllDatabases(nextTestHarnessStep);
yield undefined;
info("Running" + (testScriptFilename ? " '" + testScriptFilename + "'" : ""));
info("Running test in given scopes");
if (testScriptFilename && !window.disableWorkerTest) {
if (workerScriptPaths.length) {
info("Running test in a worker");
let workerScriptBlob = new Blob(["(" + workerScript.toString() + ")();"], {
@ -104,7 +81,7 @@ function* testHarnessSteps() {
break;
case "ready":
worker.postMessage({ op: "load", files: [testScriptPath] });
worker.postMessage({ op: "load", files: workerScriptPaths });
break;
case "loaded":
@ -140,23 +117,10 @@ function* testHarnessSteps() {
clearAllDatabases(nextTestHarnessStep);
yield undefined;
} else if (testScriptFilename) {
todo(
false,
"Skipping test in a worker because it is explicitly disabled: " +
disableWorkerTest
);
} else {
todo(
false,
"Skipping test in a worker because it's not structured properly"
);
}
info("Running test in main thread");
yield* loadScript("head-shared.js");
// Now run the test script in the main thread.
if (testSteps.constructor.name === "AsyncFunction") {
SimpleTest.registerCleanupFunction(async function() {
@ -165,6 +129,7 @@ function* testHarnessSteps() {
add_task(testSteps);
} else {
testGenerator = testSteps();
testGenerator.next();
yield undefined;
@ -174,6 +139,7 @@ function* testHarnessSteps() {
if (!window.runTest) {
window.runTest = function() {
SimpleTest.waitForExplicitFinish();
testHarnessGenerator = testHarnessSteps();
testHarnessGenerator.next();
};
}
@ -203,6 +169,8 @@ function continueToNextStepSync() {
function workerScript() {
"use strict";
self.testGenerator = null;
self.repr = function(_thing_) {
if (typeof _thing_ == "undefined") {
return "undefined";
@ -321,6 +289,7 @@ function workerScript() {
case "start":
executeSoon(function() {
info("Worker: starting tests");
testGenerator = testSteps();
testGenerator.next();
});
break;
@ -341,59 +310,3 @@ function workerScript() {
self.postMessage({ op: "ready" });
}
// SimpleDB connections and SpecialPowers wrapping:
//
// SpecialPowers provides a SpecialPowersHandler Proxy mechanism that lets our
// content-privileged code borrow its chrome-privileged principal to access
// things we shouldn't be able to access. The proxies wrap their returned
// values, so once we have something wrapped we can rely on returned objects
// being wrapped as well. The proxy will also automatically unwrap wrapped
// arguments we pass in. However, we need to invoke wrapCallback on callback
// functions so that the arguments they receive will be wrapped because the
// proxy does not automatically wrap content-privileged functions.
//
// Our use of (wrapped) SpecialPowers.Cc results in getSimpleDatabase()
// producing a wrapped nsISDBConnection instance. The nsISDBResult instances
// exposed on the (wrapped) nsISDBRequest are also wrapped, so our
// requestFinished helper wraps the results in helper objects that behave the
// same as the result, automatically unwrapping the wrapped array/arraybuffer
// results.
function getSimpleDatabase() {
let connection = SpecialPowers.Cc[
"@mozilla.org/dom/sdb-connection;1"
].createInstance(SpecialPowers.Ci.nsISDBConnection);
let principal = SpecialPowers.wrap(document).nodePrincipal;
connection.init(principal);
return connection;
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = SpecialPowers.wrapCallback(function(req) {
if (req.resultCode === SpecialPowers.Cr.NS_OK) {
let result = req.result;
if (
SpecialPowers.call_Instanceof(result, SpecialPowers.Ci.nsISDBResult)
) {
let wrapper = {};
for (let i in result) {
if (typeof result[i] == "function") {
wrapper[i] = SpecialPowers.unwrap(result[i]);
} else {
wrapper[i] = result[i];
}
}
result = wrapper;
}
resolve(result);
} else {
reject(req.resultCode);
}
});
});
}

Просмотреть файл

@ -4,12 +4,7 @@
[DEFAULT]
support-files =
head-shared.js
helpers.js
unit/test_simpledb.js
unit/test_storage_manager_persist_allow.js
unit/test_storage_manager_persist_deny.js
unit/test_storage_manager_persisted.js
[test_simpledb.html]
[test_storage_manager_persist_allow.html]

Просмотреть файл

@ -9,8 +9,10 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="unit/test_simpledb.js"></script>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript">
loadScript("dom/quota/test/common/test_simpledb.js");
</script>
</head>

Просмотреть файл

@ -9,8 +9,10 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="unit/test_storage_manager_persist_allow.js"></script>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript">
loadScript("dom/quota/test/common/test_storage_manager_persist_allow.js");
</script>
</head>

Просмотреть файл

@ -9,8 +9,10 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="unit/test_storage_manager_persist_deny.js"></script>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript">
loadScript("dom/quota/test/common/test_storage_manager_persist_deny.js");
</script>
</head>

Просмотреть файл

@ -9,8 +9,13 @@
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="unit/test_storage_manager_persisted.js"></script>
<script type="text/javascript" src="helpers.js"></script>
<script type="text/javascript">
const path = "dom/quota/test/common/test_storage_manager_persisted.js";
loadScript(path);
loadWorkerScript(path);
</script>
</head>

47
dom/quota/test/moz.build Normal file
Просмотреть файл

@ -0,0 +1,47 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
TEST_DIRS += ['gtest']
BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']
MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']
XPCSHELL_TESTS_MANIFESTS += [
'xpcshell/telemetry/xpcshell.ini',
'xpcshell/upgrades/xpcshell.ini',
'xpcshell/xpcshell.ini'
]
TEST_HARNESS_FILES.testing.mochitest.browser.dom.quota.test.common += [
'common/browser.js',
'common/content.js',
'common/file.js',
'common/nestedtest.js',
'common/system.js',
]
TEST_HARNESS_FILES.testing.mochitest.tests.dom.quota.test.common += [
'common/content.js',
'common/file.js',
'common/mochitest.js',
'common/test_simpledb.js',
'common/test_storage_manager_persist_allow.js',
'common/test_storage_manager_persist_deny.js',
'common/test_storage_manager_persisted.js',
]
TEST_HARNESS_FILES.xpcshell.dom.quota.test.common += [
'common/file.js',
'common/system.js',
'common/test_simpledb.js',
'common/xpcshell.js',
]
TEST_HARNESS_FILES.xpcshell.dom.quota.test.xpcshell.common += [
'xpcshell/common/head.js',
'xpcshell/common/utils.js',
]

Просмотреть файл

@ -1,15 +0,0 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Cu.import("resource://gre/modules/Services.jsm");
function loadSubscript(path) {
let file = do_get_file(path, false);
let uri = Services.io.newFileURI(file);
Services.scriptloader.loadSubScript(uri.spec);
}
loadSubscript("../head-shared.js");
loadSubscript("head-shared.js");

Просмотреть файл

@ -1,15 +0,0 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Cu.import("resource://gre/modules/Services.jsm");
function loadSubscript(path) {
let file = do_get_file(path, false);
let uri = Services.io.newFileURI(file);
Services.scriptloader.loadSubScript(uri.spec);
}
loadSubscript("../../head-shared.js");
loadSubscript("../head-shared.js");

Просмотреть файл

@ -6,12 +6,13 @@
const NS_OK = Cr.NS_OK;
const NS_ERROR_FAILURE = Cr.NS_ERROR_FAILURE;
const NS_ERROR_UNEXPECTED = Cr.NS_ERROR_UNEXPECTED;
const NS_ERROR_STORAGE_BUSY = Cr.NS_ERROR_STORAGE_BUSY;
const NS_ERROR_FILE_NO_DEVICE_SPACE = Cr.NS_ERROR_FILE_NO_DEVICE_SPACE;
const loggingEnabled = false;
Cu.import("resource://gre/modules/Services.jsm");
var testGenerator;
loadScript("dom/quota/test/common/xpcshell.js");
function log(msg) {
if (loggingEnabled) {
@ -39,6 +40,7 @@ if (!this.runTest) {
this.runTest = function() {
do_get_profile();
enableStorageTesting();
enableTesting();
Cu.importGlobalProperties(["indexedDB", "File", "Blob", "FileReader"]);
@ -53,7 +55,10 @@ if (!this.runTest) {
if (testSteps.constructor.name === "AsyncFunction") {
// Do run our existing cleanup function that would normally be called by
// the generator's call to finishTest().
registerCleanupFunction(resetTesting);
registerCleanupFunction(function() {
resetStorageTesting();
resetTesting();
});
add_task(testSteps);
@ -68,12 +73,14 @@ if (!this.runTest) {
do_test_pending();
testGenerator = testSteps();
testGenerator.next();
}
};
}
function finishTest() {
resetStorageTesting();
resetTesting();
executeSoon(function() {
@ -96,20 +103,10 @@ function continueToNextStepSync() {
}
function enableTesting() {
SpecialPowers.setBoolPref("dom.quotaManager.testing", true);
if (Services.appinfo.OS === "WINNT") {
SpecialPowers.setBoolPref("dom.quotaManager.useDOSDevicePathSyntax", true);
}
SpecialPowers.setBoolPref("dom.simpleDB.enabled", true);
SpecialPowers.setBoolPref("dom.storage.next_gen", true);
}
function resetTesting() {
SpecialPowers.clearUserPref("dom.quotaManager.testing");
if (Services.appinfo.OS === "WINNT") {
SpecialPowers.clearUserPref("dom.quotaManager.useDOSDevicePathSyntax");
}
SpecialPowers.clearUserPref("dom.simpleDB.enabled");
SpecialPowers.clearUserPref("dom.storage.next_gen");
}
@ -175,13 +172,6 @@ function initStorageAndChromeOrigin(persistence, callback) {
return request;
}
function clear(callback) {
let request = SpecialPowers._getQuotaManager().clear();
request.callback = callback;
return request;
}
function clearClient(principal, persistence, client, callback) {
let request = SpecialPowers._getQuotaManager().clearStoragesForPrincipal(
principal,
@ -216,13 +206,6 @@ function clearChromeOrigin(callback) {
return request;
}
function reset(callback) {
let request = SpecialPowers._getQuotaManager().reset();
request.callback = callback;
return request;
}
function resetClient(principal, client) {
let request = Services.qms.resetStoragesForPrincipal(
principal,
@ -254,91 +237,6 @@ function listOrigins(callback) {
return request;
}
function installPackage(packageRelativePath, allowFileOverwrites) {
let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
let packageFile = getRelativeFile(packageRelativePath + ".zip", currentDir);
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(
Ci.nsIZipReader
);
zipReader.open(packageFile);
let entryNames = Array.from(zipReader.findEntries(null));
entryNames.sort();
for (let entryName of entryNames) {
let zipentry = zipReader.getEntry(entryName);
let file = getRelativeFile(entryName);
if (zipentry.isDirectory) {
if (!file.exists()) {
file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8));
}
} else {
if (!allowFileOverwrites && file.exists()) {
throw new Error("File already exists!");
}
let istream = zipReader.getInputStream(entryName);
var ostream = Cc[
"@mozilla.org/network/file-output-stream;1"
].createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, parseInt("0644", 8), 0);
let bostream = Cc[
"@mozilla.org/network/buffered-output-stream;1"
].createInstance(Ci.nsIBufferedOutputStream);
bostream.init(ostream, 32768);
bostream.writeFrom(istream, istream.available());
istream.close();
bostream.close();
}
}
zipReader.close();
}
function getProfileDir() {
let directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(
Ci.nsIProperties
);
return directoryService.get("ProfD", Ci.nsIFile);
}
// Given a "/"-delimited path relative to a base file (or the profile
// directory if a base file is not provided) return an nsIFile representing the
// path. This does not test for the existence of the file or parent
// directories. It is safe even on Windows where the directory separator is
// not "/", but make sure you're not passing in a "\"-delimited path.
function getRelativeFile(relativePath, baseFile) {
if (!baseFile) {
baseFile = getProfileDir();
}
let file = baseFile.clone();
if (Services.appinfo.OS === "WINNT") {
let winFile = file.QueryInterface(Ci.nsILocalFileWin);
winFile.useDOSDevicePathSyntax = true;
}
relativePath.split("/").forEach(function(component) {
if (component == "..") {
file = file.parent;
} else {
file.append(component);
}
});
return file;
}
function getPersistedFromMetadata(readBuffer) {
const persistedPosition = 8; // Persisted state is stored in the 9th byte
let view =
@ -393,36 +291,6 @@ function getPrincipal(url, attr = {}) {
return ssm.createContentPrincipal(uri, attr);
}
function getCurrentPrincipal() {
return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
}
function getSimpleDatabase(principal, persistence) {
let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance(
Ci.nsISDBConnection
);
if (!principal) {
principal = getCurrentPrincipal();
}
connection.init(principal, persistence);
return connection;
}
function requestFinished(request) {
return new Promise(function(resolve, reject) {
request.callback = function(req) {
if (req.resultCode == Cr.NS_OK) {
resolve(req.result);
} else {
reject(req.resultCode);
}
};
});
}
var SpecialPowers = {
getBoolPref(prefName) {
return this._getPrefs().getBoolPref(prefName);

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Cu.import("resource://gre/modules/Services.jsm");
function getOriginDir(persistence, origin) {
return getRelativeFile(`storage/${persistence}/${origin}`);
}
@ -27,12 +25,3 @@ function makeRepositoryUnusable(persistence) {
const metadataFile = getMetadataFile(persistence, "https+++bad-example.com");
metadataFile.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
}
function loadSubscript(path) {
let file = do_get_file(path, false);
let uri = Services.io.newFileURI(file);
Services.scriptloader.loadSubScript(uri.spec);
}
loadSubscript("../../head-shared.js");
loadSubscript("../head-shared.js");

Просмотреть файл

@ -0,0 +1,16 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// The path to the top level directory.
const depth = "../../../../";
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
loadScript("dom/quota/test/xpcshell/common/head.js");
function loadScript(path) {
let uri = Services.io.newFileURI(do_get_file(depth + path));
Services.scriptloader.loadSubScript(uri.spec);
}

Просмотреть файл

@ -0,0 +1,16 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// The path to the top level directory.
const depth = "../../../../../";
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
loadScript("dom/quota/test/xpcshell/common/head.js");
function loadScript(path) {
let uri = Services.io.newFileURI(do_get_file(depth + path));
Services.scriptloader.loadSubScript(uri.spec);
}

Просмотреть файл

@ -706,6 +706,8 @@ const testcases = [
},
];
loadScript("dom/quota/test/xpcshell/common/utils.js");
function verifyHistogram(histogram, mainKey, expectedSnapshot) {
const snapshot = histogram.snapshot();

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const invalidOrigin = {
url: "ftp://ftp.invalid.origin",

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const storageFile = "storage.sqlite";
@ -67,7 +65,7 @@ function* testSteps() {
// The profile contains just one empty IndexedDB database. The file
// create_db.js in the package was run locally, specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
// mach xpcshell-test --interactive dom/quota/test/xpcshell/create_db.js
installPackage("basics_profile");
info("Getting usage");

Просмотреть файл

@ -26,7 +26,7 @@ async function testSteps() {
// - storage.sqlite
// The file create_db.js in the package was run locally, specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
// mach xpcshell-test --interactive dom/quota/test/xpcshell/create_db.js
// Note: to make it become the profile in the test, additional manual steps
// are needed.
// 1. Manually change the group and accessed values in the origin table in

Просмотреть файл

@ -4,9 +4,9 @@
*/
/**
* This test is an unit test for clearStorageForPrincipal. It verifies that if
* the removing client is the last client in the targeting origin, then it is
* expected to remove the origin directory as well.
* This test is an xpcshell test for clearStorageForPrincipal. It verifies that
* if the removing client is the last client in the targeting origin, then it
* is expected to remove the origin directory as well.
*/
async function testSteps() {

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const origins = [
{
@ -106,7 +104,7 @@ function* testSteps() {
// The profile contains IndexedDB databases placed across the repositories.
// The file create_db.js in the package was run locally, specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
// mach xpcshell-test --interactive dom/quota/test/xpcshell/create_db.js
installPackage("getUsage_profile");
info("Getting usage");

Просмотреть файл

@ -8,6 +8,8 @@
* get updated. See bug 1535995.
*/
loadScript("dom/quota/test/common/file.js");
async function testSteps() {
const principal = getPrincipal("https://foo.bar.mozilla-iot.org");
const metadataFile = getRelativeFile(
@ -40,7 +42,7 @@ async function testSteps() {
// - storage.sqlite
// The file create_db.js in the package was run locally, specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/localstorage/test/unit/create_db.js
// mach xpcshell-test --interactive dom/localstorage/test/xpcshell/create_db.js
// Note: to make it become the profile in the test, additional manual steps
// are needed.
// 1. Manually change the group in .metadata and .metadata-v2 from

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const origin = {
url: "http://default.test.persist",

Просмотреть файл

@ -3,6 +3,14 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* This test is mainly to verify that normally the oldest origin will be
* evicted if the global limit is reached, but if the oldest origin is
* persisted, then it won't be evicted.
*/
loadScript("dom/quota/test/common/file.js");
async function fillOrigin(principal, size) {
let database = getSimpleDatabase(principal);
@ -21,12 +29,6 @@ async function fillOrigin(principal, size) {
await requestFinished(request);
}
/**
* This test is mainly to verify that normally the oldest origin will be
* evicted if the global limit is reached, but if the oldest origin is
* persisted, then it won't be evicted.
*/
async function testSteps() {
// The group limit is calculated as 20% of the global limit and the minimum
// value of the group limit is 10 MB.

Просмотреть файл

@ -8,6 +8,8 @@
* the global limit.
*/
loadScript("dom/quota/test/common/file.js");
async function testSteps() {
const globalLimitKB = 1;

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const lsArchiveFile = "storage/ls-archive.sqlite";
const lsArchiveTmpFile = "storage/ls-archive-tmp.sqlite";

Просмотреть файл

@ -0,0 +1,6 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
loadScript("dom/quota/test/common/test_simpledb.js");

Просмотреть файл

@ -3,6 +3,15 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* This test is mainly to verify that the storage pressure event is fired when
* the eviction process is not able to free some space when a quota client
* attempts to write over the global limit or when the global limit is reduced
* below the global usage.
*/
loadScript("dom/quota/test/common/file.js");
function awaitStoragePressure() {
let promise_resolve;
@ -24,13 +33,6 @@ function awaitStoragePressure() {
return promise;
}
/**
* This test is mainly to verify that the storage pressure event is fired when
* the eviction process is not able to free some space when a quota client
* attempts to write over the global limit or when the global limit is reduced
* below the global usage.
*/
async function testSteps() {
const globalLimitKB = 2;

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const tempMetadataFiles = [
"storage/permanent/chrome/.metadata-tmp",

Просмотреть файл

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function* testSteps() {
const exampleUrl = "http://example.com";
const unknownRepoFile = {

Просмотреть файл

@ -0,0 +1,16 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// The path to the top level directory.
const depth = "../../../../../";
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
loadScript("dom/quota/test/xpcshell/common/head.js");
function loadScript(path) {
let uri = Services.io.newFileURI(do_get_file(depth + path));
Services.scriptloader.loadSubScript(uri.spec);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше