Bug 1237983 - Investigate and remove the Bagheera Client Implementation. r=gfritzsche
authorbrendan <brendantgood@gmail.com>
Sun, 24 Jan 2016 22:33:52 -0500
changeset 282192 a24f3a35d1c88c199af1693d82d9dafc70b3c4a2
parent 282191 e2d11e2d506c8df2a1d8d28cdf3b18473f2a103e
child 282193 27b8c20eeacb289f2a5dea94c1d4c20931ffb72c
push id71072
push userkwierso@gmail.com
push dateFri, 29 Jan 2016 01:50:27 +0000
treeherdermozilla-inbound@fd3b8111af34 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche
bugs1237983
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1237983 - Investigate and remove the Bagheera Client Implementation. r=gfritzsche
CLOBBER
services/common/bagheeraclient.js
services/common/modules-testing/bagheeraserver.js
services/common/moz.build
services/common/tests/mach_commands.py
services/common/tests/run_bagheera_server.js
services/common/tests/unit/test_bagheera_client.js
services/common/tests/unit/test_bagheera_server.js
services/common/tests/unit/test_load_modules.js
services/common/tests/unit/xpcshell.ini
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,10 +17,10 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-to fix another bustage from bug 1069556 landing;
+Bug 1237983 - Investigate and remove the Bagheera Client implementation.
 
deleted file mode 100644
--- a/services/common/bagheeraclient.js
+++ /dev/null
@@ -1,278 +0,0 @@
-/* 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/. */
-
-/**
- * This file contains a client API for the Bagheera data storage service.
- *
- * Information about Bagheera is available at
- * https://github.com/mozilla-metrics/bagheera
- */
-
-#ifndef MERGED_COMPARTMENT
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [
-  "BagheeraClient",
-  "BagheeraClientRequestResult",
-];
-
-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-#endif
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://services-common/rest.js");
-Cu.import("resource://services-common/utils.js");
-
-/**
- * Represents the result of a Bagheera request.
- */
-this.BagheeraClientRequestResult = function BagheeraClientRequestResult() {
-  this.transportSuccess = false;
-  this.serverSuccess = false;
-  this.request = null;
-};
-
-Object.freeze(BagheeraClientRequestResult.prototype);
-
-
-/**
- * Wrapper around RESTRequest so logging is sane.
- */
-function BagheeraRequest(uri) {
-  RESTRequest.call(this, uri);
-
-  this._log = Log.repository.getLogger("Services.BagheeraClient");
-  this._log.level = Log.Level.Debug;
-}
-
-BagheeraRequest.prototype = Object.freeze({
-  __proto__: RESTRequest.prototype,
-});
-
-
-/**
- * Create a new Bagheera client instance.
- *
- * Each client is associated with a specific Bagheera HTTP URI endpoint.
- *
- * @param baseURI
- *        (string) The base URI of the Bagheera HTTP endpoint.
- */
-this.BagheeraClient = function BagheeraClient(baseURI) {
-  if (!baseURI) {
-    throw new Error("baseURI argument must be defined.");
-  }
-
-  this._log = Log.repository.getLogger("Services.BagheeraClient");
-  this._log.level = Log.Level.Debug;
-
-  this.baseURI = baseURI;
-
-  if (!baseURI.endsWith("/")) {
-    this.baseURI += "/";
-  }
-};
-
-BagheeraClient.prototype = Object.freeze({
-  /**
-   * Channel load flags for all requests.
-   *
-   * Caching is not applicable, so we bypass and disable it. We also
-   * ignore any cookies that may be present for the domain because
-   * Bagheera does not utilize cookies and the release of cookies may
-   * inadvertantly constitute unncessary information disclosure.
-   */
-  _loadFlags: Ci.nsIRequest.LOAD_BYPASS_CACHE |
-              Ci.nsIRequest.INHIBIT_CACHING |
-              Ci.nsIRequest.LOAD_ANONYMOUS,
-
-  DEFAULT_TIMEOUT_MSEC: 5 * 60 * 1000, // 5 minutes.
-
-  _RE_URI_IDENTIFIER: /^[a-zA-Z0-9_-]+$/,
-
-  /**
-   * Upload a JSON payload to the server.
-   *
-   * The return value is a Promise which will be resolved with a
-   * BagheeraClientRequestResult when the request has finished.
-   *
-   * @param namespace
-   *        (string) The namespace to post this data to.
-   * @param id
-   *        (string) The ID of the document being uploaded. This is typically
-   *        a UUID in hex form.
-   * @param payload
-   *        (string|object) Data to upload. Can be specified as a string (which
-   *        is assumed to be JSON) or an object. If an object, it will be fed into
-   *        JSON.stringify() for serialization.
-   * @param options
-   *        (object) Extra options to control behavior. Recognized properties:
-   *
-   *          deleteIDs -- (array) Old document IDs to delete as part of
-   *            upload. If not specified, no old documents will be deleted as
-   *            part of upload. The array values are typically UUIDs in hex
-   *            form.
-   *
-   *          telemetryCompressed -- (string) Telemetry histogram to record
-   *            compressed size of payload under. If not defined, no telemetry
-   *            data for the compressed size will be recorded.
-   *
-   * @return Promise<BagheeraClientRequestResult>
-   */
-  uploadJSON: function uploadJSON(namespace, id, payload, options={}) {
-    if (!namespace) {
-      throw new Error("namespace argument must be defined.");
-    }
-
-    if (!id) {
-      throw new Error("id argument must be defined.");
-    }
-
-    if (!payload) {
-      throw new Error("payload argument must be defined.");
-    }
-
-    if (options && typeof(options) != "object") {
-      throw new Error("Unexpected type for options argument. Expected object. " +
-                      "Got: " + typeof(options));
-    }
-
-    let uri = this._submitURI(namespace, id);
-
-    let data = payload;
-
-    if (typeof(payload) == "object") {
-      data = JSON.stringify(payload);
-    }
-
-    if (typeof(data) != "string") {
-      throw new Error("Unknown type for payload: " + typeof(data));
-    }
-
-    this._log.info("Uploading data to " + uri);
-
-    let request = new BagheeraRequest(uri);
-    request.loadFlags = this._loadFlags;
-    request.timeout = this.DEFAULT_TIMEOUT_MSEC;
-
-    // Since API changed, throw on old API usage.
-    if ("deleteID" in options) {
-      throw new Error("API has changed, use (array) deleteIDs instead");
-    }
-
-    let deleteIDs;
-    if (options.deleteIDs && options.deleteIDs.length > 0) {
-      deleteIDs = options.deleteIDs;
-      this._log.debug("Will delete " + deleteIDs.join(", "));
-      request.setHeader("X-Obsolete-Document", deleteIDs.join(","));
-    }
-
-    let deferred = Promise.defer();
-
-    // The string converter service used by CommonUtils.convertString()
-    // silently throws away high bytes. We need to convert the string to
-    // consist of only low bytes first.
-    data = CommonUtils.encodeUTF8(data);
-    data = CommonUtils.convertString(data, "uncompressed", "deflate");
-    if (options.telemetryCompressed) {
-      try {
-        let h = Services.telemetry.getHistogramById(options.telemetryCompressed);
-        h.add(data.length);
-      } catch (ex) {
-        this._log.warn("Unable to record telemetry for compressed payload size", ex);
-      }
-    }
-
-    // TODO proper header per bug 807134.
-    request.setHeader("Content-Type", "application/json+zlib; charset=utf-8");
-
-    this._log.info("Request body length: " + data.length);
-
-    let result = new BagheeraClientRequestResult();
-    result.namespace = namespace;
-    result.id = id;
-    result.deleteIDs = deleteIDs ? deleteIDs.slice(0) : null;
-
-    request.onComplete = this._onComplete.bind(this, request, deferred, result);
-    request.post(data);
-
-    return deferred.promise;
-  },
-
-  /**
-   * Delete the specified document.
-   *
-   * @param namespace
-   *        (string) Namespace from which to delete the document.
-   * @param id
-   *        (string) ID of document to delete.
-   *
-   * @return Promise<BagheeraClientRequestResult>
-   */
-  deleteDocument: function deleteDocument(namespace, id) {
-    let uri = this._submitURI(namespace, id);
-
-    let request = new BagheeraRequest(uri);
-    request.loadFlags = this._loadFlags;
-    request.timeout = this.DEFAULT_TIMEOUT_MSEC;
-
-    let result = new BagheeraClientRequestResult();
-    result.namespace = namespace;
-    result.id = id;
-    let deferred = Promise.defer();
-
-    request.onComplete = this._onComplete.bind(this, request, deferred, result);
-    request.delete();
-
-    return deferred.promise;
-  },
-
-  _submitURI: function _submitURI(namespace, id) {
-    if (!this._RE_URI_IDENTIFIER.test(namespace)) {
-      throw new Error("Illegal namespace name. Must be alphanumeric + [_-]: " +
-                      namespace);
-    }
-
-    if (!this._RE_URI_IDENTIFIER.test(id)) {
-      throw new Error("Illegal id value. Must be alphanumeric + [_-]: " + id);
-    }
-
-    return this.baseURI + "1.0/submit/" + namespace + "/" + id;
-  },
-
-  _onComplete: function _onComplete(request, deferred, result, error) {
-    result.request = request;
-
-    if (error) {
-      this._log.info("Transport failure on request", error);
-      result.transportSuccess = false;
-      deferred.resolve(result);
-      return;
-    }
-
-    result.transportSuccess = true;
-
-    let response = request.response;
-
-    switch (response.status) {
-      case 200:
-      case 201:
-        result.serverSuccess = true;
-        break;
-
-      default:
-        result.serverSuccess = false;
-
-        this._log.info("Received unexpected status code: " + response.status);
-        this._log.debug("Response body: " + response.body);
-    }
-
-    deferred.resolve(result);
-  },
-});
-
deleted file mode 100644
--- a/services/common/modules-testing/bagheeraserver.js
+++ /dev/null
@@ -1,296 +0,0 @@
-/* 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";
-
-var {utils: Cu} = Components;
-
-this.EXPORTED_SYMBOLS = ["BagheeraServer"];
-
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://testing-common/httpd.js");
-
-/**
- * This is an implementation of the Bagheera server.
- *
- * The purpose of the server is to facilitate testing of the Bagheera
- * client and the Firefox Health report. It is *not* meant to be a
- * production grade server.
- *
- * The Bagheera server is essentially a glorified document store.
- */
-this.BagheeraServer = function BagheeraServer() {
-  this._log = Log.repository.getLogger("metrics.BagheeraServer");
-
-  this.server = new HttpServer();
-  this.namespaces = {};
-
-  this.allowAllNamespaces = false;
-}
-
-BagheeraServer.prototype = {
-  /**
-   * Whether this server has a namespace defined.
-   *
-   * @param ns
-   *        (string) Namepsace whose existence to query for.
-   * @return bool
-   */
-  hasNamespace: function hasNamespace(ns) {
-    return ns in this.namespaces;
-  },
-
-  /**
-   * Whether this server has an ID in a particular namespace.
-   *
-   * @param ns
-   *        (string) Namespace to look for item in.
-   * @param id
-   *        (string) ID of object to look for.
-   * @return bool
-   */
-  hasDocument: function hasDocument(ns, id) {
-    let namespace = this.namespaces[ns];
-
-    if (!namespace) {
-      return false;
-    }
-
-    return id in namespace;
-  },
-
-  /**
-   * Obtain a document from the server.
-   *
-   * @param ns
-   *        (string) Namespace to retrieve document from.
-   * @param id
-   *        (string) ID of document to retrieve.
-   *
-   * @return string The content of the document or null if the document
-   *                does not exist.
-   */
-  getDocument: function getDocument(ns, id) {
-    let namespace = this.namespaces[ns];
-
-    if (!namespace) {
-      return null;
-    }
-
-    return namespace[id];
-  },
-
-  /**
-   * Set the contents of a document in the server.
-   *
-   * @param ns
-   *        (string) Namespace to add document to.
-   * @param id
-   *        (string) ID of document being added.
-   * @param payload
-   *        (string) The content of the document.
-   */
-  setDocument: function setDocument(ns, id, payload) {
-    let namespace = this.namespaces[ns];
-
-    if (!namespace) {
-      if (!this.allowAllNamespaces) {
-        throw new Error("Namespace does not exist: " + ns);
-      }
-
-      this.createNamespace(ns);
-      namespace = this.namespaces[ns];
-    }
-
-    namespace[id] = payload;
-  },
-
-  /**
-   * Create a namespace in the server.
-   *
-   * The namespace will initially be empty.
-   *
-   * @param ns
-   *        (string) The name of the namespace to create.
-   */
-  createNamespace: function createNamespace(ns) {
-    if (ns in this.namespaces) {
-      throw new Error("Namespace already exists: " + ns);
-    }
-
-    this.namespaces[ns] = {};
-  },
-
-  start: function start(port=-1) {
-    this.server.registerPrefixHandler("/", this._handleRequest.bind(this));
-    this.server.start(port);
-    let i = this.server.identity;
-
-    this.serverURI = i.primaryScheme + "://" + i.primaryHost + ":" +
-                     i.primaryPort + "/";
-    this.port = i.primaryPort;
-  },
-
-  stop: function stop(cb) {
-    let handler = {onStopped: cb};
-
-    this.server.stop(handler);
-  },
-
-  /**
-   * Our root path handler.
-   */
-  _handleRequest: function _handleRequest(request, response) {
-    let path = request.path;
-    this._log.info("Received request: " + request.method + " " + path + " " +
-                   "HTTP/" + request.httpVersion);
-
-    try {
-      if (path.startsWith("/1.0/submit/")) {
-        return this._handleV1Submit(request, response,
-                                    path.substr("/1.0/submit/".length));
-      } else {
-        throw HTTP_404;
-      }
-    } catch (ex) {
-      if (ex instanceof HttpError) {
-        this._log.info("HttpError thrown: " + ex.code + " " + ex.description);
-      } else {
-        this._log.warn("Exception processing request", ex);
-      }
-
-      throw ex;
-    }
-  },
-
-  /**
-   * Handles requests to /submit/*.
-   */
-  _handleV1Submit: function _handleV1Submit(request, response, rest) {
-    if (!rest.length) {
-      throw HTTP_404;
-    }
-
-    let namespace;
-    let index = rest.indexOf("/");
-    if (index == -1) {
-      namespace = rest;
-      rest = "";
-    } else {
-      namespace = rest.substr(0, index);
-      rest = rest.substr(index + 1);
-    }
-
-    this._handleNamespaceSubmit(namespace, rest, request, response);
-  },
-
-  _handleNamespaceSubmit: function _handleNamespaceSubmit(namespace, rest,
-                                                          request, response) {
-    if (!this.hasNamespace(namespace)) {
-      if (!this.allowAllNamespaces) {
-        this._log.info("Request to unknown namespace: " + namespace);
-        throw HTTP_404;
-      }
-
-      this.createNamespace(namespace);
-    }
-
-    if (!rest) {
-      this._log.info("No ID defined.");
-      throw HTTP_404;
-    }
-
-    let id = rest;
-    if (id.includes("/")) {
-      this._log.info("URI has too many components.");
-      throw HTTP_404;
-    }
-
-    if (request.method == "POST") {
-      return this._handleNamespaceSubmitPost(namespace, id, request, response);
-    }
-
-    if (request.method == "DELETE") {
-      return this._handleNamespaceSubmitDelete(namespace, id, request, response);
-    }
-
-    this._log.info("Unsupported HTTP method on namespace handler: " +
-                   request.method);
-    response.setHeader("Allow", "POST,DELETE");
-    throw HTTP_405;
-  },
-
-  _handleNamespaceSubmitPost:
-    function _handleNamespaceSubmitPost(namespace, id, request, response) {
-
-    this._log.info("Handling data upload for " + namespace + ":" + id);
-
-    let requestBody = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
-    this._log.info("Raw body length: " + requestBody.length);
-
-    if (!request.hasHeader("Content-Type")) {
-      this._log.info("Request does not have Content-Type header.");
-      throw HTTP_400;
-    }
-
-    const ALLOWED_TYPES = [
-      // TODO proper content types from bug 807134.
-      "application/json; charset=utf-8",
-      "application/json+zlib; charset=utf-8",
-    ];
-
-    let ct = request.getHeader("Content-Type");
-    if (ALLOWED_TYPES.indexOf(ct) == -1) {
-      this._log.info("Unknown media type: " + ct);
-      // Should generate proper HTTP response headers for this error.
-      throw HTTP_415;
-    }
-
-    if (ct.startsWith("application/json+zlib")) {
-      this._log.debug("Uncompressing entity body with deflate.");
-      requestBody = CommonUtils.convertString(requestBody, "deflate",
-                                              "uncompressed");
-    }
-
-    requestBody = CommonUtils.decodeUTF8(requestBody);
-
-    this._log.debug("HTTP request body: " + requestBody);
-
-    let doc;
-    try {
-      doc = JSON.parse(requestBody);
-    } catch(ex) {
-      this._log.info("JSON parse error.");
-      throw HTTP_400;
-    }
-
-    this.namespaces[namespace][id] = doc;
-
-    if (request.hasHeader("X-Obsolete-Document")) {
-      let obsolete = request.getHeader("X-Obsolete-Document");
-      this._log.info("Deleting from X-Obsolete-Document header: " + obsolete);
-      for (let obsolete_id of obsolete.split(",")) {
-        delete this.namespaces[namespace][obsolete_id];
-      }
-    }
-
-    response.setStatusLine(request.httpVersion, 201, "Created");
-    response.setHeader("Content-Type", "text/plain");
-
-    let body = id;
-    response.bodyOutputStream.write(body, body.length);
-  },
-
-  _handleNamespaceSubmitDelete:
-    function _handleNamespaceSubmitDelete(namespace, id, request, response) {
-
-    delete this.namespaces[namespace][id];
-
-    let body = id;
-    response.bodyOutputStream.write(body, body.length);
-  },
-};
-
-Object.freeze(BagheeraServer.prototype);
--- a/services/common/moz.build
+++ b/services/common/moz.build
@@ -26,24 +26,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'andr
         'hawkrequest.js',
         'tokenserverclient.js',
     ]
 
     TESTING_JS_MODULES.services.common += [
         'modules-testing/storageserver.js',
     ]
 
-    if CONFIG['MOZ_SERVICES_HEALTHREPORT']:
-        EXTRA_PP_JS_MODULES['services-common'] += [
-            'bagheeraclient.js',
-        ]
-        TESTING_JS_MODULES.services.common += [
-            'modules-testing/bagheeraserver.js',
-        ]
-
 EXTRA_PP_JS_MODULES['services-common'] += [
     'async.js',
     'observers.js',
     'rest.js',
 ]
 
 TESTING_JS_MODULES.services.common += [
     'modules-testing/logging.js',
--- a/services/common/tests/mach_commands.py
+++ b/services/common/tests/mach_commands.py
@@ -29,17 +29,16 @@ from tempfile import mkdtemp
 
 
 DEFAULT_PORT = 8080
 DEFAULT_HOSTNAME = 'localhost'
 
 SRCDIR = mozpath.abspath(mozpath.dirname(__file__))
 
 STORAGE_SERVER_SCRIPT = mozpath.join(SRCDIR, 'run_storage_server.js')
-BAGHEERA_SERVER_SCRIPT = mozpath.join(SRCDIR, 'run_bagheera_server.js')
 
 def SyncStorageCommand(func):
     """Decorator that adds shared command arguments to services commands."""
 
     port = CommandArgument('--port', metavar='PORT', type=int,
                            default=DEFAULT_PORT, help='Port to run server on.')
     func = port(func)
 
@@ -105,13 +104,8 @@ class SyncTestCommands(MachCommandBase):
             print 'Removing profile directory %s' % profile_dir
             rmtree(profile_dir)
 
     @Command('storage-server', category='services',
              description='Run a storage server.')
     @SyncStorageCommand
     def run_storage_server(self, port=DEFAULT_PORT, address=DEFAULT_HOSTNAME):
         exit(self.run_server(STORAGE_SERVER_SCRIPT, address, port))
-
-    @Command('bagheera-server', category='services',
-             description='Run a bagheera server.')
-    def run_bagheera_server(self, port=DEFAULT_PORT, address=DEFAULT_HOSTNAME):
-        exit(self.run_server(BAGHEERA_SERVER_SCRIPT, address, port))
deleted file mode 100644
--- a/services/common/tests/run_bagheera_server.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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/. */
-
-/**
- * This file runs a stub Bagheera server.
- *
- * It is meant to be executed with an xpcshell.
- *
- * The Makefile in this directory contains a target to run it:
- *
- *   $ make bagheera-server
- */
-
-Cu.import("resource://testing-common/services/common/bagheeraserver.js");
-
-initTestLogging();
-
-var server = new BagheeraServer();
-server.allowAllNamespaces = true;
-server.start(SERVER_PORT);
-_("Bagheera server started on port " + SERVER_PORT);
-
-// Launch the thread manager.
-_do_main();
-
deleted file mode 100644
--- a/services/common/tests/unit/test_bagheera_client.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://services-common/bagheeraclient.js");
-Cu.import("resource://services-common/rest.js");
-Cu.import("resource://testing-common/services/common/bagheeraserver.js");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-function getClientAndServer() {
-  let server = new BagheeraServer();
-  server.start();
-
-  let client = new BagheeraClient(server.serverURI);
-
-  return [client, server];
-}
-
-function run_test() {
-  initTestLogging("Trace");
-  run_next_test();
-}
-
-add_test(function test_constructor() {
-  let client = new BagheeraClient("http://localhost:1234/");
-
-  run_next_test();
-});
-
-add_test(function test_post_json_transport_failure() {
-  let client = new BagheeraClient("http://localhost:1234/");
-
-  client.uploadJSON("foo", "bar", {}).then(function onResult(result) {
-    do_check_false(result.transportSuccess);
-
-    run_next_test();
-  });
-});
-
-add_test(function test_post_json_simple() {
-  let [client, server] = getClientAndServer();
-
-  server.createNamespace("foo");
-  let promise = client.uploadJSON("foo", "bar", {foo: "bar", biz: "baz"});
-
-  promise.then(function onSuccess(result) {
-    do_check_true(result instanceof BagheeraClientRequestResult);
-    do_check_true(result.request instanceof RESTRequest);
-    do_check_true(result.transportSuccess);
-    do_check_true(result.serverSuccess);
-
-    server.stop(run_next_test);
-  }, do_check_null);
-});
-
-add_test(function test_post_json_bad_data() {
-  let [client, server] = getClientAndServer();
-
-  server.createNamespace("foo");
-
-  client.uploadJSON("foo", "bar", "{this is invalid json}").then(
-    function onResult(result) {
-    do_check_true(result.transportSuccess);
-    do_check_false(result.serverSuccess);
-
-    server.stop(run_next_test);
-  });
-});
-
-add_task(function* test_unicode_payload() {
-  let [client, server] = getClientAndServer();
-  server.createNamespace("foo");
-
-  const EXPECTED = "πόλλ' οἶδ' ἀλώπηξ, ἀλλ' ἐχῖνος ἓν μέγα";
-
-  let result = yield client.uploadJSON("foo", "bar", {test: EXPECTED});
-  Assert.ok(result.transportSuccess);
-  Assert.ok(result.serverSuccess);
-
-  let p = server.getDocument("foo", "bar");
-  Assert.equal(p.test, EXPECTED);
-
-  result = yield client.uploadJSON("foo", "baz", JSON.stringify({test: EXPECTED}));
-  Assert.ok(result.transportSuccess);
-  Assert.ok(result.serverSuccess);
-  p = server.getDocument("foo", "baz");
-  Assert.equal(p.test, EXPECTED);
-
-  let deferred = Promise.defer();
-  server.stop(() => deferred.resolve());
-  yield deferred.promise;
-});
-
-add_task(function test_post_delete_multiple_obsolete_documents () {
-  let [client, server] = getClientAndServer();
-  let namespace = "foo";
-  let documents = [
-    [namespace, "one", "{v:1}"],
-    [namespace, "two", "{v:2}"],
-    [namespace, "three", "{v:3}"],
-    [namespace, "four", "{v:4}"],
-  ];
-
-  try {
-    // create initial documents
-    server.createNamespace(namespace);
-    for (let [ns, id, payload] of documents) {
-      server.setDocument(ns, id, payload);
-      do_check_true(server.hasDocument(ns, id));
-    }
-
-    // Test uploading with deleting some documents.
-    let deleteIDs = [0, 1].map((no) => { return documents[no][1]; });
-    let result = yield client.uploadJSON(namespace, "new-1", {foo: "bar"}, {deleteIDs: deleteIDs});
-    do_check_true(result.transportSuccess);
-    do_check_true(result.serverSuccess);
-    do_check_true(server.hasDocument(namespace, "new-1"));
-    for (let id of deleteIDs) {
-      do_check_false(server.hasDocument(namespace, id));
-    }
-    // Check if the documents that were not staged for deletion are still there.
-    for (let [,id,] of documents) {
-      if (deleteIDs.indexOf(id) == -1) {
-        do_check_true(server.hasDocument(namespace, id));
-      }
-    }
-
-    // Test upload without deleting documents.
-    let ids = Object.keys(server.namespaces[namespace]);
-    result = yield client.uploadJSON(namespace, "new-2", {foo: "bar"});
-    do_check_true(result.transportSuccess);
-    do_check_true(result.serverSuccess);
-    do_check_true(server.hasDocument(namespace, "new-2"));
-    // Check to see if all the original documents are still there.
-    for (let id of ids) {
-      do_check_true(deleteIDs.indexOf(id) !== -1 || server.hasDocument(namespace, id));
-    }
-  } finally {
-    let deferred = Promise.defer();
-    server.stop(deferred.resolve.bind(deferred));
-    yield deferred.promise;
-  }
-});
-
-add_test(function test_delete_document() {
-  let [client, server] = getClientAndServer();
-
-  server.createNamespace("foo");
-  server.setDocument("foo", "bar", "{}");
-
-  client.deleteDocument("foo", "bar").then(function onResult(result) {
-    do_check_true(result.transportSuccess);
-    do_check_true(result.serverSuccess);
-
-    do_check_null(server.getDocument("foo", "bar"));
-
-    server.stop(run_next_test);
-  });
-});
deleted file mode 100644
--- a/services/common/tests/unit/test_bagheera_server.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://testing-common/services/common/bagheeraserver.js");
-
-function run_test() {
-  run_next_test();
-}
-
-add_test(function test_server_empty() {
-  let server = new BagheeraServer();
-
-  do_check_false(server.hasNamespace("foo"));
-  do_check_false(server.hasDocument("foo", "bar"));
-  do_check_null(server.getDocument("foo", "bar"));
-
-  server.createNamespace("foo");
-  do_check_true(server.hasNamespace("foo"));
-
-  run_next_test();
-});
-
-add_test(function test_server_start() {
-  let server = new BagheeraServer();
-  server.start();
-  server.stop(run_next_test);
-});
-
--- a/services/common/tests/unit/test_load_modules.js
+++ b/services/common/tests/unit/test_load_modules.js
@@ -11,33 +11,25 @@ const shared_modules = [
   "stringbundle.js",
   "utils.js",
 ];
 
 const non_android_modules = [
   "tokenserverclient.js",
 ];
 
-const non_android_healthreport_modules = [
-  "bagheeraclient.js",
-];
-
 const TEST_BASE = "resource://testing-common/services/common/";
 const shared_test_modules = [
   "logging.js",
 ];
 
 const non_android_test_modules = [
   "storageserver.js",
 ];
 
-const non_android_healthreport_test_modules = [
-  "bagheeraserver.js",
-];
-
 function expectImportsToSucceed(mm, base=MODULE_BASE) {
   for (let m of mm) {
     let resource = base + m;
     let succeeded = false;
     try {
       Components.utils.import(resource, {});
       succeeded = true;
     } catch (e) {}
@@ -65,19 +57,13 @@ function expectImportsToFail(mm, base=MO
 
 function run_test() {
   expectImportsToSucceed(shared_modules);
   expectImportsToSucceed(shared_test_modules, TEST_BASE);
 
   if (AppConstants.platform != "android") {
     expectImportsToSucceed(non_android_modules);
     expectImportsToSucceed(non_android_test_modules, TEST_BASE);
-    if (AppConstants.MOZ_SERVICES_HEALTHREPORT) {
-      expectImportsToSucceed(non_android_healthreport_modules);
-      expectImportsToSucceed(non_android_healthreport_test_modules, TEST_BASE);
-    }
   } else {
     expectImportsToFail(non_android_modules);
     expectImportsToFail(non_android_test_modules, TEST_BASE);
-    expectImportsToFail(non_android_healthreport_modules);
-    expectImportsToFail(non_android_healthreport_test_modules, TEST_BASE);
   }
 }
--- a/services/common/tests/unit/xpcshell.ini
+++ b/services/common/tests/unit/xpcshell.ini
@@ -24,22 +24,16 @@ support-files =
 [test_utils_namedTimer.js]
 [test_utils_sets.js]
 [test_utils_utf8.js]
 [test_utils_uuid.js]
 
 [test_async_chain.js]
 [test_async_querySpinningly.js]
 
-[test_bagheera_server.js]
-skip-if = (os == "android" || !healthreport)
-
-[test_bagheera_client.js]
-skip-if = (os == "android" || !healthreport)
-
 [test_hawkclient.js]
 skip-if = os == "android"
 [test_hawkrequest.js]
 skip-if = os == "android"
 
 [test_logmanager.js]
 [test_observers.js]
 [test_restrequest.js]