From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.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 | 125 +++++++++++++++++++ .../tests/unit_base_updater/marVersionDowngrade.js | 41 +++++++ .../tests/unit_base_updater/marWrongChannel.js | 47 +++++++ .../unit_base_updater/marWrongChannelStage.js | 40 ++++++ .../update/tests/unit_base_updater/xpcshell.ini | 136 +++++++++++++++++++++ 51 files changed, 2161 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.ini (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..8a809d8c3e --- /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..31e01998ca --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartialWhileBackgroundTaskRunning.js @@ -0,0 +1,125 @@ +/* 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.import( + "resource://testing-common/BackgroundTasksTestUtils.jsm" +); +BackgroundTasksTestUtils.init(this); +const do_backgroundtask = BackgroundTasksTestUtils.do_backgroundtask.bind( + BackgroundTasksTestUtils +); + +const { PromiseUtils } = ChromeUtils.importESModule( + "resource://gre/modules/PromiseUtils.sys.mjs" +); + +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 = PromiseUtils.defer(); + 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..e10c845f8b --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js @@ -0,0 +1,47 @@ +/* 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..3092e67d71 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js @@ -0,0 +1,40 @@ +/* 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.ini b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini new file mode 100644 index 0000000000..84325c4312 --- /dev/null +++ b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini @@ -0,0 +1,136 @@ +# 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/. + +# Tests that require the updater binary. + +[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] +skip-if = os != 'win' +reason = Windows only test +[invalidArgPatchDirPathTraversalFailure.js] +[invalidArgStageDirNotInInstallDirFailure_win.js] +skip-if = os != 'win' +reason = Windows only test +[invalidArgWorkingDirPathLocalUNCFailure_win.js] +skip-if = os != 'win' +reason = Windows only test +[invalidArgWorkingDirPathRelativeFailure.js] +[marSuccessComplete.js] +[marSuccessPartial.js] +[marSuccessPartialWhileBackgroundTaskRunning.js] +skip-if = + apple_silicon # Bug 1754931 + apple_catalina # Bug 1754931 +[marFailurePartial.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 +[marVersionDowngrade.js] +[marMissingUpdateSettings.js] +[marMissingUpdateSettingsStage.js] +[marWrongChannel.js] +[marWrongChannelStage.js] +[marStageFailurePartial.js] +[marCallbackAppSuccessComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marCallbackAppSuccessPartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marCallbackAppStageSuccessComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marCallbackAppStageSuccessPartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marCallbackUmask_unix.js] +skip-if = + os == 'win' # not a Windows test +reason = Unix only test +[marAppInUseBackgroundTaskFailure_win.js] +skip-if = os != 'win' +reason = Windows only test +[marAppInUseSuccessComplete.js] +[marAppInUseStageSuccessComplete_unix.js] +skip-if = + os == 'win' # not a Windows test + apple_silicon # bug 1707753 + apple_catalina # Bug 1713329 +[marAppInUseStageFailureComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileLockedFailureComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileLockedFailurePartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileLockedStageFailureComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileLockedStageFailurePartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileInUseSuccessComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileInUseSuccessPartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marRMRFDirFileInUseSuccessComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marRMRFDirFileInUseSuccessPartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileInUseStageFailureComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marFileInUseStageFailurePartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marRMRFDirFileInUseStageFailureComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marRMRFDirFileInUseStageFailurePartial_win.js] +skip-if = os != 'win' +reason = Windows only test +[marPIDPersistsSuccessComplete_win.js] +skip-if = os != 'win' +reason = Windows only test +[marAppApplyDirLockedStageFailure_win.js] +skip-if = os != 'win' +reason = Windows only test +[marAppApplyUpdateAppBinInUseStageSuccess_win.js] +skip-if = os != 'win' +reason = Windows only test +[marAppApplyUpdateSuccess.js] +skip-if = + apple_silicon # bug 1724579 +[marAppApplyUpdateStageSuccess.js] +skip-if = + apple_silicon # bug 1707753 + apple_catalina # Bug 1713329 +[marAppApplyUpdateStageOldVersionFailure.js] +[marAppApplyUpdateSkippedWriteAccess_win.js] +skip-if = os != 'win' +reason = Windows only test -- cgit v1.2.3