michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: Cu.import("resource://gre/modules/Metrics.jsm"); michael@0: Cu.import("resource://gre/modules/Task.jsm"); michael@0: Cu.import("resource:///modules/experiments/Experiments.jsm"); michael@0: Cu.import("resource://testing-common/services/healthreport/utils.jsm"); michael@0: Cu.import("resource://testing-common/services-common/logging.js"); michael@0: michael@0: const kMeasurementVersion = 2; michael@0: michael@0: function getStorageAndProvider(name) { michael@0: return Task.spawn(function* get() { michael@0: let storage = yield Metrics.Storage(name); michael@0: let provider = new ExperimentsProvider(); michael@0: yield provider.init(storage); michael@0: michael@0: return [storage, provider]; michael@0: }); michael@0: } michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: } michael@0: michael@0: add_test(function setup() { michael@0: do_get_profile(); michael@0: initTestLogging(); michael@0: michael@0: Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); michael@0: Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, true); michael@0: Services.prefs.setBoolPref(PREF_HEALTHREPORT_ENABLED, true); michael@0: michael@0: run_next_test(); michael@0: }); michael@0: michael@0: add_task(function test_constructor() { michael@0: Experiments.instance(); michael@0: yield Experiments._mainTask; michael@0: let provider = new ExperimentsProvider(); michael@0: }); michael@0: michael@0: add_task(function* test_init() { michael@0: let storage = yield Metrics.Storage("init"); michael@0: let provider = new ExperimentsProvider(); michael@0: yield provider.init(storage); michael@0: yield provider.shutdown(); michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function* test_collect() { michael@0: let [storage, provider] = yield getStorageAndProvider("no_active"); michael@0: michael@0: // Initial state should not report anything. michael@0: yield provider.collectDailyData(); michael@0: let m = provider.getMeasurement("info", kMeasurementVersion); michael@0: let values = yield m.getValues(); michael@0: Assert.equal(values.days.size, 0, "Have no data if no experiments known."); michael@0: michael@0: // An old experiment that ended today should be reported. michael@0: replaceExperiments(provider._experiments, FAKE_EXPERIMENTS_2); michael@0: let now = new Date(FAKE_EXPERIMENTS_2[0].endDate); michael@0: defineNow(provider._experiments._policy, now.getTime()); michael@0: michael@0: yield provider.collectDailyData(); michael@0: values = yield m.getValues(); michael@0: Assert.equal(values.days.size, 1, "Have 1 day of data"); michael@0: Assert.ok(values.days.hasDay(now), "Has day the experiment ended."); michael@0: let day = values.days.getDay(now); michael@0: Assert.ok(day.has("lastActive"), "Has lastActive field."); michael@0: Assert.equal(day.get("lastActive"), "id2", "Last active ID is sane."); michael@0: Assert.strictEqual(day.get("lastActiveBranch"), undefined, michael@0: "no branch should be set yet"); michael@0: michael@0: // Making an experiment active replaces the lastActive value. michael@0: replaceExperiments(provider._experiments, FAKE_EXPERIMENTS_1); michael@0: yield provider.collectDailyData(); michael@0: values = yield m.getValues(); michael@0: day = values.days.getDay(now); michael@0: Assert.equal(day.get("lastActive"), "id1", "Last active ID is the active experiment."); michael@0: Assert.equal(day.get("lastActiveBranch"), "foo", michael@0: "Experiment branch should be visible"); michael@0: michael@0: // And make sure the observer works. michael@0: replaceExperiments(provider._experiments, FAKE_EXPERIMENTS_2); michael@0: Services.obs.notifyObservers(null, "experiments-changed", null); michael@0: // This may not wait long enough. It relies on the SQL insert happening michael@0: // in the same tick as the observer notification. michael@0: yield storage.enqueueOperation(function () { michael@0: return Promise.resolve(); michael@0: }); michael@0: michael@0: values = yield m.getValues(); michael@0: day = values.days.getDay(now); michael@0: Assert.equal(day.get("lastActive"), "id2", "Last active ID set by observer."); michael@0: michael@0: yield provider.shutdown(); michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function* test_healthreporterJSON() { michael@0: let reporter = yield getHealthReporter("healthreporterJSON"); michael@0: yield reporter.init(); michael@0: try { michael@0: yield reporter._providerManager.registerProvider(new ExperimentsProvider()); michael@0: let experiments = Experiments.instance(); michael@0: defineNow(experiments._policy, Date.now()); michael@0: replaceExperiments(experiments, FAKE_EXPERIMENTS_1); michael@0: yield reporter.collectMeasurements(); michael@0: michael@0: let payload = yield reporter.getJSONPayload(true); michael@0: let today = reporter._formatDate(reporter._policy.now()); michael@0: michael@0: Assert.ok(today in payload.data.days, "Day in payload."); michael@0: let day = payload.data.days[today]; michael@0: michael@0: Assert.ok("org.mozilla.experiments.info" in day, "Measurement present."); michael@0: let m = day["org.mozilla.experiments.info"]; michael@0: Assert.ok("lastActive" in m, "lastActive field present."); michael@0: Assert.equal(m["lastActive"], "id1", "Last active ID proper."); michael@0: } finally { michael@0: reporter._shutdown(); michael@0: } michael@0: });