Created
September 15, 2020 22:35
-
-
Save ncalexan/b222fe7c80f26256cd19870e59f1996e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// Copied form | |
// taskcluster/docker/periodic-updates/scripts/getHSTSPreloadList.js, | |
// which simplified a version from | |
// browser/components/migration/MigrationUtils.jsm. | |
function spinResolve(promise) { | |
if (!(promise instanceof Promise)) { | |
return promise; | |
} | |
let done = false; | |
let result = null; | |
let error = null; | |
promise | |
.catch(e => { | |
dump(e); | |
console.log(`e: ${e}`, e, e.stack); | |
error = e; | |
}) | |
.then(r => { | |
result = r; | |
done = true; | |
}); | |
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); | |
tm.spinEventLoopUntil(() => done); | |
if (error) { | |
throw error; | |
} else { | |
return result; | |
} | |
} | |
/** | |
* Returns a Promise which resolves when the given observer topic has been | |
* observed. | |
* | |
* @param {string} topic | |
* The topic to observe. | |
* @param {function(nsISupports, string)} [test] | |
* An optional test function which, when called with the | |
* observer's subject and data, should return true if this is the | |
* expected notification, false otherwise. | |
* @returns {Promise<object>} | |
*/ | |
function promiseObserved(topic, test = () => true) { | |
return new Promise(resolve => { | |
let observer = (subject, topic, data) => { | |
if (test(subject, data)) { | |
Services.obs.removeObserver(observer, topic); | |
resolve({ subject, data }); | |
} | |
}; | |
Services.obs.addObserver(observer, topic); | |
}); | |
}; | |
// Determine if we're running on parent or child | |
var runningInParent = true; | |
try { | |
// Don't use Services.appinfo here as it disables replacing appinfo with stubs | |
// for test usage. | |
runningInParent = | |
// eslint-disable-next-line mozilla/use-services | |
Cc["@mozilla.org/xre/runtime;1"].getService(Ci.nsIXULRuntime).processType == | |
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; | |
} catch (e) {} | |
/** | |
* Registers a directory with the profile service, | |
* and return the directory as an nsIFile. | |
* | |
* @param notifyProfileAfterChange Whether to notify for "profile-after-change". | |
* @return nsIFile of the profile directory. | |
*/ | |
function do_get_profile(notifyProfileAfterChange = false) { | |
if (!runningInParent) { | |
console.info("Ignoring profile creation from child process."); | |
return null; | |
} | |
let env = Cc["@mozilla.org/process/environment;1"].getService( | |
Ci.nsIEnvironment | |
); | |
// XXX generate this properly. | |
let profd = "/Users/nalexander/Mozilla/gecko/test-profile"; | |
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); | |
file.initWithPath(profd); | |
let provider = { | |
getFile(prop, persistent) { | |
persistent.value = true; | |
if ( | |
prop == "ProfD" || | |
prop == "ProfLD" || | |
prop == "ProfDS" || | |
prop == "ProfLDS" || | |
prop == "TmpD" | |
) { | |
return file.clone(); | |
} | |
return null; | |
}, | |
QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]), | |
}; | |
Services.dirsvc | |
.QueryInterface(Ci.nsIDirectoryService) | |
.registerProvider(provider); | |
try { | |
Services.dirsvc.undefine("TmpD"); | |
} catch (e) { | |
// This throws if the key is not already registered, but that | |
// doesn't matter. | |
if (e.result != Cr.NS_ERROR_FAILURE) { | |
throw e; | |
} | |
} | |
// We need to update the crash events directory when the profile changes. | |
if (runningInParent && "@mozilla.org/toolkit/crash-reporter;1" in Cc) { | |
let crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService( | |
Ci.nsICrashReporter | |
); | |
crashReporter.UpdateCrashEventsDir(); | |
} | |
// if (!_profileInitialized) { | |
Services.obs.notifyObservers( | |
null, | |
"profile-do-change", | |
"xpcshell-do-get-profile" | |
); | |
// _profileInitialized = true; | |
// if (notifyProfileAfterChange) { | |
Services.obs.notifyObservers( | |
null, | |
"profile-after-change", | |
"xpcshell-do-get-profile" | |
); | |
// } | |
// } | |
// The methods of 'provider' will retain this scope so null out everything | |
// to avoid spurious leak reports. | |
env = null; | |
profd = null; | |
provider = null; | |
return file.clone(); | |
} | |
(() => { | |
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. | |
getService(Ci.nsIMemoryReporterManager); | |
let amounts = [ | |
"vsize", | |
// "vsizeMaxContiguous", | |
"resident", | |
// "residentFast", | |
"residentPeak", | |
"residentUnique", | |
"heapAllocated", | |
"heapOverheadFraction", | |
"JSMainRuntimeGCHeap", | |
"JSMainRuntimeTemporaryPeak", | |
"JSMainRuntimeRealmsSystem", | |
"JSMainRuntimeRealmsUser", | |
// "imagesContentUsedUncompressed", | |
// "storageSQLite", | |
// "lowMemoryEventsVirtual", | |
// "lowMemoryEventsCommitSpace", | |
// "lowMemoryEventsPhysical", | |
// "ghostWindows", | |
// "pageFaultsHard", | |
]; | |
for (let i = 0; i < amounts.length; i++) { | |
// try { | |
// If mgr[amounts[i]] throws an exception, just move on -- some amounts | |
// aren't available on all platforms. But if the attribute simply | |
// isn't present, that indicates the distinguished amounts have changed | |
// and this file hasn't been updated appropriately. | |
let dummy = mgr[amounts[i]]; | |
console.log(`amounts: ${amounts[i]}: ${dummy}`); | |
// } catch (ex) { | |
// } | |
} | |
})(); | |
const { AppConstants } = ChromeUtils.import( | |
"resource://gre/modules/AppConstants.jsm" | |
); | |
// Can't use app info from xpcshell. | |
// let appInfo = Cc["@mozilla.org/xre/app-info;1"] | |
// .getService(Ci.nsIXULAppInfo); | |
dump(`version: ${AppConstants.MOZ_APP_VERSION} (${AppConstants.MOZ_BUILDID})\n`); | |
const { XPCOMUtils } = ChromeUtils.import( | |
"resource://gre/modules/XPCOMUtils.jsm" | |
); | |
const { UpdateUtils } = ChromeUtils.import( | |
"resource://gre/modules/UpdateUtils.jsm" | |
); | |
ChromeUtils.import("resource://gre/modules/Services.jsm", this); | |
const PREF_APP_UPDATE_LOG = "app.update.log"; | |
const PREF_APP_UPDATE_FILE_LOGGING = "app.update.log.file"; | |
// XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() { | |
Services.prefs.setCharPref("browser.policies.loglevel", "debug"); | |
Services.prefs.setBoolPref(PREF_APP_UPDATE_LOG, true); | |
// }); | |
// Launching the socket process fails. | |
// File: ipc/glue/GeckoChildProcessHost.cpp | |
// 1725: MOZ_CRASH("Failed to get app path"); | |
Services.prefs.setBoolPref("network.process.enabled", false); | |
// Addons, and in particular langpacks, are per-profile. Background | |
// tasks are always going to use a temporary profile so updating | |
// langpacks from a background task will require significant | |
// additional work. | |
Services.prefs.setBoolPref("app.update.langpack.enabled", false); | |
function _register_modules_protocol_handler() { | |
if (!_TESTING_MODULES_DIR) { | |
throw new Error( | |
"Please define a path where the testing modules can be " + | |
"found in a variable called '_TESTING_MODULES_DIR' before " + | |
"head.js is included." | |
); | |
} | |
let protocolHandler = Services.io | |
.getProtocolHandler("resource") | |
.QueryInterface(Ci.nsIResProtocolHandler); | |
let modulesFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); | |
modulesFile.initWithPath(_TESTING_MODULES_DIR); | |
if (!modulesFile.exists()) { | |
throw new Error( | |
"Specified modules directory does not exist: " + _TESTING_MODULES_DIR | |
); | |
} | |
if (!modulesFile.isDirectory()) { | |
throw new Error( | |
"Specified modules directory is not a directory: " + _TESTING_MODULES_DIR | |
); | |
} | |
let modulesURI = Services.io.newFileURI(modulesFile); | |
protocolHandler.setSubstitution("testing-common", modulesURI); | |
} | |
_register_modules_protocol_handler(); | |
const { updateAppInfo } = ChromeUtils.import("resource://testing-common/AppInfo.jsm"); | |
// "https://aus5.mozilla.org/update/6/Firefox/81.0a1/20200818092452/Darwin_x86_64-gcc3/en-CA/nightly/Darwin%2018.7.0/ISET:SSE4_2,MEM:32768/default/default/update.xml" | |
/** | |
* Creates an nsIXULAppInfo | |
* | |
* @param aID | |
* The ID of the test application | |
* @param aName | |
* A name for the test application | |
* @param aVersion | |
* The version of the application | |
* @param aPlatformVersion | |
* The gecko version of the application | |
*/ | |
function createAppInfo(aID, aName, aVersion, aPlatformVersion) { | |
updateAppInfo({ | |
vendor: "Mozilla", | |
name: aName, | |
ID: aID, | |
version: aVersion, | |
appBuildID: "2007010101", | |
platformVersion: aPlatformVersion, | |
platformBuildID: "2007010101", | |
inSafeMode: false, | |
logConsoleErrors: true, | |
OS: "XPCShell", | |
XPCOMABI: "noarch-spidermonkey", | |
// XXX. | |
updateURL: "http://localhost:8000/update.xml", | |
// https://aus5.mozilla.org/update/6/Firefox/81.0a1/20200818092452/Darwin_x86_64-gcc3/en-CA/nightly/Darwin%2018.7.0/ISET:SSE4_2,MEM:32768/default/default/update.xml", | |
}); | |
} | |
createAppInfo("[email protected]", "XPCShell", "1.0", "2.0"); | |
// This initializes the policy engine for xpcshell tests | |
let policies = Cc["@mozilla.org/enterprisepolicies;1"].getService( | |
Ci.nsIObserver | |
); | |
policies.observe(null, "policies-startup", null); | |
// console.log(`Services.policies: ${Services.policies}`); | |
// if (Services.policies) { | |
// // // Initialize the Enterprise Policies service in the parent process | |
// // // In the content process it's loaded on demand when needed | |
// // if (XRE_IsParentProcess()) { | |
// // nsCOMPtr<nsIObserver> policies( | |
// // do_GetService("@mozilla.org/enterprisepolicies;1")); | |
// // if (policies) { | |
// // policies->Observe(nullptr, "policies-startup", nullptr); | |
// // } | |
// // } | |
// Services.policies.QueryInterface(Ci.nsIObserver).observe(null, "policies-startup", null); | |
// } | |
// let p = promiseObserved("EnterprisePolicies:AllPoliciesApplied"); | |
let profile = do_get_profile(); | |
console.log(`profile: ${profile.path}`); | |
try { | |
// Services.obs.notifyObservers(null, "policies-startup"); | |
// Services.obs.notifyObservers(null, "EnterprisePolicies:Restart"); // policies-startup"); | |
// spinResolve(p); | |
console.log(`Running task: after spinResolve`); | |
// console.log(`XREAppDist: ${Services.dirsvc.get("XREAppDist", Ci.nsIFile).path}`); | |
let activePolicies = Services.policies.getActivePolicies(); | |
// if (policies) { // && "AppUpdateURL" in policies) { | |
console.log(`policies: ${JSON.stringify(activePolicies)}`); | |
// } | |
// } | |
// exit(0); | |
// const { AppUpdater } = ChromeUtils.import( | |
// "resource:///modules/AppUpdater.jsm" | |
// ); | |
// XPCOMUtils.defineLazyModuleGetters(this, { | |
// AppUpdater: "resource:///modules/AppUpdater.jsm", | |
// // Services: "resource://gre/modules/Services.jsm", | |
// }); | |
// XPCOMUtils.defineLazyGetter(this, "appUpdater", () => new AppUpdater()); | |
(() => { | |
if (!_UPDROOTD) { | |
throw new Error("Please define '_UPDROOTD_DIR'!"); | |
} | |
let env = Cc["@mozilla.org/process/environment;1"].getService( | |
Ci.nsIEnvironment | |
); | |
let profd = "/Users/nalexander/Mozilla/gecko/buprof"; // env.get("XPCSHELL_TEST_PROFILE_DIR"); | |
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); | |
file.initWithPath(profd); | |
let updRootD = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); | |
updRootD.initWithPath(_UPDROOTD); | |
let dirsvc = Cc["@mozilla.org/file/directory_service;1"].getService( | |
Ci.nsIDirectoryServiceProvider | |
); | |
let provider = { | |
getFile(prop, persistent) { | |
persistent.value = true; | |
if ( | |
prop == "ProfD" || | |
prop == "ProfLD" || | |
prop == "ProfDS" || | |
prop == "ProfLDS" || | |
prop == "TmpD" | |
) { | |
return file.clone(); | |
} | |
if (prop == "UpdRootD") { | |
return updRootD.clone(); | |
} | |
return null; | |
}, | |
QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]), | |
}; | |
dirsvc | |
.QueryInterface(Ci.nsIDirectoryService) | |
.registerProvider(provider); | |
// try { | |
// dirsvc.undefine("TmpD"); | |
// } catch (e) { | |
// // This throws if the key is not already registered, but that | |
// // doesn't matter. | |
// if (e.result != Cr.NS_ERROR_FAILURE) { | |
// throw e; | |
// } | |
// } | |
// // We need to update the crash events directory when the profile changes. | |
// if (runningInParent && "@mozilla.org/toolkit/crash-reporter;1" in Cc) { | |
// let crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService( | |
// Ci.nsICrashReporter | |
// ); | |
// crashReporter.UpdateCrashEventsDir(); | |
// } | |
// if (!_profileInitialized) { | |
// Services.obs.notifyObservers( | |
// null, | |
// "profile-do-change", | |
// "xpcshell-do-get-profile" | |
// ); | |
// _profileInitialized = true; | |
// if (notifyProfileAfterChange) { | |
// Services.obs.notifyObservers( | |
// null, | |
// "profile-after-change", | |
// "xpcshell-do-get-profile" | |
// ); | |
// } | |
// } | |
// The methods of 'provider' will retain this scope so null out everything | |
// to avoid spurious leak reports. | |
env = null; | |
profd = null; | |
provider = null; | |
return file.clone(); | |
})(); | |
let um = Cc["@mozilla.org/updates/update-manager;1"] | |
.getService(Ci.nsIUpdateManager); | |
let checker = Cc["@mozilla.org/updates/update-checker;1"] | |
.getService(Ci.nsIUpdateChecker); | |
let aus = Cc["@mozilla.org/updates/update-service;1"] | |
.getService(Ci.nsIApplicationUpdateService); | |
// // Clear prefs that could prevent a user from discovering available updates. | |
// if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CANCELATIONS_OSX)) { | |
// Services.prefs.clearUserPref(PREF_APP_UPDATE_CANCELATIONS_OSX); | |
// } | |
// if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ELEVATE_NEVER)) { | |
// Services.prefs.clearUserPref(PREF_APP_UPDATE_ELEVATE_NEVER); | |
// } | |
// let updateCheckListener = { | |
// _setStatus: (...args) => { | |
// console.log(`_setStatus: ${JSON.stringify(args)}`); | |
// }, | |
// /** | |
// * See nsIUpdateService.idl | |
// */ | |
// onCheckComplete: (aRequest, aUpdates, ...args) => { | |
// console.log(`onCheckComplete: ${JSON.stringify(args)}`); | |
// this.update = aus.selectUpdate(aUpdates); | |
// if (!this.update) { | |
// this._setStatus("AppUpdater.STATUS.NO_UPDATES_FOUND"); | |
// return; | |
// } | |
// if (this.update.unsupported) { | |
// this._setStatus("AppUpdater.STATUS.UNSUPPORTED_SYSTEM"); | |
// return; | |
// } | |
// if (!aus.canApplyUpdates) { | |
// this._setStatus("AppUpdater.STATUS.MANUAL_UPDATE"); | |
// return; | |
// } | |
// if (!this.promiseAutoUpdateSetting) { | |
// this.promiseAutoUpdateSetting = UpdateUtils.getAppUpdateAutoEnabled(); | |
// } | |
// this.promiseAutoUpdateSetting.then(updateAuto => { | |
// if (updateAuto) { | |
// // automatically download and install | |
// this.startDownload(); | |
// } else { | |
// // ask | |
// this._setStatus("AppUpdater.STATUS.DOWNLOAD_AND_INSTALL"); | |
// } | |
// }); | |
// }, | |
// /** | |
// * See nsIUpdateService.idl | |
// */ | |
// onError: (aRequest, aUpdate, ...args) => { | |
// console.log(`onError: ${JSON.stringify(args)}`); | |
// // Errors in the update check are treated as no updates found. If the | |
// // update check fails repeatedly without a success the user will be | |
// // notified with the normal app update user interface so this is safe. | |
// this._setStatus("AppUpdater.STATUS.NO_UPDATES_FOUND"); | |
// }, | |
// /** | |
// * See nsISupports.idl | |
// */ | |
// QueryInterface: ChromeUtils.generateQI(["nsIUpdateCheckListener"]), | |
// }; | |
// try { | |
// checker.checkForUpdates(updateCheckListener, true); | |
// } catch (e) { | |
// dump(e); | |
// dump(e.stack); | |
// console.log(`e: ${e}`, e, e.stack); | |
// } | |
// spinResolve(new Promise(resolve => {})); | |
const { AppUpdater } = ChromeUtils.import( | |
"resource:///modules/AppUpdater.jsm" | |
); | |
let p = new Promise(resolve => { | |
try { | |
let appUpdater = new AppUpdater(); | |
let _appUpdaterListener = (...args) => { | |
console.log(`_appUpdaterListener: ${JSON.stringify(args)}`); | |
// appUpdater.removeListener(_appUpdaterListener); | |
// resolve(); | |
}; | |
appUpdater.addListener(_appUpdaterListener); | |
appUpdater.check(); | |
} catch (e) { | |
console.log(`e: ${e}`, e, e.stack); | |
throw e; | |
} | |
}); | |
try { | |
spinResolve(p); | |
} catch (e) { | |
dump(e); | |
dump(e.stack); | |
console.log(`e: ${e}`, e, e.stack); | |
} | |
} finally { | |
if (true) { // _profileInitialized) { | |
// Since we have a profile, we will notify profile shutdown topics at | |
// the end of the current test, to ensure correct cleanup on shutdown. | |
Services.obs.notifyObservers(null, "profile-change-net-teardown"); | |
Services.obs.notifyObservers(null, "profile-change-teardown"); | |
Services.obs.notifyObservers(null, "profile-before-change"); | |
Services.obs.notifyObservers(null, "profile-before-change-qm"); | |
// _profileInitialized = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment