mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1234526 - Remove services/healthreport. r=gfritzsche
This commit is contained in:
parent
aa10ab3291
commit
d3777d94c4
@ -631,10 +631,6 @@
|
||||
#endif
|
||||
@RESPATH@/components/servicesComponents.manifest
|
||||
@RESPATH@/components/cryptoComponents.manifest
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@RESPATH@/components/HealthReportComponents.manifest
|
||||
@RESPATH@/components/HealthReportService.js
|
||||
#endif
|
||||
@RESPATH@/components/CaptivePortalDetectComponents.manifest
|
||||
@RESPATH@/components/captivedetect.js
|
||||
@RESPATH@/components/TelemetryStartup.js
|
||||
|
@ -502,7 +502,6 @@
|
||||
@RESPATH@/components/nsPrompter.manifest
|
||||
@RESPATH@/components/nsPrompter.js
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@RESPATH@/components/HealthReportComponents.manifest
|
||||
@RESPATH@/browser/components/SelfSupportService.manifest
|
||||
@RESPATH@/browser/components/SelfSupportService.js
|
||||
#endif
|
||||
|
@ -432,11 +432,6 @@
|
||||
@BINPATH@/components/PeerConnection.manifest
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/components/HealthReportComponents.manifest
|
||||
@BINPATH@/components/HealthReportService.js
|
||||
#endif
|
||||
|
||||
@BINPATH@/components/CaptivePortalDetectComponents.manifest
|
||||
@BINPATH@/components/captivedetect.js
|
||||
|
||||
|
@ -7,6 +7,6 @@
|
||||
#if MOZ_WIDGET_TOOLKIT == android
|
||||
#include ../../mobile/android/chrome/content/healthreport-prefs.js
|
||||
#else
|
||||
#include ../../services/healthreport/healthreport-prefs.js
|
||||
#include ../../toolkit/components/telemetry/healthreport-prefs.js
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"HealthReporter",
|
||||
"AddonsProvider",
|
||||
"AppInfoProvider",
|
||||
"CrashesProvider",
|
||||
"HealthReportProvider",
|
||||
"HotfixProvider",
|
||||
"Metrics",
|
||||
"PlacesProvider",
|
||||
"ProfileMetadataProvider",
|
||||
"SearchesProvider",
|
||||
"SessionsProvider",
|
||||
"SysInfoProvider",
|
||||
];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
// We concatenate the JSMs together to eliminate compartment overhead.
|
||||
// This is a giant hack until compartment overhead is no longer an
|
||||
// issue.
|
||||
#define MERGED_COMPARTMENT
|
||||
|
||||
#include ../common/async.js
|
||||
;
|
||||
#include ../common/bagheeraclient.js
|
||||
;
|
||||
#include ../metrics/Metrics.jsm
|
||||
;
|
||||
#include healthreporter.jsm
|
||||
;
|
||||
#include profile.jsm
|
||||
;
|
||||
#include providers.jsm
|
||||
;
|
||||
|
@ -1,16 +0,0 @@
|
||||
# Register Firefox Health Report providers.
|
||||
category healthreport-js-provider-default AddonsProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default AppInfoProvider resource://gre/modules/HealthReport.jsm
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
category healthreport-js-provider-default CrashesProvider resource://gre/modules/HealthReport.jsm
|
||||
#endif
|
||||
category healthreport-js-provider-default HealthReportProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default HotfixProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default PlacesProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default ProfileMetadataProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default SearchesProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default SessionsProvider resource://gre/modules/HealthReport.jsm
|
||||
category healthreport-js-provider-default SysInfoProvider resource://gre/modules/HealthReport.jsm
|
||||
|
||||
# No Aurora or Beta providers yet; use the categories
|
||||
# "healthreport-js-provider-aurora", "healthreport-js-provider-beta".
|
File diff suppressed because it is too large
Load Diff
@ -1,198 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"getAppInfo",
|
||||
"updateAppInfo",
|
||||
"createFakeCrash",
|
||||
"InspectedHealthReporter",
|
||||
"getHealthReporter",
|
||||
];
|
||||
|
||||
|
||||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/services-common/utils.js");
|
||||
Cu.import("resource://gre/modules/services/healthreport/healthreporter.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
|
||||
var APP_INFO = {
|
||||
vendor: "Mozilla",
|
||||
name: "xpcshell",
|
||||
ID: "xpcshell@tests.mozilla.org",
|
||||
version: "1",
|
||||
appBuildID: "20121107",
|
||||
platformVersion: "p-ver",
|
||||
platformBuildID: "20121106",
|
||||
inSafeMode: false,
|
||||
logConsoleErrors: true,
|
||||
OS: "XPCShell",
|
||||
XPCOMABI: "noarch-spidermonkey",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, Ci.nsIXULRuntime]),
|
||||
invalidateCachesOnRestart: function() {},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Obtain a reference to the current object used to define XULAppInfo.
|
||||
*/
|
||||
this.getAppInfo = function () { return APP_INFO; }
|
||||
|
||||
/**
|
||||
* Update the current application info.
|
||||
*
|
||||
* If the argument is defined, it will be the object used. Else, APP_INFO is
|
||||
* used.
|
||||
*
|
||||
* To change the current XULAppInfo, simply call this function. If there was
|
||||
* a previously registered app info object, it will be unloaded and replaced.
|
||||
*/
|
||||
this.updateAppInfo = function (obj) {
|
||||
obj = obj || APP_INFO;
|
||||
APP_INFO = obj;
|
||||
|
||||
let id = Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}");
|
||||
let cid = "@mozilla.org/xre/app-info;1";
|
||||
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
|
||||
// Unregister an existing factory if one exists.
|
||||
try {
|
||||
let existing = Components.manager.getClassObjectByContractID(cid, Ci.nsIFactory);
|
||||
registrar.unregisterFactory(id, existing);
|
||||
} catch (ex) {}
|
||||
|
||||
let factory = {
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null) {
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
return obj.QueryInterface(iid);
|
||||
},
|
||||
};
|
||||
|
||||
registrar.registerFactory(id, "XULAppInfo", cid, factory);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a fake crash in the Crash Reports directory.
|
||||
*
|
||||
* Currently, we just create a dummy file. A more robust implementation would
|
||||
* create something that actually resembles a crash report file.
|
||||
*
|
||||
* This is very similar to code in crashreporter/tests/browser/head.js.
|
||||
*
|
||||
* FUTURE consolidate code in a shared JSM.
|
||||
*/
|
||||
this.createFakeCrash = function (submitted=false, date=new Date()) {
|
||||
let id = CommonUtils.generateUUID();
|
||||
let filename;
|
||||
|
||||
let paths = ["Crash Reports"];
|
||||
let mode;
|
||||
|
||||
if (submitted) {
|
||||
paths.push("submitted");
|
||||
filename = "bp-" + id + ".txt";
|
||||
mode = OS.Constants.libc.S_IRUSR | OS.Constants.libc.S_IWUSR |
|
||||
OS.Constants.libc.S_IRGRP | OS.Constants.libc.S_IROTH;
|
||||
} else {
|
||||
paths.push("pending");
|
||||
filename = id + ".dmp";
|
||||
mode = OS.Constants.libc.S_IRUSR | OS.Constants.libc.S_IWUSR;
|
||||
}
|
||||
|
||||
paths.push(filename);
|
||||
|
||||
let file = FileUtils.getFile("UAppData", paths, true);
|
||||
file.create(file.NORMAL_FILE_TYPE, mode);
|
||||
file.lastModifiedTime = date.getTime();
|
||||
dump("Created fake crash: " + id + "\n");
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A HealthReporter that is probed with various callbacks and counters.
|
||||
*
|
||||
* The purpose of this type is to aid testing of startup and shutdown.
|
||||
*/
|
||||
this.InspectedHealthReporter = function (branch, policy, stateLeaf) {
|
||||
HealthReporter.call(this, branch, policy, stateLeaf);
|
||||
|
||||
this.onStorageCreated = null;
|
||||
this.onProviderManagerInitialized = null;
|
||||
this.providerManagerShutdownCount = 0;
|
||||
this.storageCloseCount = 0;
|
||||
}
|
||||
|
||||
InspectedHealthReporter.prototype = {
|
||||
__proto__: HealthReporter.prototype,
|
||||
|
||||
_onStorageCreated: function (storage) {
|
||||
if (this.onStorageCreated) {
|
||||
this.onStorageCreated(storage);
|
||||
}
|
||||
|
||||
return HealthReporter.prototype._onStorageCreated.call(this, storage);
|
||||
},
|
||||
|
||||
_initializeProviderManager: Task.async(function* () {
|
||||
yield HealthReporter.prototype._initializeProviderManager.call(this);
|
||||
|
||||
if (this.onInitializeProviderManagerFinished) {
|
||||
this.onInitializeProviderManagerFinished();
|
||||
}
|
||||
}),
|
||||
|
||||
_onProviderManagerInitialized: function () {
|
||||
if (this.onProviderManagerInitialized) {
|
||||
this.onProviderManagerInitialized();
|
||||
}
|
||||
|
||||
return HealthReporter.prototype._onProviderManagerInitialized.call(this);
|
||||
},
|
||||
|
||||
_onProviderManagerShutdown: function () {
|
||||
this.providerManagerShutdownCount++;
|
||||
|
||||
return HealthReporter.prototype._onProviderManagerShutdown.call(this);
|
||||
},
|
||||
|
||||
_onStorageClose: function () {
|
||||
this.storageCloseCount++;
|
||||
|
||||
return HealthReporter.prototype._onStorageClose.call(this);
|
||||
},
|
||||
};
|
||||
|
||||
const DUMMY_URI="http://localhost:62013/";
|
||||
|
||||
this.getHealthReporter = function (name, uri=DUMMY_URI, inspected=false) {
|
||||
let branch = "healthreport.testing." + name + ".";
|
||||
|
||||
let prefs = new Preferences(branch + "healthreport.");
|
||||
prefs.set("documentServerURI", uri);
|
||||
prefs.set("dbName", name);
|
||||
|
||||
let reporter;
|
||||
|
||||
let policyPrefs = new Preferences(branch + "policy.");
|
||||
let policy = {};
|
||||
let type = inspected ? InspectedHealthReporter : HealthReporter;
|
||||
reporter = new type(branch + "healthreport.", policy,
|
||||
"state-" + name + ".json");
|
||||
|
||||
return reporter;
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SPHINX_TREES['healthreport'] = 'docs'
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'HealthReportComponents.manifest',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'HealthReport.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES.services.healthreport += [
|
||||
'healthreporter.jsm',
|
||||
'profile.jsm',
|
||||
'providers.jsm',
|
||||
]
|
||||
|
||||
TESTING_JS_MODULES.services.healthreport += [
|
||||
'modules-testing/utils.jsm',
|
||||
]
|
@ -1,124 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MERGED_COMPARTMENT
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ProfileMetadataProvider"];
|
||||
|
||||
const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
|
||||
|
||||
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
|
||||
#endif
|
||||
|
||||
const DEFAULT_PROFILE_MEASUREMENT_NAME = "age";
|
||||
const DEFAULT_PROFILE_MEASUREMENT_VERSION = 2;
|
||||
const REQUIRED_UINT32_TYPE = {type: "TYPE_UINT32"};
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm")
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
Cu.import("resource://gre/modules/ProfileAge.jsm");
|
||||
|
||||
/**
|
||||
* Measurements pertaining to the user's profile.
|
||||
*/
|
||||
// This is "version 1" of the metadata measurement - it must remain, but
|
||||
// it's currently unused - see bug 1063714 comment 12 for why.
|
||||
function ProfileMetadataMeasurement() {
|
||||
Metrics.Measurement.call(this);
|
||||
}
|
||||
ProfileMetadataMeasurement.prototype = {
|
||||
__proto__: Metrics.Measurement.prototype,
|
||||
|
||||
name: DEFAULT_PROFILE_MEASUREMENT_NAME,
|
||||
version: 1,
|
||||
|
||||
fields: {
|
||||
// Profile creation date. Number of days since Unix epoch.
|
||||
profileCreation: {type: Metrics.Storage.FIELD_LAST_NUMERIC},
|
||||
},
|
||||
};
|
||||
|
||||
// This is the current measurement - it adds the profileReset value.
|
||||
function ProfileMetadataMeasurement2() {
|
||||
Metrics.Measurement.call(this);
|
||||
}
|
||||
ProfileMetadataMeasurement2.prototype = {
|
||||
__proto__: Metrics.Measurement.prototype,
|
||||
|
||||
name: DEFAULT_PROFILE_MEASUREMENT_NAME,
|
||||
version: DEFAULT_PROFILE_MEASUREMENT_VERSION,
|
||||
|
||||
fields: {
|
||||
// Profile creation date. Number of days since Unix epoch.
|
||||
profileCreation: {type: Metrics.Storage.FIELD_LAST_NUMERIC},
|
||||
// Profile reset date. Number of days since Unix epoch.
|
||||
profileReset: {type: Metrics.Storage.FIELD_LAST_NUMERIC},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn a millisecond timestamp into a day timestamp.
|
||||
*
|
||||
* @param msec a number of milliseconds since epoch.
|
||||
* @return the number of whole days denoted by the input.
|
||||
*/
|
||||
function truncate(msec) {
|
||||
return Math.floor(msec / MILLISECONDS_PER_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Metrics.Provider for profile metadata, such as profile creation and
|
||||
* reset time.
|
||||
*/
|
||||
this.ProfileMetadataProvider = function() {
|
||||
Metrics.Provider.call(this);
|
||||
}
|
||||
this.ProfileMetadataProvider.prototype = {
|
||||
__proto__: Metrics.Provider.prototype,
|
||||
|
||||
name: "org.mozilla.profile",
|
||||
|
||||
measurementTypes: [ProfileMetadataMeasurement2],
|
||||
|
||||
pullOnly: true,
|
||||
|
||||
getProfileDays: Task.async(function* () {
|
||||
let result = {};
|
||||
let accessor = new ProfileAge(null, this._log);
|
||||
|
||||
let created = yield accessor.created;
|
||||
result["profileCreation"] = truncate(created);
|
||||
let reset = yield accessor.reset;
|
||||
if (reset) {
|
||||
result["profileReset"] = truncate(reset);
|
||||
}
|
||||
return result;
|
||||
}),
|
||||
|
||||
collectConstantData: function () {
|
||||
let m = this.getMeasurement(DEFAULT_PROFILE_MEASUREMENT_NAME,
|
||||
DEFAULT_PROFILE_MEASUREMENT_VERSION);
|
||||
|
||||
return Task.spawn(function* collectConstants() {
|
||||
let days = yield this.getProfileDays();
|
||||
|
||||
yield this.enqueueStorageOperation(function storeDays() {
|
||||
return Task.spawn(function* () {
|
||||
yield m.setLastNumeric("profileCreation", days["profileCreation"]);
|
||||
if (days["profileReset"]) {
|
||||
yield m.setLastNumeric("profileReset", days["profileReset"]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,21 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// We need to initialize the profile or OS.File may not work. See bug 810543.
|
||||
do_get_profile();
|
||||
|
||||
(function initMetricsTestingInfrastructure() {
|
||||
let ns = {};
|
||||
Components.utils.import("resource://testing-common/services/common/logging.js",
|
||||
ns);
|
||||
|
||||
ns.initTestLogging();
|
||||
}).call(this);
|
||||
|
||||
(function createAppInfo() {
|
||||
let ns = {};
|
||||
Components.utils.import("resource://testing-common/services/healthreport/utils.jsm", ns);
|
||||
ns.updateAppInfo();
|
||||
}).call(this);
|
@ -1,20 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const modules = [
|
||||
"healthreporter.jsm",
|
||||
"profile.jsm",
|
||||
"providers.jsm",
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
for (let m of modules) {
|
||||
let resource = "resource://gre/modules/services/healthreport/" + m;
|
||||
Components.utils.import(resource, {});
|
||||
}
|
||||
|
||||
Components.utils.import("resource://gre/modules/HealthReport.jsm", {});
|
||||
}
|
||||
|
@ -1,258 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
// Create profile directory before use.
|
||||
// It can be no older than a day ago….
|
||||
var profile_creation_lower = Date.now() - MILLISECONDS_PER_DAY;
|
||||
do_get_profile();
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/profile.jsm");
|
||||
Cu.import("resource://gre/modules/ProfileAge.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
|
||||
function MockProfileMetadataProvider(name="MockProfileMetadataProvider") {
|
||||
this.name = name;
|
||||
ProfileMetadataProvider.call(this);
|
||||
}
|
||||
MockProfileMetadataProvider.prototype = {
|
||||
__proto__: ProfileMetadataProvider.prototype,
|
||||
includeProfileReset: false,
|
||||
|
||||
getProfileDays: function getProfileDays() {
|
||||
let result = {profileCreation: 1234};
|
||||
if (this.includeProfileReset) {
|
||||
result.profileReset = 5678;
|
||||
}
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that OS.File works in our environment.
|
||||
* This test can go once there are xpcshell tests for OS.File.
|
||||
*/
|
||||
add_test(function use_os_file() {
|
||||
Cu.import("resource://gre/modules/osfile.jsm")
|
||||
|
||||
// Ensure that we get constants, too.
|
||||
do_check_neq(OS.Constants.Path.profileDir, null);
|
||||
|
||||
let iterator = new OS.File.DirectoryIterator(".");
|
||||
iterator.forEach(function onEntry(entry) {
|
||||
print("Got " + entry.path);
|
||||
}).then(function onSuccess() {
|
||||
iterator.close();
|
||||
print("Done.");
|
||||
run_next_test();
|
||||
}, function onFail() {
|
||||
iterator.close();
|
||||
do_throw("Iterating over current directory failed.");
|
||||
});
|
||||
});
|
||||
|
||||
function getAccessor() {
|
||||
let acc = new ProfileAge();
|
||||
print("Profile is " + acc.profilePath);
|
||||
return acc;
|
||||
}
|
||||
|
||||
add_test(function test_time_accessor_no_file() {
|
||||
let acc = getAccessor();
|
||||
|
||||
// There should be no file yet.
|
||||
acc.readTimes()
|
||||
.then(function onSuccess(json) {
|
||||
do_throw("File existed!");
|
||||
},
|
||||
function onFailure() {
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_time_accessor_named_file() {
|
||||
let acc = getAccessor();
|
||||
|
||||
// There should be no file yet.
|
||||
yield acc.writeTimes({created: 12345}, "test.json");
|
||||
let json = yield acc.readTimes("test.json")
|
||||
print("Read: " + JSON.stringify(json));
|
||||
do_check_eq(12345, json.created);
|
||||
});
|
||||
|
||||
add_task(function test_time_accessor_creates_file() {
|
||||
let lower = profile_creation_lower;
|
||||
|
||||
// Ensure that provided contents are merged, and existing
|
||||
// files can be overwritten. These two things occur if we
|
||||
// read and then decide that we have to write.
|
||||
let acc = getAccessor();
|
||||
let existing = {abc: "123", easy: "abc"};
|
||||
let expected;
|
||||
|
||||
let created = yield acc.computeAndPersistCreated(existing, "test2.json")
|
||||
let upper = Date.now() + 1000;
|
||||
print(lower + " < " + created + " <= " + upper);
|
||||
do_check_true(lower < created);
|
||||
do_check_true(upper >= created);
|
||||
expected = created;
|
||||
|
||||
let json = yield acc.readTimes("test2.json")
|
||||
print("Read: " + JSON.stringify(json));
|
||||
do_check_eq("123", json.abc);
|
||||
do_check_eq("abc", json.easy);
|
||||
do_check_eq(expected, json.created);
|
||||
});
|
||||
|
||||
add_task(function test_time_accessor_all() {
|
||||
let lower = profile_creation_lower;
|
||||
let acc = getAccessor();
|
||||
let expected;
|
||||
let created = yield acc.created
|
||||
let upper = Date.now() + 1000;
|
||||
do_check_true(lower < created);
|
||||
do_check_true(upper >= created);
|
||||
expected = created;
|
||||
|
||||
let again = yield acc.created
|
||||
do_check_eq(expected, again);
|
||||
});
|
||||
|
||||
add_task(function* test_time_reset() {
|
||||
let lower = profile_creation_lower;
|
||||
let acc = getAccessor();
|
||||
let testTime = 100000;
|
||||
yield acc.recordProfileReset(testTime);
|
||||
let reset = yield acc.reset;
|
||||
Assert.equal(reset, testTime);
|
||||
});
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new ProfileMetadataProvider("named");
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_profile_files() {
|
||||
let provider = new ProfileMetadataProvider();
|
||||
|
||||
function onSuccess(answer) {
|
||||
let now = Date.now() / MILLISECONDS_PER_DAY;
|
||||
print("Got " + answer.profileCreation + ", versus now = " + now);
|
||||
Assert.ok(answer.profileCreation < now);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function onFailure(ex) {
|
||||
do_throw("Directory iteration failed: " + ex);
|
||||
}
|
||||
|
||||
provider.getProfileDays().then(onSuccess, onFailure);
|
||||
});
|
||||
|
||||
// A generic test helper. We use this with both real
|
||||
// and mock providers in these tests.
|
||||
function test_collect_constant(provider, expectReset) {
|
||||
return Task.spawn(function* () {
|
||||
yield provider.collectConstantData();
|
||||
|
||||
let m = provider.getMeasurement("age", 2);
|
||||
Assert.notEqual(m, null);
|
||||
let values = yield m.getValues();
|
||||
Assert.ok(values.singular.has("profileCreation"));
|
||||
let createValue = values.singular.get("profileCreation")[1];
|
||||
let resetValue;
|
||||
if (expectReset) {
|
||||
Assert.equal(values.singular.size, 2);
|
||||
Assert.ok(values.singular.has("profileReset"));
|
||||
resetValue = values.singular.get("profileReset")[1];
|
||||
} else {
|
||||
Assert.equal(values.singular.size, 1);
|
||||
Assert.ok(!values.singular.has("profileReset"));
|
||||
}
|
||||
return [createValue, resetValue];
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* test_collect_constant_mock_no_reset() {
|
||||
let storage = yield Metrics.Storage("collect_constant_mock");
|
||||
let provider = new MockProfileMetadataProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let v = yield test_collect_constant(provider, false);
|
||||
Assert.equal(v.length, 2);
|
||||
Assert.equal(v[0], 1234);
|
||||
Assert.equal(v[1], undefined);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_constant_mock_with_reset() {
|
||||
let storage = yield Metrics.Storage("collect_constant_mock");
|
||||
let provider = new MockProfileMetadataProvider();
|
||||
provider.includeProfileReset = true;
|
||||
yield provider.init(storage);
|
||||
|
||||
let v = yield test_collect_constant(provider, true);
|
||||
Assert.equal(v.length, 2);
|
||||
Assert.equal(v[0], 1234);
|
||||
Assert.equal(v[1], 5678);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_constant_real_no_reset() {
|
||||
let provider = new ProfileMetadataProvider();
|
||||
let storage = yield Metrics.Storage("collect_constant_real");
|
||||
yield provider.init(storage);
|
||||
|
||||
let vals = yield test_collect_constant(provider, false);
|
||||
let created = vals[0];
|
||||
let reset = vals[1];
|
||||
Assert.equal(reset, undefined);
|
||||
|
||||
let ms = created * MILLISECONDS_PER_DAY;
|
||||
let lower = profile_creation_lower;
|
||||
let upper = Date.now() + 1000;
|
||||
print("Day: " + created);
|
||||
print("msec: " + ms);
|
||||
print("Lower: " + lower);
|
||||
print("Upper: " + upper);
|
||||
Assert.ok(lower <= ms);
|
||||
Assert.ok(upper >= ms);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_constant_real_with_reset() {
|
||||
let now = Date.now();
|
||||
let acc = getAccessor();
|
||||
yield acc.writeTimes({created: now-MILLISECONDS_PER_DAY, // yesterday
|
||||
reset: Date.now()}); // today
|
||||
|
||||
let provider = new ProfileMetadataProvider();
|
||||
let storage = yield Metrics.Storage("collect_constant_real");
|
||||
yield provider.init(storage);
|
||||
|
||||
let [created, reset] = yield test_collect_constant(provider, true);
|
||||
// we've already tested truncate() works as expected, so here just check
|
||||
// we got values.
|
||||
Assert.ok(created);
|
||||
Assert.ok(reset);
|
||||
Assert.ok(created <= reset);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,339 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
|
||||
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
// The hack, it burns. This could go away if extensions code exposed its
|
||||
// test environment setup functions as a testing-only JSM. See similar
|
||||
// code in Sync's head_helpers.js.
|
||||
var gGlobalScope = this;
|
||||
function loadAddonManager() {
|
||||
let ns = {};
|
||||
Cu.import("resource://gre/modules/Services.jsm", ns);
|
||||
let head = "../../../../toolkit/mozapps/extensions/test/xpcshell/head_addons.js";
|
||||
let file = do_get_file(head);
|
||||
let uri = ns.Services.io.newFileURI(file);
|
||||
ns.Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
startupManager();
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
loadAddonManager();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new AddonsProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function test_init() {
|
||||
let storage = yield Metrics.Storage("init");
|
||||
let provider = new AddonsProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
function monkeypatchAddons(provider, addons) {
|
||||
if (!Array.isArray(addons)) {
|
||||
throw new Error("Must define array of addon objects.");
|
||||
}
|
||||
|
||||
Object.defineProperty(provider, "_createDataStructure", {
|
||||
value: function _createDataStructure() {
|
||||
return AddonsProvider.prototype._createDataStructure.call(provider, addons);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function test_collect() {
|
||||
let storage = yield Metrics.Storage("collect");
|
||||
let provider = new AddonsProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let now = new Date();
|
||||
|
||||
// FUTURE install add-on via AddonManager and don't use monkeypatching.
|
||||
let testAddons = [
|
||||
{
|
||||
id: "addon0",
|
||||
userDisabled: false,
|
||||
appDisabled: false,
|
||||
version: "1",
|
||||
type: "extension",
|
||||
scope: 1,
|
||||
foreignInstall: false,
|
||||
hasBinaryComponents: false,
|
||||
installDate: now,
|
||||
updateDate: now,
|
||||
},
|
||||
// This plugin entry should get ignored.
|
||||
{
|
||||
id: "addon1",
|
||||
userDisabled: false,
|
||||
appDisabled: false,
|
||||
version: "2",
|
||||
type: "plugin",
|
||||
scope: 1,
|
||||
foreignInstall: false,
|
||||
hasBinaryComponents: false,
|
||||
installDate: now,
|
||||
updateDate: now,
|
||||
},
|
||||
// Is counted but full details are omitted because it is a theme.
|
||||
{
|
||||
id: "addon2",
|
||||
userDisabled: false,
|
||||
appDisabled: false,
|
||||
version: "3",
|
||||
type: "theme",
|
||||
scope: 1,
|
||||
foreignInstall: false,
|
||||
hasBinaryComponents: false,
|
||||
installDate: now,
|
||||
updateDate: now,
|
||||
},
|
||||
{
|
||||
id: "addon3",
|
||||
userDisabled: false,
|
||||
appDisabled: false,
|
||||
version: "4",
|
||||
type: "service",
|
||||
scope: 1,
|
||||
foreignInstall: false,
|
||||
hasBinaryComponents: false,
|
||||
installDate: now,
|
||||
updateDate: now,
|
||||
description: "addon3 description"
|
||||
},
|
||||
{
|
||||
// Should be excluded from the report completely
|
||||
id: "pluginfake",
|
||||
type: "plugin",
|
||||
userDisabled: false,
|
||||
appDisabled: false,
|
||||
},
|
||||
{
|
||||
// Should be in gm-plugins
|
||||
id: "gmp-testgmp",
|
||||
type: "plugin",
|
||||
userDisabled: false,
|
||||
version: "7.2",
|
||||
isGMPlugin: true,
|
||||
},
|
||||
];
|
||||
|
||||
monkeypatchAddons(provider, testAddons);
|
||||
|
||||
let testPlugins = {
|
||||
"Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Plug-in for testing purposes.™ (हिन्दी 中文 العربية)",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-test"
|
||||
],
|
||||
},
|
||||
"Second Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Second plug-in for testing purposes.",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-second-test"
|
||||
],
|
||||
},
|
||||
"Java Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Dummy Java plug-in for testing purposes.",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-java-test"
|
||||
],
|
||||
},
|
||||
"Third Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Third plug-in for testing purposes.",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-third-test"
|
||||
],
|
||||
},
|
||||
"Flash Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Flash plug-in for testing purposes.",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-shockwave-flash-test"
|
||||
],
|
||||
},
|
||||
"Silverlight Test Plug-in":
|
||||
{
|
||||
"version": "1.0.0.0",
|
||||
"description": "Silverlight plug-in for testing purposes.",
|
||||
"blocklisted": false,
|
||||
"disabled": false,
|
||||
"clicktoplay": false,
|
||||
"mimeTypes":[
|
||||
"application/x-silverlight-test"
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
let pluginTags = Cc["@mozilla.org/plugin/host;1"]
|
||||
.getService(Ci.nsIPluginHost)
|
||||
.getPluginTags({});
|
||||
|
||||
for (let tag of pluginTags) {
|
||||
if (tag.name in testPlugins) {
|
||||
let p = testPlugins[tag.name];
|
||||
p.id = tag.filename+":"+tag.name+":"+p.version+":"+p.description;
|
||||
}
|
||||
}
|
||||
|
||||
yield provider.collectConstantData();
|
||||
|
||||
// Test addons measurement.
|
||||
|
||||
let addons = provider.getMeasurement("addons", 2);
|
||||
let data = yield addons.getValues();
|
||||
|
||||
do_check_eq(data.days.size, 0);
|
||||
do_check_eq(data.singular.size, 1);
|
||||
do_check_true(data.singular.has("addons"));
|
||||
|
||||
let json = data.singular.get("addons")[1];
|
||||
let value = JSON.parse(json);
|
||||
do_check_eq(typeof(value), "object");
|
||||
do_check_eq(Object.keys(value).length, 2);
|
||||
do_check_true("addon0" in value);
|
||||
do_check_true(!("addon1" in value));
|
||||
do_check_true(!("addon2" in value));
|
||||
do_check_true("addon3" in value);
|
||||
do_check_true(!("pluginfake" in value));
|
||||
do_check_true(!("gmp-testgmp" in value));
|
||||
|
||||
let serializer = addons.serializer(addons.SERIALIZE_JSON);
|
||||
let serialized = serializer.singular(data.singular);
|
||||
do_check_eq(typeof(serialized), "object");
|
||||
do_check_eq(Object.keys(serialized).length, 3); // Our entries, plus _v.
|
||||
do_check_true("addon0" in serialized);
|
||||
do_check_true("addon3" in serialized);
|
||||
do_check_eq(serialized._v, 2);
|
||||
|
||||
// Test plugins measurement.
|
||||
|
||||
let plugins = provider.getMeasurement("plugins", 1);
|
||||
data = yield plugins.getValues();
|
||||
|
||||
do_check_eq(data.days.size, 0);
|
||||
do_check_eq(data.singular.size, 1);
|
||||
do_check_true(data.singular.has("plugins"));
|
||||
|
||||
json = data.singular.get("plugins")[1];
|
||||
value = JSON.parse(json);
|
||||
do_check_eq(typeof(value), "object");
|
||||
do_check_eq(Object.keys(value).length, pluginTags.length);
|
||||
|
||||
do_check_true(testPlugins["Test Plug-in"].id in value);
|
||||
do_check_true(testPlugins["Second Test Plug-in"].id in value);
|
||||
do_check_true(testPlugins["Java Test Plug-in"].id in value);
|
||||
|
||||
for (let id in value) {
|
||||
let item = value[id];
|
||||
let testData = testPlugins[item.name];
|
||||
for (let prop in testData) {
|
||||
if (prop == "mimeTypes" || prop == "id") {
|
||||
continue;
|
||||
}
|
||||
do_check_eq(testData[prop], item[prop]);
|
||||
}
|
||||
|
||||
for (let mime of testData.mimeTypes) {
|
||||
do_check_true(item.mimeTypes.indexOf(mime) != -1);
|
||||
}
|
||||
}
|
||||
|
||||
serializer = plugins.serializer(plugins.SERIALIZE_JSON);
|
||||
serialized = serializer.singular(data.singular);
|
||||
do_check_eq(typeof(serialized), "object");
|
||||
do_check_eq(Object.keys(serialized).length, pluginTags.length+1); // Our entries, plus _v.
|
||||
for (let name in testPlugins) {
|
||||
// Special case for bug 1165981. There is a test plugin that
|
||||
// exists to make sure we don't load it on certain platforms.
|
||||
// We skip the check for that plugin here, as it will work on some
|
||||
// platforms but not others.
|
||||
if (name == "Third Test Plug-in") {
|
||||
continue;
|
||||
}
|
||||
do_check_true(testPlugins[name].id in serialized);
|
||||
}
|
||||
do_check_eq(serialized._v, 1);
|
||||
|
||||
// Test GMP plugins measurement.
|
||||
|
||||
let gmPlugins = provider.getMeasurement("gm-plugins", 1);
|
||||
data = yield gmPlugins.getValues();
|
||||
|
||||
do_check_eq(data.days.size, 0);
|
||||
do_check_eq(data.singular.size, 1);
|
||||
do_check_true(data.singular.has("gm-plugins"));
|
||||
|
||||
json = data.singular.get("gm-plugins")[1];
|
||||
value = JSON.parse(json);
|
||||
do_print("value: " + json);
|
||||
do_check_eq(typeof(value), "object");
|
||||
do_check_eq(Object.keys(value).length, 1);
|
||||
|
||||
do_check_eq(value["gmp-testgmp"].version, "7.2");
|
||||
do_check_eq(value["gmp-testgmp"].userDisabled, false);
|
||||
|
||||
serializer = gmPlugins.serializer(plugins.SERIALIZE_JSON);
|
||||
serialized = serializer.singular(data.singular);
|
||||
do_check_eq(typeof(serialized), "object");
|
||||
do_check_eq(serialized["gmp-testgmp"].version, "7.2");
|
||||
do_check_eq(serialized._v, 1);
|
||||
|
||||
// Test counts measurement.
|
||||
|
||||
let counts = provider.getMeasurement("counts", 2);
|
||||
data = yield counts.getValues();
|
||||
do_check_eq(data.days.size, 1);
|
||||
do_check_eq(data.singular.size, 0);
|
||||
do_check_true(data.days.hasDay(now));
|
||||
|
||||
value = data.days.getDay(now);
|
||||
do_check_eq(value.size, 4);
|
||||
do_check_eq(value.get("extension"), 1);
|
||||
do_check_eq(value.get("plugin"), pluginTags.length);
|
||||
do_check_eq(value.get("theme"), 1);
|
||||
do_check_eq(value.get("service"), 1);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,270 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {interfaces: Ci, results: Cr, utils: Cu, classes: Cc} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
Cu.import("resource://testing-common/services/healthreport/utils.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new AppInfoProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function test_collect_smoketest() {
|
||||
let storage = yield Metrics.Storage("collect_smoketest");
|
||||
let provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let now = new Date();
|
||||
yield provider.collectConstantData();
|
||||
|
||||
let m = provider.getMeasurement("appinfo", 2);
|
||||
let data = yield storage.getMeasurementValues(m.id);
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let d = serializer.singular(data.singular);
|
||||
|
||||
do_check_eq(d._v, 2);
|
||||
do_check_eq(d.vendor, "Mozilla");
|
||||
do_check_eq(d.name, "xpcshell");
|
||||
do_check_eq(d.id, "xpcshell@tests.mozilla.org");
|
||||
do_check_eq(d.version, "1");
|
||||
do_check_eq(d.appBuildID, "20121107");
|
||||
do_check_eq(d.platformVersion, "p-ver");
|
||||
do_check_eq(d.platformBuildID, "20121106");
|
||||
do_check_eq(d.os, "XPCShell");
|
||||
do_check_eq(d.xpcomabi, "noarch-spidermonkey");
|
||||
|
||||
do_check_eq(data.days.size, 1);
|
||||
do_check_true(data.days.hasDay(now));
|
||||
let day = data.days.getDay(now);
|
||||
do_check_eq(day.size, 3);
|
||||
do_check_true(day.has("isDefaultBrowser"));
|
||||
do_check_true(day.has("isTelemetryEnabled"));
|
||||
do_check_true(day.has("isBlocklistEnabled"));
|
||||
|
||||
// TODO Bug 827189 Actually test this properly. On some local builds, this
|
||||
// is always -1 (the service throws). On buildbot, it seems to always be 0.
|
||||
do_check_neq(day.get("isDefaultBrowser"), 1);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_record_version() {
|
||||
let storage = yield Metrics.Storage("record_version");
|
||||
|
||||
let provider = new AppInfoProvider();
|
||||
let now = new Date();
|
||||
yield provider.init(storage);
|
||||
|
||||
// The provider records information on startup.
|
||||
let m = provider.getMeasurement("versions", 2);
|
||||
let data = yield m.getValues();
|
||||
|
||||
do_check_true(data.days.hasDay(now));
|
||||
let day = data.days.getDay(now);
|
||||
do_check_eq(day.size, 4);
|
||||
do_check_true(day.has("appVersion"));
|
||||
do_check_true(day.has("platformVersion"));
|
||||
do_check_true(day.has("appBuildID"));
|
||||
do_check_true(day.has("platformBuildID"));
|
||||
|
||||
let value = day.get("appVersion");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 1);
|
||||
let ai = getAppInfo();
|
||||
do_check_eq(value[0], ai.version);
|
||||
|
||||
value = day.get("platformVersion");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 1);
|
||||
do_check_eq(value[0], ai.platformVersion);
|
||||
|
||||
value = day.get("appBuildID");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 1);
|
||||
do_check_eq(value[0], ai.appBuildID);
|
||||
|
||||
value = day.get("platformBuildID");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 1);
|
||||
do_check_eq(value[0], ai.platformBuildID);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_record_version_change() {
|
||||
let storage = yield Metrics.Storage("record_version_change");
|
||||
|
||||
let provider = new AppInfoProvider();
|
||||
let now = new Date();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
|
||||
let ai = getAppInfo();
|
||||
ai.version = "new app version";
|
||||
ai.platformVersion = "new platform version";
|
||||
ai.appBuildID = "new app id";
|
||||
ai.platformBuildID = "new platform id";
|
||||
updateAppInfo(ai);
|
||||
|
||||
provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
// There should be 2 records in the versions history.
|
||||
let m = provider.getMeasurement("versions", 2);
|
||||
let data = yield m.getValues();
|
||||
do_check_true(data.days.hasDay(now));
|
||||
let day = data.days.getDay(now);
|
||||
|
||||
let value = day.get("appVersion");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 2);
|
||||
do_check_eq(value[1], "new app version");
|
||||
|
||||
value = day.get("platformVersion");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 2);
|
||||
do_check_eq(value[1], "new platform version");
|
||||
|
||||
// There should be 2 records in the buildID history.
|
||||
value = day.get("appBuildID");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 2);
|
||||
do_check_eq(value[1], "new app id");
|
||||
|
||||
value = day.get("platformBuildID");
|
||||
do_check_true(Array.isArray(value));
|
||||
do_check_eq(value.length, 2);
|
||||
do_check_eq(value[1], "new platform id");
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_record_telemetry() {
|
||||
let storage = yield Metrics.Storage("record_telemetry");
|
||||
let provider;
|
||||
|
||||
let now = new Date();
|
||||
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
|
||||
provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.collectConstantData();
|
||||
|
||||
let m = provider.getMeasurement("appinfo", 2);
|
||||
let data = yield m.getValues();
|
||||
let d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(1, d.isTelemetryEnabled);
|
||||
yield provider.shutdown();
|
||||
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
|
||||
provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.collectConstantData();
|
||||
|
||||
m = provider.getMeasurement("appinfo", 2);
|
||||
data = yield m.getValues();
|
||||
d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(0, d.isTelemetryEnabled);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_record_blocklist() {
|
||||
let storage = yield Metrics.Storage("record_blocklist");
|
||||
|
||||
let now = new Date();
|
||||
|
||||
Services.prefs.setBoolPref("extensions.blocklist.enabled", true);
|
||||
let provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.collectConstantData();
|
||||
|
||||
let m = provider.getMeasurement("appinfo", 2);
|
||||
let data = yield m.getValues();
|
||||
let d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(d.isBlocklistEnabled, 1);
|
||||
yield provider.shutdown();
|
||||
|
||||
Services.prefs.setBoolPref("extensions.blocklist.enabled", false);
|
||||
provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.collectConstantData();
|
||||
|
||||
m = provider.getMeasurement("appinfo", 2);
|
||||
data = yield m.getValues();
|
||||
d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(d.isBlocklistEnabled, 0);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_record_app_update () {
|
||||
let storage = yield Metrics.Storage("record_update");
|
||||
|
||||
Services.prefs.setBoolPref("app.update.enabled", true);
|
||||
Services.prefs.setBoolPref("app.update.auto", true);
|
||||
let provider = new AppInfoProvider();
|
||||
yield provider.init(storage);
|
||||
let now = new Date();
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("update", 1);
|
||||
let data = yield m.getValues();
|
||||
let d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(d.enabled, 1);
|
||||
do_check_eq(d.autoDownload, 1);
|
||||
|
||||
Services.prefs.setBoolPref("app.update.enabled", false);
|
||||
Services.prefs.setBoolPref("app.update.auto", false);
|
||||
|
||||
yield provider.collectDailyData();
|
||||
data = yield m.getValues();
|
||||
d = yield m.serializer(m.SERIALIZE_JSON).daily(data.days.getDay(now));
|
||||
do_check_eq(d.enabled, 0);
|
||||
do_check_eq(d.autoDownload, 0);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_healthreporter_integration () {
|
||||
let reporter = getHealthReporter("healthreporter_integration");
|
||||
yield reporter.init();
|
||||
|
||||
try {
|
||||
yield reporter._providerManager.registerProviderFromType(AppInfoProvider);
|
||||
yield reporter.collectMeasurements();
|
||||
|
||||
let payload = yield reporter.getJSONPayload(true);
|
||||
let days = payload['data']['days'];
|
||||
|
||||
for (let [day, measurements] in Iterator(days)) {
|
||||
do_check_eq(Object.keys(measurements).length, 3);
|
||||
do_check_true("org.mozilla.appInfo.appinfo" in measurements);
|
||||
do_check_true("org.mozilla.appInfo.update" in measurements);
|
||||
do_check_true("org.mozilla.appInfo.versions" in measurements);
|
||||
}
|
||||
} finally {
|
||||
yield reporter._shutdown();
|
||||
}
|
||||
});
|
@ -1,137 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
Cu.import("resource://testing-common/AppData.jsm");
|
||||
Cu.import("resource://testing-common/services/healthreport/utils.jsm");
|
||||
Cu.import("resource://testing-common/CrashManagerTest.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* init() {
|
||||
do_get_profile();
|
||||
yield makeFakeAppDir();
|
||||
});
|
||||
|
||||
add_task(function test_constructor() {
|
||||
let provider = new CrashesProvider();
|
||||
});
|
||||
|
||||
add_task(function* test_init() {
|
||||
let storage = yield Metrics.Storage("init");
|
||||
let provider = new CrashesProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect() {
|
||||
let storage = yield Metrics.Storage("collect");
|
||||
let provider = new CrashesProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
// Install custom manager so we don't interfere with other tests.
|
||||
let manager = yield getManager();
|
||||
provider._manager = manager;
|
||||
|
||||
let day1 = new Date(2014, 0, 1, 0, 0, 0);
|
||||
let day2 = new Date(2014, 0, 3, 0, 0, 0);
|
||||
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_MAIN,
|
||||
manager.CRASH_TYPE_CRASH,
|
||||
"mc1", day1, { OOMAllocationSize: 1073741824 });
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_MAIN,
|
||||
manager.CRASH_TYPE_CRASH,
|
||||
"mc2", day1);
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_CONTENT,
|
||||
manager.CRASH_TYPE_HANG,
|
||||
"ch", day1);
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_PLUGIN,
|
||||
manager.CRASH_TYPE_CRASH,
|
||||
"pc", day1);
|
||||
|
||||
yield manager.addSubmissionAttempt("mc1", "sub1", day1);
|
||||
yield manager.addSubmissionResult("mc1", "sub1", day1,
|
||||
manager.SUBMISSION_RESULT_OK);
|
||||
yield manager.addSubmissionAttempt("ch", "sub1", day1);
|
||||
yield manager.addSubmissionResult("ch", "sub1", day1,
|
||||
manager.SUBMISSION_RESULT_FAILED);
|
||||
yield manager.addSubmissionAttempt("ch", "sub2", day1);
|
||||
yield manager.addSubmissionResult("ch", "sub2", day1,
|
||||
manager.SUBMISSION_RESULT_FAILED);
|
||||
yield manager.addSubmissionAttempt("ch", "sub3", day1);
|
||||
yield manager.addSubmissionResult("ch", "sub3", day1,
|
||||
manager.SUBMISSION_RESULT_OK);
|
||||
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_MAIN,
|
||||
manager.CRASH_TYPE_HANG,
|
||||
"mh", day2);
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_CONTENT,
|
||||
manager.CRASH_TYPE_CRASH,
|
||||
"cc", day2);
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_PLUGIN,
|
||||
manager.CRASH_TYPE_HANG,
|
||||
"ph", day2);
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_GMPLUGIN,
|
||||
manager.CRASH_TYPE_CRASH,
|
||||
"gmpc", day2);
|
||||
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("crashes", 6);
|
||||
let values = yield m.getValues();
|
||||
do_check_eq(values.days.size, 2);
|
||||
do_check_true(values.days.hasDay(day1));
|
||||
do_check_true(values.days.hasDay(day2));
|
||||
|
||||
let value = values.days.getDay(day1);
|
||||
do_check_true(value.has("main-crash"));
|
||||
do_check_eq(value.get("main-crash"), 2);
|
||||
do_check_true(value.has("main-crash-oom"));
|
||||
do_check_eq(value.get("main-crash-oom"), 1);
|
||||
do_check_true(value.has("content-hang"));
|
||||
do_check_eq(value.get("content-hang"), 1);
|
||||
do_check_true(value.has("plugin-crash"));
|
||||
do_check_eq(value.get("plugin-crash"), 1);
|
||||
|
||||
do_check_true(value.has("main-crash-submission-succeeded"));
|
||||
do_check_eq(value.get("main-crash-submission-succeeded"), 1);
|
||||
do_check_true(value.has("content-hang-submission-failed"));
|
||||
do_check_eq(value.get("content-hang-submission-failed"), 2);
|
||||
do_check_true(value.has("content-hang-submission-succeeded"));
|
||||
do_check_eq(value.get("content-hang-submission-succeeded"), 1);
|
||||
|
||||
value = values.days.getDay(day2);
|
||||
do_check_true(value.has("main-hang"));
|
||||
do_check_eq(value.get("main-hang"), 1);
|
||||
do_check_true(value.has("content-crash"));
|
||||
do_check_eq(value.get("content-crash"), 1);
|
||||
do_check_true(value.has("plugin-hang"));
|
||||
do_check_eq(value.get("plugin-hang"), 1);
|
||||
do_check_true(value.has("gmplugin-crash"));
|
||||
do_check_eq(value.get("gmplugin-crash"), 1);
|
||||
|
||||
// Check that adding a new crash increments counter on next collect.
|
||||
yield manager.addCrash(manager.PROCESS_TYPE_MAIN,
|
||||
manager.CRASH_TYPE_HANG,
|
||||
"mc3", day2);
|
||||
|
||||
yield provider.collectDailyData();
|
||||
values = yield m.getValues();
|
||||
value = values.days.getDay(day2);
|
||||
do_check_eq(value.get("main-hang"), 2);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,179 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
const EXAMPLE_2014052701 = {
|
||||
"upgradedFrom":"13.0.1",
|
||||
"uninstallReason":"SUCCESSFUL_UPGRADE",
|
||||
"_entityID":null,
|
||||
"forensicsID":"29525548-b653-49db-bfb8-a160cdfbeb4a",
|
||||
"_installInProgress":false,
|
||||
"_everCompatible":true,
|
||||
"reportedWindowsVersion":[6,1,1],
|
||||
"actualWindowsVersion":[6,1,1],
|
||||
"firstNotifyDay":0,
|
||||
"lastNotifyDay":0,
|
||||
"downloadAttempts":1,
|
||||
"downloadFailures":0,
|
||||
"installAttempts":1,
|
||||
"installSuccesses":1,
|
||||
"installLauncherFailures":0,
|
||||
"installFailures":0,
|
||||
"notificationsShown":0,
|
||||
"notificationsClicked":0,
|
||||
"notificationsDismissed":0,
|
||||
"notificationsRemoved":0,
|
||||
"launcherExitCodes":{"0":1}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function* init() {
|
||||
do_get_profile();
|
||||
});
|
||||
|
||||
add_task(function test_constructor() {
|
||||
new HotfixProvider();
|
||||
});
|
||||
|
||||
add_task(function* test_init() {
|
||||
let storage = yield Metrics.Storage("init");
|
||||
let provider = new HotfixProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_empty() {
|
||||
let storage = yield Metrics.Storage("collect_empty");
|
||||
let provider = new HotfixProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("update", 1);
|
||||
let data = yield m.getValues();
|
||||
Assert.equal(data.singular.size, 0);
|
||||
Assert.equal(data.days.size, 0);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_20140527() {
|
||||
let storage = yield Metrics.Storage("collect_20140527");
|
||||
let provider = new HotfixProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let path = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"hotfix.v20140527.01.json");
|
||||
let encoder = new TextEncoder();
|
||||
yield OS.File.writeAtomic(path,
|
||||
encoder.encode(JSON.stringify(EXAMPLE_2014052701)));
|
||||
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("update", 1);
|
||||
let data = yield m.getValues();
|
||||
let s = data.singular;
|
||||
Assert.equal(s.size, 7);
|
||||
Assert.equal(s.get("v20140527.upgradedFrom")[1], "13.0.1");
|
||||
Assert.equal(s.get("v20140527.uninstallReason")[1], "SUCCESSFUL_UPGRADE");
|
||||
Assert.equal(s.get("v20140527.downloadAttempts")[1], 1);
|
||||
Assert.equal(s.get("v20140527.downloadFailures")[1], 0);
|
||||
Assert.equal(s.get("v20140527.installAttempts")[1], 1);
|
||||
Assert.equal(s.get("v20140527.installFailures")[1], 0);
|
||||
Assert.equal(s.get("v20140527.notificationsShown")[1], 0);
|
||||
|
||||
// Ensure the dynamic fields get serialized.
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let d = serializer.singular(s);
|
||||
|
||||
Assert.deepEqual(d, {
|
||||
"_v": 1,
|
||||
"v20140527.upgradedFrom": "13.0.1",
|
||||
"v20140527.uninstallReason": "SUCCESSFUL_UPGRADE",
|
||||
"v20140527.downloadAttempts": 1,
|
||||
"v20140527.downloadFailures": 0,
|
||||
"v20140527.installAttempts": 1,
|
||||
"v20140527.installFailures": 0,
|
||||
"v20140527.notificationsShown": 0,
|
||||
});
|
||||
|
||||
// Don't interfere with next test.
|
||||
yield OS.File.remove(path);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_collect_multiple_versions() {
|
||||
let storage = yield Metrics.Storage("collect_multiple_versions");
|
||||
let provider = new HotfixProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let p1 = {
|
||||
upgradedFrom: "12.0",
|
||||
uninstallReason: "SUCCESSFUL_UPGRADE",
|
||||
downloadAttempts: 3,
|
||||
downloadFailures: 1,
|
||||
installAttempts: 1,
|
||||
installFailures: 1,
|
||||
notificationsShown: 2,
|
||||
};
|
||||
|
||||
let p2 = {
|
||||
downloadAttempts: 5,
|
||||
downloadFailures: 3,
|
||||
installAttempts: 2,
|
||||
installFailures: 2,
|
||||
uninstallReason: null,
|
||||
notificationsShown: 1,
|
||||
};
|
||||
|
||||
let path1 = OS.Path.join(OS.Constants.Path.profileDir, "updateHotfix.v20140601.json");
|
||||
let path2 = OS.Path.join(OS.Constants.Path.profileDir, "updateHotfix.v20140701.json");
|
||||
|
||||
let encoder = new TextEncoder();
|
||||
yield OS.File.writeAtomic(path1, encoder.encode(JSON.stringify(p1)));
|
||||
yield OS.File.writeAtomic(path2, encoder.encode(JSON.stringify(p2)));
|
||||
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("update", 1);
|
||||
let data = yield m.getValues();
|
||||
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let d = serializer.singular(data.singular);
|
||||
|
||||
Assert.deepEqual(d, {
|
||||
"_v": 1,
|
||||
"v20140601.upgradedFrom": "12.0",
|
||||
"v20140601.uninstallReason": "SUCCESSFUL_UPGRADE",
|
||||
"v20140601.downloadAttempts": 3,
|
||||
"v20140601.downloadFailures": 1,
|
||||
"v20140601.installAttempts": 1,
|
||||
"v20140601.installFailures": 1,
|
||||
"v20140601.notificationsShown": 2,
|
||||
"v20140701.uninstallReason": "STILL_INSTALLED",
|
||||
"v20140701.downloadAttempts": 5,
|
||||
"v20140701.downloadFailures": 3,
|
||||
"v20140701.installAttempts": 2,
|
||||
"v20140701.installFailures": 2,
|
||||
"v20140701.notificationsShown": 1,
|
||||
});
|
||||
|
||||
// Don't interfere with next test.
|
||||
yield OS.File.remove(path1);
|
||||
yield OS.File.remove(path2);
|
||||
|
||||
yield storage.close();
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new PlacesProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function test_collect_smoketest() {
|
||||
let storage = yield Metrics.Storage("collect_smoketest");
|
||||
let provider = new PlacesProvider();
|
||||
|
||||
yield provider.init(storage);
|
||||
|
||||
let now = new Date();
|
||||
yield provider.collectDailyData();
|
||||
|
||||
let m = provider.getMeasurement("places", 1);
|
||||
let data = yield storage.getMeasurementValues(m.id);
|
||||
do_check_eq(data.days.size, 1);
|
||||
do_check_true(data.days.hasDay(now));
|
||||
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let day = serializer.daily(data.days.getDay(now));
|
||||
|
||||
do_check_eq(day._v, 1);
|
||||
do_check_eq(Object.keys(day).length, 3);
|
||||
do_check_eq(day.pages, 0);
|
||||
do_check_eq(day.bookmarks, 0);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,187 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
var bsp = Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
const DEFAULT_ENGINES = [
|
||||
{name: "Amazon.com", identifier: "amazondotcom"},
|
||||
{name: "Bing", identifier: "bing"},
|
||||
{name: "Google", identifier: "google"},
|
||||
{name: "Yahoo", identifier: "yahoo"},
|
||||
{name: "Foobar Search", identifier: "foobar"},
|
||||
];
|
||||
|
||||
function MockSearchCountMeasurement() {
|
||||
bsp.SearchCountMeasurement3.call(this);
|
||||
}
|
||||
MockSearchCountMeasurement.prototype = {
|
||||
__proto__: bsp.SearchCountMeasurement3.prototype,
|
||||
};
|
||||
|
||||
function MockSearchesProvider() {
|
||||
SearchesProvider.call(this);
|
||||
}
|
||||
MockSearchesProvider.prototype = {
|
||||
__proto__: SearchesProvider.prototype,
|
||||
measurementTypes: [MockSearchCountMeasurement],
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
// Tell the search service we are running in the US. This also has the
|
||||
// desired side-effect of preventing our geoip lookup.
|
||||
Services.prefs.setBoolPref("browser.search.isUS", true);
|
||||
Services.prefs.setCharPref("browser.search.countryCode", "US");
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new SearchesProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function* test_record() {
|
||||
let storage = yield Metrics.Storage("record");
|
||||
let provider = new MockSearchesProvider();
|
||||
|
||||
yield provider.init(storage);
|
||||
|
||||
let now = new Date();
|
||||
|
||||
// Record searches for all but one of our defaults, and one engine that's
|
||||
// not a default.
|
||||
for (let engine of DEFAULT_ENGINES.concat([{name: "Not Default", identifier: "notdef"}])) {
|
||||
if (engine.identifier == "yahoo") {
|
||||
continue;
|
||||
}
|
||||
yield provider.recordSearch(engine, "abouthome");
|
||||
yield provider.recordSearch(engine, "contextmenu");
|
||||
yield provider.recordSearch(engine, "newtab");
|
||||
yield provider.recordSearch(engine, "searchbar");
|
||||
yield provider.recordSearch(engine, "urlbar");
|
||||
}
|
||||
|
||||
// Invalid sources should throw.
|
||||
let errored = false;
|
||||
try {
|
||||
yield provider.recordSearch(DEFAULT_ENGINES[0], "bad source");
|
||||
} catch (ex) {
|
||||
errored = true;
|
||||
} finally {
|
||||
do_check_true(errored);
|
||||
}
|
||||
|
||||
let m = provider.getMeasurement("counts", 3);
|
||||
let data = yield m.getValues();
|
||||
do_check_eq(data.days.size, 1);
|
||||
do_check_true(data.days.hasDay(now));
|
||||
|
||||
let day = data.days.getDay(now);
|
||||
for (let engine of DEFAULT_ENGINES) {
|
||||
let identifier = engine.identifier;
|
||||
let expected = identifier != "yahoo";
|
||||
|
||||
for (let source of ["abouthome", "contextmenu", "searchbar", "urlbar"]) {
|
||||
let field = identifier + "." + source;
|
||||
if (expected) {
|
||||
do_check_true(day.has(field));
|
||||
do_check_eq(day.get(field), 1);
|
||||
} else {
|
||||
do_check_false(day.has(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also, check that our non-default engine contributed, with a computed
|
||||
// identifier.
|
||||
let identifier = "notdef";
|
||||
for (let source of ["abouthome", "contextmenu", "searchbar", "urlbar"]) {
|
||||
let field = identifier + "." + source;
|
||||
do_check_true(day.has(field));
|
||||
}
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_includes_other_fields() {
|
||||
let storage = yield Metrics.Storage("includes_other_fields");
|
||||
let provider = new MockSearchesProvider();
|
||||
|
||||
yield provider.init(storage);
|
||||
let m = provider.getMeasurement("counts", 3);
|
||||
|
||||
// Register a search against a provider that isn't live in this session.
|
||||
let id = yield m.storage.registerField(m.id, "test.searchbar",
|
||||
Metrics.Storage.FIELD_DAILY_COUNTER);
|
||||
|
||||
let testField = "test.searchbar";
|
||||
let now = new Date();
|
||||
yield m.storage.incrementDailyCounterFromFieldID(id, now);
|
||||
|
||||
// Make sure we don't know about it.
|
||||
do_check_false(testField in m.fields);
|
||||
|
||||
// But we want to include it in payloads.
|
||||
do_check_true(m.shouldIncludeField(testField));
|
||||
|
||||
// And we do so.
|
||||
let data = yield provider.storage.getMeasurementValues(m.id);
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let formatted = serializer.daily(data.days.getDay(now));
|
||||
do_check_true(testField in formatted);
|
||||
do_check_eq(formatted[testField], 1);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function* test_default_search_engine() {
|
||||
let storage = yield Metrics.Storage("default_search_engine");
|
||||
let provider = new SearchesProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
let m = provider.getMeasurement("engines", 2);
|
||||
|
||||
let now = new Date();
|
||||
yield provider.collectDailyData();
|
||||
let data = yield m.getValues();
|
||||
Assert.ok(data.days.hasDay(now));
|
||||
|
||||
let day = data.days.getDay(now);
|
||||
Assert.equal(day.size, 1);
|
||||
Assert.ok(day.has("default"));
|
||||
|
||||
// test environment doesn't have a default engine.
|
||||
Assert.equal(day.get("default"), "NONE");
|
||||
|
||||
Services.search.addEngineWithDetails("testdefault",
|
||||
"http://localhost/icon.png",
|
||||
null,
|
||||
"test description",
|
||||
"GET",
|
||||
"http://localhost/search/%s");
|
||||
let engine1 = Services.search.getEngineByName("testdefault");
|
||||
Assert.ok(engine1);
|
||||
Services.search.defaultEngine = engine1;
|
||||
|
||||
yield provider.collectDailyData();
|
||||
data = yield m.getValues();
|
||||
Assert.equal(data.days.getDay(now).get("default"), "other-testdefault");
|
||||
|
||||
// If no cohort identifier is set, we shouldn't report a cohort.
|
||||
Assert.equal(data.days.getDay(now).get("cohort"), undefined);
|
||||
|
||||
// Set a cohort identifier and verify we record it.
|
||||
Services.prefs.setCharPref("browser.search.cohort", "testcohort");
|
||||
yield provider.collectDailyData();
|
||||
data = yield m.getValues();
|
||||
Assert.equal(data.days.getDay(now).get("cohort"), "testcohort");
|
||||
|
||||
yield storage.close();
|
||||
});
|
@ -1,217 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {utils: Cu} = Components;
|
||||
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/services-common/utils.js");
|
||||
Cu.import("resource://gre/modules/SessionRecorder.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new SessionsProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function test_init() {
|
||||
let storage = yield Metrics.Storage("init");
|
||||
let provider = new SessionsProvider();
|
||||
yield provider.init(storage);
|
||||
yield provider.shutdown();
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
function monkeypatchStartupInfo(recorder, start=new Date(), offset=500) {
|
||||
Object.defineProperty(recorder, "_getStartupInfo", {
|
||||
value: function _getStartupInfo() {
|
||||
return {
|
||||
process: start,
|
||||
main: new Date(start.getTime() + offset),
|
||||
firstPaint: new Date(start.getTime() + 2 * offset),
|
||||
sessionRestored: new Date(start.getTime() + 3 * offset),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sleep(wait) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let timer = CommonUtils.namedTimer(function onTimer() {
|
||||
deferred.resolve();
|
||||
}, wait, deferred.promise, "_sleepTimer");
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function getProvider(name, now=new Date(), init=true) {
|
||||
return Task.spawn(function () {
|
||||
let storage = yield Metrics.Storage(name);
|
||||
let provider = new SessionsProvider();
|
||||
|
||||
let recorder = new SessionRecorder("testing." + name + ".sessions.");
|
||||
monkeypatchStartupInfo(recorder, now);
|
||||
provider.healthReporter = {sessionRecorder: recorder};
|
||||
recorder.onStartup();
|
||||
|
||||
if (init) {
|
||||
yield provider.init(storage);
|
||||
}
|
||||
|
||||
throw new Task.Result([provider, storage, recorder]);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function test_current_session() {
|
||||
let now = new Date();
|
||||
let [provider, storage, recorder] = yield getProvider("current_session", now);
|
||||
|
||||
yield sleep(25);
|
||||
recorder.onActivity(true);
|
||||
|
||||
let current = provider.getMeasurement("current", 3);
|
||||
let values = yield current.getValues();
|
||||
let fields = values.singular;
|
||||
|
||||
for (let field of ["startDay", "activeTicks", "totalTime", "main", "firstPaint", "sessionRestored"]) {
|
||||
do_check_true(fields.has(field));
|
||||
}
|
||||
|
||||
do_check_eq(fields.get("startDay")[1], Metrics.dateToDays(now));
|
||||
do_check_eq(fields.get("totalTime")[1], recorder.totalTime);
|
||||
do_check_eq(fields.get("activeTicks")[1], 1);
|
||||
do_check_eq(fields.get("main")[1], 500);
|
||||
do_check_eq(fields.get("firstPaint")[1], 1000);
|
||||
do_check_eq(fields.get("sessionRestored")[1], 1500);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_collect() {
|
||||
let now = new Date();
|
||||
let [provider, storage, recorder] = yield getProvider("collect");
|
||||
|
||||
recorder.onShutdown();
|
||||
yield sleep(25);
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
let recorder2 = new SessionRecorder("testing.collect.sessions.");
|
||||
recorder2.onStartup();
|
||||
yield sleep(25);
|
||||
recorder2.onShutdown();
|
||||
yield sleep(25);
|
||||
}
|
||||
|
||||
recorder = new SessionRecorder("testing.collect.sessions.");
|
||||
recorder.onStartup();
|
||||
|
||||
// Collecting the provider should prune all previous sessions.
|
||||
let sessions = recorder.getPreviousSessions();
|
||||
do_check_eq(Object.keys(sessions).length, 6);
|
||||
yield provider.collectConstantData();
|
||||
sessions = recorder.getPreviousSessions();
|
||||
do_check_eq(Object.keys(sessions).length, 0);
|
||||
|
||||
// And those previous sessions should make it to storage.
|
||||
let daily = provider.getMeasurement("previous", 3);
|
||||
let values = yield daily.getValues();
|
||||
do_check_true(values.days.hasDay(now));
|
||||
do_check_eq(values.days.size, 1);
|
||||
let day = values.days.getDay(now);
|
||||
do_check_eq(day.size, 5);
|
||||
let previousStorageCount = day.get("main").length;
|
||||
|
||||
for (let field of ["cleanActiveTicks", "cleanTotalTime", "main", "firstPaint", "sessionRestored"]) {
|
||||
do_check_true(day.has(field));
|
||||
do_check_true(Array.isArray(day.get(field)));
|
||||
do_check_eq(day.get(field).length, 6);
|
||||
}
|
||||
|
||||
let lastIndex = yield provider.getState("lastSession");
|
||||
do_check_eq(lastIndex, "" + (previousStorageCount - 1)); // 0-indexed
|
||||
|
||||
// Fake an aborted session. If we create a 2nd recorder against the same
|
||||
// prefs branch as a running one, this simulates what would happen if the
|
||||
// first recorder didn't shut down.
|
||||
let recorder2 = new SessionRecorder("testing.collect.sessions.");
|
||||
recorder2.onStartup();
|
||||
do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 1);
|
||||
yield provider.collectConstantData();
|
||||
do_check_eq(Object.keys(recorder.getPreviousSessions()).length, 0);
|
||||
|
||||
values = yield daily.getValues();
|
||||
day = values.days.getDay(now);
|
||||
do_check_eq(day.size, previousStorageCount + 1);
|
||||
previousStorageCount = day.get("main").length;
|
||||
for (let field of ["abortedActiveTicks", "abortedTotalTime"]) {
|
||||
do_check_true(day.has(field));
|
||||
do_check_true(Array.isArray(day.get(field)));
|
||||
do_check_eq(day.get(field).length, 1);
|
||||
}
|
||||
|
||||
lastIndex = yield provider.getState("lastSession");
|
||||
do_check_eq(lastIndex, "" + (previousStorageCount - 1));
|
||||
|
||||
recorder.onShutdown();
|
||||
recorder2.onShutdown();
|
||||
|
||||
// If we try to insert a already-inserted session, it will be ignored.
|
||||
recorder = new SessionRecorder("testing.collect.sessions.");
|
||||
recorder._currentIndex = recorder._currentIndex - 1;
|
||||
recorder._prunedIndex = recorder._currentIndex;
|
||||
recorder.onStartup();
|
||||
// Session is left over from recorder2.
|
||||
sessions = recorder.getPreviousSessions();
|
||||
do_check_eq(Object.keys(sessions).length, 1);
|
||||
do_check_true(previousStorageCount - 1 in sessions);
|
||||
yield provider.collectConstantData();
|
||||
lastIndex = yield provider.getState("lastSession");
|
||||
do_check_eq(lastIndex, "" + (previousStorageCount - 1));
|
||||
values = yield daily.getValues();
|
||||
day = values.days.getDay(now);
|
||||
// We should not get additional entry.
|
||||
do_check_eq(day.get("main").length, previousStorageCount);
|
||||
recorder.onShutdown();
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
||||
add_task(function test_serialization() {
|
||||
let [provider, storage, recorder] = yield getProvider("serialization");
|
||||
|
||||
yield sleep(1025);
|
||||
recorder.onActivity(true);
|
||||
|
||||
let current = provider.getMeasurement("current", 3);
|
||||
let data = yield current.getValues();
|
||||
do_check_true("singular" in data);
|
||||
|
||||
let serializer = current.serializer(current.SERIALIZE_JSON);
|
||||
let fields = serializer.singular(data.singular);
|
||||
|
||||
do_check_eq(fields._v, 3);
|
||||
do_check_eq(fields.activeTicks, 1);
|
||||
do_check_eq(fields.startDay, Metrics.dateToDays(recorder.startDate));
|
||||
do_check_eq(fields.main, 500);
|
||||
do_check_eq(fields.firstPaint, 1000);
|
||||
do_check_eq(fields.sessionRestored, 1500);
|
||||
do_check_true(fields.totalTime > 0);
|
||||
|
||||
yield provider.shutdown();
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var {interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Metrics.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/providers.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let provider = new SysInfoProvider();
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_task(function test_collect_smoketest() {
|
||||
let storage = yield Metrics.Storage("collect_smoketest");
|
||||
let provider = new SysInfoProvider();
|
||||
yield provider.init(storage);
|
||||
|
||||
yield provider.collectConstantData();
|
||||
|
||||
let m = provider.getMeasurement("sysinfo", 2);
|
||||
let data = yield storage.getMeasurementValues(m.id);
|
||||
let serializer = m.serializer(m.SERIALIZE_JSON);
|
||||
let d = serializer.singular(data.singular);
|
||||
|
||||
do_check_eq(d._v, 2);
|
||||
do_check_true(d.cpuCount > 0);
|
||||
do_check_neq(d.name, null);
|
||||
|
||||
yield storage.close();
|
||||
});
|
||||
|
@ -1,19 +0,0 @@
|
||||
[DEFAULT]
|
||||
head = head.js
|
||||
tail =
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
|
||||
[test_load_modules.js]
|
||||
[test_profile.js]
|
||||
[test_provider_addons.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
tags = addons
|
||||
[test_provider_appinfo.js]
|
||||
[test_provider_crashes.js]
|
||||
skip-if = !crashreporter
|
||||
[test_provider_hotfix.js]
|
||||
[test_provider_places.js]
|
||||
[test_provider_searches.js]
|
||||
[test_provider_sysinfo.js]
|
||||
[test_provider_sessions.js]
|
||||
|
@ -12,12 +12,6 @@ DIRS += [
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' or CONFIG['MOZ_B2GDROID']:
|
||||
DIRS += ['fxaccounts']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
|
||||
# MOZ_SERVICES_HEALTHREPORT and therefore MOZ_DATA_REPORTING are
|
||||
# defined on Android, but these features are implemented using Java.
|
||||
if CONFIG['MOZ_SERVICES_HEALTHREPORT']:
|
||||
DIRS += ['healthreport']
|
||||
|
||||
if CONFIG['MOZ_SERVICES_METRICS']:
|
||||
DIRS += ['metrics']
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
.. _healthreport:
|
||||
|
||||
=====================
|
||||
Firefox Health Report
|
||||
=====================
|
||||
================================
|
||||
Firefox Health Report (Obsolete)
|
||||
================================
|
||||
|
||||
``/services/healthreport`` contains the implementation of the
|
||||
``Firefox Health Report`` (FHR).
|
||||
**Firefox Health Report (FHR) is obsolete and no longer ships with Firefox.
|
||||
This documentation will live here for a few more cycles.**
|
||||
|
||||
Firefox Health Report is a background service that collects application
|
||||
metrics and periodically submits them to a central server. The core
|
@ -81,3 +81,4 @@ LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
SPHINX_TREES['telemetry'] = 'docs'
|
||||
SPHINX_TREES['healthreport'] = 'docs/fhr'
|
||||
|
Loading…
Reference in New Issue
Block a user