From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../tests/unit_aus_update/languagePackUpdates.js | 291 +++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js (limited to 'toolkit/mozapps/update/tests/unit_aus_update/languagePackUpdates.js') 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); +}); -- cgit v1.2.3