testing/modules/AppInfo.jsm
author Eric Rahm <erahm@mozilla.com>
Thu, 10 Nov 2016 12:47:23 -0800
changeset 348770 e27050b02d69b88e19e0dcd151916f78259f9bb1
parent 313551 89d44b4257f1896af77af5940f6cb4787f7b8252
permissions -rw-r--r--
Bug 1313488 - Part 1: Convert XPCOM test TestDeadlockDetector to a gtest. r=froydnj This converts TestDeadlockDetector to a gtest. The logic for spawning off subprocesses is replaced with gtest's built-in death tests. On linux this will clone() the process and assert that the child process generates the appropriate assertion message. On OSX it will use fork(). In theory this should work on Windows as well buy spawning a new process but this test currently disabled there. MozReview-Commit-ID: 9Sl0hHBVGT3

/* 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/. */

"use strict";

this.EXPORTED_SYMBOLS = [
  "newAppInfo",
  "getAppInfo",
  "updateAppInfo",
];


const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;

Cu.import("resource://gre/modules/XPCOMUtils.jsm");

let origPlatformInfo = Cc["@mozilla.org/xre/app-info;1"]
    .getService(Ci.nsIPlatformInfo);

/**
 * Create new XULAppInfo instance with specified options.
 *
 * options is a object with following keys:
 *   ID:              nsIXULAppInfo.ID
 *   name:            nsIXULAppInfo.name
 *   version:         nsIXULAppInfo.version
 *   platformVersion: nsIXULAppInfo.platformVersion
 *   OS:              nsIXULRuntime.OS
 *
 *   crashReporter:   nsICrashReporter interface is implemented if true
 *   extraProps:      extra properties added to XULAppInfo
 */
this.newAppInfo = function (options={}) {
  let ID = ("ID" in options) ? options.ID : "xpcshell@tests.mozilla.org";
  let name = ("name" in options) ? options.name : "xpcshell";
  let version = ("version" in options) ? options.version : "1";
  let platformVersion
      = ("platformVersion" in options) ? options.platformVersion : "p-ver";
  let OS = ("OS" in options) ? options.OS : "XPCShell";
  let extraProps = ("extraProps" in options) ? options.extraProps : {};

  let appInfo = {
    // nsIXULAppInfo
    vendor: "Mozilla",
    name: name,
    ID: ID,
    version: version,
    appBuildID: "20160315",

    // nsIPlatformInfo
    platformVersion: platformVersion,
    platformBuildID: origPlatformInfo.platformBuildID,

    // nsIXULRuntime
    inSafeMode: false,
    logConsoleErrors: true,
    OS: OS,
    XPCOMABI: "noarch-spidermonkey",
    invalidateCachesOnRestart() {},

    // nsIWinAppHelper
    get userCanElevate() {
      return false;
    },
  };

  let interfaces = [Ci.nsIXULAppInfo,
                    Ci.nsIPlatformInfo,
                    Ci.nsIXULRuntime];
  if ("nsIWinAppHelper" in Ci) {
    interfaces.push(Ci.nsIWinAppHelper);
  }

  if ("crashReporter" in options && options.crashReporter) {
    // nsICrashReporter
    appInfo.annotations = {};
    appInfo.annotateCrashReport = function(key, data) {
      this.annotations[key] = data;
    };
    interfaces.push(Ci.nsICrashReporter);
  }

  for (let key of Object.keys(extraProps)) {
    appInfo.browserTabsRemoteAutostart = extraProps[key];
  }

  appInfo.QueryInterface = XPCOMUtils.generateQI(interfaces);

  return appInfo;
};

var currentAppInfo = newAppInfo();

/**
 * Obtain a reference to the current object used to define XULAppInfo.
 */
this.getAppInfo = function () { return currentAppInfo; };

/**
 * Update the current application info.
 *
 * See newAppInfo for options.
 *
 * To change the current XULAppInfo, simply call this function. If there was
 * a previously registered app info object, it will be unloaded and replaced.
 */
this.updateAppInfo = function (options) {
  currentAppInfo = newAppInfo(options);

  let id = Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}");
  let cid = "@mozilla.org/xre/app-info;1";
  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);

  // Unregister an existing factory if one exists.
  try {
    let existing = Components.manager.getClassObjectByContractID(cid, Ci.nsIFactory);
    registrar.unregisterFactory(id, existing);
  } catch (ex) {}

  let factory = {
    createInstance: function (outer, iid) {
      if (outer != null) {
        throw Cr.NS_ERROR_NO_AGGREGATION;
      }

      return currentAppInfo.QueryInterface(iid);
    },
  };

  registrar.registerFactory(id, "XULAppInfo", cid, factory);
};