browser/experiments/test/xpcshell/test_telemetry.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.

     1 /* Any copyright is dedicated to the Public Domain.
     2  * http://creativecommons.org/publicdomain/zero/1.0/ */
     4 "use strict";
     6 Cu.import("resource://testing-common/httpd.js");
     7 Cu.import("resource://gre/modules/TelemetryLog.jsm");
     8 let bsp = Cu.import("resource:///modules/experiments/Experiments.jsm");
    11 const FILE_MANIFEST            = "experiments.manifest";
    12 const MANIFEST_HANDLER         = "manifests/handler";
    14 const SEC_IN_ONE_DAY  = 24 * 60 * 60;
    15 const MS_IN_ONE_DAY   = SEC_IN_ONE_DAY * 1000;
    18 let gProfileDir          = null;
    19 let gHttpServer          = null;
    20 let gHttpRoot            = null;
    21 let gDataRoot            = null;
    22 let gReporter            = null;
    23 let gPolicy              = null;
    24 let gManifestObject      = null;
    25 let gManifestHandlerURI  = null;
    27 const TLOG = bsp.TELEMETRY_LOG;
    29 let gGlobalScope = this;
    30 function loadAddonManager() {
    31   let ns = {};
    32   Cu.import("resource://gre/modules/Services.jsm", ns);
    33   let head = "../../../../toolkit/mozapps/extensions/test/xpcshell/head_addons.js";
    34   let file = do_get_file(head);
    35   let uri = ns.Services.io.newFileURI(file);
    36   ns.Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
    37   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
    38   startupManager();
    39 }
    41 function checkEvent(event, id, data)
    42 {
    43   do_print("Checking message " + id);
    44   Assert.equal(event[0], id, "id should match");
    45   Assert.ok(event[1] > 0, "timestamp should be greater than 0");
    47   if (data === undefined) {
    48    Assert.equal(event.length, 2, "event array should have 2 entries");
    49   } else {
    50     Assert.equal(event.length, data.length + 2, "event entry count should match expected count");
    51     for (var i = 0; i < data.length; ++i) {
    52       Assert.equal(typeof(event[i + 2]), "string", "event entry should be a string");
    53       Assert.equal(event[i + 2], data[i], "event entry should match expected entry");
    54     }
    55   }
    56 }
    58 function run_test() {
    59   run_next_test();
    60 }
    62 add_task(function* test_setup() {
    63   loadAddonManager();
    64   gProfileDir = do_get_profile();
    66   gHttpServer = new HttpServer();
    67   gHttpServer.start(-1);
    68   let port = gHttpServer.identity.primaryPort;
    69   gHttpRoot = "http://localhost:" + port + "/";
    70   gDataRoot = gHttpRoot + "data/";
    71   gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER;
    72   gHttpServer.registerDirectory("/data/", do_get_cwd());
    73   gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => {
    74     response.setStatusLine(null, 200, "OK");
    75     response.write(JSON.stringify(gManifestObject));
    76     response.processAsync();
    77     response.finish();
    78   });
    79   do_register_cleanup(() => gHttpServer.stop(() => {}));
    81   disableCertificateChecks();
    83   Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true);
    84   Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0);
    85   Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true);
    86   Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI);
    87   Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0);
    89   gReporter = yield getReporter("json_payload_simple");
    90   yield gReporter.collectMeasurements();
    91   let payload = yield gReporter.getJSONPayload(true);
    92   do_register_cleanup(() => gReporter._shutdown());
    94   gPolicy = new Experiments.Policy();
    95   let dummyTimer = { cancel: () => {}, clear: () => {} };
    96   patchPolicy(gPolicy, {
    97     updatechannel: () => "nightly",
    98     healthReportPayload: () => Promise.resolve(payload),
    99     oneshotTimer: (callback, timeout, thisObj, name) => dummyTimer,
   100   });
   102   yield removeCacheFile();
   103 });
   105 // Test basic starting and stopping of experiments.
   107 add_task(function* test_telemetryBasics() {
   108   // Check TelemetryLog instead of TelemetryPing.getPayload().log because
   109   // TelemetryPing gets Experiments.instance() and side-effects log entries.
   111   const OBSERVER_TOPIC = "experiments-changed";
   112   let observerFireCount = 0;
   113   let expectedLogLength = 0;
   115   // Dates the following tests are based on.
   117   let baseDate   = new Date(2014, 5, 1, 12);
   118   let startDate1 = futureDate(baseDate,  50 * MS_IN_ONE_DAY);
   119   let endDate1   = futureDate(baseDate, 100 * MS_IN_ONE_DAY);
   120   let startDate2 = futureDate(baseDate, 150 * MS_IN_ONE_DAY);
   121   let endDate2   = futureDate(baseDate, 200 * MS_IN_ONE_DAY);
   123   // The manifest data we test with.
   125   gManifestObject = {
   126     "version": 1,
   127     experiments: [
   128       {
   129         id:               EXPERIMENT1_ID,
   130         xpiURL:           gDataRoot + EXPERIMENT1_XPI_NAME,
   131         xpiHash:          EXPERIMENT1_XPI_SHA1,
   132         startTime:        dateToSeconds(startDate1),
   133         endTime:          dateToSeconds(endDate1),
   134         maxActiveSeconds: 10 * SEC_IN_ONE_DAY,
   135         appName:          ["XPCShell"],
   136         channel:          ["nightly"],
   137       },
   138       {
   139         id:               EXPERIMENT2_ID,
   140         xpiURL:           gDataRoot + EXPERIMENT2_XPI_NAME,
   141         xpiHash:          EXPERIMENT2_XPI_SHA1,
   142         startTime:        dateToSeconds(startDate2),
   143         endTime:          dateToSeconds(endDate2),
   144         maxActiveSeconds: 10 * SEC_IN_ONE_DAY,
   145         appName:          ["XPCShell"],
   146         channel:          ["nightly"],
   147       },
   148     ],
   149   };
   151   // Data to compare the result of Experiments.getExperiments() against.
   153   let experimentListData = [
   154     {
   155       id: EXPERIMENT2_ID,
   156       name: "Test experiment 2",
   157       description: "And yet another experiment that experiments experimentally.",
   158     },
   159     {
   160       id: EXPERIMENT1_ID,
   161       name: EXPERIMENT1_NAME,
   162       description: "Yet another experiment that experiments experimentally.",
   163     },
   164   ];
   166   let experiments = new Experiments.Experiments(gPolicy);
   168   // Trigger update, clock set to before any activation.
   169   // Use updateManifest() to provide for coverage of that path.
   171   let now = baseDate;
   172   defineNow(gPolicy, now);
   174   yield experiments.updateManifest();
   175   let list = yield experiments.getExperiments();
   176   Assert.equal(list.length, 0, "Experiment list should be empty.");
   178   expectedLogLength += 2;
   179   let log = TelemetryLog.entries();
   180   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   181   checkEvent(log[log.length-2], TLOG.ACTIVATION_KEY,
   182              [TLOG.ACTIVATION.REJECTED, EXPERIMENT1_ID, "startTime"]);
   183   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   184              [TLOG.ACTIVATION.REJECTED, EXPERIMENT2_ID, "startTime"]);
   186   // Trigger update, clock set for experiment 1 to start.
   188   now = futureDate(startDate1, 5 * MS_IN_ONE_DAY);
   189   defineNow(gPolicy, now);
   191   yield experiments.updateManifest();
   192   list = yield experiments.getExperiments();
   193   Assert.equal(list.length, 1, "Experiment list should have 1 entry now.");
   195   expectedLogLength += 1;
   196   log = TelemetryLog.entries();
   197   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries. Got " + log.toSource());
   198   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   199              [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT1_ID]);
   201   // Trigger update, clock set for experiment 1 to stop.
   203   now = futureDate(endDate1, 1000);
   204   defineNow(gPolicy, now);
   206   yield experiments.updateManifest();
   207   list = yield experiments.getExperiments();
   208   Assert.equal(list.length, 1, "Experiment list should have 1 entry.");
   210   expectedLogLength += 2;
   211   log = TelemetryLog.entries();
   212   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   213   checkEvent(log[log.length-2], TLOG.TERMINATION_KEY,
   214              [TLOG.TERMINATION.EXPIRED, EXPERIMENT1_ID]);
   215   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   216              [TLOG.ACTIVATION.REJECTED, EXPERIMENT2_ID, "startTime"]);
   218   // Trigger update, clock set for experiment 2 to start with invalid hash.
   220   now = startDate2;
   221   defineNow(gPolicy, now);
   222   gManifestObject.experiments[1].xpiHash = "sha1:0000000000000000000000000000000000000000";
   224   yield experiments.updateManifest();
   225   list = yield experiments.getExperiments();
   226   Assert.equal(list.length, 1, "Experiment list should have 1 entries.");
   228   expectedLogLength += 1;
   229   log = TelemetryLog.entries();
   230   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   231   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   232              [TLOG.ACTIVATION.INSTALL_FAILURE, EXPERIMENT2_ID]);
   234   // Trigger update, clock set for experiment 2 to properly start now.
   236   now = futureDate(now, MS_IN_ONE_DAY);
   237   defineNow(gPolicy, now);
   238   gManifestObject.experiments[1].xpiHash = EXPERIMENT2_XPI_SHA1;
   240   yield experiments.updateManifest();
   241   list = yield experiments.getExperiments();
   242   Assert.equal(list.length, 2, "Experiment list should have 2 entries.");
   244   expectedLogLength += 1;
   245   log = TelemetryLog.entries();
   246   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   247   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   248              [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT2_ID]);
   250   // Fake user uninstall of experiment via add-on manager.
   252   now = futureDate(now, MS_IN_ONE_DAY);
   253   defineNow(gPolicy, now);
   255   yield experiments.disableExperiment(TLOG.TERMINATION.ADDON_UNINSTALLED);
   256   list = yield experiments.getExperiments();
   257   Assert.equal(list.length, 2, "Experiment list should have 2 entries.");
   259   expectedLogLength += 1;
   260   log = TelemetryLog.entries();
   261   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   262   checkEvent(log[log.length-1], TLOG.TERMINATION_KEY,
   263              [TLOG.TERMINATION.ADDON_UNINSTALLED, EXPERIMENT2_ID]);
   265   // Trigger update with experiment 1a ready to start.
   267   now = futureDate(now, MS_IN_ONE_DAY);
   268   defineNow(gPolicy, now);
   269   gManifestObject.experiments[0].id      = EXPERIMENT3_ID;
   270   gManifestObject.experiments[0].endTime = dateToSeconds(futureDate(now, 50 * MS_IN_ONE_DAY));
   272   yield experiments.updateManifest();
   273   list = yield experiments.getExperiments();
   274   Assert.equal(list.length, 3, "Experiment list should have 3 entries.");
   276   expectedLogLength += 1;
   277   log = TelemetryLog.entries();
   278   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   279   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   280              [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT3_ID]);
   282   // Trigger disable of an experiment via the API.
   284   now = futureDate(now, MS_IN_ONE_DAY);
   285   defineNow(gPolicy, now);
   287   yield experiments.disableExperiment(TLOG.TERMINATION.FROM_API);
   288   list = yield experiments.getExperiments();
   289   Assert.equal(list.length, 3, "Experiment list should have 3 entries.");
   291   expectedLogLength += 1;
   292   log = TelemetryLog.entries();
   293   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   294   checkEvent(log[log.length-1], TLOG.TERMINATION_KEY,
   295              [TLOG.TERMINATION.FROM_API, EXPERIMENT3_ID]);
   297   // Trigger update with experiment 1a ready to start.
   299   now = futureDate(now, MS_IN_ONE_DAY);
   300   defineNow(gPolicy, now);
   301   gManifestObject.experiments[0].id      = EXPERIMENT4_ID;
   302   gManifestObject.experiments[0].endTime = dateToSeconds(futureDate(now, 50 * MS_IN_ONE_DAY));
   304   yield experiments.updateManifest();
   305   list = yield experiments.getExperiments();
   306   Assert.equal(list.length, 4, "Experiment list should have 4 entries.");
   308   expectedLogLength += 1;
   309   log = TelemetryLog.entries();
   310   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   311   checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY,
   312              [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT4_ID]);
   314   // Trigger experiment termination by something other than expiry via the manifest.
   316   now = futureDate(now, MS_IN_ONE_DAY);
   317   defineNow(gPolicy, now);
   318   gManifestObject.experiments[0].os = "Plan9";
   320   yield experiments.updateManifest();
   321   list = yield experiments.getExperiments();
   322   Assert.equal(list.length, 4, "Experiment list should have 4 entries.");
   324   expectedLogLength += 1;
   325   log = TelemetryLog.entries();
   326   Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries.");
   327   checkEvent(log[log.length-1], TLOG.TERMINATION_KEY,
   328              [TLOG.TERMINATION.RECHECK, EXPERIMENT4_ID, "os"]);
   330   // Cleanup.
   332   yield experiments.uninit();
   333   yield removeCacheFile();
   334 });

mercurial