зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1772943 - Port osfile.jsm usage to IOUtils in toolkit/mozapps/ r=Gijs,mixedpuppy
Differential Revision: https://phabricator.services.mozilla.com/D148967
This commit is contained in:
Родитель
6b159ffeb4
Коммит
ccc656a53b
|
@ -4,10 +4,6 @@ const { AddonTestUtils } = ChromeUtils.import(
|
|||
"resource://testing-common/AddonTestUtils.jsm"
|
||||
);
|
||||
|
||||
const { ProductAddonCheckerTestUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/addons/ProductAddonChecker.jsm"
|
||||
);
|
||||
|
||||
AddonTestUtils.initMochitest(this);
|
||||
|
||||
const testServer = AddonTestUtils.createHttpServer();
|
||||
|
@ -69,9 +65,9 @@ add_task(async function test_management_install() {
|
|||
},
|
||||
});
|
||||
|
||||
let themeXPIFileHash = await ProductAddonCheckerTestUtils.computeHash(
|
||||
"sha256",
|
||||
themeXPIFile.path
|
||||
let themeXPIFileHash = await IOUtils.computeHexDigest(
|
||||
themeXPIFile.path,
|
||||
"sha256"
|
||||
);
|
||||
|
||||
const otherXPIFile = AddonTestUtils.createTempWebExtensionFile({
|
||||
|
|
|
@ -947,10 +947,7 @@ async function test_checkForAddons_installAddon(
|
|||
let data = "e~=0.5772156649";
|
||||
let zipFile = createNewZipFile(zipFileName, data);
|
||||
let hashFunc = "sha256";
|
||||
let expectedDigest = await ProductAddonCheckerTestUtils.computeHash(
|
||||
hashFunc,
|
||||
zipFile.path
|
||||
);
|
||||
let expectedDigest = await IOUtils.computeHexDigest(zipFile.path, hashFunc);
|
||||
let fileSize = zipFile.fileSize;
|
||||
if (wantInstallReject) {
|
||||
fileSize = 1;
|
||||
|
|
|
@ -27,7 +27,6 @@ const { XPCOMUtils } = ChromeUtils.importESModule(
|
|||
const { EventEmitter } = ChromeUtils.import(
|
||||
"resource://gre/modules/EventEmitter.jsm"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const lazy = {};
|
||||
|
||||
|
@ -657,13 +656,14 @@ var AddonTestUtils = {
|
|||
let loadedData = {};
|
||||
let fileSuffix = "extensions";
|
||||
const fileName = `${prefix}-${fileSuffix}.json`;
|
||||
let jsonStr = await OS.File.read(OS.Path.join(dir.path, fileName), {
|
||||
encoding: "UTF-8",
|
||||
}).catch(() => {});
|
||||
if (jsonStr) {
|
||||
|
||||
try {
|
||||
loadedData[fileSuffix] = await IOUtils.readJSON(
|
||||
PathUtils.join(dir.path, fileName)
|
||||
);
|
||||
this.info(`Loaded ${fileName}`);
|
||||
loadedData[fileSuffix] = JSON.parse(jsonStr);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return this.loadBlocklistRawData(loadedData);
|
||||
},
|
||||
|
||||
|
@ -933,32 +933,6 @@ var AddonTestUtils = {
|
|||
this.addonsList = new AddonsList(this.addonStartup);
|
||||
},
|
||||
|
||||
/**
|
||||
* Recursively create all directories up to and including the given
|
||||
* path, if they do not exist.
|
||||
*
|
||||
* @param {string} path The path of the directory to create.
|
||||
* @returns {Promise} Resolves when all directories have been created.
|
||||
*/
|
||||
recursiveMakeDir(path) {
|
||||
let paths = [];
|
||||
for (
|
||||
let lastPath;
|
||||
path != lastPath;
|
||||
lastPath = path, path = OS.Path.dirname(path)
|
||||
) {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
paths
|
||||
.reverse()
|
||||
.map(path =>
|
||||
OS.File.makeDir(path, { ignoreExisting: true }).catch(() => {})
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the given data to a file in the given zip file.
|
||||
*
|
||||
|
@ -1008,7 +982,7 @@ var AddonTestUtils = {
|
|||
},
|
||||
|
||||
async promiseWriteFilesToZip(zip, files, flags) {
|
||||
await this.recursiveMakeDir(OS.Path.dirname(zip));
|
||||
await IOUtils.makeDirectory(PathUtils.parent(zip));
|
||||
|
||||
this.writeFilesToZip(zip, files, flags);
|
||||
|
||||
|
@ -1016,7 +990,7 @@ var AddonTestUtils = {
|
|||
},
|
||||
|
||||
async promiseWriteFilesToDir(dir, files) {
|
||||
await this.recursiveMakeDir(dir);
|
||||
await IOUtils.makeDirectory(dir);
|
||||
|
||||
for (let [path, data] of Object.entries(files)) {
|
||||
path = path.split("/");
|
||||
|
@ -1025,21 +999,19 @@ var AddonTestUtils = {
|
|||
// Create parent directories, if necessary.
|
||||
let dirPath = dir;
|
||||
for (let subDir of path) {
|
||||
dirPath = OS.Path.join(dirPath, subDir);
|
||||
await OS.File.makeDir(dirPath, { ignoreExisting: true });
|
||||
dirPath = PathUtils.join(dirPath, subDir);
|
||||
await PathUtils.makeDirectory(dirPath);
|
||||
}
|
||||
|
||||
const leafPath = PathUtils.join(dirPath, leafName);
|
||||
if (
|
||||
typeof data == "object" &&
|
||||
ChromeUtils.getClassName(data) == "Object"
|
||||
) {
|
||||
data = JSON.stringify(data);
|
||||
await IOUtils.writeJSON(leafPath, data);
|
||||
} else if (typeof data == "string") {
|
||||
await IOUtils.writeUTF8(leafPath, data);
|
||||
}
|
||||
if (typeof data == "string") {
|
||||
data = new TextEncoder("utf-8").encode(data);
|
||||
}
|
||||
|
||||
await OS.File.writeAtomic(OS.Path.join(dirPath, leafName), data);
|
||||
}
|
||||
|
||||
return nsFile(dir);
|
||||
|
@ -1047,12 +1019,12 @@ var AddonTestUtils = {
|
|||
|
||||
promiseWriteFilesToExtension(dir, id, files, unpacked = this.testUnpacked) {
|
||||
if (unpacked) {
|
||||
let path = OS.Path.join(dir, id);
|
||||
let path = PathUtils.join(dir, id);
|
||||
|
||||
return this.promiseWriteFilesToDir(path, files);
|
||||
}
|
||||
|
||||
let xpi = OS.Path.join(dir, `${id}.xpi`);
|
||||
let xpi = PathUtils.join(dir, `${id}.xpi`);
|
||||
|
||||
return this.promiseWriteFilesToZip(xpi, files);
|
||||
},
|
||||
|
@ -1268,18 +1240,22 @@ var AddonTestUtils = {
|
|||
async promiseSetExtensionModifiedTime(path, time) {
|
||||
await IOUtils.setModificationTime(path, time);
|
||||
|
||||
let iterator = new OS.File.DirectoryIterator(path);
|
||||
const stat = await IOUtils.stat(path);
|
||||
if (stat.type !== "directory") {
|
||||
return;
|
||||
}
|
||||
|
||||
const children = await IOUtils.getChildren(path);
|
||||
|
||||
try {
|
||||
await iterator.forEach(entry => {
|
||||
return this.promiseSetExtensionModifiedTime(entry.path, time);
|
||||
});
|
||||
await Promise.all(
|
||||
children.map(entry => this.promiseSetExtensionModifiedTime(entry, time))
|
||||
);
|
||||
} catch (ex) {
|
||||
if (ex instanceof OS.File.Error) {
|
||||
if (DOMException.isInstance(ex)) {
|
||||
return;
|
||||
}
|
||||
throw ex;
|
||||
} finally {
|
||||
iterator.close().catch(() => {});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1792,10 +1768,7 @@ var AddonTestUtils = {
|
|||
this.tempXPIs.push(file);
|
||||
|
||||
let manifest = Services.io.newFileURI(file);
|
||||
await OS.File.writeAtomic(
|
||||
file.path,
|
||||
new TextEncoder().encode(JSON.stringify(data))
|
||||
);
|
||||
await IOUtils.writeJSON(file.path, data);
|
||||
this.overrideEntry = lazy.aomStartup.registerChrome(manifest, [
|
||||
[
|
||||
"override",
|
||||
|
|
|
@ -13,7 +13,6 @@ const { Log } = ChromeUtils.import("resource://gre/modules/Log.jsm");
|
|||
const { CertUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/CertUtils.jsm"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const lazy = {};
|
||||
|
||||
|
@ -37,8 +36,6 @@ logger.manageLevelFromPref("extensions.logging.productaddons.level");
|
|||
* ensure that we fail cleanly in such case.
|
||||
*/
|
||||
const TIMEOUT_DELAY_MS = 20000;
|
||||
// How much of a file to read into memory at a time for hashing
|
||||
const HASH_CHUNK_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* Gets the status of an XMLHttpRequest either directly or from its underlying
|
||||
|
@ -425,13 +422,13 @@ function downloadFile(url, options = { httpsOnlyNoUpgrade: false }) {
|
|||
return;
|
||||
}
|
||||
(async function() {
|
||||
let f = await OS.File.openUnique(
|
||||
OS.Path.join(OS.Constants.Path.tmpDir, "tmpaddon")
|
||||
const path = await IOUtils.createUniqueFile(
|
||||
PathUtils.osTempDir,
|
||||
"tmpaddon"
|
||||
);
|
||||
let path = f.path;
|
||||
logger.info(`Downloaded file will be saved to ${path}`);
|
||||
await f.file.close();
|
||||
await OS.File.writeAtomic(path, new Uint8Array(sr.response));
|
||||
await IOUtils.write(path, new Uint8Array(sr.response));
|
||||
|
||||
return path;
|
||||
})().then(resolve, reject);
|
||||
};
|
||||
|
@ -467,51 +464,6 @@ function downloadFile(url, options = { httpsOnlyNoUpgrade: false }) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string containing binary values to hex.
|
||||
*/
|
||||
function binaryToHex(input) {
|
||||
let result = "";
|
||||
for (let i = 0; i < input.length; ++i) {
|
||||
let hex = input.charCodeAt(i).toString(16);
|
||||
if (hex.length == 1) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
result += hex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the hash of a file.
|
||||
*
|
||||
* @param hashFunction
|
||||
* The type of hash function to use, must be supported by nsICryptoHash.
|
||||
* @param path
|
||||
* The path of the file to hash.
|
||||
* @return a promise that resolves to hash of the file or rejects with a JS
|
||||
* exception in case of error.
|
||||
*/
|
||||
var computeHash = async function(hashFunction, path) {
|
||||
let file = await OS.File.open(path, { existing: true, read: true });
|
||||
try {
|
||||
let hasher = Cc["@mozilla.org/security/hash;1"].createInstance(
|
||||
Ci.nsICryptoHash
|
||||
);
|
||||
hasher.initWithString(hashFunction);
|
||||
|
||||
let bytes;
|
||||
do {
|
||||
bytes = await file.read(HASH_CHUNK_SIZE);
|
||||
hasher.update(bytes, bytes.length);
|
||||
} while (bytes.length == HASH_CHUNK_SIZE);
|
||||
|
||||
return binaryToHex(hasher.finish(false));
|
||||
} finally {
|
||||
await file.close();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Verifies that a downloaded file matches what was expected.
|
||||
*
|
||||
|
@ -525,7 +477,7 @@ var computeHash = async function(hashFunction, path) {
|
|||
*/
|
||||
var verifyFile = async function(properties, path) {
|
||||
if (properties.size !== undefined) {
|
||||
let stat = await OS.File.stat(path);
|
||||
let stat = await IOUtils.stat(path);
|
||||
if (stat.size != properties.size) {
|
||||
throw new Error(
|
||||
"Downloaded file was " +
|
||||
|
@ -539,7 +491,7 @@ var verifyFile = async function(properties, path) {
|
|||
|
||||
if (properties.hashFunction !== undefined) {
|
||||
let expectedDigest = properties.hashValue.toLowerCase();
|
||||
let digest = await computeHash(properties.hashFunction, path);
|
||||
let digest = await IOUtils.computeHexDigest(path, properties.hashFunction);
|
||||
if (digest != expectedDigest) {
|
||||
throw new Error(
|
||||
"Hash was `" + digest + "` but expected `" + expectedDigest + "`."
|
||||
|
@ -610,7 +562,7 @@ const ProductAddonChecker = {
|
|||
await verifyFile(addon, path);
|
||||
return path;
|
||||
} catch (e) {
|
||||
await OS.File.remove(path);
|
||||
await IOUtils.remove(path);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
@ -618,8 +570,6 @@ const ProductAddonChecker = {
|
|||
|
||||
// For test use only.
|
||||
const ProductAddonCheckerTestUtils = {
|
||||
computeHash,
|
||||
|
||||
/**
|
||||
* Used to override ServiceRequest calls with a mock request.
|
||||
* @param mockRequest The mocked ServiceRequest object.
|
||||
|
|
|
@ -10,7 +10,14 @@ loadTestSubscript("head_disco.js");
|
|||
// latest AMO API, by replacing API_RESPONSE_FILE's content with latest AMO API
|
||||
// response, e.g. from https://addons.allizom.org/api/v4/discovery/?lang=en-US
|
||||
// The response must contain at least one theme, and one extension.
|
||||
const API_RESPONSE_FILE = RELATIVE_DIR + "discovery/api_response.json";
|
||||
|
||||
const API_RESPONSE_FILE = PathUtils.join(
|
||||
Services.dirsvc.get("CurWorkD", Ci.nsIFile).path,
|
||||
// Trim empty component from splitting with trailing slash.
|
||||
...RELATIVE_DIR.split("/").filter(c => c.length),
|
||||
"discovery",
|
||||
"api_response.json"
|
||||
);
|
||||
|
||||
const AMO_TEST_HOST = "rewritten-for-testing.addons.allizom.org";
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ const {
|
|||
ExtensionUtils: { promiseEvent, promiseObserved },
|
||||
} = ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
AddonTestUtils.initMochitest(this);
|
||||
|
||||
// The response to the discovery API, as documented at:
|
||||
|
@ -36,7 +34,12 @@ AddonTestUtils.initMochitest(this);
|
|||
// https://addons.allizom.org/api/v4/discovery/?lang=en-US
|
||||
//
|
||||
// The response must contain at least one theme, and one extension.
|
||||
const DISCOAPI_DEFAULT_FIXTURE = RELATIVE_DIR + "discovery/api_response.json";
|
||||
const DISCOAPI_DEFAULT_FIXTURE = PathUtils.join(
|
||||
Services.dirsvc.get("CurWorkD", Ci.nsIFile).path,
|
||||
...RELATIVE_DIR.split("/"),
|
||||
"discovery",
|
||||
"api_response.json"
|
||||
);
|
||||
|
||||
// Read the content of API_RESPONSE_FILE, and replaces any embedded URLs with
|
||||
// URLs that point to the `amoServer` test server.
|
||||
|
@ -44,7 +47,7 @@ async function readAPIResponseFixture(
|
|||
amoTestHost,
|
||||
fixtureFilePath = DISCOAPI_DEFAULT_FIXTURE
|
||||
) {
|
||||
let apiText = await OS.File.read(fixtureFilePath, { encoding: "utf-8" });
|
||||
let apiText = await IOUtils.readUTF8(fixtureFilePath);
|
||||
apiText = apiText.replace(/\bhttps?:\/\/[^"]+(?=")/g, url => {
|
||||
try {
|
||||
url = new URL(url);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const { AddonTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/AddonTestUtils.jsm"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
|
||||
|
||||
|
@ -15,7 +14,7 @@ add_task(async function test_non_ascii_path() {
|
|||
Ci.nsIEnvironment
|
||||
);
|
||||
const PROFILE_VAR = "XPCSHELL_TEST_PROFILE_DIR";
|
||||
let profileDir = OS.Path.join(
|
||||
let profileDir = PathUtils.join(
|
||||
env.get(PROFILE_VAR),
|
||||
"\u00ce \u00e5m \u00f1\u00f8t \u00e5s\u00e7ii"
|
||||
);
|
||||
|
@ -51,9 +50,8 @@ add_task(async function test_non_ascii_path() {
|
|||
await AddonTestUtils.promiseInstallFile(xpi2);
|
||||
await AddonTestUtils.promiseShutdownManager();
|
||||
|
||||
let dbfile = OS.Path.join(profileDir, "extensions.json");
|
||||
let raw = new TextDecoder().decode(await OS.File.read(dbfile));
|
||||
let data = JSON.parse(raw);
|
||||
let dbfile = PathUtils.join(profileDir, "extensions.json");
|
||||
let data = await IOUtils.readJSON(dbfile);
|
||||
|
||||
let addons = data.addons.filter(a => a.id !== DEFAULT_THEME_ID);
|
||||
Assert.ok(Array.isArray(addons), "extensions.json has addons array");
|
||||
|
|
|
@ -36,7 +36,7 @@ const ID1 = "addon1@tests.mozilla.org";
|
|||
const ID2 = "addon2@tests.mozilla.org";
|
||||
const ID3 = "addon3@tests.mozilla.org";
|
||||
const ID4 = "addon4@tests.mozilla.org";
|
||||
const PATH4 = OS.Path.join(globalDir.path, `${ID4}.xpi`);
|
||||
const PATH4 = PathUtils.join(globalDir.path, `${ID4}.xpi`);
|
||||
|
||||
add_task(async function setup() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
|
|
@ -34,7 +34,7 @@ add_task(async function test_upgrade_incompatible() {
|
|||
});
|
||||
|
||||
// swap the incompatible extension in for the original
|
||||
let path = OS.Path.join(gProfD.path, "extensions", `${ID}.xpi`);
|
||||
let path = PathUtils.join(gProfD.path, "extensions", `${ID}.xpi`);
|
||||
let fileInfo = await IOUtils.stat(path);
|
||||
let timestamp = fileInfo.lastModified;
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
let { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
let { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
const RELATIVE_PATH = "browser/toolkit/mozapps/extensions/test/xpinstall";
|
||||
|
@ -50,7 +49,7 @@ function handleRequest(aRequest, aResponse) {
|
|||
LOG("Completing download");
|
||||
|
||||
try {
|
||||
// Doesn't seem to be a sane way to read using OS.File and write to an
|
||||
// Doesn't seem to be a sane way to read using IOUtils and write to an
|
||||
// nsIOutputStream so here we are.
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
file.initWithPath(xpiFile);
|
||||
|
@ -79,17 +78,16 @@ function handleRequest(aRequest, aResponse) {
|
|||
|
||||
aResponse.processAsync();
|
||||
|
||||
OS.File.getCurrentDirectory().then(dir => {
|
||||
xpiFile = OS.Path.join(dir, ...RELATIVE_PATH.split("/"), params.file);
|
||||
LOG("Starting slow download of " + xpiFile);
|
||||
const dir = Services.dirsvc.get("CurWorkD", Ci.nsIFile).path;
|
||||
xpiFile = PathUtils.join(dir, ...RELATIVE_PATH.split("/"), params.file);
|
||||
LOG("Starting slow download of " + xpiFile);
|
||||
|
||||
OS.File.stat(xpiFile).then(info => {
|
||||
aResponse.setHeader("Content-Type", "binary/octet-stream");
|
||||
aResponse.setHeader("Content-Length", info.size.toString());
|
||||
IOUtils.stat(xpiFile).then(info => {
|
||||
aResponse.setHeader("Content-Type", "binary/octet-stream");
|
||||
aResponse.setHeader("Content-Length", info.size.toString());
|
||||
|
||||
LOG("Download paused");
|
||||
waitForComplete.then(complete_download);
|
||||
});
|
||||
LOG("Download paused");
|
||||
waitForComplete.then(complete_download);
|
||||
});
|
||||
} else if (params.continue) {
|
||||
dump(
|
||||
|
|
|
@ -18,6 +18,8 @@ module.exports = {
|
|||
ContentTask: false,
|
||||
ContentTaskUtils: false,
|
||||
EventUtils: false,
|
||||
IOUtils: false,
|
||||
PathUtils: false,
|
||||
PromiseDebugging: false,
|
||||
SpecialPowers: false,
|
||||
TestUtils: false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче