summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js')
-rw-r--r--toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js291
1 files changed, 291 insertions, 0 deletions
diff --git a/toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js b/toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js
new file mode 100644
index 0000000000..5c67c59fe0
--- /dev/null
+++ b/toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js
@@ -0,0 +1,291 @@
+const { AddonTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/AddonTestUtils.sys.mjs"
+);
+const { getAppInfo } = ChromeUtils.importESModule(
+ "resource://testing-common/AppInfo.sys.mjs"
+);
+const { XPIInstall } = ChromeUtils.import(
+ "resource://gre/modules/addons/XPIInstall.jsm"
+);
+const { PromiseUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/PromiseUtils.sys.mjs"
+);
+const { setTimeout } = ChromeUtils.importESModule(
+ "resource://gre/modules/Timer.sys.mjs"
+);
+const { TelemetryTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TelemetryTestUtils.sys.mjs"
+);
+
+AddonTestUtils.init(this);
+setupTestCommon();
+AddonTestUtils.appInfo = getAppInfo();
+start_httpserver();
+setUpdateURL(gURLData + gHTTPHandlerPath);
+setUpdateChannel("test_channel");
+Services.prefs.setBoolPref(PREF_APP_UPDATE_LANGPACK_ENABLED, true);
+
+/**
+ * Checks for updates and waits for the update to download.
+ */
+async function downloadUpdate() {
+ let patches = getRemotePatchString({});
+ let updateString = getRemoteUpdateString({}, patches);
+ gResponseBody = getRemoteUpdatesXMLString(updateString);
+
+ let { updates } = await waitForUpdateCheck(true);
+
+ initMockIncrementalDownload();
+ gIncrementalDownloadErrorType = 3;
+
+ await waitForUpdateDownload(updates, Cr.NS_OK);
+}
+
+/**
+ * Returns a promise that will resolve when the add-ons manager attempts to
+ * stage langpack updates. The returned object contains the appVersion and
+ * platformVersion parameters as well as resolve and reject functions to
+ * complete the mocked langpack update.
+ */
+function mockLangpackUpdate() {
+ let stagingCall = PromiseUtils.defer();
+ XPIInstall.stageLangpacksForAppUpdate = (appVersion, platformVersion) => {
+ let result = PromiseUtils.defer();
+ stagingCall.resolve({
+ appVersion,
+ platformVersion,
+ resolve: result.resolve,
+ reject: result.reject,
+ });
+
+ return result.promise;
+ };
+
+ return stagingCall.promise;
+}
+
+add_setup(async function () {
+ // Thunderbird doesn't have one or more of the probes used in this test.
+ // Ensure the data is collected anyway.
+ Services.prefs.setBoolPref(
+ "toolkit.telemetry.testing.overrideProductsCheck",
+ true
+ );
+
+ await AddonTestUtils.promiseStartupManager();
+});
+
+add_task(async function testLangpackUpdateSuccess() {
+ let histogram = TelemetryTestUtils.getAndClearHistogram(
+ "UPDATE_LANGPACK_OVERTIME"
+ );
+
+ let updateDownloadNotified = false;
+ let notified = waitForEvent("update-downloaded").then(
+ () => (updateDownloadNotified = true)
+ );
+
+ let stagingCall = mockLangpackUpdate();
+
+ await downloadUpdate();
+
+ // We have to wait for UpdateService's onStopRequest to run far enough that
+ // the notification will have been sent if the language pack update completed.
+ await TestUtils.waitForCondition(() => readStatusFile() == "pending");
+
+ Assert.ok(
+ !updateDownloadNotified,
+ "Should not have seen the notification yet."
+ );
+
+ let { appVersion, platformVersion, resolve } = await stagingCall;
+ Assert.equal(
+ appVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right app version"
+ );
+ Assert.equal(
+ platformVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right platform version"
+ );
+
+ resolve();
+
+ await notified;
+
+ // Because we resolved the lang pack call after the download completed a value
+ // should have been recorded in telemetry.
+ let snapshot = histogram.snapshot();
+ Assert.ok(
+ !Object.values(snapshot.values).every(val => val == 0),
+ "Should have recorded a time"
+ );
+
+ // Reload the update manager so that we can download the same update again
+ reloadUpdateManagerData(true);
+});
+
+add_task(async function testLangpackUpdateFails() {
+ let updateDownloadNotified = false;
+ let notified = waitForEvent("update-downloaded").then(
+ () => (updateDownloadNotified = true)
+ );
+
+ let stagingCall = mockLangpackUpdate();
+
+ await downloadUpdate();
+
+ // We have to wait for UpdateService's onStopRequest to run far enough that
+ // the notification will have been sent if the language pack update completed.
+ await TestUtils.waitForCondition(() => readStatusFile() == "pending");
+
+ Assert.ok(
+ !updateDownloadNotified,
+ "Should not have seen the notification yet."
+ );
+
+ let { appVersion, platformVersion, reject } = await stagingCall;
+ Assert.equal(
+ appVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right app version"
+ );
+ Assert.equal(
+ platformVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right platform version"
+ );
+
+ reject();
+
+ await notified;
+
+ // Reload the update manager so that we can download the same update again
+ reloadUpdateManagerData(true);
+});
+
+add_task(async function testLangpackStaged() {
+ let updateStagedNotified = false;
+ let notified = waitForEvent("update-staged").then(
+ () => (updateStagedNotified = true)
+ );
+
+ let stagingCall = mockLangpackUpdate();
+
+ Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
+ copyTestUpdaterToBinDir();
+
+ let greDir = getGREDir();
+ let updateSettingsIni = greDir.clone();
+ updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
+ writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
+
+ await downloadUpdate();
+
+ // We have to wait for the update to be applied and then check that the
+ // notification hasn't been sent.
+ await TestUtils.waitForCondition(() => readStatusFile() == "applied");
+
+ Assert.ok(
+ !updateStagedNotified,
+ "Should not have seen the notification yet."
+ );
+
+ let { appVersion, platformVersion, resolve } = await stagingCall;
+ Assert.equal(
+ appVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right app version"
+ );
+ Assert.equal(
+ platformVersion,
+ DEFAULT_UPDATE_VERSION,
+ "Should see the right platform version"
+ );
+
+ resolve();
+
+ await notified;
+
+ // Reload the update manager so that we can download the same update again
+ reloadUpdateManagerData(true);
+});
+
+add_task(async function testRedownload() {
+ // When the download of a partial mar fails the same downloader is re-used to
+ // download the complete mar. We should only call the add-ons manager to stage
+ // language packs once in this case.
+ Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
+ let histogram = TelemetryTestUtils.getAndClearHistogram(
+ "UPDATE_LANGPACK_OVERTIME"
+ );
+
+ let partialPatch = getRemotePatchString({
+ type: "partial",
+ url: gURLData + "missing.mar",
+ size: 28,
+ });
+ let completePatch = getRemotePatchString({});
+ let updateString = getRemoteUpdateString({}, partialPatch + completePatch);
+ gResponseBody = getRemoteUpdatesXMLString(updateString);
+
+ let { updates } = await waitForUpdateCheck(true);
+
+ initMockIncrementalDownload();
+ gIncrementalDownloadErrorType = 3;
+
+ let stageCount = 0;
+ XPIInstall.stageLangpacksForAppUpdate = () => {
+ stageCount++;
+ return Promise.resolve();
+ };
+
+ let downloadCount = 0;
+ let listener = {
+ onStartRequest: aRequest => {},
+ onProgress: (aRequest, aContext, aProgress, aMaxProgress) => {},
+ onStatus: (aRequest, aStatus, aStatusText) => {},
+ onStopRequest: (request, status) => {
+ Assert.equal(
+ status,
+ downloadCount ? 0 : Cr.NS_ERROR_CORRUPTED_CONTENT,
+ "Should have seen the right status."
+ );
+ downloadCount++;
+
+ // Keep the same status.
+ gIncrementalDownloadErrorType = 3;
+ },
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIRequestObserver",
+ "nsIProgressEventSink",
+ ]),
+ };
+ gAUS.addDownloadListener(listener);
+
+ let bestUpdate = gAUS.selectUpdate(updates);
+ await gAUS.downloadUpdate(bestUpdate, false);
+
+ await waitForEvent("update-downloaded");
+
+ gAUS.removeDownloadListener(listener);
+
+ Assert.equal(downloadCount, 2, "Should have seen two downloads");
+ Assert.equal(stageCount, 1, "Should have only tried to stage langpacks once");
+
+ // Because we resolved the lang pack call before the download completed a value
+ // should not have been recorded in telemetry.
+ let snapshot = histogram.snapshot();
+ Assert.ok(
+ Object.values(snapshot.values).every(val => val == 0),
+ "Should have recorded a time"
+ );
+
+ // Reload the update manager so that we can download the same update again
+ reloadUpdateManagerData(true);
+});
+
+add_task(async function finish() {
+ stop_httpserver(doTestFinish);
+});