Backed out changeset cea07e54707e (bug 1065052) for xpcshell test failures
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 10 Sep 2014 10:44:22 +0200
changeset 225335 1ae1483284dcdc51ac07d7c063d5ada4ad9a1741
parent 225334 7c2ae06403e89c305d7fd043e2b5360ce2ed49ba
child 225336 97040a73debbd341d92812a6e9db1b5c266bb14a
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1065052
milestone34.0a2
backs outcea07e54707e6c07a28c53e9411a7217c7a95115
Backed out changeset cea07e54707e (bug 1065052) for xpcshell test failures
browser/components/loop/MozLoopAPI.jsm
browser/components/loop/MozLoopService.jsm
browser/components/loop/content/js/client.js
browser/components/loop/test/mochitest/browser_fxa_login.js
browser/components/loop/test/mochitest/head.js
browser/components/loop/test/mochitest/loop_fxa.sjs
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -333,34 +333,25 @@ function injectLoopAPI(targetWindow) {
      * @param {Object} payloadObj An object which is converted to JSON and
      *                            transmitted with the request.
      * @param {Function} callback Called when the request completes.
      */
     hawkRequest: {
       enumerable: true,
       writable: true,
       value: function(path, method, payloadObj, callback) {
-        // XXX: Bug 1065153 - Should take a sessionType parameter instead of hard-coding GUEST
         // XXX Should really return a DOM promise here.
-        return MozLoopService.hawkRequest(LOOP_SESSION_TYPE.GUEST, path, method, payloadObj).then((response) => {
+        return MozLoopService.hawkRequest(path, method, payloadObj).then((response) => {
           callback(null, response.body);
         }, (error) => {
           callback(Cu.cloneInto(error, targetWindow));
         });
       }
     },
 
-    LOOP_SESSION_TYPE: {
-      enumerable: true,
-      writable: false,
-      value: function() {
-        return LOOP_SESSION_TYPE;
-      },
-    },
-
     logInToFxA: {
       enumerable: true,
       writable: true,
       value: function() {
         return MozLoopService.logInToFxA();
       }
     },
 
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -10,29 +10,24 @@ const { classes: Cc, interfaces: Ci, uti
 // https://github.com/mozilla-services/loop-server/blob/45787d34108e2f0d87d74d4ddf4ff0dbab23501c/loop/errno.json#L6
 const INVALID_AUTH_TOKEN = 110;
 
 // Ticket numbers are 24 bits in length.
 // The highest valid ticket number is 16777214 (2^24 - 2), so that a "now
 // serving" number of 2^24 - 1 is greater than it.
 const MAX_SOFT_START_TICKET_NUMBER = 16777214;
 
-const LOOP_SESSION_TYPE = {
-  GUEST: 1,
-  FXA: 2,
-};
-
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/osfile.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/FxAccountsOAuthClient.jsm");
 
-this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE"];
+this.EXPORTED_SYMBOLS = ["MozLoopService"];
 
 XPCOMUtils.defineLazyModuleGetter(this, "console",
   "resource://gre/modules/devtools/Console.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI",
   "resource:///modules/loop/MozLoopAPI.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport",
@@ -202,36 +197,34 @@ let MozLoopServiceInternal = {
       this.onHandleNotification.bind(this));
 
     return result;
   },
 
   /**
    * Performs a hawk based request to the loop server.
    *
-   * @param {LOOP_SESSION_TYPE} sessionType The type of session to use for the request.
-   *                                        This is one of the LOOP_SESSION_TYPE members.
    * @param {String} path The path to make the request to.
    * @param {String} method The request method, e.g. 'POST', 'GET'.
    * @param {Object} payloadObj An object which is converted to JSON and
    *                            transmitted with the request.
    * @returns {Promise}
    *        Returns a promise that resolves to the response of the API call,
    *        or is rejected with an error.  If the server response can be parsed
    *        as JSON and contains an 'error' property, the promise will be
    *        rejected with this JSON-parsed response.
    */
-  hawkRequest: function(sessionType, path, method, payloadObj) {
+  hawkRequest: function(path, method, payloadObj) {
     if (!gHawkClient) {
       gHawkClient = new HawkClient(this.loopServerUri);
     }
 
     let sessionToken;
     try {
-      sessionToken = Services.prefs.getCharPref(this.getSessionTokenPrefName(sessionType));
+      sessionToken = Services.prefs.getCharPref("loop.hawk-session-token");
     } catch (x) {
       // It is ok for this not to exist, we'll default to sending no-creds
     }
 
     let credentials;
     if (sessionToken) {
       // true = use a hex key, as required by the server (see bug 1032738).
       credentials = deriveHawkCredentials(sessionToken, "sessionToken",
@@ -239,47 +232,29 @@ let MozLoopServiceInternal = {
     }
 
     return gHawkClient.request(path, method, credentials, payloadObj).catch(error => {
       console.error("Loop hawkRequest error:", error);
       throw error;
     });
   },
 
-  getSessionTokenPrefName: function(sessionType) {
-    let suffix;
-    switch (sessionType) {
-      case LOOP_SESSION_TYPE.GUEST:
-        suffix = "";
-        break;
-      case LOOP_SESSION_TYPE.FXA:
-        suffix = ".fxa";
-        break;
-      default:
-        throw new Error("Unknown LOOP_SESSION_TYPE");
-        break;
-    }
-    return "loop.hawk-session-token" + suffix;
-  },
-
   /**
    * Used to store a session token from a request if it exists in the headers.
    *
-   * @param {LOOP_SESSION_TYPE} sessionType The type of session to use for the request.
-   *                                        One of the LOOP_SESSION_TYPE members.
    * @param {Object} headers The request headers, which may include a
    *                         "hawk-session-token" to be saved.
    * @return true on success or no token, false on failure.
    */
-  storeSessionToken: function(sessionType, headers) {
+  storeSessionToken: function(headers) {
     let sessionToken = headers["hawk-session-token"];
     if (sessionToken) {
       // XXX should do more validation here
       if (sessionToken.length === 64) {
-        Services.prefs.setCharPref(this.getSessionTokenPrefName(sessionType), sessionToken);
+        Services.prefs.setCharPref("loop.hawk-session-token", sessionToken);
       } else {
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
         console.warn("Loop server sent an invalid session token");
         gRegisteredDeferred.reject("session-token-wrong-size");
         gRegisteredDeferred = null;
         return false;
       }
     }
@@ -294,66 +269,59 @@ let MozLoopServiceInternal = {
    */
   onPushRegistered: function(err, pushUrl) {
     if (err) {
       gRegisteredDeferred.reject(err);
       gRegisteredDeferred = null;
       return;
     }
 
-    this.registerWithLoopServer(LOOP_SESSION_TYPE.GUEST, pushUrl).then(() => {
-      gRegisteredDeferred.resolve();
-      // No need to clear the promise here, everything was good, so we don't need
-      // to re-register.
-    }, (error) => {
-      Cu.reportError("Failed to register with Loop server: " + error.errno);
-      gRegisteredDeferred.reject(error.errno);
-      gRegisteredDeferred = null;
-    });
+    this.registerWithLoopServer(pushUrl);
   },
 
   /**
-   * Registers with the Loop server either as a guest or a FxA user.
+   * Registers with the Loop server.
    *
-   * @param {LOOP_SESSION_TYPE} sessionType The type of session e.g. guest or FxA
    * @param {String} pushUrl The push url given by the push server.
-   * @param {Boolean} [retry=true] Whether to retry if authentication fails.
-   * @return {Promise}
+   * @param {Boolean} noRetry Optional, don't retry if authentication fails.
    */
-  registerWithLoopServer: function(sessionType, pushUrl, retry = true) {
-    return this.hawkRequest(sessionType, "/registration", "POST", { simplePushURL: pushUrl})
+  registerWithLoopServer: function(pushUrl, noRetry) {
+    this.hawkRequest("/registration", "POST", { simplePushURL: pushUrl})
       .then((response) => {
         // If this failed we got an invalid token. storeSessionToken rejects
         // the gRegisteredDeferred promise for us, so here we just need to
         // early return.
-        if (!this.storeSessionToken(sessionType, response.headers))
+        if (!this.storeSessionToken(response.headers))
           return;
 
         this.clearError("registration");
+        gRegisteredDeferred.resolve();
+        // No need to clear the promise here, everything was good, so we don't need
+        // to re-register.
       }, (error) => {
         // There's other errors than invalid auth token, but we should only do the reset
         // as a last resort.
         if (error.code === 401 && error.errno === INVALID_AUTH_TOKEN) {
           if (this.urlExpiryTimeIsInFuture()) {
             // XXX Should this be reported to the user is a visible manner?
             Cu.reportError("Loop session token is invalid, all previously "
                            + "generated urls will no longer work.");
           }
 
           // Authorization failed, invalid token, we need to try again with a new token.
-          Services.prefs.clearUserPref(this.getSessionTokenPrefName(sessionType));
-          if (retry) {
-            return this.registerWithLoopServer(sessionType, pushUrl, false);
-          }
+          Services.prefs.clearUserPref("loop.hawk-session-token");
+          this.registerWithLoopServer(pushUrl, true);
+          return;
         }
 
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
         Cu.reportError("Failed to register with the loop server. error: " + error);
         this.setError("registration", error);
-        throw error;
+        gRegisteredDeferred.reject(error.errno);
+        gRegisteredDeferred = null;
       }
     );
   },
 
   /**
    * Callback from MozLoopPushHandler - A push notification has been received from
    * the server.
    *
@@ -536,17 +504,17 @@ let MozLoopServiceInternal = {
   },
 
   /**
    * Fetch Firefox Accounts (FxA) OAuth parameters from the Loop Server.
    *
    * @return {Promise} resolved with the body of the hawk request for OAuth parameters.
    */
   promiseFxAOAuthParameters: function() {
-    return this.hawkRequest(LOOP_SESSION_TYPE.FXA, "/fxa-oauth/params", "POST").then(response => {
+    return this.hawkRequest("/fxa-oauth/params", "POST").then(response => {
       return JSON.parse(response.body);
     });
   },
 
   /**
    * Get the OAuth client constructed with Loop OAauth parameters.
    *
    * @return {Promise}
@@ -614,17 +582,17 @@ let MozLoopServiceInternal = {
     if (!code || !state) {
       throw new Error("promiseFxAOAuthToken: code and state are required.");
     }
 
     let payload = {
       code: code,
       state: state,
     };
-    return this.hawkRequest(LOOP_SESSION_TYPE.FXA, "/fxa-oauth/token", "POST", payload).then(response => {
+    return this.hawkRequest("/fxa-oauth/token", "POST", payload).then(response => {
       return JSON.parse(response.body);
     });
   },
 
   /**
    * Called once gFxAOAuthClient fires onComplete.
    *
    * @param {Deferred} deferred used to resolve or reject the gFxAOAuthClientPromise
@@ -948,44 +916,33 @@ this.MozLoopService = {
       return Promise.resolve(gFxAOAuthTokenData);
     }
 
     return MozLoopServiceInternal.promiseFxAOAuthAuthorization().then(response => {
       return MozLoopServiceInternal.promiseFxAOAuthToken(response.code, response.state);
     }).then(tokenData => {
       gFxAOAuthTokenData = tokenData;
       return tokenData;
-    }).then(tokenData => {
-      return gRegisteredDeferred.promise.then(Task.async(function*() {
-        if (gPushHandler.pushUrl) {
-          yield MozLoopServiceInternal.registerWithLoopServer(LOOP_SESSION_TYPE.FXA, gPushHandler.pushUrl);
-        } else {
-          throw new Error("No pushUrl for FxA registration");
-        }
-        return gFxAOAuthTokenData;
-      }));
     },
     error => {
       gFxAOAuthTokenData = null;
       throw error;
     });
   },
 
   /**
    * Performs a hawk based request to the loop server.
    *
-   * @param {LOOP_SESSION_TYPE} sessionType The type of session to use for the request.
-   *                                        One of the LOOP_SESSION_TYPE members.
    * @param {String} path The path to make the request to.
    * @param {String} method The request method, e.g. 'POST', 'GET'.
    * @param {Object} payloadObj An object which is converted to JSON and
    *                            transmitted with the request.
    * @returns {Promise}
    *        Returns a promise that resolves to the response of the API call,
    *        or is rejected with an error.  If the server response can be parsed
    *        as JSON and contains an 'error' property, the promise will be
    *        rejected with this JSON-parsed response.
    */
-  hawkRequest: function(sessionType, path, method, payloadObj) {
+  hawkRequest: function(path, method, payloadObj) {
     return MozLoopServiceInternal.hawkRequest(path, method, payloadObj);
   },
 };
 Object.freeze(this.MozLoopService);
--- a/browser/components/loop/content/js/client.js
+++ b/browser/components/loop/content/js/client.js
@@ -99,16 +99,17 @@ loop.Client = (function($) {
      * Internal handler for requesting a call url from the server.
      *
      * Callback parameters:
      * - err null on successful registration, non-null otherwise.
      * - callUrlData an object of the obtained call url data if successful:
      * -- callUrl: The url of the call
      * -- expiresAt: The amount of hours until expiry of the url
      *
+     * @param  {String} simplepushUrl a registered Simple Push URL
      * @param  {string} nickname the nickname of the future caller
      * @param  {Function} cb Callback(err, callUrlData)
      */
     _requestCallUrlInternal: function(nickname, cb) {
       this.mozLoop.hawkRequest("/call-url/", "POST", {callerId: nickname},
                                function (error, responseText) {
         if (error) {
           this._failureHandler(cb, error);
--- a/browser/components/loop/test/mochitest/browser_fxa_login.js
+++ b/browser/components/loop/test/mochitest/browser_fxa_login.js
@@ -2,34 +2,27 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Test FxA logins with Loop.
  */
 
 "use strict";
 
-const {
-  LOOP_SESSION_TYPE,
-  gFxAOAuthTokenData
-} = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
-
+const gFxAOAuthTokenData = Cu.import("resource:///modules/loop/MozLoopService.jsm", {}).gFxAOAuthTokenData;
 const BASE_URL = "http://mochi.test:8888/browser/browser/components/loop/test/mochitest/loop_fxa.sjs?";
-const HAWK_TOKEN_LENGTH = 64;
 
 add_task(function* setup() {
   Services.prefs.setCharPref("loop.server", BASE_URL);
   Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
   registerCleanupFunction(function* () {
     info("cleanup time");
     yield promiseDeletedOAuthParams(BASE_URL);
     Services.prefs.clearUserPref("loop.server");
     Services.prefs.clearUserPref("services.push.serverURL");
-    Services.prefs.clearUserPref(MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.GUEST));
-    Services.prefs.clearUserPref(MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.FXA));
   });
 });
 
 add_task(function* checkOAuthParams() {
   let params = {
     client_id: "client_id",
     content_uri: BASE_URL + "/content",
     oauth_uri: BASE_URL + "/oauth",
@@ -163,51 +156,33 @@ add_task(function* basicAuthorizationAnd
     client_id: "client_id",
     content_uri: BASE_URL + "/content",
     oauth_uri: BASE_URL + "/oauth",
     profile_uri: BASE_URL + "/profile",
     state: "state",
   };
   yield promiseOAuthParamsSetup(BASE_URL, params);
 
-  info("registering");
-  mockPushHandler.pushUrl = "https://localhost/pushUrl/guest";
-  yield MozLoopService.register(mockPushHandler);
-  let prefName = MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.GUEST);
-  let padding = new Array(HAWK_TOKEN_LENGTH - mockPushHandler.pushUrl.length).fill("X").join("");
-  ise(Services.prefs.getCharPref(prefName), mockPushHandler.pushUrl + padding, "Check guest hawk token");
-
-  // Normally the same pushUrl would be registered but we change it in the test
-  // to be able to check for success on the second registration.
-  mockPushHandler.pushUrl = "https://localhost/pushUrl/fxa";
-
   let tokenData = yield MozLoopService.logInToFxA();
   ise(tokenData.access_token, "code1_access_token", "Check access_token");
   ise(tokenData.scope, "profile", "Check scope");
   ise(tokenData.token_type, "bearer", "Check token_type");
-
-  let registrationResponse = yield promiseOAuthGetRegistration(BASE_URL);
-  ise(registrationResponse.response.simplePushURL, "https://localhost/pushUrl/fxa", "Check registered push URL");
-  prefName = MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.FXA);
-  padding = new Array(HAWK_TOKEN_LENGTH - mockPushHandler.pushUrl.length).fill("X").join("");
-  ise(Services.prefs.getCharPref(prefName), mockPushHandler.pushUrl + padding, "Check FxA hawk token");
 });
 
 add_task(function* loginWithParams401() {
   resetFxA();
   let params = {
     client_id: "client_id",
     content_uri: BASE_URL + "/content",
     oauth_uri: BASE_URL + "/oauth",
     profile_uri: BASE_URL + "/profile",
     state: "state",
     test_error: "params_401",
   };
   yield promiseOAuthParamsSetup(BASE_URL, params);
-  yield MozLoopService.register(mockPushHandler);
 
   let loginPromise = MozLoopService.logInToFxA();
   yield loginPromise.then(tokenData => {
     ok(false, "Promise should have rejected");
   },
   error => {
     ise(error.code, 401, "Check error code");
     ise(gFxAOAuthTokenData, null, "Check there is no saved token data");
--- a/browser/components/loop/test/mochitest/head.js
+++ b/browser/components/loop/test/mochitest/head.js
@@ -107,51 +107,8 @@ function promiseDeletedOAuthParams(baseU
               createInstance(Ci.nsIXMLHttpRequest);
   xhr.open("DELETE", baseURL + "/setup_params", true);
   xhr.addEventListener("load", () => deferred.resolve(xhr));
   xhr.addEventListener("error", deferred.reject);
   xhr.send();
 
   return deferred.promise;
 }
-
-/**
- * Get the last registration on the test server.
- */
-function promiseOAuthGetRegistration(baseURL) {
-  let deferred = Promise.defer();
-  let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
-              createInstance(Ci.nsIXMLHttpRequest);
-  xhr.open("GET", baseURL + "/get_registration", true);
-  xhr.responseType = "json";
-  xhr.addEventListener("load", () => deferred.resolve(xhr));
-  xhr.addEventListener("error", deferred.reject);
-  xhr.send();
-
-  return deferred.promise;
-}
-
-/**
- * This is used to fake push registration and notifications for
- * MozLoopService tests. There is only one object created per test instance, as
- * once registration has taken place, the object cannot currently be changed.
- */
-let mockPushHandler = {
-  // This sets the registration result to be returned when initialize
-  // is called. By default, it is equivalent to success.
-  registrationResult: null,
-  pushUrl: undefined,
-
-  /**
-   * MozLoopPushHandler API
-   */
-  initialize: function(registerCallback, notificationCallback) {
-    registerCallback(this.registrationResult, this.pushUrl);
-    this._notificationCallback = notificationCallback;
-  },
-
-  /**
-   * Test-only API to simplify notifying a push notification result.
-   */
-  notify: function(version) {
-    this._notificationCallback(version);
-  }
-};
--- a/browser/components/loop/test/mochitest/loop_fxa.sjs
+++ b/browser/components/loop/test/mochitest/loop_fxa.sjs
@@ -3,44 +3,37 @@
 
 /**
  * This is a mock server that implements the FxA endpoints on the Loop server.
  */
 
 "use strict";
 
 const REQUIRED_PARAMS = ["client_id", "content_uri", "oauth_uri", "profile_uri", "state"];
-const HAWK_TOKEN_LENGTH = 64;
 
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
 /**
  * Entry point for HTTP requests.
  */
 function handleRequest(request, response) {
   // Look at the query string but ignore past the encoded ? when deciding on the handler.
   switch (request.queryString.replace(/%3F.*/,"")) {
-    case "/setup_params": // Test-only
+    case "/setup_params":
       setup_params(request, response);
       return;
     case "/fxa-oauth/params":
       params(request, response);
       return;
     case encodeURIComponent("/oauth/authorization"):
       oauth_authorization(request, response);
       return;
     case "/fxa-oauth/token":
       token(request, response);
       return;
-    case "/registration":
-      registration(request, response);
-      return;
-    case "/get_registration": // Test-only
-      get_registration(request, response);
-      return;
   }
   response.setStatusLine(request.httpVersion, 404, "Not Found");
 }
 
 /**
  * POST /setup_params
  * DELETE /setup_params
  *
@@ -49,17 +42,16 @@ function handleRequest(request, response
  * For a POST the X-Params header should contain a JSON object with keys to set for /fxa-oauth/params.
  * A DELETE request will delete the stored parameters and should be run in a cleanup function to
  * avoid interfering with subsequen tests.
  */
 function setup_params(request, response) {
   response.setHeader("Content-Type", "text/plain", false);
   if (request.method == "DELETE") {
     setSharedState("/fxa-oauth/params", "");
-    setSharedState("/registration", "");
     response.write("Params deleted");
     return;
   }
   let params = JSON.parse(request.getHeader("X-Params"));
   if (!params) {
     response.setStatusLine(request.httpVersion, 400, "Bad Request");
     return;
   }
@@ -144,35 +136,8 @@ function token(request, response) {
   let tokenData = {
     access_token: payload.code + "_access_token",
     scope: "profile",
     token_type: "bearer",
   };
   response.setHeader("Content-Type", "application/json; charset=utf-8", false);
   response.write(JSON.stringify(tokenData, null, 2));
 }
-
-/**
- * POST /registration
- *
- * Mock Loop registration endpoint which simply returns the simplePushURL with
- * padding as the hawk session token.
- */
-function registration(request, response) {
-  let body = NetUtil.readInputStreamToString(request.bodyInputStream,
-                                             request.bodyInputStream.available());
-  let payload = JSON.parse(body);
-  setSharedState("/registration", body);
-  let pushURL = payload.simplePushURL;
-  // Pad the pushURL with "X" to the token length to simulate a token
-  let padding = new Array(HAWK_TOKEN_LENGTH - pushURL.length).fill("X").join("");
-  response.setHeader("hawk-session-token", pushURL + padding, false);
-}
-
-/**
- * GET /get_registration
- *
- * Used for testing purposes to check if registration succeeded by returning the POST body.
- */
-function get_registration(request, response) {
-  response.setHeader("Content-Type", "application/json; charset=utf-8", false);
-  response.write(getSharedState("/registration"));
-}