Bug 850450 - Longitudinal recording of build ID in FHR; r=rnewman

This commit is contained in:
Gregory Szorc 2013-03-19 13:03:24 -07:00
parent e48b8f37d4
commit 688748fa54
2 changed files with 129 additions and 22 deletions

View File

@ -120,11 +120,11 @@ AppInfoMeasurement1.prototype = Object.freeze({
});
function AppVersionMeasurement() {
function AppVersionMeasurement1() {
Metrics.Measurement.call(this);
}
AppVersionMeasurement.prototype = Object.freeze({
AppVersionMeasurement1.prototype = Object.freeze({
__proto__: Metrics.Measurement.prototype,
name: "versions",
@ -135,6 +135,24 @@ AppVersionMeasurement.prototype = Object.freeze({
},
});
// Version 2 added the build ID.
function AppVersionMeasurement2() {
Metrics.Measurement.call(this);
}
AppVersionMeasurement2.prototype = Object.freeze({
__proto__: Metrics.Measurement.prototype,
name: "versions",
version: 2,
fields: {
appVersion: {type: Metrics.Storage.FIELD_DAILY_DISCRETE_TEXT},
platformVersion: {type: Metrics.Storage.FIELD_DAILY_DISCRETE_TEXT},
appBuildID: {type: Metrics.Storage.FIELD_DAILY_DISCRETE_TEXT},
platformBuildID: {type: Metrics.Storage.FIELD_DAILY_DISCRETE_TEXT},
},
});
this.AppInfoProvider = function AppInfoProvider() {
@ -150,7 +168,8 @@ AppInfoProvider.prototype = Object.freeze({
measurementTypes: [
AppInfoMeasurement,
AppInfoMeasurement1,
AppVersionMeasurement,
AppVersionMeasurement1,
AppVersionMeasurement2,
],
pullOnly: true,
@ -175,6 +194,13 @@ AppInfoProvider.prototype = Object.freeze({
},
_onInit: function () {
let recordEmptyAppInfo = function () {
this._setCurrentAppVersion("");
this._setCurrentPlatformVersion("");
this._setCurrentAppBuildID("");
return this._setCurrentPlatformBuildID("");
}.bind(this);
// Services.appInfo should always be defined for any reasonably behaving
// Gecko app. If it isn't, we insert a empty string sentinel value.
let ai;
@ -183,33 +209,75 @@ AppInfoProvider.prototype = Object.freeze({
} catch (ex) {
this._log.error("Could not obtain Services.appinfo: " +
CommonUtils.exceptionStr(ex));
yield this._setCurrentVersion("");
yield recordEmptyAppInfo();
return;
}
if (!ai) {
this._log.error("Services.appinfo is unavailable.");
yield this._setCurrentVersion("");
yield recordEmptyAppInfo();
return;
}
let currentVersion = ai.version;
let lastVersion = yield this.getState("lastVersion");
let currentAppVersion = ai.version;
let currentPlatformVersion = ai.platformVersion;
let currentAppBuildID = ai.appBuildID;
let currentPlatformBuildID = ai.platformBuildID;
if (currentVersion == lastVersion) {
return;
// State's name doesn't contain "app" for historical compatibility.
let lastAppVersion = yield this.getState("lastVersion");
let lastPlatformVersion = yield this.getState("lastPlatformVersion");
let lastAppBuildID = yield this.getState("lastAppBuildID");
let lastPlatformBuildID = yield this.getState("lastPlatformBuildID");
if (currentAppVersion != lastAppVersion) {
yield this._setCurrentAppVersion(currentAppVersion);
}
yield this._setCurrentVersion(currentVersion);
if (currentPlatformVersion != lastPlatformVersion) {
yield this._setCurrentPlatformVersion(currentPlatformVersion);
}
if (currentAppBuildID != lastAppBuildID) {
yield this._setCurrentAppBuildID(currentAppBuildID);
}
if (currentPlatformBuildID != lastPlatformBuildID) {
yield this._setCurrentPlatformBuildID(currentPlatformBuildID);
}
},
_setCurrentVersion: function (version) {
_setCurrentAppVersion: function (version) {
this._log.info("Recording new application version: " + version);
let m = this.getMeasurement("versions", 1);
m.addDailyDiscreteText("version", version);
let m = this.getMeasurement("versions", 2);
m.addDailyDiscreteText("appVersion", version);
// "app" not encoded in key for historical compatibility.
return this.setState("lastVersion", version);
},
_setCurrentPlatformVersion: function (version) {
this._log.info("Recording new platform version: " + version);
let m = this.getMeasurement("versions", 2);
m.addDailyDiscreteText("platformVersion", version);
return this.setState("lastPlatformVersion", version);
},
_setCurrentAppBuildID: function (build) {
this._log.info("Recording new application build ID: " + build);
let m = this.getMeasurement("versions", 2);
m.addDailyDiscreteText("appBuildID", build);
return this.setState("lastAppBuildID", build);
},
_setCurrentPlatformBuildID: function (build) {
this._log.info("Recording new platform build ID: " + build);
let m = this.getMeasurement("versions", 2);
m.addDailyDiscreteText("platformBuildID", build);
return this.setState("lastPlatformBuildID", build);
},
collectConstantData: function () {
return this.enqueueStorageOperation(function collect() {
return Task.spawn(this._populateConstants.bind(this));

View File

@ -70,18 +70,37 @@ add_task(function test_record_version() {
yield provider.init(storage);
// The provider records information on startup.
let m = provider.getMeasurement("versions", 1);
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, 1);
do_check_true(day.has("version"));
let value = day.get("version");
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, ai.version);
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();
@ -96,21 +115,41 @@ add_task(function test_record_version_change() {
yield provider.shutdown();
let ai = getAppInfo();
ai.version = "2";
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", 1);
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("version");
let value = day.get("appVersion");
do_check_true(Array.isArray(value));
do_check_eq(value.length, 2);
do_check_eq(value[1], "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();