From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../update/tests/unit_base_updater/head_update.js | 7 + ...invalidArgCallbackFileNotInInstallDirFailure.js | 32 ++++ .../invalidArgCallbackFilePathTooLongFailure.js | 39 +++++ .../invalidArgInstallDirPathTooLongFailure.js | 53 ++++++ .../invalidArgInstallDirPathTraversalFailure.js | 50 ++++++ ...idArgInstallWorkingDirPathNotSameFailure_win.js | 45 +++++ .../invalidArgPatchDirPathTraversalFailure.js | 32 ++++ ...invalidArgStageDirNotInInstallDirFailure_win.js | 45 +++++ .../invalidArgWorkingDirPathLocalUNCFailure_win.js | 45 +++++ .../invalidArgWorkingDirPathRelativeFailure.js | 44 +++++ .../marAppApplyDirLockedStageFailure_win.js | 29 ++++ ...marAppApplyUpdateAppBinInUseStageSuccess_win.js | 50 ++++++ .../marAppApplyUpdateSkippedWriteAccess_win.js | 74 +++++++++ .../marAppApplyUpdateStageOldVersionFailure.js | 64 ++++++++ .../marAppApplyUpdateStageSuccess.js | 49 ++++++ .../unit_base_updater/marAppApplyUpdateSuccess.js | 47 ++++++ .../marAppInUseBackgroundTaskFailure_win.js | 51 ++++++ .../marAppInUseStageFailureComplete_win.js | 37 +++++ .../marAppInUseStageSuccessComplete_unix.js | 68 ++++++++ .../marAppInUseSuccessComplete.js | 26 +++ .../marCallbackAppStageSuccessComplete_win.js | 30 ++++ .../marCallbackAppStageSuccessPartial_win.js | 30 ++++ .../marCallbackAppSuccessComplete_win.js | 24 +++ .../marCallbackAppSuccessPartial_win.js | 24 +++ .../unit_base_updater/marCallbackUmask_unix.js | 42 +++++ .../tests/unit_base_updater/marFailurePartial.js | 39 +++++ .../marFileInUseStageFailureComplete_win.js | 40 +++++ .../marFileInUseStageFailurePartial_win.js | 40 +++++ .../marFileInUseSuccessComplete_win.js | 29 ++++ .../marFileInUseSuccessPartial_win.js | 29 ++++ .../marFileLockedFailureComplete_win.js | 27 +++ .../marFileLockedFailurePartial_win.js | 26 +++ .../marFileLockedStageFailureComplete_win.js | 34 ++++ .../marFileLockedStageFailurePartial_win.js | 33 ++++ .../unit_base_updater/marMissingUpdateSettings.js | 42 +++++ .../marMissingUpdateSettingsStage.js | 35 ++++ .../marPIDPersistsSuccessComplete_win.js | 25 +++ .../marRMRFDirFileInUseStageFailureComplete_win.js | 43 +++++ .../marRMRFDirFileInUseStageFailurePartial_win.js | 41 +++++ .../marRMRFDirFileInUseSuccessComplete_win.js | 31 ++++ .../marRMRFDirFileInUseSuccessPartial_win.js | 29 ++++ .../unit_base_updater/marStageFailurePartial.js | 31 ++++ .../unit_base_updater/marStageSuccessComplete.js | 71 ++++++++ .../unit_base_updater/marStageSuccessPartial.js | 35 ++++ .../tests/unit_base_updater/marSuccessComplete.js | 26 +++ .../tests/unit_base_updater/marSuccessPartial.js | 29 ++++ .../marSuccessPartialWhileBackgroundTaskRunning.js | 121 ++++++++++++++ .../tests/unit_base_updater/marVersionDowngrade.js | 41 +++++ .../tests/unit_base_updater/marWrongChannel.js | 43 +++++ .../unit_base_updater/marWrongChannelStage.js | 36 ++++ .../update/tests/unit_base_updater/xpcshell.toml | 181 +++++++++++++++++++++ 51 files changed, 2194 insertions(+) create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/head_update.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSkippedWriteAccess_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppInUseBackgroundTaskFailure_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marCallbackUmask_unix.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettings.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartialWhileBackgroundTaskRunning.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js create mode 100644 toolkit/mozapps/update/tests/unit_base_updater/xpcshell.toml (limited to 'toolkit/mozapps/update/tests/unit_base_updater') diff --git a/toolkit/mozapps/update/tests/unit_base_updater/head_update.js b/toolkit/mozapps/update/tests/unit_base_updater/head_update.js new file mode 100644 index 0000000000..1ab1a70a0b --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/head_update.js @@ -0,0 +1,7 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* import-globals-from ../data/xpcshellUtilsAUS.js */ +load("xpcshellUtilsAUS.js"); +gIsServiceTest = false; diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js new file mode 100644 index 0000000000..cc61a75dd7 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js @@ -0,0 +1,32 @@ +/* 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/. + */ + +/* Callback file not in install directory or a sub-directory of the install + directory failure */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_DIR_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = getTestDirFile(FILE_HELPER_BIN).path; + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, null, path); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_CALLBACK_DIR_ERROR, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js new file mode 100644 index 0000000000..0b432e2e15 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js @@ -0,0 +1,39 @@ +/* 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/. + */ + +/* Too long callback file path failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_PATH_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = "123456789"; + if (AppConstants.platform == "win") { + path = "\\" + path; + path = path.repeat(30); // 300 characters + path = "C:" + path; + } else { + path = "/" + path; + path = path.repeat(1000); // 10000 characters + } + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, null, path); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_CALLBACK_PATH_ERROR, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js new file mode 100644 index 0000000000..c2746e2bd1 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js @@ -0,0 +1,53 @@ +/* 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/. + */ + +/* Too long install directory path failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR + : STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = "123456789"; + if (AppConstants.platform == "win") { + path = "\\" + path; + path = path.repeat(30); // 300 characters + path = "C:" + path; + } else { + path = "/" + path; + path = path.repeat(1000); // 10000 characters + } + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_INSTALL_DIR_PATH_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js new file mode 100644 index 0000000000..b611fac972 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js @@ -0,0 +1,50 @@ +/* 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/. + */ + +/* Install directory path traversal failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR + : STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = "123456789"; + if (AppConstants.platform == "win") { + path = "C:\\" + path + "\\..\\" + path; + } else { + path = "/" + path + "/../" + path; + } + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_INSTALL_DIR_PATH_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js new file mode 100644 index 0000000000..0506d100fd --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js @@ -0,0 +1,45 @@ +/* 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/. + */ + +/* Different install and working directories for a regular update failure */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_ERROR + : STATE_FAILED_INVALID_APPLYTO_DIR_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = getApplyDirFile("..", false).path; + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_APPLYTO_DIR_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js new file mode 100644 index 0000000000..cf053e3ff5 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js @@ -0,0 +1,32 @@ +/* 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/. + */ + +/* Patch directory path traversal failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = getUpdateDirFile(DIR_PATCH); + if (AppConstants.platform == "win") { + path = path + "\\..\\"; + } else { + path = path + "/../"; + } + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, path, null, null, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js new file mode 100644 index 0000000000..4624179bfd --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js @@ -0,0 +1,45 @@ +/* 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/. + */ + +/* Different install and working directories for a regular update failure */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR + : STATE_FAILED_INVALID_APPLYTO_DIR_STAGED_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = getApplyDirFile("..", false).path; + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true, null, null, path, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_APPLYTO_DIR_STAGED_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js new file mode 100644 index 0000000000..7c0af26e37 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js @@ -0,0 +1,45 @@ +/* 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/. + */ + +/* Working directory path local UNC failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR + : STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + let path = "\\\\.\\" + getApplyDirFile(null, false).path; + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_WORKING_DIR_PATH_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js new file mode 100644 index 0000000000..cfbd9eaec9 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js @@ -0,0 +1,44 @@ +/* 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/. + */ + +/* Relative working directory path failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR + : STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, "test", null); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + if (gIsServiceTest) { + // The invalid argument service tests launch the maintenance service + // directly so the unelevated updater doesn't handle the invalid argument. + // By doing this it is possible to test that the maintenance service + // properly handles the invalid argument but since the updater isn't used to + // launch the maintenance service the update.status file isn't copied from + // the secure log directory to the patch directory and the update manager + // won't read the failure from the update.status file. + checkUpdateManager(STATE_NONE, false, STATE_PENDING_SVC, 0, 1); + } else { + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + INVALID_WORKING_DIR_PATH_ERROR, + 1 + ); + } + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js new file mode 100644 index 0000000000..a845cb70c5 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + createUpdateInProgressLockFile(getGREBinDir()); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, false); + removeUpdateInProgressLockFile(getGREBinDir()); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(PERFORMING_STAGED_UPDATE); + checkUpdateLogContains(ERR_UPDATE_IN_PROGRESS); + await waitForUpdateXMLFiles(true, false); + checkUpdateManager(STATE_AFTER_STAGE, true, STATE_AFTER_STAGE, 0, 0); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js new file mode 100644 index 0000000000..319aee8e34 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js @@ -0,0 +1,50 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true, false); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + lockDirectory(getGREBinDir().path); + // Switch the application to the staged application that was updated. + await runUpdateUsingApp(STATE_SUCCEEDED); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + + let updatesDir = getUpdateDirFile(DIR_PATCH); + Assert.ok( + updatesDir.exists(), + MSG_SHOULD_EXIST + getMsgPath(updatesDir.path) + ); + + let log = getUpdateDirFile(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_LAST_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSkippedWriteAccess_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSkippedWriteAccess_win.js new file mode 100644 index 0000000000..aa1336b7ed --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSkippedWriteAccess_win.js @@ -0,0 +1,74 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test an update isn't attempted when the update.status file can't be written + * to. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + + // To simulate a user that doesn't have write access to the update directory + // lock the relevant files in the update directory. + let filesToLock = [ + FILE_ACTIVE_UPDATE_XML, + FILE_UPDATE_MAR, + FILE_UPDATE_STATUS, + FILE_UPDATE_TEST, + FILE_UPDATE_VERSION, + ]; + filesToLock.forEach(function (aFileLeafName) { + let file = getUpdateDirFile(aFileLeafName); + if (!file.exists()) { + file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o444); + } + file.QueryInterface(Ci.nsILocalFileWin); + file.readOnly = true; + Assert.ok(file.exists(), MSG_SHOULD_EXIST + getMsgPath(file.path)); + Assert.ok(!file.isWritable(), "the file should not be writeable"); + }); + + registerCleanupFunction(() => { + filesToLock.forEach(function (aFileLeafName) { + let file = getUpdateDirFile(aFileLeafName); + if (file.exists()) { + file.QueryInterface(Ci.nsILocalFileWin); + file.readOnly = false; + file.remove(false); + } + }); + }); + + // Reload the update manager now that the update directory files are locked. + reloadUpdateManagerData(); + await runUpdateUsingApp(STATE_PENDING); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateManager(STATE_PENDING, false, STATE_NONE, 0, 0); + + let dir = getUpdateDirFile(DIR_PATCH); + Assert.ok(dir.exists(), MSG_SHOULD_EXIST + getMsgPath(dir.path)); + + let file = getUpdateDirFile(FILE_UPDATES_XML); + Assert.ok(!file.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(file.path)); + + file = getUpdateDirFile(FILE_UPDATE_LOG); + Assert.ok(!file.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(file.path)); + + file = getUpdateDirFile(FILE_LAST_UPDATE_LOG); + Assert.ok(!file.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(file.path)); + + file = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG); + Assert.ok(!file.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(file.path)); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js new file mode 100644 index 0000000000..3dfad0f58e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js @@ -0,0 +1,64 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test a replace request for a staged update with a version file that specifies + * an older version failure. The same check is used in nsUpdateDriver.cpp for + * all update types which is why there aren't tests for the maintenance service + * as well as for other update types. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, null, "", false); + let patchProps = { state: STATE_AFTER_STAGE }; + let patches = getLocalPatchString(patchProps); + let updateProps = { appVersion: "0.9" }; + let updates = getLocalUpdateString(updateProps, patches); + writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true); + getUpdateDirFile(FILE_UPDATE_LOG).create( + Ci.nsIFile.NORMAL_FILE_TYPE, + PERMS_FILE + ); + writeStatusFile(STATE_AFTER_STAGE); + // Create the version file with an older version to simulate installing a new + // version of the application while there is an update that has been staged. + writeVersionFile("0.9"); + // Try to switch the application to the fake staged application. + await runUpdateUsingApp(STATE_AFTER_STAGE); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + ERR_OLDER_VERSION_OR_SAME_BUILD, + 1 + ); + + let updatesDir = getUpdateDirFile(DIR_PATCH); + Assert.ok( + updatesDir.exists(), + MSG_SHOULD_EXIST + getMsgPath(updatesDir.path) + ); + + let log = getUpdateDirFile(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_LAST_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js new file mode 100644 index 0000000000..34b47866b1 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by staging an update and launching an application to + * apply it. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, true); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + await runUpdateUsingApp(STATE_SUCCEEDED); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + + let updatesDir = getUpdateDirFile(DIR_PATCH); + Assert.ok( + updatesDir.exists(), + MSG_SHOULD_EXIST + getMsgPath(updatesDir.path) + ); + + let log = getUpdateDirFile(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_LAST_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js new file mode 100644 index 0000000000..980b0cb89a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/** + * Test applying an update by launching an application to apply it. + */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + // The third parameter will test that a full path to the post update binary + // doesn't execute. + await setupUpdaterTest( + FILE_COMPLETE_MAR, + undefined, + getApplyDirFile(null, true).path + "/" + ); + await runUpdateUsingApp(STATE_SUCCEEDED); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + + let updatesDir = getUpdateDirFile(DIR_PATCH); + Assert.ok( + updatesDir.exists(), + MSG_SHOULD_EXIST + getMsgPath(updatesDir.path) + ); + + let log = getUpdateDirFile(FILE_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_LAST_UPDATE_LOG); + Assert.ok(log.exists(), MSG_SHOULD_EXIST + getMsgPath(log.path)); + + log = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG); + Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST + getMsgPath(log.path)); + + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseBackgroundTaskFailure_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseBackgroundTaskFailure_win.js new file mode 100644 index 0000000000..bcb24bee94 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseBackgroundTaskFailure_win.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Fail to apply a complete MAR when the application is in use and the callback is a background task. */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + + // Add a dummy --backgroundtask arg; this will have no effect on the + // callback (TestAUSHelper) but will cause the updater to detect + // that this is a background task. + gCallbackArgs = gCallbackArgs.concat(["--backgroundtask", "not_found"]); + + // Run the update with the helper file in use, expecting failure. + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false); + runUpdate( + STATE_FAILED_WRITE_ERROR_BACKGROUND_TASK_SHARING_VIOLATION, + false, // aSwitchApp + 1, // aExpectedExitValue + true // aCheckSvcLog + ); + await waitForHelperExit(); + + standardInit(); + + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_BGTASK_EXCLUSIVE); + + // Check that the update was reset to "pending". + await waitForUpdateXMLFiles( + true, // aActiveUpdateExists + false // aUpdatesExists + ); + checkUpdateManager( + STATE_PENDING, // aStatusFileState + true, // aHasActiveUpdate + STATE_PENDING, // aUpdateStatusState + WRITE_ERROR_BACKGROUND_TASK_SHARING_VIOLATION, + 0 // aUpdateCount + ); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js new file mode 100644 index 0000000000..502561ed1e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file staged patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains( + ERR_MOVE_DESTDIR_7 + "\n" + STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT + ); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js new file mode 100644 index 0000000000..29c2c2a30e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js @@ -0,0 +1,68 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file staged patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, true); + setupSymLinks(); + await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_SUCCEEDED, true, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + checkSymLinks(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} + +/** + * Setup symlinks for the test. + */ +function setupSymLinks() { + if (AppConstants.platform == "macosx" || AppConstants.platform == "linux") { + removeSymlink(); + createSymlink(); + registerCleanupFunction(removeSymlink); + gTestFiles.splice(gTestFiles.length - 3, 0, { + description: "Readable symlink", + fileName: "link", + relPathDir: DIR_RESOURCES, + originalContents: "test", + compareContents: "test", + originalFile: null, + compareFile: null, + originalPerms: 0o666, + comparePerms: 0o666, + }); + } +} + +/** + * Checks the state of the symlinks for the test. + */ +function checkSymLinks() { + if (AppConstants.platform == "macosx" || AppConstants.platform == "linux") { + checkSymlink(); + } +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js new file mode 100644 index 0000000000..e08777d042 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js new file mode 100644 index 0000000000..2f8155c790 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Replace app binary complete MAR file staged patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + gCallbackBinFile = "exe0.exe"; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_SUCCEEDED, true, 0, true); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js new file mode 100644 index 0000000000..04c72896b4 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Patch app binary partial MAR file staged patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + gCallbackBinFile = "exe0.exe"; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_SUCCEEDED, true, 0, true); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js new file mode 100644 index 0000000000..fa13f07f46 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js @@ -0,0 +1,24 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Replace app binary complete MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + gCallbackBinFile = "exe0.exe"; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js new file mode 100644 index 0000000000..e74509c06e --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js @@ -0,0 +1,24 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Patch app binary partial MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + gCallbackBinFile = "exe0.exe"; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackUmask_unix.js b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackUmask_unix.js new file mode 100644 index 0000000000..be3b3707b4 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackUmask_unix.js @@ -0,0 +1,42 @@ +/* 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/. + */ + +/* Verify that app callback is launched with the same umask as was set + * before applying an update. */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + preventDistributionFiles(); + + // Our callback is `TestAUSHelper check-umask `. + // Including the umask from before updating as an argument allows to re-use + // the callback log checking code below. The argument is also used as the log + // file name, so we prefix it with "umask" so that it doesn't clash with + // numericfile and directory names in the update data. In particular, "2" + // clashes with an existing directory name in the update data, leading to + // failing tests. + let umask = Services.sysinfo.getProperty("umask"); + gCallbackArgs = ["check-umask", `umask-${umask}`]; + + await setupUpdaterTest(FILE_COMPLETE_MAR, true); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, false, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + + // This compares the callback arguments given, including the umask before + // updating, to the umask set when the app callback is launched. They should + // be the same. + checkCallbackLog(getApplyDirFile(DIR_RESOURCES + "callback_app.log")); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js b/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js new file mode 100644 index 0000000000..de8db067bc --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js @@ -0,0 +1,39 @@ +/* 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/. + */ + +/* General Partial MAR File Patch Apply Failure Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[11].originalFile = "partial.png"; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + // If execv is used the updater process will turn into the callback process + // and the updater's return code will be that of the callback process. + runUpdate( + STATE_FAILED_LOADSOURCE_ERROR_WRONG_SIZE, + false, + USE_EXECV ? 0 : 1, + true + ); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContents(LOG_PARTIAL_FAILURE); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + LOADSOURCE_ERROR_WRONG_SIZE, + 1 + ); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js new file mode 100644 index 0000000000..b93b023934 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js @@ -0,0 +1,40 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use complete MAR file staged patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse( + gTestFiles[13].relPathDir + gTestFiles[13].fileName, + false + ); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains( + ERR_MOVE_DESTDIR_7 + "\n" + STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT + ); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js new file mode 100644 index 0000000000..b41da12396 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js @@ -0,0 +1,40 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use partial MAR file staged patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperFileInUse( + gTestFiles[11].relPathDir + gTestFiles[11].fileName, + false + ); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains( + ERR_MOVE_DESTDIR_7 + "\n" + STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT + ); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js new file mode 100644 index 0000000000..4b946ac3e4 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use complete MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse( + gTestFiles[13].relPathDir + gTestFiles[13].fileName, + false + ); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js new file mode 100644 index 0000000000..15c3a1121a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use partial MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperFileInUse( + gTestFiles[11].relPathDir + gTestFiles[11].fileName, + false + ); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js new file mode 100644 index 0000000000..698ccb7fe5 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked complete MAR file patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperLockFile(gTestFiles[3]); + runUpdate(STATE_FAILED_WRITE_ERROR, false, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_BACKUP_CREATE_7); + checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(true, false); + checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js new file mode 100644 index 0000000000..c8c019ec5c --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked partial MAR file patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperLockFile(gTestFiles[2]); + runUpdate(STATE_FAILED_READ_ERROR, false, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_UNABLE_OPEN_DEST); + checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js new file mode 100644 index 0000000000..7b582dbd45 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked complete MAR file staged patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperLockFile(gTestFiles[3]); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + // Files aren't checked after staging since this test locks a file which + // prevents reading the file. + checkUpdateLogContains(ERR_ENSURE_COPY); + // Switch the application to the staged application that was updated. + runUpdate(STATE_FAILED_WRITE_ERROR, false, 1, false); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains(ERR_BACKUP_CREATE_7); + checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(true, false); + checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js new file mode 100644 index 0000000000..bf3abd8c37 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js @@ -0,0 +1,33 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File locked partial MAR file staged patch apply failure test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_PENDING; + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperLockFile(gTestFiles[2]); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + // Files aren't checked after staging since this test locks a file which + // prevents reading the file. + checkUpdateLogContains(ERR_ENSURE_COPY); + // Switch the application to the staged application that was updated. + runUpdate(STATE_FAILED_READ_ERROR, false, 1, false); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_UNABLE_OPEN_DEST); + checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettings.js b/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettings.js new file mode 100644 index 0000000000..b0a0cfe657 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettings.js @@ -0,0 +1,42 @@ +/* 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/. + */ + +/* Test update-settings.ini missing channel MAR security check */ + +async function run_test() { + if (!MOZ_VERIFY_MAR_SIGNATURE) { + return; + } + + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 2].originalContents = null; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + // If execv is used the updater process will turn into the callback process + // and the updater's return code will be that of the callback process. + runUpdate( + STATE_FAILED_UPDATE_SETTINGS_FILE_CHANNEL, + false, + USE_EXECV ? 0 : 1, + false + ); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(STATE_FAILED_UPDATE_SETTINGS_FILE_CHANNEL); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + UPDATE_SETTINGS_FILE_CHANNEL, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js b/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js new file mode 100644 index 0000000000..e26d2aefc3 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js @@ -0,0 +1,35 @@ +/* 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/. + */ + +/* Test update-settings.ini missing channel MAR security check */ + +async function run_test() { + if (!MOZ_VERIFY_MAR_SIGNATURE) { + return; + } + + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_FAILED; + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 2].originalContents = null; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(STATE_FAILED_UPDATE_SETTINGS_FILE_CHANNEL); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + UPDATE_SETTINGS_FILE_CHANNEL, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js new file mode 100644 index 0000000000..4918fea140 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* Application in use complete MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperPIDPersists(DIR_RESOURCES + gCallbackBinFile, false); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContains(ERR_PARENT_PID_PERSISTS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js new file mode 100644 index 0000000000..31c5b8bd7a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir complete MAR file staged patch apply failure + test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse( + gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0] + + gTestDirs[4].subDirFiles[0], + true + ); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains( + ERR_MOVE_DESTDIR_7 + "\n" + STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT + ); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js new file mode 100644 index 0000000000..b57f8c81b7 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js @@ -0,0 +1,41 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir partial MAR file staged patch apply failure + test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + const STATE_AFTER_RUNUPDATE = gIsServiceTest + ? STATE_PENDING_SVC + : STATE_PENDING; + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperFileInUse( + gTestDirs[2].relPathDir + gTestDirs[2].files[0], + true + ); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true); + await waitForHelperExit(); + standardInit(); + checkPostUpdateRunningFile(false); + setTestFilesAndDirsForFailure(); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_RENAME_FILE); + checkUpdateLogContains( + ERR_MOVE_DESTDIR_7 + "\n" + STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT + ); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js new file mode 100644 index 0000000000..0683df0d8d --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js @@ -0,0 +1,31 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir complete MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await runHelperFileInUse( + gTestDirs[4].relPathDir + + gTestDirs[4].subDirs[0] + + gTestDirs[4].subDirFiles[0], + true + ); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js new file mode 100644 index 0000000000..d4da3a5f37 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* File in use inside removed dir partial MAR file patch apply success test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestDirs = gTestDirsPartialSuccess; + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await runHelperFileInUse( + gTestDirs[2].relPathDir + gTestDirs[2].files[0], + true + ); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await waitForHelperExit(); + await checkPostUpdateAppLog(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContains(ERR_BACKUP_DISCARD); + checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js b/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js new file mode 100644 index 0000000000..a1a0de0fe4 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js @@ -0,0 +1,31 @@ +/* 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/. + */ + +/* General Partial MAR File Staged Patch Apply Failure Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_FAILED; + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[11].originalFile = "partial.png"; + gTestDirs = gTestDirsPartialSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_PARTIAL_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(ERR_LOADSOURCEFILE_FAILED); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + LOADSOURCE_ERROR_WRONG_SIZE, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js new file mode 100644 index 0000000000..943a45ba95 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js @@ -0,0 +1,71 @@ +/* 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/. + */ + +/* General Complete MAR File Staged Patch Apply Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestDirs = gTestDirsCompleteSuccess; + setupSymLinks(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_SUCCEEDED, true, 0, true); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + checkSymLinks(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} + +/** + * Setup symlinks for the test. + */ +function setupSymLinks() { + // Don't test symlinks on Mac OS X in this test since it tends to timeout. + // It is tested on Mac OS X in marAppInUseStageSuccessComplete_unix.js + if (AppConstants.platform == "linux") { + removeSymlink(); + createSymlink(); + registerCleanupFunction(removeSymlink); + gTestFiles.splice(gTestFiles.length - 3, 0, { + description: "Readable symlink", + fileName: "link", + relPathDir: DIR_RESOURCES, + originalContents: "test", + compareContents: "test", + originalFile: null, + compareFile: null, + originalPerms: 0o666, + comparePerms: 0o666, + }); + } +} + +/** + * Checks the state of the symlinks for the test. + */ +function checkSymLinks() { + // Don't test symlinks on Mac OS X in this test since it tends to timeout. + // It is tested on Mac OS X in marAppInUseStageSuccessComplete_unix.js + if (AppConstants.platform == "linux") { + checkSymlink(); + } +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js new file mode 100644 index 0000000000..dd5c240919 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js @@ -0,0 +1,35 @@ +/* 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/. + */ + +/* General Partial MAR File Staged Patch Apply Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = gIsServiceTest ? STATE_APPLIED_SVC : STATE_APPLIED; + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromPartial\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestDirs = gTestDirsPartialSuccess; + preventDistributionFiles(); + await setupUpdaterTest(FILE_PARTIAL_MAR, true); + await stageUpdate(STATE_AFTER_STAGE, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getStageDirFile, true); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true, false, true); + // Switch the application to the staged application that was updated. + runUpdate(STATE_SUCCEEDED, true, 0, true); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile, false, true); + checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js new file mode 100644 index 0000000000..2dd1e54f90 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js @@ -0,0 +1,26 @@ +/* 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/. + */ + +/* General Complete MAR File Patch Apply Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + preventDistributionFiles(); + await setupUpdaterTest(FILE_COMPLETE_MAR, true); + runUpdate(STATE_SUCCEEDED, false, 0, true); + await checkPostUpdateAppLog(); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(true); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_COMPLETE_SUCCESS, false, false, true); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js new file mode 100644 index 0000000000..8e8e9d094a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js @@ -0,0 +1,29 @@ +/* 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/. + */ + +/* General Partial MAR File Patch Apply Test */ + +async function run_test() { + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesPartialSuccess; + gTestFiles[gTestFiles.length - 1].originalContents = null; + gTestFiles[gTestFiles.length - 1].compareContents = "FromPartial\n"; + gTestFiles[gTestFiles.length - 1].comparePerms = 0o644; + gTestDirs = gTestDirsPartialSuccess; + // The third parameter will test that a relative path that contains a + // directory traversal to the post update binary doesn't execute. + await setupUpdaterTest(FILE_PARTIAL_MAR, false, "test/../"); + runUpdate(STATE_SUCCEEDED, false, 0, true); + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartialWhileBackgroundTaskRunning.js b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartialWhileBackgroundTaskRunning.js new file mode 100644 index 0000000000..37511bd789 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartialWhileBackgroundTaskRunning.js @@ -0,0 +1,121 @@ +/* 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/. + */ + +/* General Partial MAR File Patch Apply Test */ + +const { setTimeout } = ChromeUtils.importESModule( + "resource://gre/modules/Timer.sys.mjs" +); + +const { BackgroundTasksTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/BackgroundTasksTestUtils.sys.mjs" +); +BackgroundTasksTestUtils.init(this); +const do_backgroundtask = BackgroundTasksTestUtils.do_backgroundtask.bind( + BackgroundTasksTestUtils +); + +async function run_test() { + // Without omnijars, the background task apparatus will fail to find task + // definitions. + { + let omniJa = Services.dirsvc.get("XCurProcD", Ci.nsIFile); + omniJa.append("omni.ja"); + if (!omniJa.exists()) { + Assert.ok( + false, + "This test requires a packaged build, " + + "run 'mach package' and then use 'mach xpcshell-test --xre-path=...'" + ); + return; + } + } + + if (!setupTestCommon()) { + return; + } + + // `channel-prefs.js` is required for Firefox to launch, including in + // background task mode. The testing partial MAR updates `channel-prefs.js` + // to have contents `FromPartial`, which is not a valid prefs file and causes + // Firefox to crash. However, `channel-prefs.js` is listed as `add-if-not + // "defaults/pref/channel-prefs.js" "defaults/pref/channel-prefs.js"`, so it + // won't be updated if it already exists. The manipulations below arrange a) + // for the file to exist and b) for the comparison afterward to succeed. + gTestFiles = gTestFilesPartialSuccess; + let channelPrefs = gTestFiles[gTestFiles.length - 1]; + Assert.equal("channel-prefs.js", channelPrefs.fileName); + let f = gGREDirOrig.clone(); + f.append("defaults"); + f.append("pref"); + f.append("channel-prefs.js"); + // `originalFile` is a relative path, so we can't just point to the one in the + // original GRE directory. + channelPrefs.originalFile = null; + channelPrefs.originalContents = readFile(f); + channelPrefs.compareContents = channelPrefs.originalContents; + gTestDirs = gTestDirsPartialSuccess; + // The third parameter will test that a relative path that contains a + // directory traversal to the post update binary doesn't execute. + await setupUpdaterTest(FILE_PARTIAL_MAR, false, "test/../", true, { + // We need packaged JavaScript to run background tasks. + requiresOmnijar: true, + }); + + // `0/00/00text2` is just a random file in the testing partial MAR that does + // not exist before the update and is always written by the update. + let exitCode; + exitCode = await do_backgroundtask("file_exists", { + extraArgs: [getApplyDirFile(DIR_RESOURCES + "0/00/00text2").path], + }); + // Before updating, file doesn't exist. + Assert.equal(11, exitCode); + + // This task will wait 10 seconds before exiting, which should overlap with + // the update below. We wait for some output from the wait background task, + // so that there is meaningful overlap. + let taskStarted = Promise.withResolvers(); + let p = do_backgroundtask("wait", { + onStdoutLine: (line, proc) => { + // This sentinel seems pretty safe: it's printed by the task itself and so + // there should be a straight line between future test failures and + // logging changes. + if (line.includes("runBackgroundTask: wait")) { + taskStarted.resolve(proc); + } + }, + }); + let proc = await taskStarted.promise; + + runUpdate(STATE_SUCCEEDED, false, 0, true); + + checkAppBundleModTime(); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateSuccess(getApplyDirFile); + checkUpdateLogContents(LOG_PARTIAL_SUCCESS); + await waitForUpdateXMLFiles(); + checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1); + + // Once we've seen what we want, there's no need to let the task wait complete. + await proc.kill(); + + Assert.ok("Waiting for background task to die after kill()"); + exitCode = await p; + + // Windows does not support killing processes gracefully, so they will + // always exit with -9 there. + let retVal = AppConstants.platform == "win" ? -9 : -15; + Assert.equal(retVal, exitCode); + + exitCode = await do_backgroundtask("file_exists", { + extraArgs: [getApplyDirFile(DIR_RESOURCES + "0/00/00text2").path], + }); + // After updating, file exists. + Assert.equal(0, exitCode); + + // This finishes the test, so must be last. + checkCallbackLog(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js b/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js new file mode 100644 index 0000000000..6f3e26fe0f --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js @@ -0,0 +1,41 @@ +/* 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/. + */ + +/* Test version downgrade MAR security check */ + +async function run_test() { + if (!MOZ_VERIFY_MAR_SIGNATURE) { + return; + } + + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_OLD_VERSION_MAR, false); + // If execv is used the updater process will turn into the callback process + // and the updater's return code will be that of the callback process. + runUpdate( + STATE_FAILED_VERSION_DOWNGRADE_ERROR, + false, + USE_EXECV ? 0 : 1, + false + ); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(STATE_FAILED_VERSION_DOWNGRADE_ERROR); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + VERSION_DOWNGRADE_ERROR, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js new file mode 100644 index 0000000000..d31188dcca --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js @@ -0,0 +1,43 @@ +/* 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/. + */ + +/* Test product/channel MAR security check */ + +async function run_test() { + if (!MOZ_VERIFY_MAR_SIGNATURE) { + return; + } + + if (!setupTestCommon()) { + return; + } + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 2].originalContents = + UPDATE_SETTINGS_CONTENTS.replace("xpcshell-test", "wrong-channel"); + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + // If execv is used the updater process will turn into the callback process + // and the updater's return code will be that of the callback process. + runUpdate( + STATE_FAILED_MAR_CHANNEL_MISMATCH_ERROR, + false, + USE_EXECV ? 0 : 1, + false + ); + standardInit(); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(STATE_FAILED_MAR_CHANNEL_MISMATCH_ERROR); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + MAR_CHANNEL_MISMATCH_ERROR, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js new file mode 100644 index 0000000000..4d512fd12a --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js @@ -0,0 +1,36 @@ +/* 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/. + */ + +/* Test product/channel MAR security check */ + +async function run_test() { + if (!MOZ_VERIFY_MAR_SIGNATURE) { + return; + } + + if (!setupTestCommon()) { + return; + } + const STATE_AFTER_STAGE = STATE_FAILED; + gTestFiles = gTestFilesCompleteSuccess; + gTestFiles[gTestFiles.length - 2].originalContents = + UPDATE_SETTINGS_CONTENTS.replace("xpcshell-test", "wrong-channel"); + gTestDirs = gTestDirsCompleteSuccess; + setTestFilesAndDirsForFailure(); + await setupUpdaterTest(FILE_COMPLETE_MAR, false); + await stageUpdate(STATE_AFTER_STAGE, true, true); + checkPostUpdateRunningFile(false); + checkFilesAfterUpdateFailure(getApplyDirFile); + checkUpdateLogContains(STATE_FAILED_MAR_CHANNEL_MISMATCH_ERROR); + await waitForUpdateXMLFiles(); + checkUpdateManager( + STATE_NONE, + false, + STATE_FAILED, + MAR_CHANNEL_MISMATCH_ERROR, + 1 + ); + waitForFilesInUse(); +} diff --git a/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.toml b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.toml new file mode 100644 index 0000000000..0997027c28 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.toml @@ -0,0 +1,181 @@ +[DEFAULT] +tags = "appupdate" +head = "head_update.js" +skip-if = ["os == 'win' && (ccov || msix)"] # Our updater is disabled in MSIX builds +support-files = [ + "../data/shared.js", + "../data/sharedUpdateXML.js", + "../data/xpcshellUtilsAUS.js", +] + +["invalidArgCallbackFileNotInInstallDirFailure.js"] + +["invalidArgCallbackFilePathTooLongFailure.js"] + +["invalidArgInstallDirPathTooLongFailure.js"] + +["invalidArgInstallDirPathTraversalFailure.js"] + +["invalidArgInstallWorkingDirPathNotSameFailure_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["invalidArgPatchDirPathTraversalFailure.js"] + +["invalidArgStageDirNotInInstallDirFailure_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["invalidArgWorkingDirPathLocalUNCFailure_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["invalidArgWorkingDirPathRelativeFailure.js"] + +["marAppApplyDirLockedStageFailure_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marAppApplyUpdateAppBinInUseStageSuccess_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marAppApplyUpdateSkippedWriteAccess_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marAppApplyUpdateStageOldVersionFailure.js"] + +["marAppApplyUpdateStageSuccess.js"] +skip-if = [ + "apple_silicon", # bug 1707753 + "apple_catalina", # Bug 1713329 +] + +["marAppApplyUpdateSuccess.js"] +skip-if = ["apple_silicon"] # bug 1724579 + +["marAppInUseBackgroundTaskFailure_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marAppInUseStageFailureComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marAppInUseStageSuccessComplete_unix.js"] +run-if = ["os != 'win'"] # not a Windows test +skip-if = [ + "apple_silicon", # bug 1707753 + "apple_catalina", # Bug 1713329 +] + +["marAppInUseSuccessComplete.js"] + +["marCallbackAppStageSuccessComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marCallbackAppStageSuccessPartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marCallbackAppSuccessComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marCallbackAppSuccessPartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marCallbackUmask_unix.js"] +run-if = ["os != 'win'"] # not a Windows test +reason = "Unix only test" + +["marFailurePartial.js"] + +["marFileInUseStageFailureComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileInUseStageFailurePartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileInUseSuccessComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileInUseSuccessPartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileLockedFailureComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileLockedFailurePartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileLockedStageFailureComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marFileLockedStageFailurePartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marMissingUpdateSettings.js"] + +["marMissingUpdateSettingsStage.js"] + +["marPIDPersistsSuccessComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marRMRFDirFileInUseStageFailureComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marRMRFDirFileInUseStageFailurePartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marRMRFDirFileInUseSuccessComplete_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marRMRFDirFileInUseSuccessPartial_win.js"] +run-if = ["os == 'win'"] +reason = "Windows only test" + +["marStageFailurePartial.js"] + +["marStageSuccessComplete.js"] +skip-if = [ + "apple_silicon", # bug 1707753 + "apple_catalina", # Bug 1713329 +] + +["marStageSuccessPartial.js"] +skip-if = [ + "apple_silicon", # bug 1707753 + "apple_catalina", # Bug 1713329 +] + +["marSuccessComplete.js"] + +["marSuccessPartial.js"] + +["marSuccessPartialWhileBackgroundTaskRunning.js"] +skip-if = [ + "apple_silicon", # Bug 1754931 + "apple_catalina", # Bug 1754931 +] + +["marVersionDowngrade.js"] + +["marWrongChannel.js"] + +["marWrongChannelStage.js"] -- cgit v1.2.3