browser/experiments/test/xpcshell/test_conditions.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 "use strict";
michael@0 5
michael@0 6
michael@0 7 Cu.import("resource:///modules/experiments/Experiments.jsm");
michael@0 8
michael@0 9 const FILE_MANIFEST = "experiments.manifest";
michael@0 10 const SEC_IN_ONE_DAY = 24 * 60 * 60;
michael@0 11 const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000;
michael@0 12
michael@0 13 let gProfileDir = null;
michael@0 14 let gHttpServer = null;
michael@0 15 let gHttpRoot = null;
michael@0 16 let gReporter = null;
michael@0 17 let gPolicy = null;
michael@0 18
michael@0 19
michael@0 20 function ManifestEntry(data) {
michael@0 21 this.id = EXPERIMENT1_ID;
michael@0 22 this.xpiURL = "http://localhost:1/dummy.xpi";
michael@0 23 this.xpiHash = EXPERIMENT1_XPI_SHA1;
michael@0 24 this.startTime = new Date(2010, 0, 1, 12).getTime() / 1000;
michael@0 25 this.endTime = new Date(9001, 0, 1, 12).getTime() / 1000;
michael@0 26 this.maxActiveSeconds = SEC_IN_ONE_DAY;
michael@0 27 this.appName = ["XPCShell"];
michael@0 28 this.channel = ["nightly"];
michael@0 29
michael@0 30 data = data || {};
michael@0 31 for (let k of Object.keys(data)) {
michael@0 32 this[k] = data[k];
michael@0 33 }
michael@0 34
michael@0 35 if (!this.endTime) {
michael@0 36 this.endTime = this.startTime + 5 * SEC_IN_ONE_DAY;
michael@0 37 }
michael@0 38 }
michael@0 39
michael@0 40 function applicableFromManifestData(data, policy) {
michael@0 41 let manifestData = new ManifestEntry(data);
michael@0 42 let entry = new Experiments.ExperimentEntry(policy);
michael@0 43 entry.initFromManifestData(manifestData);
michael@0 44 return entry.isApplicable();
michael@0 45 }
michael@0 46
michael@0 47 function run_test() {
michael@0 48 run_next_test();
michael@0 49 }
michael@0 50
michael@0 51 add_task(function* test_setup() {
michael@0 52 createAppInfo();
michael@0 53 gProfileDir = do_get_profile();
michael@0 54 gPolicy = new Experiments.Policy();
michael@0 55
michael@0 56 gReporter = yield getReporter("json_payload_simple");
michael@0 57 yield gReporter.collectMeasurements();
michael@0 58 let payload = yield gReporter.getJSONPayload(true);
michael@0 59 do_register_cleanup(() => gReporter._shutdown());
michael@0 60
michael@0 61 patchPolicy(gPolicy, {
michael@0 62 updatechannel: () => "nightly",
michael@0 63 locale: () => "en-US",
michael@0 64 healthReportPayload: () => Promise.resolve(payload),
michael@0 65 random: () => 0.5,
michael@0 66 });
michael@0 67
michael@0 68 Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true);
michael@0 69 Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0);
michael@0 70 Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true);
michael@0 71
michael@0 72 let experiments = new Experiments.Experiments();
michael@0 73 });
michael@0 74
michael@0 75 function arraysEqual(a, b) {
michael@0 76 if (a.length !== b.length) {
michael@0 77 return false;
michael@0 78 }
michael@0 79
michael@0 80 for (let i=0; i<a.length; ++i) {
michael@0 81 if (a[i] !== b[i]) {
michael@0 82 return false;
michael@0 83 }
michael@0 84 }
michael@0 85
michael@0 86 return true;
michael@0 87 }
michael@0 88
michael@0 89 // This function exists solely to be .toSource()d
michael@0 90 const sanityFilter = function filter(c) {
michael@0 91 if (c.telemetryPayload === undefined) {
michael@0 92 throw Error("No .telemetryPayload");
michael@0 93 }
michael@0 94 if (c.telemetryPayload.simpleMeasurements === undefined) {
michael@0 95 throw Error("No .simpleMeasurements");
michael@0 96 }
michael@0 97 if (c.healthReportPayload === undefined) {
michael@0 98 throw Error("No .healthReportPayload");
michael@0 99 }
michael@0 100 if (c.healthReportPayload.geckoAppInfo == undefined) {
michael@0 101 throw Error("No .geckoAppInfo");
michael@0 102 }
michael@0 103 return true;
michael@0 104 }
michael@0 105
michael@0 106 add_task(function* test_simpleFields() {
michael@0 107 let testData = [
michael@0 108 // "expected applicable?", failure reason or null, manifest data
michael@0 109
michael@0 110 // misc. environment
michael@0 111
michael@0 112 [false, ["appName"], {appName: []}],
michael@0 113 [false, ["appName"], {appName: ["foo", gAppInfo.name + "-invalid"]}],
michael@0 114 [true, null, {appName: ["not-an-app-name", gAppInfo.name]}],
michael@0 115
michael@0 116 [false, ["os"], {os: []}],
michael@0 117 [false, ["os"], {os: ["42", "abcdef"]}],
michael@0 118 [true, null, {os: [gAppInfo.OS, "plan9"]}],
michael@0 119
michael@0 120 [false, ["channel"], {channel: []}],
michael@0 121 [false, ["channel"], {channel: ["foo", gPolicy.updatechannel() + "-invalid"]}],
michael@0 122 [true, null, {channel: ["not-a-channel", gPolicy.updatechannel()]}],
michael@0 123
michael@0 124 [false, ["locale"], {locale: []}],
michael@0 125 [false, ["locale"], {locale: ["foo", gPolicy.locale + "-invalid"]}],
michael@0 126 [true, null, {locale: ["not-a-locale", gPolicy.locale()]}],
michael@0 127
michael@0 128 // version
michael@0 129
michael@0 130 [false, ["version"], {version: []}],
michael@0 131 [false, ["version"], {version: ["-1", gAppInfo.version + "-invalid", "asdf", "0,4", "99.99", "0.1.1.1"]}],
michael@0 132 [true, null, {version: ["99999999.999", "-1", gAppInfo.version]}],
michael@0 133
michael@0 134 [false, ["minVersion"], {minVersion: "1.0.1"}],
michael@0 135 [true, null, {minVersion: "1.0b1"}],
michael@0 136 [true, null, {minVersion: "1.0"}],
michael@0 137 [true, null, {minVersion: "0.9"}],
michael@0 138
michael@0 139 [false, ["maxVersion"], {maxVersion: "0.1"}],
michael@0 140 [false, ["maxVersion"], {maxVersion: "0.9.9"}],
michael@0 141 [false, ["maxVersion"], {maxVersion: "1.0b1"}],
michael@0 142 [true, ["maxVersion"], {maxVersion: "1.0"}],
michael@0 143 [true, ["maxVersion"], {maxVersion: "1.7pre"}],
michael@0 144
michael@0 145 // build id
michael@0 146
michael@0 147 [false, ["buildIDs"], {buildIDs: []}],
michael@0 148 [false, ["buildIDs"], {buildIDs: ["not-a-build-id", gAppInfo.platformBuildID + "-invalid"]}],
michael@0 149 [true, null, {buildIDs: ["not-a-build-id", gAppInfo.platformBuildID]}],
michael@0 150
michael@0 151 [true, null, {minBuildID: "2014060501"}],
michael@0 152 [true, null, {minBuildID: "2014060601"}],
michael@0 153 [false, ["minBuildID"], {minBuildID: "2014060701"}],
michael@0 154
michael@0 155 [false, ["maxBuildID"], {maxBuildID: "2014010101"}],
michael@0 156 [true, null, {maxBuildID: "2014060601"}],
michael@0 157 [true, null, {maxBuildID: "2014060901"}],
michael@0 158
michael@0 159 // sample
michael@0 160
michael@0 161 [false, ["sample"], {sample: -1 }],
michael@0 162 [false, ["sample"], {sample: 0.0}],
michael@0 163 [false, ["sample"], {sample: 0.1}],
michael@0 164 [true, null, {sample: 0.5}],
michael@0 165 [true, null, {sample: 0.6}],
michael@0 166 [true, null, {sample: 1.0}],
michael@0 167 [true, null, {sample: 0.5}],
michael@0 168
michael@0 169 // experiment control
michael@0 170
michael@0 171 [false, ["disabled"], {disabled: true}],
michael@0 172 [true, null, {disabled: false}],
michael@0 173
michael@0 174 [false, ["frozen"], {frozen: true}],
michael@0 175 [true, null, {frozen: false}],
michael@0 176
michael@0 177 [false, null, {frozen: true, disabled: true}],
michael@0 178 [false, null, {frozen: true, disabled: false}],
michael@0 179 [false, null, {frozen: false, disabled: true}],
michael@0 180 [true, null, {frozen: false, disabled: false}],
michael@0 181
michael@0 182 // jsfilter
michael@0 183
michael@0 184 [true, null, {jsfilter: "function filter(c) { return true; }"}],
michael@0 185 [false, ["jsfilter-false"], {jsfilter: "function filter(c) { return false; }"}],
michael@0 186 [true, null, {jsfilter: "function filter(c) { return 123; }"}], // truthy
michael@0 187 [false, ["jsfilter-false"], {jsfilter: "function filter(c) { return ''; }"}], // falsy
michael@0 188 [false, ["jsfilter-false"], {jsfilter: "function filter(c) { var a = []; }"}], // undefined
michael@0 189 [false, ["jsfilter-threw", "some error"], {jsfilter: "function filter(c) { throw new Error('some error'); }"}],
michael@0 190 [false, ["jsfilter-evalfailed"], {jsfilter: "123, this won't work"}],
michael@0 191 [true, null, {jsfilter: "var filter = " + sanityFilter.toSource()}],
michael@0 192 ];
michael@0 193
michael@0 194 for (let i=0; i<testData.length; ++i) {
michael@0 195 let entry = testData[i];
michael@0 196 let applicable;
michael@0 197 let reason = null;
michael@0 198
michael@0 199 yield applicableFromManifestData(entry[2], gPolicy).then(
michael@0 200 value => applicable = value,
michael@0 201 value => {
michael@0 202 applicable = false;
michael@0 203 reason = value;
michael@0 204 }
michael@0 205 );
michael@0 206
michael@0 207 Assert.equal(applicable, entry[0],
michael@0 208 "Experiment entry applicability should match for test "
michael@0 209 + i + ": " + JSON.stringify(entry[2]));
michael@0 210
michael@0 211 let expectedReason = entry[1];
michael@0 212 if (!applicable && expectedReason) {
michael@0 213 Assert.ok(arraysEqual(reason, expectedReason),
michael@0 214 "Experiment rejection reasons should match for test " + i + ". "
michael@0 215 + "Got " + JSON.stringify(reason) + ", expected "
michael@0 216 + JSON.stringify(expectedReason));
michael@0 217 }
michael@0 218 }
michael@0 219 });
michael@0 220
michael@0 221 add_task(function* test_times() {
michael@0 222 let now = new Date(2014, 5, 6, 12);
michael@0 223 let nowSec = now.getTime() / 1000;
michael@0 224 let testData = [
michael@0 225 // "expected applicable?", rejection reason or null, fake now date, manifest data
michael@0 226
michael@0 227 // start time
michael@0 228
michael@0 229 [true, null, now,
michael@0 230 {startTime: nowSec - 5 * SEC_IN_ONE_DAY,
michael@0 231 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 232 [true, null, now,
michael@0 233 {startTime: nowSec ,
michael@0 234 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 235 [false, "startTime", now,
michael@0 236 {startTime: nowSec + 5 * SEC_IN_ONE_DAY,
michael@0 237 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 238
michael@0 239 // end time
michael@0 240
michael@0 241 [false, "endTime", now,
michael@0 242 {startTime: nowSec - 5 * SEC_IN_ONE_DAY,
michael@0 243 endTime: nowSec - 10 * SEC_IN_ONE_DAY}],
michael@0 244 [false, "endTime", now,
michael@0 245 {startTime: nowSec - 5 * SEC_IN_ONE_DAY,
michael@0 246 endTime: nowSec - 5 * SEC_IN_ONE_DAY}],
michael@0 247
michael@0 248 // max start time
michael@0 249
michael@0 250 [false, "maxStartTime", now,
michael@0 251 {maxStartTime: nowSec - 15 * SEC_IN_ONE_DAY,
michael@0 252 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 253 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 254 [false, "maxStartTime", now,
michael@0 255 {maxStartTime: nowSec - 1 * SEC_IN_ONE_DAY,
michael@0 256 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 257 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 258 [false, "maxStartTime", now,
michael@0 259 {maxStartTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 260 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 261 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 262 [true, null, now,
michael@0 263 {maxStartTime: nowSec,
michael@0 264 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 265 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 266 [true, null, now,
michael@0 267 {maxStartTime: nowSec + 1 * SEC_IN_ONE_DAY,
michael@0 268 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 269 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 270
michael@0 271 // max active seconds
michael@0 272
michael@0 273 [true, null, now,
michael@0 274 {maxActiveSeconds: 5 * SEC_IN_ONE_DAY,
michael@0 275 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 276 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 277 [true, null, now,
michael@0 278 {maxActiveSeconds: 10 * SEC_IN_ONE_DAY,
michael@0 279 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 280 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 281 [true, null, now,
michael@0 282 {maxActiveSeconds: 15 * SEC_IN_ONE_DAY,
michael@0 283 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 284 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 285 [true, null, now,
michael@0 286 {maxActiveSeconds: 20 * SEC_IN_ONE_DAY,
michael@0 287 startTime: nowSec - 10 * SEC_IN_ONE_DAY,
michael@0 288 endTime: nowSec + 10 * SEC_IN_ONE_DAY}],
michael@0 289 ];
michael@0 290
michael@0 291 for (let i=0; i<testData.length; ++i) {
michael@0 292 let entry = testData[i];
michael@0 293 let applicable;
michael@0 294 let reason = null;
michael@0 295 defineNow(gPolicy, entry[2]);
michael@0 296
michael@0 297 yield applicableFromManifestData(entry[3], gPolicy).then(
michael@0 298 value => applicable = value,
michael@0 299 value => {
michael@0 300 applicable = false;
michael@0 301 reason = value;
michael@0 302 }
michael@0 303 );
michael@0 304
michael@0 305 Assert.equal(applicable, entry[0],
michael@0 306 "Experiment entry applicability should match for test "
michael@0 307 + i + ": " + JSON.stringify([entry[2], entry[3]]));
michael@0 308 if (!applicable && entry[1]) {
michael@0 309 Assert.equal(reason, entry[1], "Experiment rejection reason should match for test " + i);
michael@0 310 }
michael@0 311 }
michael@0 312 });

mercurial