1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/experiments/test/xpcshell/head.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,248 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; 1.8 + 1.9 +Cu.import("resource://gre/modules/Services.jsm"); 1.10 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.11 +Cu.import("resource://gre/modules/Promise.jsm"); 1.12 +Cu.import("resource://gre/modules/Task.jsm"); 1.13 +Cu.import("resource://gre/modules/osfile.jsm"); 1.14 +Cu.import("resource://services-sync/healthreport.jsm", this); 1.15 +Cu.import("resource://testing-common/services/healthreport/utils.jsm", this); 1.16 +Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); 1.17 +Cu.import("resource://testing-common/AddonManagerTesting.jsm"); 1.18 + 1.19 +const PREF_EXPERIMENTS_ENABLED = "experiments.enabled"; 1.20 +const PREF_LOGGING_LEVEL = "experiments.logging.level"; 1.21 +const PREF_LOGGING_DUMP = "experiments.logging.dump"; 1.22 +const PREF_MANIFEST_URI = "experiments.manifest.uri"; 1.23 +const PREF_FETCHINTERVAL = "experiments.manifest.fetchIntervalSeconds"; 1.24 +const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled"; 1.25 +const PREF_HEALTHREPORT_ENABLED = "datareporting.healthreport.service.enabled"; 1.26 + 1.27 +function getExperimentPath(base) { 1.28 + let p = do_get_cwd(); 1.29 + p.append(base); 1.30 + return p.path; 1.31 +} 1.32 + 1.33 +function sha1File(path) { 1.34 + let f = Cc["@mozilla.org/file/local;1"] 1.35 + .createInstance(Ci.nsILocalFile); 1.36 + f.initWithPath(path); 1.37 + let hasher = Cc["@mozilla.org/security/hash;1"] 1.38 + .createInstance(Ci.nsICryptoHash); 1.39 + hasher.init(hasher.SHA1); 1.40 + 1.41 + let is = Cc["@mozilla.org/network/file-input-stream;1"] 1.42 + .createInstance(Ci.nsIFileInputStream); 1.43 + is.init(f, -1, 0, 0); 1.44 + hasher.updateFromStream(is, Math.pow(2, 32) - 1); 1.45 + is.close(); 1.46 + let bytes = hasher.finish(false); 1.47 + 1.48 + return [("0" + bytes.charCodeAt(byte).toString(16)).slice(-2) 1.49 + for (byte in bytes)] 1.50 + .join(""); 1.51 +} 1.52 + 1.53 +const EXPERIMENT1_ID = "test-experiment-1@tests.mozilla.org"; 1.54 +const EXPERIMENT1_XPI_NAME = "experiment-1.xpi"; 1.55 +const EXPERIMENT1_NAME = "Test experiment 1"; 1.56 +const EXPERIMENT1_PATH = getExperimentPath(EXPERIMENT1_XPI_NAME); 1.57 +const EXPERIMENT1_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT1_PATH); 1.58 + 1.59 + 1.60 +const EXPERIMENT1A_XPI_NAME = "experiment-1a.xpi"; 1.61 +const EXPERIMENT1A_NAME = "Test experiment 1.1"; 1.62 +const EXPERIMENT1A_PATH = getExperimentPath(EXPERIMENT1A_XPI_NAME); 1.63 +const EXPERIMENT1A_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT1A_PATH); 1.64 + 1.65 +const EXPERIMENT2_ID = "test-experiment-2@tests.mozilla.org" 1.66 +const EXPERIMENT2_XPI_NAME = "experiment-2.xpi"; 1.67 +const EXPERIMENT2_PATH = getExperimentPath(EXPERIMENT2_XPI_NAME); 1.68 +const EXPERIMENT2_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT2_PATH); 1.69 + 1.70 +const EXPERIMENT3_ID = "test-experiment-3@tests.mozilla.org"; 1.71 +const EXPERIMENT4_ID = "test-experiment-4@tests.mozilla.org"; 1.72 + 1.73 +const DEFAULT_BUILDID = "2014060601"; 1.74 + 1.75 +const FAKE_EXPERIMENTS_1 = [ 1.76 + { 1.77 + id: "id1", 1.78 + name: "experiment1", 1.79 + description: "experiment 1", 1.80 + active: true, 1.81 + detailUrl: "https://dummy/experiment1", 1.82 + branch: "foo", 1.83 + }, 1.84 +]; 1.85 + 1.86 +const FAKE_EXPERIMENTS_2 = [ 1.87 + { 1.88 + id: "id2", 1.89 + name: "experiment2", 1.90 + description: "experiment 2", 1.91 + active: false, 1.92 + endDate: new Date(2014, 2, 11, 2, 4, 35, 42).getTime(), 1.93 + detailUrl: "https://dummy/experiment2", 1.94 + branch: null, 1.95 + }, 1.96 + { 1.97 + id: "id1", 1.98 + name: "experiment1", 1.99 + description: "experiment 1", 1.100 + active: false, 1.101 + endDate: new Date(2014, 2, 10, 0, 0, 0, 0).getTime(), 1.102 + detailURL: "https://dummy/experiment1", 1.103 + branch: null, 1.104 + }, 1.105 +]; 1.106 + 1.107 +let gAppInfo = null; 1.108 + 1.109 +function getReporter(name, uri, inspected) { 1.110 + return Task.spawn(function init() { 1.111 + let reporter = getHealthReporter(name, uri, inspected); 1.112 + yield reporter.init(); 1.113 + 1.114 + yield reporter._providerManager.registerProviderFromType( 1.115 + HealthReportProvider); 1.116 + 1.117 + throw new Task.Result(reporter); 1.118 + }); 1.119 +} 1.120 + 1.121 +function removeCacheFile() { 1.122 + let path = OS.Path.join(OS.Constants.Path.profileDir, "experiments.json"); 1.123 + return OS.File.remove(path); 1.124 +} 1.125 + 1.126 +function disableCertificateChecks() { 1.127 + let pref = "experiments.manifest.cert.checkAttributes"; 1.128 + Services.prefs.setBoolPref(pref, false); 1.129 + do_register_cleanup(() => Services.prefs.clearUserPref(pref)); 1.130 +} 1.131 + 1.132 +function patchPolicy(policy, data) { 1.133 + for (let key of Object.keys(data)) { 1.134 + Object.defineProperty(policy, key, { 1.135 + value: data[key], 1.136 + writable: true, 1.137 + }); 1.138 + } 1.139 +} 1.140 + 1.141 +function defineNow(policy, time) { 1.142 + patchPolicy(policy, { now: () => new Date(time) }); 1.143 +} 1.144 + 1.145 +function futureDate(date, offset) { 1.146 + return new Date(date.getTime() + offset); 1.147 +} 1.148 + 1.149 +function dateToSeconds(date) { 1.150 + return date.getTime() / 1000; 1.151 +} 1.152 + 1.153 +let gGlobalScope = this; 1.154 +function loadAddonManager() { 1.155 + let ns = {}; 1.156 + Cu.import("resource://gre/modules/Services.jsm", ns); 1.157 + let head = "../../../../toolkit/mozapps/extensions/test/xpcshell/head_addons.js"; 1.158 + let file = do_get_file(head); 1.159 + let uri = ns.Services.io.newFileURI(file); 1.160 + ns.Services.scriptloader.loadSubScript(uri.spec, gGlobalScope); 1.161 + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); 1.162 + startupManager(); 1.163 +} 1.164 + 1.165 +function getExperimentAddons(previous=false) { 1.166 + let deferred = Promise.defer(); 1.167 + 1.168 + AddonManager.getAddonsByTypes(["experiment"], (addons) => { 1.169 + if (previous) { 1.170 + deferred.resolve(addons); 1.171 + } else { 1.172 + deferred.resolve([a for (a of addons) if (!a.appDisabled)]); 1.173 + } 1.174 + }); 1.175 + 1.176 + return deferred.promise; 1.177 +} 1.178 + 1.179 +function createAppInfo(optionsIn) { 1.180 + const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1"; 1.181 + const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}"); 1.182 + 1.183 + let options = optionsIn || {}; 1.184 + let id = options.id || "xpcshell@tests.mozilla.org"; 1.185 + let name = options.name || "XPCShell"; 1.186 + let version = options.version || "1.0"; 1.187 + let platformVersion = options.platformVersion || "1.0"; 1.188 + let date = options.date || new Date(); 1.189 + 1.190 + let buildID = options.buildID || DEFAULT_BUILDID; 1.191 + 1.192 + gAppInfo = { 1.193 + // nsIXULAppInfo 1.194 + vendor: "Mozilla", 1.195 + name: name, 1.196 + ID: id, 1.197 + version: version, 1.198 + appBuildID: buildID, 1.199 + platformVersion: platformVersion ? platformVersion : "1.0", 1.200 + platformBuildID: buildID, 1.201 + 1.202 + // nsIXULRuntime 1.203 + inSafeMode: false, 1.204 + logConsoleErrors: true, 1.205 + OS: "XPCShell", 1.206 + XPCOMABI: "noarch-spidermonkey", 1.207 + invalidateCachesOnRestart: function invalidateCachesOnRestart() { 1.208 + // Do nothing 1.209 + }, 1.210 + 1.211 + // nsICrashReporter 1.212 + annotations: {}, 1.213 + 1.214 + annotateCrashReport: function(key, data) { 1.215 + this.annotations[key] = data; 1.216 + }, 1.217 + 1.218 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, 1.219 + Ci.nsIXULRuntime, 1.220 + Ci.nsICrashReporter, 1.221 + Ci.nsISupports]) 1.222 + }; 1.223 + 1.224 + let XULAppInfoFactory = { 1.225 + createInstance: function (outer, iid) { 1.226 + if (outer != null) { 1.227 + throw Cr.NS_ERROR_NO_AGGREGATION; 1.228 + } 1.229 + return gAppInfo.QueryInterface(iid); 1.230 + } 1.231 + }; 1.232 + 1.233 + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); 1.234 + registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo", 1.235 + XULAPPINFO_CONTRACTID, XULAppInfoFactory); 1.236 +} 1.237 + 1.238 +/** 1.239 + * Replace the experiments on an Experiments with a new list. 1.240 + * 1.241 + * This monkeypatches getExperiments(). It doesn't monkeypatch the internal 1.242 + * experiments list. So its utility is not as great as it could be. 1.243 + */ 1.244 +function replaceExperiments(experiment, list) { 1.245 + Object.defineProperty(experiment, "getExperiments", { 1.246 + writable: true, 1.247 + value: () => { 1.248 + return Promise.resolve(list); 1.249 + }, 1.250 + }); 1.251 +}