toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,134 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 + */
     1.8 +
     1.9 +function run_test() {
    1.10 +  setupTestCommon();
    1.11 +
    1.12 +  // Verify write access to the custom app dir
    1.13 +  logTestInfo("testing write access to the application directory");
    1.14 +  let testFile = getCurrentProcessDir();
    1.15 +  testFile.append("update_write_access_test");
    1.16 +  testFile.create(AUS_Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
    1.17 +  do_check_true(testFile.exists());
    1.18 +  testFile.remove(false);
    1.19 +  do_check_false(testFile.exists());
    1.20 +
    1.21 +  standardInit();
    1.22 +
    1.23 +  if (IS_WIN) {
    1.24 +    // Create a mutex to prevent being able to check for or apply updates.
    1.25 +    logTestInfo("attempting to create mutex");
    1.26 +    let handle = createMutex(getPerInstallationMutexName());
    1.27 +
    1.28 +    logTestInfo("testing that the mutex was successfully created");
    1.29 +    do_check_neq(handle, null);
    1.30 +
    1.31 +    // Check if available updates cannot be checked for when there is a mutex
    1.32 +    // for this installation.
    1.33 +    logTestInfo("testing nsIApplicationUpdateService:canCheckForUpdates is " +
    1.34 +                "false when there is a mutex");
    1.35 +    do_check_false(gAUS.canCheckForUpdates);
    1.36 +
    1.37 +    // Check if updates cannot be applied when there is a mutex for this
    1.38 +    // installation.
    1.39 +    logTestInfo("testing nsIApplicationUpdateService:canApplyUpdates is " +
    1.40 +                "false when there is a mutex");
    1.41 +    do_check_false(gAUS.canApplyUpdates);
    1.42 +
    1.43 +    logTestInfo("destroying mutex");
    1.44 +    closeHandle(handle)
    1.45 +  }
    1.46 +
    1.47 +  // Check if available updates can be checked for
    1.48 +  logTestInfo("testing nsIApplicationUpdateService:canCheckForUpdates is true");
    1.49 +  do_check_true(gAUS.canCheckForUpdates);
    1.50 +  // Check if updates can be applied
    1.51 +  logTestInfo("testing nsIApplicationUpdateService:canApplyUpdates is true");
    1.52 +  do_check_true(gAUS.canApplyUpdates);
    1.53 +
    1.54 +  if (IS_WIN) {
    1.55 +    // Attempt to create a mutex when application update has already created one
    1.56 +    // with the same name.
    1.57 +    logTestInfo("attempting to create mutex");
    1.58 +    let handle = createMutex(getPerInstallationMutexName());
    1.59 +
    1.60 +    logTestInfo("testing that the mutex was not successfully created");
    1.61 +    do_check_eq(handle, null);
    1.62 +  }
    1.63 +
    1.64 +  doTestFinish();
    1.65 +}
    1.66 +
    1.67 +if (IS_WIN) {
    1.68 +  /**
    1.69 +   * Determines a unique mutex name for the installation.
    1.70 +   *
    1.71 +   * @return Global mutex path.
    1.72 +   */
    1.73 +  function getPerInstallationMutexName() {
    1.74 +    let hasher = AUS_Cc["@mozilla.org/security/hash;1"].
    1.75 +                 createInstance(AUS_Ci.nsICryptoHash);
    1.76 +    hasher.init(hasher.SHA1);
    1.77 +
    1.78 +    let exeFile = Services.dirsvc.get(XRE_EXECUTABLE_FILE, AUS_Ci.nsILocalFile);
    1.79 +
    1.80 +    let converter = AUS_Cc["@mozilla.org/intl/scriptableunicodeconverter"].
    1.81 +                    createInstance(AUS_Ci.nsIScriptableUnicodeConverter);
    1.82 +    converter.charset = "UTF-8";
    1.83 +    let data = converter.convertToByteArray(exeFile.path.toLowerCase());
    1.84 +
    1.85 +    hasher.update(data, data.length);
    1.86 +    return "Global\\MozillaUpdateMutex-" + hasher.finish(true);
    1.87 +  }
    1.88 +
    1.89 +  /**
    1.90 +   * Closes a Win32 handle.
    1.91 +   *
    1.92 +   * @param  aHandle
    1.93 +   *         The handle to close.
    1.94 +   */
    1.95 +  function closeHandle(aHandle) {
    1.96 +    let lib = ctypes.open("kernel32.dll");
    1.97 +    let CloseHandle = lib.declare("CloseHandle",
    1.98 +                                  ctypes.winapi_abi,
    1.99 +                                  ctypes.int32_t, /* success */
   1.100 +                                  ctypes.void_t.ptr); /* handle */
   1.101 +    CloseHandle(aHandle);
   1.102 +    lib.close();
   1.103 +  }
   1.104 +
   1.105 +  /**
   1.106 +   * Creates a mutex.
   1.107 +   *
   1.108 +   * @param  aName
   1.109 +   *         The name for the mutex.
   1.110 +   * @return The Win32 handle to the mutex.
   1.111 +   */
   1.112 +  function createMutex(aName) {
   1.113 +    const INITIAL_OWN = 1;
   1.114 +    const ERROR_ALREADY_EXISTS = 0xB7;
   1.115 +    let lib = ctypes.open("kernel32.dll");
   1.116 +    let CreateMutexW = lib.declare("CreateMutexW",
   1.117 +                                   ctypes.winapi_abi,
   1.118 +                                   ctypes.void_t.ptr, /* return handle */
   1.119 +                                   ctypes.void_t.ptr, /* security attributes */
   1.120 +                                   ctypes.int32_t, /* initial owner */
   1.121 +                                   ctypes.jschar.ptr); /* name */
   1.122 +
   1.123 +    let handle = CreateMutexW(null, INITIAL_OWN, aName);
   1.124 +    lib.close();
   1.125 +    let alreadyExists = ctypes.winLastError == ERROR_ALREADY_EXISTS;
   1.126 +    if (handle && !handle.isNull() && alreadyExists) {
   1.127 +      closeHandle(handle);
   1.128 +      handle = null;
   1.129 +    }
   1.130 +
   1.131 +    if (handle && handle.isNull()) {
   1.132 +      handle = null;
   1.133 +    }
   1.134 +
   1.135 +    return handle;
   1.136 +  }
   1.137 +}

mercurial